Как пропустить юнит тест во время выполнения?
Заранее спасибо!
У нас есть несколько тестов автоматизации с использованием веб-драйвера Selen, которые великолепны и дают действительно хороший регрессионный пакет.
Проблема в том, что теперь у нас есть переключатели функций в нашем коде. Поэтому я должен сказать, что игнорируйте эти тесты, если только эта функция не включена / выключена. Я не могу найти ничего, что действительно ищет в Google.
В идеале я не хочу, чтобы оператор "if" находился в начале тестов Feature, но похоже, что это будет основной путь. Мои первые мысли, где создать пользовательский атрибут
public class IsFeatureFlagTurnedOn : Attribute
{
public IsFeatureFlagTurnedOn(string featureToggleName)
{
FeatureToggleName = featureToggleName;
}
public string FeatureToggleName {get;}
}
public class MyTests
{
[TestMethod]
[IsFeatureFlagTurnedOn("MyFeature1")]
public void ItShould()
{
// only run if MyFeature1 is turned on
}
}
Мне нужно как-то подключиться к конвейеру MSTest и сказать, что этот атрибут присутствует и логика для MyFeature1 отключена, тогда не запускайте этот тест - смотрел на динамическое добавление [Ignore], но безуспешно.
Это выполняется через VSTS, и я мог бы использовать [TestCategories], но мне пришлось бы постоянно обновлять конвейер, для которого включена / выключена функция, что я не хочу делать.
Любая помощь или предложения будут великолепны!
2 ответа
MSTest v2 теперь имеет много точек расширяемости, и вы можете достичь этого, расширив TestMethodAttribute
, Сначала мы добавим два аргумента атрибута, string
для имени свойства и Type
это имеет свойство. Затем мы переопределяем Execute
метод и вызвать свойство с помощью отражения. Если результат true
, мы выполним тест как обычно, в противном случае мы вернем "неокончательный" результат теста.
public class TestMethodWithConditionAttribute : TestMethodAttribute
{
public Type ConditionParentType { get; set; }
public string ConditionPropertyName { get; set; }
public TestMethodWithConditionAttribute(string conditionPropertyName, Type conditionParentType)
{
ConditionPropertyName = conditionPropertyName;
ConditionParentType = conditionParentType;
}
public override TestResult[] Execute(ITestMethod testMethod)
{
if (ConditionParentType.GetProperty(ConditionPropertyName, BindingFlags.Static | BindingFlags.Public)?.GetValue(null) is bool condiiton && condiiton)
{
return base.Execute(testMethod);
}
else
{
return new TestResult[] { new TestResult { Outcome = UnitTestOutcome.Inconclusive } };
}
}
}
Теперь мы можем использовать наш новый атрибут следующим образом:
[TestClass]
public class MyTests
{
[TestMethodWithCondition(nameof(Configuration.IsMyFeature1Enabled), typeof(Configuration))]
public void MyTest()
{
//...
}
}
public static class Configuration
{
public static bool IsMyFeature1Enabled => false;
}
Выше приведено очень общее решение. Вы также можете настроить его немного под свой конкретный вариант использования, чтобы, возможно, избежать слишком многословия в объявлении атрибута:
public class TestMethodForConfigAttribute : TestMethodAttribute
{
public string Name { get; set; }
public TestMethodForConfigAttribute(string name)
{
Name = name;
}
public override TestResult[] Execute(ITestMethod testMethod)
{
if (IsConfigEnabled(Name))
{
return base.Execute(testMethod);
}
else
{
return new TestResult[] { new TestResult { Outcome = UnitTestOutcome.Inconclusive } };
}
}
public static bool IsConfigEnabled(string name)
{
//...
return false;
}
}
И используйте это как:
[TestClass]
public class MyTests
{
[TestMethodForConfig("MyFeature1")]
public void MyTest()
{
//...
}
}
Исходя из моего прочтения, вам может понадобиться Assert.Inconclusive