猿问

如何立即重新运行失败的JUnit测试?

如何立即重新运行失败的JUnit测试?

有没有办法让JUnit规则或类似的东西给每个失败的测试提供第二次机会,只需尝试再次运行它。

背景:我有一大堆用JUnit编写的Selenium2-WebDriver测试。由于非常激进的时间(点击后只有短暂的等待时间),一些测试(100个中的1个,总是不同的测试)可能会失败,因为服务器有时响应速度稍慢。但我不能让等待时间太久以至于它肯定足够长,因为那时测试将永远持续下去。) - 所以我认为这个用例即使需要一秒钟,测试也是绿色的是可以接受的尝试。

当然,最好有3个中的2个(重复3次失败的测试,如果其中两个测试是正确的,则将它们视为正确),但这将是未来的改进。


泛舟湖上清波郎朗
浏览 909回答 3
3回答

MM们

至于我编写自定义转轮更灵活的解决方案。上面发布的解决方案(带代码示例)有两个缺点:如果它在@BeforeClass阶段失败,它将不会重试测试;它计算测试的运行方式有点不同(当你有3次重试时,你将收到测试运行:4,成功1可能会令人困惑);这就是为什么我更喜欢写自定义跑步者的方法。自定义运行程序的代码可能如下:import&nbsp;org.junit.Ignore;import&nbsp;org.junit.internal.AssumptionViolatedException;import&nbsp;org.junit.internal.runners.model.EachTestNotifier;import&nbsp;org.junit.runner.Description;import&nbsp;org.junit.runner.notification.RunNotifier;import&nbsp;org.junit.runner.notification.StoppedByUserException;import&nbsp;org.junit.runners.BlockJUnit4ClassRunner;import&nbsp;org.junit.runners.model.FrameworkMethod;import&nbsp;org.junit.runners.model.InitializationError;import&nbsp;org.junit.runners.model.Statement;public&nbsp;class&nbsp;RetryRunner&nbsp;extends&nbsp;BlockJUnit4ClassRunner&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;final&nbsp;int&nbsp;retryCount&nbsp;=&nbsp;100; &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;int&nbsp;failedAttempts&nbsp;=&nbsp;0; &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;RetryRunner(Class<?>&nbsp;klass)&nbsp;throws&nbsp;InitializationError&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;super(klass); &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;@Override &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;run(final&nbsp;RunNotifier&nbsp;notifier)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EachTestNotifier&nbsp;testNotifier&nbsp;=&nbsp;new&nbsp;EachTestNotifier(notifier, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getDescription()); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Statement&nbsp;statement&nbsp;=&nbsp;classBlock(notifier); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;statement.evaluate(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(AssumptionViolatedException&nbsp;e)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;testNotifier.fireTestIgnored(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(StoppedByUserException&nbsp;e)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;e; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(Throwable&nbsp;e)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;retry(testNotifier,&nbsp;statement,&nbsp;e); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;@Override &nbsp;&nbsp;&nbsp;&nbsp;protected&nbsp;void&nbsp;runChild(final&nbsp;FrameworkMethod&nbsp;method,&nbsp;RunNotifier&nbsp;notifier)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Description&nbsp;description&nbsp;=&nbsp;describeChild(method); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(method.getAnnotation(Ignore.class)&nbsp;!=&nbsp;null)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;notifier.fireTestIgnored(description); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;runTestUnit(methodBlock(method),&nbsp;description,&nbsp;notifier); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;/** &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Runs&nbsp;a&nbsp;{@link&nbsp;Statement}&nbsp;that&nbsp;represents&nbsp;a&nbsp;leaf&nbsp;(aka&nbsp;atomic)&nbsp;test. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/ &nbsp;&nbsp;&nbsp;&nbsp;protected&nbsp;final&nbsp;void&nbsp;runTestUnit(Statement&nbsp;statement,&nbsp;Description&nbsp;description, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RunNotifier&nbsp;notifier)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EachTestNotifier&nbsp;eachNotifier&nbsp;=&nbsp;new&nbsp;EachTestNotifier(notifier,&nbsp;description); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eachNotifier.fireTestStarted(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;statement.evaluate(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(AssumptionViolatedException&nbsp;e)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eachNotifier.addFailedAssumption(e); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(Throwable&nbsp;e)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;retry(eachNotifier,&nbsp;statement,&nbsp;e); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;finally&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eachNotifier.fireTestFinished(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;retry(EachTestNotifier&nbsp;notifier,&nbsp;Statement&nbsp;statement,&nbsp;Throwable&nbsp;currentThrowable)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Throwable&nbsp;caughtThrowable&nbsp;=&nbsp;currentThrowable; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(retryCount&nbsp;>&nbsp;failedAttempts)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;statement.evaluate(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(Throwable&nbsp;t)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;failedAttempts++; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;caughtThrowable&nbsp;=&nbsp;t; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;notifier.addFailure(caughtThrowable); &nbsp;&nbsp;&nbsp;&nbsp;}}

吃鸡游戏

在有一个更好的选择。如果您正在使用maven插件,例如:surfire或failsefe,则可以选择添加参数rerunFailingTestsCount&nbsp;SurFire Api。这些东西在以下票证中实现:Jira Ticket。在这种情况下,您不需要编写自定义代码和插件自动修改测试结果报告。我看到这种方法只有一个缺点:如果某些测试失败,则在课前/课后阶段测试将不会重新运行。
随时随地看视频慕课网APP

相关分类

Java
我要回答