Welcome Guest! To enable all features please Login or Register.

Notification

Icon
Error

NCrunch not detecting covered code when using TestCaseSource in NUnit
mpetter
#1 Posted : Friday, September 14, 2012 6:32:58 PM(UTC)
Rank: Newbie

Groups: Registered
Joined: 9/14/2012(UTC)
Posts: 4
Location: St. Louis

Thanks: 1 times
Was thanked: 1 time(s) in 1 post(s)
I am using NCrunch 1.41 in Visual Studio 2012, and I am having an issue with NCrunch's code coverage metrics.

This is only happening when specifying a TestCaseSource in NUnit. I am using a TestCaseSource that points to a method that returns an IEnumerable of arguments for a single-argument test method.

It is not detecting code coverage for all lines even when they are obviously covered by TestCaseSource tests and can be easily debugged to prove that they are.

What's even stranger is that the coverage for TestCaseSource tests seems almost random... in fact sometimes just switching the order of tests returned by the TestCaseSource method will alter the coverage results, which logically makes no sense.

This is almost certainly a bug.
mpetter
#2 Posted : Friday, September 14, 2012 8:15:39 PM(UTC)
Rank: Newbie

Groups: Registered
Joined: 9/14/2012(UTC)
Posts: 4
Location: St. Louis

Thanks: 1 times
Was thanked: 1 time(s) in 1 post(s)
Found more detail. It apparently has to do with when a complex object is used in the enumerable as a TestCaseSource vs. using a primitive object. Not sure why this is, but I managed to create a reduced example that clearly demonstrates the issue happening.

http://petterisbetter.co...dia/CodeCoverageBug.zip

In my example, Something1/Something1Tests and Something2/Something2Tests are parallel cases. The only difference is that in Something2Tests, a container object is used instead of a primitive for the test data, but the results in code coverage are dramatically different!

Remco
#3 Posted : Saturday, September 15, 2012 12:05:47 AM(UTC)
Rank: NCrunch Developer

Groups: Administrators
Joined: 4/16/2011(UTC)
Posts: 6,996

Thanks: 932 times
Was thanked: 1258 time(s) in 1171 post(s)
Hi, thanks for posting! I appreciate the effort you've gone through to provide a code sample - this was enormously helpful in analysing the problem.

From a certain perspective this could certainly be considered a bug, although I'm not sure if there is a feasible long term fix for it, as even the best approach to a problem like this would create a certain level of ambiguity.

Essentially the use of your container object in the TestCaseSource is causing two tests to be created under the same name. When attempting to create names for the tests, NUnit is performing a ToString() against your TestCase class. Because there is no variation between the test names, NCrunch automatically disregards the duplicates and does not 'discover' all the actual test cases.

NCrunch currently does not support working with multiple tests that exist under the same name. The reason for has been mostly because of implementation difficulty, but also because having two tests under the same name is actually a serious real-world problem that can create a world of confusion for both tools and developers. I'm willing to accept that perhaps a better solution would be to display a warning or error message of some kind making this behaviour clearer.

In your specific case, I suggest implementing a ToString() override on your TestCase class that returns a value derived from the fields in the class (i.e. the 'Value' property). When I did this in your code sample, the extra test case was discovered without problems and everything was functioning normally.

I hope this helps!


Cheers,

Remco
1 user thanked Remco for this useful post.
mpetter on 9/17/2012(UTC)
mpetter
#4 Posted : Monday, September 17, 2012 2:48:06 PM(UTC)
Rank: Newbie

Groups: Registered
Joined: 9/14/2012(UTC)
Posts: 4
Location: St. Louis

Thanks: 1 times
Was thanked: 1 time(s) in 1 post(s)
Thanks for the quick response! Knowing the root cause will definitely help in writing tests that will not again cause this issue.

However, I think it's important to note that if you view this behavior as by design (even with a warning), you are creating an important (and probably undesirable) difference in the way NCrunch processes tests as compared to Visual Studio with NUnit. If you run all tests via Visual Studio 2012 (with the NUnit Test Runner extension) in the example solution I sent you, you can see that it does in fact run all four tests, even the two with the same name. It will show three passed root tests in the Test Explorer, and if you click on "Method1Test(CodeCoverageBug.Tests.Something2Tests+TestCase)", you will see the two distinct results in the detail view. Visual Studio will thus have different code coverage results as well.

I implicitly assumed that NCrunch would have the same behavior as NUnit unless otherwise specified by me in some way. I would think that to be true of most developers. I would say an obvious warning is an absolute must at minimum, although I myself would certainly prefer behavior to be implicitly consistent with NUnit. :)

-Michael

P.S. - Since this is my first set of posts, let me also say "thank you" for the great tool and the efforts you've put into it! You've done great work!
Remco
#5 Posted : Monday, September 17, 2012 9:01:30 PM(UTC)
Rank: NCrunch Developer

Groups: Administrators
Joined: 4/16/2011(UTC)
Posts: 6,996

Thanks: 932 times
Was thanked: 1258 time(s) in 1171 post(s)
Thanks for the feedback on this. It's definitely a goal to try and align NCrunch as closely as possible with the normal behaviour of the testing frameworks it implements with, so you are 100% correct that the current implementation does not exhibit intuitive behaviour and thus is undesirable.

However, as with any software application, there are always trade-offs that need to be made between features/compatibility and complexity. Supporting multiple tests with the same physical name is one of those problems that would require massive effort to implement reliably, although would only improve the experience for a small minority of users. Compared with say, a feature that could take half the implementation time and reduce engine execution time by 20% (which would impact ALL users of NCrunch), it can be hard to justify spending time on 100% alignment with NUnit (I'm happy with 99%!).

So I guess in summary, you've convinced me. I'm just not certain that it'll ever make sense to completely fix this.

Thanks again for reporting the issue and I'm glad your enjoying NCrunch!


Cheers,

Remco
mpetter
#6 Posted : Monday, September 17, 2012 10:01:10 PM(UTC)
Rank: Newbie

Groups: Registered
Joined: 9/14/2012(UTC)
Posts: 4
Location: St. Louis

Thanks: 1 times
Was thanked: 1 time(s) in 1 post(s)
I work in Agile software development myself, so I get it. I only wanted to make sure it gets onto your backlog... priority is at your discretion, of course! :)
1 user thanked mpetter for this useful post.
Remco on 9/18/2012(UTC)
CoolBreeze
#7 Posted : Friday, May 15, 2015 6:35:05 PM(UTC)
Rank: Advanced Member

Groups: Registered
Joined: 7/11/2014(UTC)
Posts: 79
Location: United States of America

Was thanked: 9 time(s) in 9 post(s)
I just ran into the same problem.

I noticed a class wasn't getting 100% code coverage by a test so I decided to update the test to bring the code coverage up to 100%.

I wrote a test which used NUnit TestCaseSource. I created a test data class and a test factory method. The test factory method created and populated instances of the test data class and returned the list to caller.

The test function used test values from test data class to pass to the code unit under test and used values in the test data class with asserts to determine if the unit code under test performed the expected actions.

I noticed NCrunch wasn't identifying all the code lines that should have been executed by all the test cases.

I created a simple example code and related test code sample using TestCase versus TestCaseSource. I then ran the tests both ways. And indeed the
code coverage was 87.5% when using TestCase and 62.5% when using TestCaseSource. The code coverage icons showed up only on the lines in the unit code
tested by the last item in the list of test cases for the TestCaseSource usage.

Of course, I thought this was a bug and decided to post my discovery and code samples.

But I see someone has already discovered and written about this problem.

For the short term I'll override the ToString function as suggested.

My unit code methods frequently work with data classes with 20+ properties. So for me it's easier to create a test case factory method and use
TestCaseSource. So I'm putting in my vote for NCunch to correctly compute the code coverage stats in this case or at least give a warning.

On the one hand it was puzzling to run into this problem. On the other hand I do understand the complexity of trying to design code to handle the TestCaseSource
case correctly for code coverage statistics.

Thanks,

Ed
CoolBreeze
#8 Posted : Friday, May 15, 2015 7:29:59 PM(UTC)
Rank: Advanced Member

Groups: Registered
Joined: 7/11/2014(UTC)
Posts: 79
Location: United States of America

Was thanked: 9 time(s) in 9 post(s)
Here's my idea for overriding ToString():


Pass a test description to the test class in the constructor, save it in a member variable, and in ToString()
return the test description.

This option has two benefits:

1) NCrunch shows the test description in the NCrunch Tests window. The developer can know the purpose for each test.
2) NCrunch will correctly compute the code coverage statistics (assuming the developer supplied a different TestDescription for each test case)


Public Class TestData

Private m_TestDescription As String

Public Sub New(TestDescription As String)
m_TestDescription = TestDescription
End Sub

Public Overrides Function ToString()
Return m_TestDescription
End Function
End Class

Perhaps make a base class with these functions. When creating test data classes inherit from the base class and you're all set.


Possible enhancement:

In ToString()

If m_TestDescription is null or blank then return a mono-tonically increasing value.

Thanks, Ed
1 user thanked CoolBreeze for this useful post.
Remco on 5/15/2015(UTC)
Users browsing this topic
Guest
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.

YAF | YAF © 2003-2011, Yet Another Forum.NET
This page was generated in 0.065 seconds.
Trial NCrunch
Take NCrunch for a spin
Do your fingers a favour and supercharge your testing workflow
Free Download