如何在运行时跳过单元测试? [英] How to skip a Unit Test at runtime?

查看:99
本文介绍了如何在运行时跳过单元测试?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

提前致谢!

我们有一些使用 selenium web 驱动程序的自动化测试,它们非常棒,并提供了一个非常好的回归包.

We have some Automation tests using the selenium web driver which are great and provide a really good regression pack.

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

The problem is now we have feature toggles in our code. So I need to say ignore these tests unless that feature toggle is turned On/ Off. I can't find anything really searching Google.

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

Ideally I don't want a 'if' statement at the top of the Feature tests but it looks like it's going to be the main way. My initial thoughts where to create a custom attribute

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] 但没有运气.

I some how need to hook into the MSTest pipeline and say if this attribute is present and the logic for MyFeature1 is turned off then don't run this test - Looked at dynamically adding the [Ignore] but with no luck.

这是通过 VSTS 运行的,我可以使用 [TestCategories],但我必须不断更新我不想打开/关闭的功能的管道.

This is running through VSTS and I could use [TestCategories] but I'd have to keep updating the pipeline to which feature is turned on/off which I don't want to do.

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

Any help or suggestions would be great!

推荐答案

MSTest v2 现在有很多扩展点,您可以通过扩展 TestMethodAttribute 来实现这一点.首先,我们添加两个属性参数,一个用于属性名称的 string 和一个具有该属性的 Type.然后我们覆盖 Execute 方法并通过反射调用属性.如果结果为 true,我们将照常执行测试,否则我们将返回一个不确定"的测试结果.

MSTest v2 now has a lot of extensibility points, and you can achieve this by extending the TestMethodAttribute. First we add two attribute arguments, a string for a property name and a Type that has the property. Then we override the Execute method and invoke the property via reflection. If the result is true, we'll execute the test as normal, otherwise we return an 'inconclusive` test result.

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 } };
        }
    }
}

现在我们可以像这样使用我们的新属性:

Now we can use our new attribute like this:

[TestClass]
public class MyTests
{
    [TestMethodWithCondition(nameof(Configuration.IsMyFeature1Enabled), typeof(Configuration))]
    public void MyTest()
    {
        //...
    }
}

public static class Configuration
{
    public static bool IsMyFeature1Enabled => false;
}

<小时>

以上是一个非常通用的解决方案.您还可以根据您的特定用例对其进行更多自定义,以避免在属性声明中过于冗长:


The above is a very generic solution. You could also customize it a little more to your particular use case to perhaps avoid quite so much verbosity in the attribute declaration:

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

这篇关于如何在运行时跳过单元测试?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆