了解MSTest TestContext

时间:2014-06-16 17:32:31

标签: c# mstest testcontext

使用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); } } } 之间存在意外差异(并且由测试运行器设置)。 / p>

请考虑以下代码:

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

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

TestContext

我以前认为public TestContext的两个实例是等价的,但显然它们不是。

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

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

5 个答案:

答案 0 :(得分:15)

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

为每个方法设置了

TestContext,因此具有当前的测试名称。

是的,这有点傻。

答案 1 :(得分:4)

方法

[ClassInitialize]
public static void SetupTests(TestContext testContext) { }
在设置属性集TestContext之前调用

。因此,如果您需要SetupTests中的上下文,那么该参数是有用的。否则使用TestContext属性,该属性在每个

之前设置
[TestInitialize]
public void SetupTest() { }

答案 2 :(得分: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()
        }

    }

答案 3 :(得分:0)

如果要将在[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]方法的上下文对象,因此,除非您显式保存它们,否则它们将永远丢失。

答案 4 :(得分:0)

问题可以这样解决:

首先定义一个静态属性:

    private static string _targetUrl;

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

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

变量已初始化,可以进一步使用。