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

本文关键字:测试 初始化 方法 团队 测试类 VS | 更新日期: 2023-09-27 18:34:51

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

参考:

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

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

  3. VS 2010 负载测试结果与自定义计数器

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

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

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

根据MSDN,TestInitializeAttribute

  • 不能多次使用(允许倍数 = 假(,并且
  • 不能继承以创建自己的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
    }
}

如果你有三个测试方法,并且每个方法都有自己的初始化步骤,那么为什么要将初始化移动到每次测试之前都会运行的方法呢?我看到的唯一好处是那个漂亮的开关块,它会在您的源文件中添加一些行。但它给你带来了缺点 - 查看这些测试方法中的任何一个,你都无法真正知道将在哪个上下文方法中执行。因此,我使用初始化方法仅设置基本上下文,该上下文实际上被夹具中的所有测试使用。

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

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

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

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

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

如果他们需要三个单独的初始化; 那么他们可能应该在三个单独的装置中,每个装置都有自己的初始化!

在我的工作中,我们将一个参数传递给 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);

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