In addition to lukbl's answer, you can do the same assembly-wide, so if you have multiple test classes, you'll have a global management on the tests, during vstest.console.exe's run-time (if you're calling it multiple times for example).
Care should be taken depending on how you're employing vstest.console (or mstest). If you're load-balancing between multiple test agents, each test agent will run their own vstest.console.exe, and thus will have their own assembly-level values, so the session management will be limited by the group of tests running on the same agent. Let's say this approach will give you management on the whole set of tests you run with a command:
vstest.console.exe /filter: tests.dll
That means regardless of the scope of your session_failed variable (class-wide or assembly-wide) if you end up running different tests from same class with different vstest.console.exe calls, you'll lose the variable value, or the control.
That being said, a simple approach for multi-class test scenario:
[TestClass]
public static class TestSettings
{
public static bool SessionTestsFailed = false;
[AssemblyInitialize]
public static void runsBeforeAnyTest(TestContext t)
{
TestSettings.SessionTestsFailed = false;
}
}
[TestClass]
public class Tests1
{
public TestContext TestContext { get; set; }
[TestInitialize()]
public void MyTestInitialize()
{
if (TestSettings.SessionTestsFailed)
Assert.Fail("Session failed, test aborted");
}
[TestCleanup]
public void MyTestFinalize()
{
if (TestContext.CurrentTestOutcome != UnitTestOutcome.Passed)
TestSettings.SessionTestsFailed = true;
}
[TestMethod]
public void test11()
{
Console.WriteLine("test11 ran");
Assert.Fail("fail the test");
}
[TestMethod]
public void test12()
{
Console.WriteLine("test12 ran");
Assert.Fail("fail the test");
}
}
[TestClass]
public class Tests2
{
public TestContext TestContext { get; set; }
[TestInitialize()]
public void MyTestInitialize()
{
if (TestSettings.SessionTestsFailed)
Assert.Fail("Session failed, test aborted");
}
[TestCleanup]
public void MyTestFinalize()
{
if (TestContext.CurrentTestOutcome != UnitTestOutcome.Passed)
TestSettings.SessionTestsFailed = true;
}
[TestMethod]
public void test21()
{
Console.WriteLine("test21 ran");
Assert.Fail("fail the test");
}
[TestMethod]
public void test22()
{
Console.WriteLine("test22 ran");
Assert.Fail("fail the test");
}
And here's an easy way to update all your test initialize methods at once, if their signature is the same, using regexp matching, visual studio replace all:
find:
(\s*)public void MyTestInitialize\(\)(\s*)(\r*\n)(\s*){(\r*\n)
replace:
$1public void MyTestInitialize()$3$4{$1\tif (TestSettings.SessionTestsFailed) Assert.Fail("Session failed, test aborted");
and similar for TestFinalize().