我想知道某人应该如何使用Assert.Inconclusive()。
我正在使用它,如果我的单元测试即将失败的原因不是测试的目的。
例如,我在一个类上有一个方法来计算一个int数组的总和。在同一个类中,还有一种计算元素平均值的方法。它通过调用sum并将其除以数组的长度来实现。
为Sum()编写单元测试很简单。但是,当我为Average()编写测试时,Sum()失败,那么Average()也可能会失败。
平均值的失败并未明确失败的原因;它失败的原因不是它应该测试的原因。这就是为什么我会检查Sum()是否返回正确的结果,否则我是Assert.Inconclusive()。
这是否被视为良好做法?什么是Assert.Inconclusive用于?或者我应该通过隔离框架来解决前面的例子?
答案 0 :(得分:24)
不确定性测试是一种无法确定结果的测试。例如,如果您的测试使用某种外部资源(例如,Internet连接),该怎么办?如果连接当前不可用,这并不意味着测试失败。另一方面,您不应该只是在没有实际运行的情况下将其标记为成功。因此,您将其标记为不确定,这可以在测试报告中看到。
注意:通常,您不应在测试中使用此类外部资源,因为这会使测试变得脆弱。
对于尚未完成的测试,我使用MbUnit的Explicit
属性。
答案 1 :(得分:15)
当我使用VS生成单元测试时,我得到Assert.Inclusive用于生成的测试方法,并且通常我更改断言以便在我工作时使用其他东西。我在测试结果中使用Assert.Inconclusive的问号作为标记,快速告诉我哪些测试还没有完成。
嗯,这就是我使用它的方式。从它的名字“Inconclusive”,我想你可以用来表明你的不确定状态,只要你记录它的含义。
但是,根据您的Average()
方法的描述,我认为您的单元测试可能不足以覆盖一个“单元”,一个特定情况。有时,我为单个方法编写2或3个单元测试方法。或者,您可以将Average()
方法分解为涵盖单一职责的较小方法。这样,您可以在单元测试Average()
之前对这些较小的方法进行单元测试。
约翰,
这是我实施Sum()
和Average()
方法的方法。
public static class MyMath
{
private static void ValidateInput(ICollection<int> numbers)
{
if (numbers == null)
throw new ArgumentNullException("numbers", "Null input. Nothing to compute!");
if (numbers.Count == 0)
throw new ArgumentException("Input is empty. Nothing to compute!");
}
public static int Sum(int[] numbers)
{
ValidateInput(numbers);
var total = 0;
foreach (var number in numbers)
total += number;
return total;
}
public static double Average(int[] numbers)
{
ValidateInput(numbers);
return Sum(numbers) / numbers.Length;
}
}
为简单起见,我只是从ArgumentException
方法中抛出ValidateInput(ICollection<int>)
个例外。您还可以检查溢出的可能性,并在OverflowException
方法中抛出ValidateInput(ICollection<int>)
。
话虽如此,这是我如何测试Average(int[])
函数。
[TestMethod]
public void AverageTest_GoodInput()
{
int[] numbers = {1, 2, 3};
const double expected = 2.0;
var actual = MyMath.Average(numbers);
Assert.AreEqual(expected, actual);
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void AverageTest_NullInput()
{
int[] numbers = null;
MyMath.Average(numbers);
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void AverageTest_EmptyInput()
{
var numbers = new int[0];
MyMath.Average(numbers);
}
通过这些测试设置,我可以确定当所有测试通过时,我的功能是正确的。好吧,除了溢出的情况。现在我可以回到ValidateInput(ICollection<int>)
方法添加逻辑来检查溢出,然后再添加一个测试以期望OverflowException
引发导致溢出的输入类型。如果您想使用TDD,请按相反的顺序执行此操作。
我希望这有助于澄清这个想法。
答案 2 :(得分:9)
我只是Assert.Inconclusive单元测试我尚未编写。有时在写东西的时候我会发现一些我不想错过的角落。所以我快速跳过,用描述性名称编写测试方法并添加一行Assert.Inconclusive。
这样做的原因是它提供了我需要测试的内容的文档,而不会过多地中断我的工作流程。它还可以在结果列表中快速过滤掉测试失败。有一个不确定的失败意味着我没有破坏任何我只是更多的测试编写。
答案 3 :(得分:7)
Assert.Inconclusive表示:
我还没有编写测试;我只创建了测试方法
-OR -
我的测试有一个依赖项,并且该依赖项不可用。例如
List<Customer> custs = o.GetAllCustomers();
if (custs.Count == 0)
{
Assert.Inconclusive("No customers to test");
return;
}