Visual Studio MSTest / VSTest重试逻辑

mspsb9vt  于 2023-10-23  发布在  其他
关注(0)|答案(2)|浏览(104)

不幸的是,没有用于MStest / VStest的本地测试逻辑
我正在尝试实现这样的自定义逻辑:
试验部件:

static int testNum = 1;

    [TestMethod]
    public void RerunTestOnce_Test()
    {
        testNum = testNum + 1;
        Console.WriteLine("Test started");
        Assert.IsTrue(testNum == 3, $"Test Failed with number {testNum}");

    }

这个测试第一次应该失败,第二次应该通过,当测试值达到值3时。

  • UP:这是一个模拟首次运行失败的合成示例。真实的测试是复杂的,并且有UI搜索方法和其他与系统和网络相关的工作,并且没有信心在一个大而长的测试套件中一切都很好。*

有一个特殊的方法- RerunTestOnce(),在TestNode中调用:

[TestCleanup]
    public void TestCleanup()
    {
        TestHelper.RerunTestOnce(TestContext, this);
    }

下面是测试助手类中RerunTestOnce的实现。在其中,使用Reflection & TestContext,我们获得了测试方法和初始化方法的名称,并再次运行它们:

public static void RerunTestOnce(TestContext testContext, object testInstance)
    {
        if (testContext.CurrentTestOutcome == UnitTestOutcome.Failed)
        {
            var type = testInstance.GetType();
            if (type != null)
            {
                var testMethod = type.GetMethod(testContext.TestName);
                var initMethod = type.GetMethods().SingleOrDefault(m=>m.CustomAttributes.SingleOrDefault(a=>a.AttributeType.Name == "TestInitializeAttribute")!= null);
                var cleanupMethod = type.GetMethods().SingleOrDefault(m => m.CustomAttributes.SingleOrDefault(a => a.AttributeType.Name == "TestCleanupAttribute") != null);

                Console.WriteLine($"[WARNING] Method [{testMethod}] was failed in first attempt. Trying to rerun...");
                try
                {
                    initMethod.Invoke(testInstance, null);
                    testMethod.Invoke(testInstance, null);
                }
                catch
                {
                    Console.WriteLine($"[ERROR] Method [{testMethod}] was failed in second attempt. Rerun finished.");
                }
            }
        }
    }

一切正常,第二次尝试测试方法通过,但最后我看到失败的结果,并Assert第一次尝试的错误消息:

Test Failed - RerunTestOnce_Test
Message: Assert.IsTrue failed. Test Failed with number 2

MSTest如何以及何时创建测试结果-是否可以在第二次尝试后更新测试结果?

eqqqjvef

eqqqjvef1#

更新

今天我学到了你可以编写自己的TestMethod属性。
默认实现如下所示

public class TestMethodAttribute : Attribute
{
    public virtual TestResult[] Execute(ITestMethod testMethod)
    {
        return new TestResult[1] { testMethod.Invoke(null) };
    }
}

因此,您实际上可以创建自己的TestMethodWithRetry属性,并在方法上使用该属性

[TestMethodWithRetry]
public void TestRetry()
{
    var x = new Random().Next(0, 2);
    Assert.AreEqual(1, x);
}

// or
[TestMethodWithRetry(Count = 10)]
public void TestRetry()
{
    var x = new Random().Next(0, 2);
    Assert.AreEqual(1, x);
}

// even works with DataRow
[TestMethodWithRetry(Count = 10)]
[DataRow(2)]
[DataRow(5)]
[DataRow(10)]
public void TestRetry(int max)
{
    var x = new Random().Next(0, max);
    Assert.AreEqual(1, x);
}
public class TestMethodWithRetryAttribute : TestMethodAttribute
{

    public int Count { get; set; } = 1;

    public override TestResult[] Execute(ITestMethod testMethod)
    {
        var count = Count;
        TestResult[] result = null;
        while (count > 0)
        {
            try
            {
                result = base.Execute(testMethod);
                if (result[0].TestFailureException != null)
                {
                    throw result[0].TestFailureException;
                }
            }
            catch (Exception) when (count > 0)
            {
            }
            finally
            {
                count--;
            }
        }
        return result;
    }

}

这只是一个简单的实现,但它似乎工作得非常好。
我想出了以下解决方案

public static void Retry(Action test, int retry = 10, int sleep = 0, [CallerMemberName] string testName = null)
{
    int current = 1;
    retry = Math.Max(1, Math.Min(retry, 10));
    while (current <= retry)
    {
        try
        {
            test();
            break;
        }
        catch (Exception ex) when (current < retry)
        {
            Debug.WriteLine("Test {0} failed ({1}. try): {2}", testName, current, ex);
        }

        if (sleep > 0)
        {
            Thread.Sleep(sleep);
        }
        current++;
    }
}

使用

[TestMethod]
public void CanRollbackTransaction()
{
    Helpers.Retry(() =>
    {
        var even = DateTime.Now.Second % 2 == 0;
        Assert.IsTrue(even);
    }, 3, 1000);
}
pw136qt2

pw136qt22#

MSTest测试框架本身并不支持原生的测试逻辑。
请考虑使用MSTestEx,这是MSTest测试框架的一组扩展,支持测试-验证逻辑:https://www.nuget.org/packages/MSTestEx/

相关问题