Intellitest

时间:2016-02-09 05:54:26

标签: unit-testing visual-studio-2015 assertions intellitest

这里我将以一个例子来解释这个问题。最初的问题更抽象地提出了问题。不需要阅读它。

更新:问题为例

让我们说我们已经实现了这个错误的函数来找到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为我们提供: enter image description here

注意,对于测试#4和#6,由于其错误实现,该函数未正确计算最小值。但是,这些测试正在通过,这是不希望的。

Intellitest无法神奇地确定MyMin的预期行为,并使测试失败。但是,如果我们可以手动指定这些测试的所需结果,那将是非常好的。

@michał-komorowski的解决方案是可行的,但对于每个测试用例,我必须以PexAssume s重复其输入。是否有更加优雅/干净的方式来为测试输入指定所需的输出?

原始问题

Intelitest生成可修改的参数化测试,并可在其中添加常规/全局断言。它还生成最大数量的输入,以最大化代码覆盖率。 Intellitest将输入存储为单独的单元测试,每个测试都使用精心设计的输入调用参数化测试。

我正在寻找一种方法来为每个输入添加断言。

由于每个输入都作为单元测试函数存储在 .g.cs 文件中,因此可以在此处添加断言。问题是这些功能不应由用户自定义,因为它们将在后续运行中被Intellitest覆盖。

为每个单元测试添加断言的推荐方法是什么?

2 个答案:

答案 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都会生成一组测试。