我将如何在 MSTest 中实现基于范围的测试

How would I achieve a range based test in MSTest

我想使用 MSTest 运行 这样的测试...

var range = Enumerable.Range(0, 9);
foreach(var i in range)
{
   Test(i);
}

...我的一个理论是创建一个像这样的新测试属性...

[TestClass]
public class CubeTests
{

    [TestMethod]
    [TestRange(0, 9)]
    public void Test(int i)
    {
        // Test stuff
    }
}

...

这里的关键是我有一些非常占用内存的代码,我希望 MSTest 在测试之间为我清理这些代码。

对于如此简单的事情,我真的不想依赖文件并使用数据源和部署项。

这可以做到吗?如果可以,有人准备好提供如何做的想法吗?

在单独的方法中实现测试并从测试方法中调用方法

我认为您可以在 NUnit 中执行此操作,但我敢肯定您不能在 MS 测试中执行此操作。

如果您想进行清理,那么您可以在每次调用后调用 GC,或者创建一个 TestCleanUpImpl 方法(在片段调用 GC.Collect() 中执行此操作以展示如何强制执行 GC )。

建议如下:

public void TestSetup()
{
    //Setup tests
}    

public void TestCleanUpImpl()
{
   //unassign variables
   //dispose disposable object
   GC.Collect();
}

public void TestImpl(int i) 
{
    // Test stuff
    // Do assert statements here 
}

[TestMethod]
public void Test()
{
    int fromNum = 0;
    int untilNum = 9;

    for(int i=fromNum;i<=untilNum;i++)
    {
        TestSetup();
        TestImpl(i);
        TestCleanUpImpl();
    }
}

如果你有复杂的设置和清理可以实现一个 class 来处理处理和创建,在构造函数中处理设置,在 Dispose 方法中处理

我不会将此作为我的第一选择,我宁愿让我的测试尽可能简单,即使我的测试 违反 DRY 它使它们更容易遵循,这意味着更少的调试,在我看来这是一个很好的权衡

public class TestImplObj : IDisposable
{
    public TestImplObj()
    {
         //Setup test
    }

    public void TestImpl(int i)
    {
        //Do the actual test
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            // Do the clean up here
        }
    }
}

您不必求助于内置的测试运行程序魔法。只需将您的范围添加为测试 class 的 属性:

private static IEnumerable<int> TestRange
{
    get
    {
        int i = 0;
        while(i < 10)
            yield return i++;
    }
}

现在在您的测试方法中,您可以像往常一样使用您唯一定义的测试范围执行 for 循环:

[TestMethod]
public void DoStuff_RangeIsValid_NoExceptions(){

  // Act
  foreach(var i in TestRange){
    // do the unit test here
  }
}

也许这就是您要找的。几年前,微软为 visual studio 提供了一个名为 PEX 的扩展。

PEX generate unit tests from a single parametric test, Pex finds interesting input-output values of your methods, which you can save as a small test suite with high code coverage.

您可以使用 assumption and precondition 作为测试参数,以确保对测试生成进行最佳控制。

Pex 不再可用(这是一个研究项目),但现在可用 Intellitest,它仍然使用相同的静态分析引擎。

Intellitest generates a parameterized test that is modifiable and general/global assertions can be added there. It also generates the minimum number of inputs that maximize the code coverage; stores the inputs as individual unit tests, each one calling the parameterized test with a crafted input.

[PexMethod]
public void Test(int i)
    {
       PexAssume.IsTrue(i >= 0); 
       PexAssume.IsTrue(i < 10);
       // Test stuff
    }