Visual Studio MSTest / VSTest重试逻辑

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

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

  1. static int testNum = 1;
  2. [TestMethod]
  3. public void RerunTestOnce_Test()
  4. {
  5. testNum = testNum + 1;
  6. Console.WriteLine("Test started");
  7. Assert.IsTrue(testNum == 3, $"Test Failed with number {testNum}");
  8. }

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

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

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

  1. [TestCleanup]
  2. public void TestCleanup()
  3. {
  4. TestHelper.RerunTestOnce(TestContext, this);
  5. }

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

  1. public static void RerunTestOnce(TestContext testContext, object testInstance)
  2. {
  3. if (testContext.CurrentTestOutcome == UnitTestOutcome.Failed)
  4. {
  5. var type = testInstance.GetType();
  6. if (type != null)
  7. {
  8. var testMethod = type.GetMethod(testContext.TestName);
  9. var initMethod = type.GetMethods().SingleOrDefault(m=>m.CustomAttributes.SingleOrDefault(a=>a.AttributeType.Name == "TestInitializeAttribute")!= null);
  10. var cleanupMethod = type.GetMethods().SingleOrDefault(m => m.CustomAttributes.SingleOrDefault(a => a.AttributeType.Name == "TestCleanupAttribute") != null);
  11. Console.WriteLine($"[WARNING] Method [{testMethod}] was failed in first attempt. Trying to rerun...");
  12. try
  13. {
  14. initMethod.Invoke(testInstance, null);
  15. testMethod.Invoke(testInstance, null);
  16. }
  17. catch
  18. {
  19. Console.WriteLine($"[ERROR] Method [{testMethod}] was failed in second attempt. Rerun finished.");
  20. }
  21. }
  22. }
  23. }

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

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

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

eqqqjvef

eqqqjvef1#

更新

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

  1. public class TestMethodAttribute : Attribute
  2. {
  3. public virtual TestResult[] Execute(ITestMethod testMethod)
  4. {
  5. return new TestResult[1] { testMethod.Invoke(null) };
  6. }
  7. }

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

  1. [TestMethodWithRetry]
  2. public void TestRetry()
  3. {
  4. var x = new Random().Next(0, 2);
  5. Assert.AreEqual(1, x);
  6. }
  7. // or
  8. [TestMethodWithRetry(Count = 10)]
  9. public void TestRetry()
  10. {
  11. var x = new Random().Next(0, 2);
  12. Assert.AreEqual(1, x);
  13. }
  14. // even works with DataRow
  15. [TestMethodWithRetry(Count = 10)]
  16. [DataRow(2)]
  17. [DataRow(5)]
  18. [DataRow(10)]
  19. public void TestRetry(int max)
  20. {
  21. var x = new Random().Next(0, max);
  22. Assert.AreEqual(1, x);
  23. }
  1. public class TestMethodWithRetryAttribute : TestMethodAttribute
  2. {
  3. public int Count { get; set; } = 1;
  4. public override TestResult[] Execute(ITestMethod testMethod)
  5. {
  6. var count = Count;
  7. TestResult[] result = null;
  8. while (count > 0)
  9. {
  10. try
  11. {
  12. result = base.Execute(testMethod);
  13. if (result[0].TestFailureException != null)
  14. {
  15. throw result[0].TestFailureException;
  16. }
  17. }
  18. catch (Exception) when (count > 0)
  19. {
  20. }
  21. finally
  22. {
  23. count--;
  24. }
  25. }
  26. return result;
  27. }
  28. }

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

  1. public static void Retry(Action test, int retry = 10, int sleep = 0, [CallerMemberName] string testName = null)
  2. {
  3. int current = 1;
  4. retry = Math.Max(1, Math.Min(retry, 10));
  5. while (current <= retry)
  6. {
  7. try
  8. {
  9. test();
  10. break;
  11. }
  12. catch (Exception ex) when (current < retry)
  13. {
  14. Debug.WriteLine("Test {0} failed ({1}. try): {2}", testName, current, ex);
  15. }
  16. if (sleep > 0)
  17. {
  18. Thread.Sleep(sleep);
  19. }
  20. current++;
  21. }
  22. }

使用

  1. [TestMethod]
  2. public void CanRollbackTransaction()
  3. {
  4. Helpers.Retry(() =>
  5. {
  6. var even = DateTime.Now.Second % 2 == 0;
  7. Assert.IsTrue(even);
  8. }, 3, 1000);
  9. }
展开查看全部
pw136qt2

pw136qt22#

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

相关问题