I'm using dotCover to analyze code coverage of my unit tests, and I'm getting some strange results... I have an iterator method for which the coverage is not complete, but the statements that are not covered are just the closing braces at the end of the method.
Here's the method I'm testing:
public static IEnumerable<T> CommonPrefix<T>(
this IEnumerable<T> source,
IEnumerable<T> other,
IEqualityComparer<T> comparer)
{
source.CheckArgumentNull("source");
other.CheckArgumentNull("other");
return source.CommonPrefixImpl(other, comparer);
}
private static IEnumerable<T> CommonPrefixImpl<T>(
this IEnumerable<T> source,
IEnumerable<T> other,
IEqualityComparer<T> comparer)
{
comparer = comparer ?? EqualityComparer<T>.Default;
using (IEnumerator<T> en1 = source.GetEnumerator(),
en2 = other.GetEnumerator())
{
while (en1.MoveNext() && en2.MoveNext())
{
if (comparer.Equals(en1.Current, en2.Current))
yield return en1.Current;
else
yield break;
}
} // not covered
} // not covered
The unit test:
[Test]
public void Test_CommonPrefix_SpecificComparer()
{
var first = new[] { "Foo", "Bar", "Baz", "Titi", "Tata", "Toto" };
var second = new[] { "FOO", "bAR", "baz", "tata", "Toto" };
var expected = new[] { "Foo", "Bar", "Baz" };
var actual = first.CommonPrefix(second, StringComparer.CurrentCultureIgnoreCase);
Assert.That(actual, Is.EquivalentTo(expected));
}
And the coverage results:
I assume the closing brace of the using
block is actually the calls to Dispose
on the enumerators; but then, why is it not executed? I first suspected that NUnit wasn't disposing the enumerators, but I get the same result if I do a foreach on actual
.
As for the second uncovered closing brace, I have no idea what it stands for... I guess it's related to how the compiler transforms the iterator block.
Can anyone shed some light on what these two "statements" are, and why they are not executed ?
EDIT: Peter raised a very good question: the results shown above were obtained when running the tests on a debug build. If I run the tests on a release build, coverage of the CommonPrefixImpl
method is 100%, so it's probably related to compiler optimizations.