Как остановить тест, если один тест не пройден с помощью vstest.console.exe?
У меня есть пакетный файл, который содержит несколько тестов, определенных в аналогичной форме ниже.
vstest.console.exe Test.dll /Settings:"test.runsettings" /Tests:"t1,t2,t3,t4,t5"
Тесты проходят в порядке от t1 до t5. Тем не менее, я хочу остановить vstest, если один из тестов не пройден. Это возможно с помощью vstest.console.exe?
Кстати, содержимое моего test.runsettings
<?xml version="1.0" encoding="utf-8"?>
<RunSettings>
<MSTest>
<ForcedLegacyMode>true</ForcedLegacyMode>
<KeepExecutorAliveAfterLegacyRun>true</KeepExecutorAliveAfterLegacyRun>
</MSTest>
</RunSettings>
Я проверил Документацию на наличие настроек выполнения, похоже, для этого случая нет флага / атрибута.
3 ответа
Если это вариант для вас, вы можете ввести базовый класс для тестов с очисткой, инициализировать методы и TestContext
имущество.
В методе очистки вы проверите, если тест не пройден, и запустив Assert.Fail
в TestInitialize
Вы не позволяете никакому другому тесту пройти после этого.
[TestClass]
public class BaseTest
{
private static bool _failAllTests;
public TestContext TestContext { get; set; }
[TestInitialize]
public void InitializeMethod()
{
if (_failAllTests)
{
Assert.Fail("Fail all tests");
}
}
[TestCleanup]
public void CleanUpMethod()
{
if (TestContext.CurrentTestOutcome == UnitTestOutcome.Failed)
{
_failAllTests = true;
}
}
}
[TestClass]
public class UnitTest1 : BaseTest
{
[TestMethod]
public void TestMethod1()
{
Assert.Fail("TestMethod1 failed!");
}
[TestMethod]
public void TestMethod2()
{
Assert.IsTrue(true, "TestMethod2 passed!");
}
}
Если количество запускаемых тестов мало, как в вашем примере, вы можете разделить его на несколько запусков vstest.console.exe и проверить ERRORLEVEL в пакете. Если ваш ERRORLEVEL не равен 0, это означает, что тест не пройден, вы можете выйти из пакета.
vstest.console.exe Test.dll /Settings:"test.runsettings" /Tests:"t1"
IF ERRORLEVEL 1 GOTO exit
vstest.console.exe Test.dll /Settings:"test.runsettings" /Tests:"t2"
IF ERRORLEVEL 1 GOTO exit
...
:exit
В дополнение к ответу lukbl вы можете сделать то же самое для всей сборки, поэтому, если у вас есть несколько классов тестов, у вас будет глобальное управление тестами во время выполнения vstest.console.exe (если вы его вызываете) несколько раз, например).
Следует соблюдать осторожность в зависимости от того, как вы используете vstest.console (или mstest). Если вы балансируете нагрузку между несколькими агентами тестирования, каждый агент тестирования будет запускать свой собственный vstest.console.exe и, таким образом, будет иметь свои собственные значения уровня сборки, поэтому управление сеансами будет ограничено группой тестов, запущенных на тот же агент. Допустим, этот подход даст вам управление всем набором тестов, которые вы запускаете с помощью команды: vstest.console.exe / filter: tests.dll
Это означает, что независимо от области действия вашей переменной session_failed (для всего класса или для всей сборки), если вы в конечном итоге будете запускать разные тесты из одного класса с разными вызовами vstest.console.exe, вы потеряете значение переменной или элемент управления.
При этом, простой подход для мультиклассового сценария тестирования:
[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");
}
И вот простой способ обновить все ваши методы инициализации теста сразу, если их сигнатура одна и та же, с помощью соответствия регулярному выражению, Visual Studio заменит все: find:
(\s*)public void MyTestInitialize\(\)(\s*)(\r*\n)(\s*){(\r*\n)
заменить:
$1public void MyTestInitialize()$3$4{$1\tif (TestSettings.SessionTestsFailed) Assert.Fail("Session failed, test aborted");
и аналогичный для TestFinalize().