R#5 Unit Test-Classes and Method should not marked as never used

Hi,

the topic says it all ;)

Unit Test-Classes and Method should not marked as never used

Regards


Albert


0
12 comments
Avatar
Andrey Serebryansky

Hello Albert
     Which unit testing framework do you use?

Andrey Serebryansky

Support Engineer

JetBrains, Inc

http://www.jetbrains.com

"Develop with pleasure!"
0

Hello Andrey,

Hello Albert
Which unit testing framework do you use?


xUnit & VS2010

Regards

Albert


0
Avatar
Andrey Serebryansky

Hello Albert
     By default, ReSharper doesn't know that methods/types marked with xUnit attributes are meant to be used elsewhere. In order to avoid this behavior, you can provide external annotations for xUnit attributes in the same way as it's done for NUnit attributes. For an example, please take a look at <ReSharper Install Dir>\Bin\ExternalAnnotations\NUnit.Framework.xml file.

Andrey Serebryansky

Support Engineer

JetBrains, Inc

http://www.jetbrains.com

"Develop with pleasure!"
0

Hello,

I suppose Albert may be using xunit plugin for ReSharper, and in this case
xunit plugin should respond to IsUnitTestElement calls, which are used in
analysis.

Sincerely,
Ilya Ryzhenkov

JetBrains, Inc
http://www.jetbrains.com
"Develop with pleasure!"


IR> Hello Albert
IR> By default, ReSharper doesn't know that methods/types marked
IR> with xUnit attributes are meant to be used elsewhere. In order to
IR> avoid this behavior, you can provide external annotations for xUnit
IR> attributes in the same way as it's done for NUnit attributes. For an
IR> example, please take a look at  http://www.jetbrains.net/devnet/message/5248514#5248514


0

Hello Ilya,

Hello,

I suppose Albert may be using xunit plugin for ReSharper, and in this
case xunit plugin should respond to IsUnitTestElement calls, which are
used in analysis.


Yes. I'm using the PlugIin, the TestCases are known by R#5 because R#
displays is at Unit Tests an i can run the test with R#. In my eyes, that
should be enough Information for R# ;)

On they other side, xUnit doesnot have a attribute for classes to declare
it as a test class, it has only attributes for test methods.

Regards

Albert


Sincerely,
Ilya Ryzhenkov
JetBrains, Inc
http://www.jetbrains.com
"Develop with pleasure!"


IR>> Hello Albert
IR>> By default, ReSharper doesn't know that methods/types marked
IR>> with xUnit attributes are meant to be used elsewhere. In order to
IR>> avoid this behavior, you can provide external annotations for xUnit
IR>> attributes in the same way as it's done for NUnit attributes. For


0

Brilliant. I've spent the last few days trying to figure out how nunit had this working, and why the xunit plugin wasn't working. Didn't think of checking external annotations.

To jump straight to the point - I've just uploaded a new build of the plugin that works with this:

http://xunitcontrib.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=35006

Now we've got that out of the way...

The external annotations method won't work for the xunit plugin because:

1) there is no class level attribute, meaning classes would still be marked as unused

2) it won't work for custom Fact or Theory based attributes

3) it won't work for nested test classes

So, I've created a class that implements IUsageInspectionsSupressor (and is marked with UsageInspectionsSupressorAttribute), and made that call UnitTestManager.IsUnitTestElement. This is quite a nice, easy solution for me, in that my IUnitTestProvider.IsUnitTestElement method simply needs to call IsUnitTest, IsUnitTestContainer and then recurse up through any parent containing classes, and I'm done - and it does work very nicely. I have two concerns:

1) I don't know if IsUnitTestElement should really be returning true for an element that isn't *strictly* a unit test element (i.e. the parent class of a nested test class). I think it's ok, but you guys would know for sure

2) I think this is something that should be part of ReSharper. By calling UnitTestManager.IsUnitTestElement, I'm asking all unit test providers if that element is related to a unit test or not - so it would work for nunit and mstest, if they didn't have the external annotations. Are there any plans to incorporate it?


Thanks

Matt

0

I've just checked with ReSharper 4.5 and the class that used to call IsUnitTestStuff has been removed, replaced with attribute annotations for nunit and mstest. I've essentially added the class back into the xunit plugin - would it not be better if it were added back to ReSharper?

Thanks

Matt

0

Hi Matt,

sorry for confusion, we are refactoring Unit Test Support in ReSharper to improve its perfomance and in order to find better way of communication between different subsystems.

As you noticed we've changed default way of suppressing usage  inspections: now its done via external annotations, like for other  features.

So we decided to remove IsUnitTest* methods and replace them with single one: IsElementOfKind(IDeclaredElement, UnitTestElementKind)
UnitTestElementKind is a new enum, introduced in build 1530.

Having such single method for identifing IDeclaredElement as unit-test-related-entity will improve readability of code, perfomance (there are some optimizations in UnitTestManager) and API stability.

In your case, I suggest you to create XUnitUsageInspectionsSuppressor and suppress inspections of XUnit-related types and methods. If possible please use external annotations, it's simply faster.

Sorry for the inconvinience with all that, its still WIP. Don't hesitate to contact me, if you need additional details about  UnitTesting framework in ReSharper.

0

No problem. It makes it more interesting being on the bleeding edge. I'm well aware that things may change and break, and that's absolutely fine - I'll be trying to track the changes and keep as up to date as I can.

I've got build 1530, and have made (most of) the necessary changes. Turns out that I can use the external annotations for test methods, and since custom test method attributes all derive from the one in the external annotations file, all custom test methods are handled as well. Hooray! Test classes are not, though, so I still need to use a custom suppressor - and it also lets me support nested classes and properties that provide test data for parameterised tests (via the PropertyDataAttribute). I just need to make it xunit specific, rather than just going through the UnitTestManager, before I can get a new release out - probably tomorrow.

Cheers!
Matt

0

Just to confirm, are external annotations necessary?  Gallio has no way of providing annotations for all test frameworks it supports so there needs to be a programmatic alternative for most declarative abstractions.

0

It can definitely be done through code, and it's very easy. I'm going to use a mixture of annotations and code for xunitcontrib - the annotations just provide a short-circuit to prevent calling into code, so as Victor says, it's an optimisation, but I can't do everything through annotations.

Here's the code I was using (I still need to specialise it to xunit, but that'll be easy):

    [UsageInspectionsSupressor]
    public class SuppressUnusedUnitTestElements : IUsageInspectionsSupressor
    {
        public bool SupressUsageInspectionsOnElement(IDeclaredElement element)
        {
            return UnitTestManager.GetInstance(SolutionManager.Instance.CurrentSolution).IsElementOfKind(element, UnitTestElementKind.TestStuff);
        }
    }

Cheers

Matt

0

I think this code is a little dangerous because it could end up asking all Unit Test Providers for the kind of element.  If each provider came bundled with a similar suppressor of this sort then we could potentially do a lot of redundant work.

I think this suppression mechanism or something equivalent with better performance should be baked into R#.

0

Please sign in to leave a comment.