这里我将以一个例子来解释这个问题。最初的问题更抽象地提出了问题。不需要阅读它。
让我们说我们已经实现了这个错误的函数来找到int []的最小值:
public int MyMin(int[] data)
{
int min = 1000;
for (int i = 1; i < data.Length; i++)
{
if (data[i] < min)
{
min = data[i];
}
}
return min;
}
在此函数上运行Intellitest为我们提供:
注意,对于测试#4和#6,由于其错误实现,该函数未正确计算最小值。但是,这些测试正在通过,这是不希望的。
Intellitest无法神奇地确定MyMin
的预期行为,并使测试失败。但是,如果我们可以手动指定这些测试的所需结果,那将是非常好的。
@michał-komorowski的解决方案是可行的,但对于每个测试用例,我必须以PexAssume
s重复其输入。是否有更加优雅/干净的方式来为测试输入指定所需的输出?
Intelitest生成可修改的参数化测试,并可在其中添加常规/全局断言。它还生成最大数量的输入,以最大化代码覆盖率。 Intellitest将输入存储为单独的单元测试,每个测试都使用精心设计的输入调用参数化测试。
我正在寻找一种方法来为每个输入添加断言。
由于每个输入都作为单元测试函数存储在 .g.cs 文件中,因此可以在此处添加断言。问题是这些功能不应由用户自定义,因为它们将在后续运行中被Intellitest覆盖。
为每个单元测试添加断言的推荐方法是什么?
答案 0 :(得分:2)
您不应该向测试方法添加断言(具有[TestMethod]
属性的方法)。它们仅用于提供参数值。放置断言的地方是具有[PexMethod]
属性的方法。
首先,它可能看起来像一个限制。但是,如果我们考虑IntelliTest的工作方式,则不然。没有意义为每个输入添加断言,因为可以随时删除,更新或创建输入。例如:
PexAssume
使用了类。PexMethod
属性的配置已更改。但是,您可以执行其他操作,即为正在测试的方法添加多个“Pex方法”并使用PexAssume
。例如,假设我们有BubbleSort
方法,我们希望根据输入数组的长度定义不同的断言。
[PexMethod]
public void BubbleSort(int[] a)
{
PexAssume.IsTrue(a.Length == 5);
int[] result = Program.BubbleSort(a);
// Assertions specific for an array with 5 elements
}
[PexMethod]
public void BubbleSort(int[] a)
{
PexAssume.IsTrue(a.Length == 10);
int[] result = Program.BubbleSort(a);
// Assertions specific for an array with 10 elements
}
答案 1 :(得分:0)
这个答案建立在之前的答案之上。对于提出的问题,它更具体。
Pex为所有代码路径生成测试,但对您的代码一无所知。您仍然需要在PUT(参数化单元测试)中安排/执行/断言,告诉Pex您认为代码应该如何工作。此外,您可以在排列之前添加假设,以便模式采用/ arrange / act / assert。
对于你的例子,我从这个PUT开始。
[PexMethod(MaxRunsWithoutNewTests = 200)]
[PexAllowedException(typeof(NullReferenceException))]
public int MyMin([PexAssumeUnderTest]Class1 target, int[] data)
{
//assume
PexAssume.IsTrue(data.Length == 1);
//arrange
data[0] = 0;
//act
int result = target.MyMin(data);
//assert
PexAssert.AreEqual(0, result);
return result;
}
结果显示只有3/8块被覆盖,测试2失败,预期为'0',得到'1000'
这告诉我,我需要查看代码,找出为什么我得到1000。
我看到我用1而不是0开始for循环。所以我修复了代码并再次运行IntelliTest。
这次我得到两次通过测试,这很好。但是只测试了6/8块。我错过了什么。
我创建了一个新的PUT,它允许Pex生成看起来像这样的数据。
[PexMethod(MaxRunsWithoutNewTests = 200)]
[PexAllowedException(typeof(NullReferenceException))]
public int MyMin2([PexAssumeUnderTest]Class1 target, int[] data)
{
//assume
//act
int result = target.MyMin(data);
//assert
return result;
}
现在我有7个单元测试,它运行所有代码路径并且所有测试都通过。
您会注意到每个PUT都会生成一组测试。