VS团队测试:测试类中的多个测试初始化​​方法

LCJ*_*LCJ 10 .net c# unit-testing visual-studio-2010

我在TeamTest中有一个名为"MyClassTest"的单元测试项目.这个项目有三个TestMethods.每种方法都需要自己的测试初始化​​步骤.但是当我将TestInitializeAttribute应用于三个初始化方法时,它表示不应该多次使用该属性.那么在Visual Studio Team Test中用于初始化每个测试方法的属性应该是什么?

参考:

  1. VS团队测试:使用Excel作为数据源的.Net单元测试:适配器失败

  2. 如何为Visual Studio测试项目创建启动和清理脚本?

  3. VS 2010使用自定义计数器加载测试结果

  4. 如何记录单元测试条目并离开MSTest

  5. 单元测试项目可以加载目标应用程序的app.config文件吗?

cha*_*sos 21

根据MSDNTestInitializeAttribute:

  • 不能多次使用(AllowMultiple = false),和
  • 不能继承创建自己的TestInitializeAttribute.

所以,我的建议是创建没有TestInitialize属性的Test Initialize Methods .然后在唯一TestInitialize方法检查当前执行的TestMethod并调用适当的initialize方法:

[TestClass]
public class UnitTest
{
    public TestContext TestContext { get; set; }

    [TestInitialize]
    public void Initialize()
    {
        switch (TestContext.TestName)
        {
            case "TestMethod1":
                this.IntializeTestMethod1();
                break;
            case "TestMethod2":
                this.IntializeTestMethod2();
                break;
            default:
                break;
        }
    }

    [TestMethod]
    public void TestMethod1()
    {
    }

    [TestMethod]
    public void TestMethod2()
    {
    }

    public void IntializeTestMethod1()
    {
        //Initialize Test Method 1
    }

    public void IntializeTestMethod2()
    {
        //Initialize Test Method 2
    }
}
Run Code Online (Sandbox Code Playgroud)

  • `AllowMultiple = false`仅在同一元素中强制使用单个用法...这意味着单个方法不能用多个`TestInitializeAttribute`标记.它不能用于不同方法的规则与`AllowMultiple = false`无关. (6认同)
  • 尽管这可行,但它的缺点是,如果重构测试名称而未更新魔术字符串,则测试会中断。为什么初始化不能成为测试“安排”部分的一部分(如果在多个测试中需要相同的初始化,则在测试主体或私有方法中)?然后可以从try..finally块中启动清理。我个人这样做,到目前为止效果很好。 (2认同)

Ser*_*kiy 12

如果您有三种测试方法,并且每种方法都有自己的初始化步骤,那么为什么要将初始化移动到每次测试之前运行的方法?只有我看到的好处是,这是一个很好的开关块,它为你的源文件增加了一些线条.但是它给你带来了一些缺点 - 看看这些测试方法中的任何一个,你都无法确定将在哪个上下文中执行方法.所以,我使用初始化方法只设置基本上下文,它实际上被夹具中的所有测试使用.

只需将上下文创建移动到arrange每个方法的一部分.

如果你有几个使用公共上下文的方法,那么只需提取方法,它将为它们设置上下文,并在arrange部分调用它.您还可以将每个上下文设置拆分为多个步骤并重用这些步骤(就像在Specflow中使用Given-When-Then工具一样).

当然,也可以选择创建不同的灯具.


Dav*_*ave 6

这是一个旧帖子,但我想出了以下似乎工作正常:首先,定义一个属性类:

[AttributeUsage(AttributeTargets.Method, Inherited = true)]
public class InitialiseWithAttribute : Attribute
{
    public string Id { get; private set; }

    public InitialiseWithAttribute(string id)
    {
        Id = id;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在一些方便的实用程序类中定义扩展方法:

    public static bool IsInitialisedWith(this string testName, string value)
    {
        bool result = false;
        Type testClassType = new StackFrame(1).GetMethod().DeclaringType;
        MethodInfo methodInfo = testClassType.GetMethod(testName);
        if (methodInfo != null)
        {
            InitialiseWithAttribute initialiseWithAttribute =
                methodInfo.GetCustomAttribute<InitialiseWithAttribute>(true);
            if (initialiseWithAttribute != null)
            {
                result = initialiseWithAttribute.Id == value;
            }
        }
        return result;
    }
Run Code Online (Sandbox Code Playgroud)

现在编写测试,因此:

    public TestContext TestContext {get; set;}
    [TestInitialize]
    public void TestInitialise()
    {
        if (TestContext.TestName.IsInitalisedWith("DoSomethingSpecial")
        {
             // ... Do something special
        }
        else
        {
             // ... Do something normal
        }
    }

    [TestMethod]
    [InitialiseWith("DoSomethingSpecial")]
    public void MySpecialTest()
    {
         // The test
    }
Run Code Online (Sandbox Code Playgroud)