oxm*_*man 3 c# asp.net visual-studio-2010 opencover
我有一个简单的方法可以计算集合中的总数。
public void MethodToTest(Collection<int> collection)
{
int sum = 0;
foreach (int value in collection)
{
sum += value;
}
}
Run Code Online (Sandbox Code Playgroud)
目标是使用在命令行中运行的opencoverage工具获得100%的分支覆盖率。我还得到了一个调用方法MethodToTest的单元测试:
[TestMethod]
public void TestMethodToTest()
{
BomProviderMock mock = new BomProviderMock();
BomManager bomManager = new BomManager(mock);
List<int> list = new List<int>();
for (int i = 0; i <= Int16.MaxValue; i++)
{
list.Add(i);
}
// Firts attempt with a non empty collection
bomManager.MethodToTest(new Collection<int>(list));
// Second attempt with an empty collection
bomManager.MethodToTest(new Collection<int>());
}
Run Code Online (Sandbox Code Playgroud)
使用工具opencover之后,MethodToTest方法的分支覆盖率达到80%。我的问题是,foreach循环是否会影响分支覆盖率,如果是,那么如何使用此简单代码获得100%的收益?
正如[原始]接受的答案指出,您的实际情况减少到 collection.Sum()但是您将无法每次都摆脱掉。
如果我们使用TDD来开发此功能(我同意但容易解释的过大杀伤力),我们将[可能]执行以下操作(在本示例中,我也不希望使用NUnit)
[Test]
public void Sum_Is_Zero_When_No_Entries()
{
var bomManager = new BomManager();
Assert.AreEqual(0, bomManager.MethodToTest(new Collection<int>()));
}
Run Code Online (Sandbox Code Playgroud)
然后编写以下代码(注意:我们编写满足当前测试集的最低要求)
public int MethodToTest(Collection<int> collection)
{
var sum = 0;
return sum;
}
Run Code Online (Sandbox Code Playgroud)
然后,我们将编写一个新的测试,例如
[Test]
[TestCase(new[] { 0 }, 0)]
public void Sum_Is_Calculated_Correctly_When_Entries_Supplied(int[] data, int expected)
{
var bomManager = new BomManager();
Assert.AreEqual(expected, bomManager.MethodToTest(new Collection<int>(data)));
}
Run Code Online (Sandbox Code Playgroud)
如果我们运行测试,它们都将通过(绿色),因此我们需要一个新的测试(案例)
[TestCase(new[] { 1 }, 1)]
[TestCase(new[] { 1, 2, 3 }, 6)]
Run Code Online (Sandbox Code Playgroud)
为了满足那些测试,我需要修改我的代码,例如
public int MethodToTest(Collection<int> collection)
{
var sum = 0;
foreach (var value in collection)
{
sum += value;
}
return sum;
}
Run Code Online (Sandbox Code Playgroud)
现在我所有的测试工作正常,并且如果我通过opencover运行该测试,我将获得100%的序列和分支覆盖率-Hurrah!....我这样做的时候没有使用覆盖率作为控件,而是编写了正确的测试来支持我的代码。
但是有一个“可能的”缺陷……如果我通过了该null怎么办?是时候进行新的测试了
[Test]
public void Sum_Is_Zero_When_Null_Collection()
{
var bomManager = new BomManager();
Assert.AreEqual(0, bomManager.MethodToTest(null));
}
Run Code Online (Sandbox Code Playgroud)
测试失败,因此我们需要更新代码,例如
public int MethodToTest(Collection<int> collection)
{
var sum = 0;
if (collection != null)
{
foreach (var value in collection)
{
sum += value;
}
}
return sum;
}
Run Code Online (Sandbox Code Playgroud)
现在,我们有支持代码的测试,而不是支持代码的测试,即我们的测试不在乎编写代码的方式。
现在我们有一组很好的测试,因此我们现在可以安全地重构代码,例如
public int MethodToTest(IEnumerable<int> collection)
{
return (collection ?? new int[0]).Sum();
}
Run Code Online (Sandbox Code Playgroud)
我这样做并没有影响任何现有测试。
我希望这有帮助。