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

时间:2012-05-22 10:01:56

标签: c# .net visual-studio-2010 unit-testing

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

参考:

  1. VS Team Test: .Net Unit Testing with Excel as Data Source: Adapter Failed

  2. How to create Startup and Cleanup script for Visual Studio Test Project?

  3. VS 2010 Load Tests Results with custom counters

  4. How to log unit test entry and leave in MSTest

  5. Can a unit test project load the target application's app.config file?

5 个答案:

答案 0 :(得分:21)

根据MSDN TestInitializeAttribute

  • 不能多次使用( AllowMultiple = false ),
  • 无法继承
  • 来创建您自己的TestInitializeAttribute

所以,我的建议是创建没有TestInitialize属性的测试初始化​​方法。然后在唯一的TestInitialize方法检查中检查当前执行的TestMethod并调用相应的初始化方法:

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

答案 1 :(得分:12)

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

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

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

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

答案 2 :(得分:6)

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

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

    public InitialiseWithAttribute(string id)
    {
        Id = id;
    }
}

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

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

现在编写测试,因此:

    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
    }

答案 3 :(得分:3)

如果他们需要三个单独的单位;然后他们可能应该在三个独立的灯具中,每个灯具都有自己的初始化!

答案 4 :(得分:2)

在我的工作中,我们将一个参数传递给TestInitialize方法,以确定我们希望初始化如何工作。

public partial class CommonActions
{
   public void TestInitialize(bool adminTest)
   {
      try
      {
         if (adminTest)
         {
            //do stuff
         } 

然后我们在类定义中进行标准初始化,默认为false。

[TestClass]
public class ProjectTestBase : FrameworkTestBase
{ 
  public CommonActions common { get; set; } = new CommonActions();

  [TestInitialize]
   public void TestInitialize() => common.TestInitialize(false);

然后在测试用例本身中,您可以覆盖TestInitialize以进行任何所需的测试。

[TestClass]
public class SetReportsInAdmin : ProjectTestBase
{
    [TestInitialize]
    public new void TestInitialize() => common.TestInitialize(true);

我们使用布尔值来判断是否需要管理员测试,这需要额外的设置开销。拿这个并应用你想要的任何变量,通过使用一种方法为你提供多次初始化。