使用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}},或者最好忽略它并且从不使用?
答案 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:
示例代码:
[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();
}
变量已初始化,可以进一步使用。