gan*_*ool 9 testng automated-tests
我浏览 stackoverflow 已经有几天了,试图找到如何重新运行整个测试类,而不仅仅是一个@Test步骤。许多人说 TestNG 和 不支持此功能IRetryAnalyzer,而有些人已经发布了解决方法,但实际上并没有用。有没有人设法做到这一点?并且只是为了澄清其原因,以避免回答说不支持的目的:TestNG 不仅是开发人员的工具。意思是 sw 测试人员也用于 e2e 测试。E2e 测试可以包含依赖于前一个测试的每个步骤。所以是的,重新运行整个测试类是有效的,而不是简单的@Test,这很容易通过IRetryAnalyzer.
我想要实现的一个例子是:
public class DemoTest extends TestBase {
@Test(alwaysRun = true, description = "Do this")
public void testStep_1() {
driver.navigate().to("http://www.stackoverflow.com");
Assert.assertEquals(driver.getCurrentUrl().contains("stackoverflow)"));
}
@Test(alwaysRun = true, dependsOnMethods = "testStep_1", description = "Do that")
public void testStep_2() {
driver.press("button");
Assert.assertEquals(true, driver.elementIsVisible("button"));
}
@Test(alwaysRun = true, dependsOnMethods = "testStep_2", description = "Do something else")
public void testStep_3() {
driver.press("button2");
Assert.assertEquals(true, driver.elementIsVisible("button"));
}
}
Run Code Online (Sandbox Code Playgroud)
假设testStep_2失败了,我想重新运行class DemoTest,而不仅仅是testStep_2
好的,我知道您可能想要一些可以在 @BeforeClass 中指定的简单属性或类似的属性,但我们可能需要等待它的实现。至少我也找不到。
下面的内容很难看,但我认为它至少在小范围内完成了工作,剩下的就是看看它在更复杂的场景中的表现如何。也许有了更多的时间,这可以改进成更好的东西。
好的,所以我创建了一个与您类似的测试类:
public class RetryTest extends TestConfig {
public class RetryTest extends TestConfig {
Assertion assertion = new Assertion();
@Test( enabled = true,
groups = { "retryTest" },
retryAnalyzer = TestRetry.class,
ignoreMissingDependencies = false)
public void testStep_1() {
}
@Test( enabled = true,
groups = { "retryTest" },
retryAnalyzer = TestRetry.class,
dependsOnMethods = "testStep_1",
ignoreMissingDependencies = false)
public void testStep_2() {
if (fail) assertion.fail("This will fail the first time and not the second.");
}
@Test( enabled = true,
groups = { "retryTest" },
retryAnalyzer = TestRetry.class,
dependsOnMethods = "testStep_2",
ignoreMissingDependencies = false)
public void testStep_3() {
}
@Test( enabled = true)
public void testStep_4() {
assertion.fail("This should leave a failure in the end.");
}
}
Run Code Online (Sandbox Code Playgroud)
我Listener在超类中有 ,以防万一我想将其扩展到其他类,但您也可以在测试类中设置侦听器。
@Listeners(TestListener.class)
public class TestConfig {
protected static boolean retrySuccessful = false;
protected static boolean fail = true;
}
Run Code Online (Sandbox Code Playgroud)
上述 4 种方法中的 3 种都有RetryAnalyzer. 我testStep_4没有使用它,以确保我接下来要做的事情不会干扰其余的执行。SaidRetryAnalyzer实际上不会重试(请注意该方法返回false),但它会执行以下操作:
public class TestRetry implements IRetryAnalyzer {
public static TestNG retryTestNG = null;
@Override
public boolean retry(ITestResult result) {
Class[] classes = {CreateBookingTest.class};
TestNG retryTestNG = new TestNG();
retryTestNG.setDefaultTestName("RETRY TEST");
retryTestNG.setTestClasses(classes);
retryTestNG.setGroups("retryTest");
retryTestNG.addListener(new RetryAnnotationTransformer());
retryTestNG.addListener(new TestListenerRetry());
retryTestNG.run();
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
这将在您的执行中创建一个执行。它不会扰乱报告,并且一旦完成,它将继续您的主要执行。但它会“重试”该组内的方法。
是的,我知道,我知道。这意味着您将在永恒循环中永远执行您的测试套件。这就是为什么RetryAnnotationTransformer. 在其中,我们将从这些测试的第二次执行中删除 RetryAnalyzer:
public class RetryAnnotationTransformer extends TestConfig implements IAnnotationTransformer {
@SuppressWarnings("rawtypes")
@Override
public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) {
fail = false; // This is just for debugging. Will make testStep_2 pass in the second run.
annotation.setRetryAnalyzer(null);
}
}
Run Code Online (Sandbox Code Playgroud)
现在我们面临最后一个问题。我们最初的测试套件对那里的“重试”执行一无所知。这就是事情变得非常丑陋的地方。我们需要告诉我们的记者刚刚发生了什么。这就是我鼓励你改进的部分。我没有时间做更好的事情,但如果可以的话,我会在某个时候对其进行编辑。
首先,我们需要知道retryTestNG执行是否成功。可能有一百万种方法可以做得更好,但目前这是有效的。我设置了一个监听器只是为了重试执行。您可以在上面看到它TestRetry,它由以下部分组成:
public class TestListenerRetry extends TestConfig implements ITestListener {
(...)
@Override
public void onFinish(ITestContext context) {
if (context.getFailedTests().size()==0 && context.getSkippedTests().size()==0) {
successful = true;
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,主套件的监听器(您在上面的超类中看到的监听器)TestConfig将查看运行是否发生以及运行是否顺利,并将更新报告:
public class TestListener extends TestConfig implements ITestListener , ISuiteListener {
(...)
@Override
public void onFinish(ISuite suite) {
if (TestRetry.retryTestNG != null) {
for (ITestNGMethod iTestNGMethod : suite.getMethodsByGroups().get("retryTest")) {
Collection<ISuiteResult> iSuiteResultList = suite.getResults().values();
for (ISuiteResult iSuiteResult : iSuiteResultList) {
ITestContext iTestContext = iSuiteResult.getTestContext();
List<ITestResult> unsuccessfulMethods = new ArrayList<ITestResult>();
for (ITestResult iTestResult : iTestContext.getFailedTests().getAllResults()) {
if (iTestResult.getMethod().equals(iTestNGMethod)) {
iTestContext.getFailedTests().removeResult(iTestResult);
unsuccessfulMethods.add(iTestResult);
}
}
for (ITestResult iTestResult : iTestContext.getSkippedTests().getAllResults()) {
if (iTestResult.getMethod().equals(iTestNGMethod)) {
iTestContext.getSkippedTests().removeResult(iTestResult);
unsuccessfulMethods.add(iTestResult);
}
}
for (ITestResult iTestResult : unsuccessfulMethods) {
iTestResult.setStatus(1);
iTestContext.getPassedTests().addResult(iTestResult, iTestResult.getMethod());
}
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
该报告现在应该显示 3 个测试已通过(因为它们已重试),而一个测试则失败,因为它不属于其他 3 个测试:
我知道这不是您想要的,但我会帮助它为您服务,直到他们将功能添加到 TestNG。
| 归档时间: |
|
| 查看次数: |
231 次 |
| 最近记录: |