测试更多输入

时间:2010-09-03 11:10:55

标签: c# unit-testing testing mstest

我正在使用MSTest进行测试,当我想应用更多输入时,测试看起来像这样:

[TestMethod]
public void SumTest()
{
  // data to test
  var items = new [] {
    new { First = 1, Second = 1, Expected = 2 },
    new { First = -1, Second = 1, Expected = 0 },
    new { First = 1, Second = 2, Expected = 3 },
    new { First = 1, Second = -1, Expected = 0 },
  };

  ICalculator target = GetSum(); // can be in the loop body

  foreach(var item in items)
  {
    var actual = target.Sum(item.First, item.Second);
    Assert.AreEqual(item.Expected, actual);
  }
}

我觉得这种测试不是正确的方法。即我想将测试数据生成和测试本身分开。

我知道,MSTest中有“数据驱动测试”支持但对我来说还不够:

  1. 无法使用某种算法生成items集合。
  2. 我不能使用非基本类型。
  3. 那么你对这种测试的建议是什么?

    我想有这样的东西,但我不确定这是否是正确的方法,如果某些测试框架支持这种情况。

    [TestData]
    public IEnumerable<object> SumTestData()
    {
      yield return new { First = 1, Second = 1, Expected = 2 };
      yield return new { First = -1, Second = 1, Expected = 0 };
      yield return new { First = 1, Second = 2, Expected = 3 };
      yield return new { First = 1, Second = -1, Expected = 0 };
    }
    
    [TestMethod(DataSource="method:SumTestData")]
    public void SumTest(int first, int second, int expected)
    {
      // this test is runned for each item that is got from SumTestData method
      // (property -> parameter mapping is no problem)
      ICalculator target = GetSum();
      var actual = target.Sum(first, second);
      Assert.AreEqual(expected, actual);
    }
    

3 个答案:

答案 0 :(得分:3)

NUnit支持这种情况:

public static IEnumerable SumTestData() {
    return new List<TestCaseData> {
        new TestCaseData( 1,  1,  2),
        new TestCaseData(-1,  1,  0),
        new TestCaseData( 1,  2,  3),
        new TestCaseData( 1, -1,  0)
    };
}

[Test]
[TestCaseSource("SumTestData")]
public void SumTest(int first, int second, int expected) {
}

参数可以是任何类型。 TestCaseData构造函数采用param对象数组,因此您只需确保测试值可以转换为实际的测试方法参数类型。

非空参数化测试方法(由@RobertKoritnik提供)

通过使用非空白测试方法并沿测试数据提供结果,可以进一步增强上层代码。我还提供了创建测试数据方法的替代方法。

public static IEnumerable SumTestData() {
    yield return new TestCaseData( 1,  1).Returns(2);
    yield return new TestCaseData(-1,  1).Returns(0);
    yield return new TestCaseData( 1,  2).Returns(3);
    yield return new TestCaseData( 1, -1).Returns(0);
}

[Test]
[TestCaseSource("SumTestData")]
public int SumTest(int first, int second)
{
    return Sum(first, second);
}

答案 1 :(得分:2)

http://xunit.codeplex.com/可以执行此类操作:请参阅[理论]属性详细信息http://xunit.codeplex.com/wikipage?title=Comparisons

看起来像这样:

        [Theory]
        [InlineData(SourceType.BackupFile, "RestoreMode")]
        [InlineData(SourceType.ExistingDatabase, "MonitorMode")]
        public void ShouldShowProperReportDependentOnSource(SourceType sourceType, string commandMode)
        {...}

答案 2 :(得分:-1)

MSTest(和NUnit)允许您识别在每次测试之前或实例化测试类时运行的方法。

因此,您可以提取一个设置测试数据的方法,并在运行测试之前运行它。

在MSTest中,您可以使用TestInitializeAttribute来标识在每次测试之前运行的方法,并且可以使用ClassInitializeAttribute来标识在创建测试类时运行一次的方法。