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.
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.
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
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.
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
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:
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?
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?
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.
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.
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.
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); } }
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#.
Hello Albert
Which unit testing framework do you use?
Andrey Serebryansky
Support Engineer
JetBrains, Inc
http://www.jetbrains.com
"Develop with pleasure!"Hello Andrey,
xUnit & VS2010
Regards
Albert
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!"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
Hello Ilya,
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
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
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
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
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.
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
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.
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
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#.