【问题标题】:How to skip a Unit Test at runtime?如何在运行时跳过单元测试?
【发布时间】:2018-11-16 13:30:09
【问题描述】:

提前致谢!

我们使用 selenium Web 驱动程序进行了一些自动化测试,这些测试非常棒,并提供了一个非常好的回归包。

问题是现在我们的代码中有功能切换。所以我需要说忽略这些测试,除非该功能切换被打开/关闭。我找不到任何真正搜索谷歌的东西。

理想情况下,我不希望在功能测试的顶部使用“if”语句,但看起来它将成为主要方式。我最初的想法是在哪里创建自定义属性

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],但我必须不断更新我不想打开/关闭功能的管道。

任何帮助或建议都会很棒!

【问题讨论】:

    标签: c# unit-testing mstest featuretoggle


    【解决方案1】:

    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()
        {
            //...
        }
    }
    

    【讨论】:

    • 很好的答案! #H5YR
    【解决方案2】:

    根据我对this的阅读,您可能需要使用Assert.Inconclusive

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-10
      • 2011-12-22
      • 2013-05-31
      • 1970-01-01
      • 2015-07-19
      • 2012-11-28
      • 2012-09-25
      • 1970-01-01
      相关资源
      最近更新 更多