35

使用 MSTest,我需要从[TestInitialize]方法中获取当前测试的名称。你可以从酒店得到这个TestContext.TestName

TestContext我发现传递给[ClassInitialize]方法的静态变量和声明为公共属性(并由测试运行程序设置)的静态变量之间的行为存在意外差异。

考虑以下代码:

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace TestContext.Tests
{
    [TestClass]
    public class UnitTest1
    {
        public TestContext TestContext { get; set; }

        private static TestContext _testContext;

        [ClassInitialize]
        public static void SetupTests(TestContext testContext)
        {
            _testContext = testContext;
        }

        [TestInitialize]
        public void SetupTest()
        {
            Console.WriteLine(
                "TestContext.TestName='{0}'  static _testContext.TestName='{1}'",
                TestContext.TestName,
                _testContext.TestName);
        }

        [TestMethod] public void TestMethod1() { Assert.IsTrue(true); }

        [TestMethod] public void TestMethod2() { Assert.IsTrue(true); }

        [TestMethod] public void TestMethod3() { Assert.IsTrue(true); }
    }
}

这会导致输出以下内容(从 VS2013 中的 Resharper 测试运行器输出复制粘贴):

TestContext.TestName='TestMethod1'  static _testContext.TestName='TestMethod1'
TestContext.TestName='TestMethod2'  static _testContext.TestName='TestMethod1'
TestContext.TestName='TestMethod3'  static _testContext.TestName='TestMethod1'

我之前假设两个实例TestContext是等价的,但显然它们不是。

  • public TestContext物业的行为符合我的预期
  • private static TestContext传递给该方法的值[ClassInitialize]不会。由于TestContext具有与当前正在运行的测试相关的属性,因此此实现似乎具有误导性和破坏性

是否有任何情况下您实际上更喜欢使用TestContext传递给方法的[ClassInitialize]方法,或者最好忽略它并且从不使用它?

4

5 回答 5

28

由于[ClassInitialize]仅在开头调用,因此测试名称为TestMethod1. 这是第一次测试运行后陈旧的。

TestContext为每个方法设置,因此具有当前的测试名称。

是的,这有点傻。

于 2014-06-17T14:36:54.477 回答
5

方法

[ClassInitialize]
public static void SetupTests(TestContext testContext) { }

在设置属性集 TestContext 之前调用。因此,如果您需要 SetupTests 中的上下文,则该参数很有用。否则使用 TestContext 属性,该属性在每个之前设置

[TestInitialize]
public void SetupTest() { }
于 2014-06-17T14:32:30.593 回答
1

如果要将在方法 [ClassInitialize](或 [AssemblyInitialize])中创建的对象传递给清理方法和测试,则必须将其初始化上下文保存在一个单独的静态变量中,除了常规的 TestContext。只有这样,您以后才能在代码中检索它。

public TestContext TestContext { get; set; } // regular test context
private static TestContext ClassTestContext { get; set; } // global class test context

[ClassInitialize]
public static void ClassInit(TestContext context)
{
        ClassTestContext = context;
        context.Properties["myobj"] = <Some Class Level Object>;
}

[ClassCleanup]
public static void ClassCleanup()
{
    object myobj = (object)ClassTestContext.Properties["myobj"];
}

[TestMethod]
public void Test()
{
    string testname = (string)TestContext.Properties["TestName"] // object from regular context
    object myobj = (object)ClassTestContext.Properties["myobj"]; // object from global class context
}

MSTest 框架不保留传递给 [ClassInitialize]/[AssemblyInitialize] 方法的上下文对象,因此在返回后它们将永远丢失,除非您明确保存它们。

于 2019-06-28T16:35:03.267 回答
0

场景:每个测试的上下文。

适用于具有以下库的 Visual Studio 2017:

  • Microsoft.VisualStudio.TestPlatform.TestFramework
  • Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions

示例代码:

    [TestClass]
    public class MyTestClass
    {

        public TestContext TestContext { get; set; }

        /// <summary>
        /// Run before each UnitTest to provide additional contextual information.
        /// TestContext reinitialized before each test, no need to clean up after each test.
        /// </summary>
        [TestInitialize]
        public void SetupTest()
        {
            TestContext.Properties.Add("MyKey", "My value ...");

            switch (TestContext.TestName)
            {
                case "MyTestMethod2":
                    TestContext.Properties["MyKey2"] = "My value 2 ...";
                    break;
            }

        }

        [TestMethod]
        public void MyTestMethod()
        {
            // Usage:
            // TestContext.Properties["MyKey"].ToString()
        }   

        [TestMethod]
        public void MyTestMethod2()
        {
            // Usage:
            // TestContext.Properties["MyKey"].ToString()

            // also has:
            // TestContext.Properties["MyKey2"].ToString()
        }

    }
于 2018-12-05T18:27:56.340 回答
0

问题可以这样解决:

首先定义一个静态属性:

    private static string _targetUrl;

然后在 ClassInitialize 类型的方法中从 runsetting 文件中获取值,使用 TestContext 作为输入参数。

[ClassInitialize]
    public static void Initialize(TestContext testContext)
    {
        _targetUrl = testContext.Properties["targetUrl"].ToString();           
    }

变量已初始化,准备进一步使用它。

于 2019-12-19T10:01:17.667 回答