测试更多输入

发布于 2024-09-17 17:44:03 字数 1462 浏览 4 评论 0原文

我正在使用 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. 我不能使用非原始类型。

那么您对此类测试有何建议?

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

[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);
}

I'm using MSTest for testing and when I want to apply more inputs then the test looks like this:

[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);
  }
}

I feel that this kind of testing is not the right way. I.e. I would like to separate testing data generation and testing itself.

I know, there is "data driven test" support in MSTest but it isn't sufficient for me:

  1. The items collection cannot be generated using some algorithm.
  2. I cannot use non-primitive types.

So what is your suggestion for this kind of tests?

I would like to have something like this but I'm not sure if this is the right way and if some testing framework supports this scenario.

[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);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

夜访吸血鬼 2024-09-24 17:44:03

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);
}

NUnit supports that scenario:

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) {
}

The parameters can be any type. The TestCaseData constructor takes a param array of objects, so you just have to make sure that your test values are castable to the actual test method parameter types.

Non-void parametrised test method (by @RobertKoritnik)

Upper code can be even further enhanced by having a non void test method and provide results along test data. I also provided an alternative of creating test data method.

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);
}
揽清风入怀 2024-09-24 17:44:03

http://xunit.codeplex.com/ 可以做这样的事情:参见[Theory]属性详细信息http://xunit.codeplex.com/wikipage?title=Comparisons

看起来像这样:

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

http://xunit.codeplex.com/ can do such stuff: see [Theory] attribute details http://xunit.codeplex.com/wikipage?title=Comparisons

looks something like this:

        [Theory]
        [InlineData(SourceType.BackupFile, "RestoreMode")]
        [InlineData(SourceType.ExistingDatabase, "MonitorMode")]
        public void ShouldShowProperReportDependentOnSource(SourceType sourceType, string commandMode)
        {...}
爱她像谁 2024-09-24 17:44:03

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

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

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

MSTest (and NUnit) allows you to identify methods that are run either before each test or when the test class is instantiated.

So you can extract a method that sets up your test data and have it run before your tests are run.

In MSTest you can use the TestInitializeAttribute to identify a method that is run before each test and you can use the ClassInitializeAttribute to identify a method that is run once when the test class is created.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文