Ответ 1
Поскольку [ClassInitialize]
вызывается только в начале, имя теста - TestMethod1
. Это устарело после первого пробного запуска.
TestContext
устанавливается для каждого метода и поэтому имеет текущее имя теста.
Да, это немного глупо.
Используя MSTest, мне нужно было получить имя текущего теста из метода [TestInitialize]
. Вы можете получить это из свойства TestContext.TestName
.
Я обнаружил неожиданное различие в поведении между статическим TestContext
который передается методу [ClassInitialize]
и тем, который объявлен как открытое свойство (и устанавливается [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); }
}
}
Это приводит к выводу следующего (скопированного из выходных данных тестера Resharper в VS2013):
TestContext.TestName='TestMethod1' static _testContext.TestName='TestMethod1'
TestContext.TestName='TestMethod2' static _testContext.TestName='TestMethod1'
TestContext.TestName='TestMethod3' static _testContext.TestName='TestMethod1'
Ранее я предполагал, что два экземпляра TestContext
будут эквивалентны, но, очевидно, это не так.
public TestContext
свойство public TestContext
ведет себя так, как я ожидаюprivate static TestContext
значение private static TestContext
которое передается методу [ClassInitialize]
не имеет. Поскольку TestContext
имеет свойства, которые относятся к TestContext
тесту, эта реализация кажется вводящей в заблуждение и нарушенной Есть ли сценарий, в котором вы бы предпочли использовать TestContext
переданный методу [ClassInitialize]
, или его лучше игнорировать и никогда не использовать?
Поскольку [ClassInitialize]
вызывается только в начале, имя теста - TestMethod1
. Это устарело после первого пробного запуска.
TestContext
устанавливается для каждого метода и поэтому имеет текущее имя теста.
Да, это немного глупо.
Метод
[ClassInitialize]
public static void SetupTests(TestContext testContext) { }
вызывается перед установкой свойства TestContext. Поэтому, если вам нужен контекст в SetupTests, этот параметр полезен. В противном случае используйте свойство TestContext, которое устанавливается перед каждым
[TestInitialize]
public void SetupTest() { }
Сценарий: контекст для каждого теста.
Применяется к 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()
}
}
Если вы хотите передать свои объекты, созданные в методе [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], поэтому после возврата они будут потеряны навсегда, если вы явно не сохраните их.