Всем привет. Сегодня решил вернутся к теме TestNG и каснуться возможности перезапуска тестов в случае, если первый раз определенный тест “зафейлился”. Когда это имеет смысл? Я бы сказал тогда, когда мы тестируем приложение с большим объемом “рендомного” контента, данных, которые не всегда возможно покрыть проверками даже полного A\B тестирования. Например, автоматизируя интернет-магазин с кучей товаров, которые не всегда имеют изображение, описание и т.д в процессе разработки. В этом случае имеет смысл перезапускать упавшие тесты в связи с корявыми тестовыми данными.
Мы можем написать свой класс, который после фейла теста(ов) будет снова перезапускать его(их) n-ое количество раз и проверять обновленные результаты. Для достижения этого понадобится реализовать TestNG IRetryAnalyzer. Внизу кусок кода:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
package com.pack.test; import org.testng.IRetryAnalyzer; import org.testng.ITestResult; public class Retry implements IRetryAnalyzer { private int retryCount = 0; private int maxRetryCount = 1; // Below method returns 'true' if the test method has to be retried else 'false' //and it takes the 'Result' as parameter of the test method that just ran public boolean retry(ITestResult result) { if (retryCount < maxRetryCount) { System.out.println("Retrying test " + result.getName() + " with status " + getResultStatusName(result.getStatus()) + " for the " + (retryCount+1) + " time(s)."); retryCount++; return true; } return false; } public String getResultStatusName(int status) { String resultName = null; if(status==1) resultName = "SUCCESS"; if(status==2) resultName = "FAILURE"; if(status==3) resultName = "SKIP"; return resultName; } } |
Также нам понадобиться внедрить класс RetryListener для использовании аннотации @Test(retryAnalyzer=Retry.class), которую нужно использовать для перезапуска тестов.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
package com.pack.test; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import org.testng.IAnnotationTransformer; import org.testng.IRetryAnalyzer; import org.testng.annotations.ITestAnnotation; public class RetryListener implements IAnnotationTransformer { @Override public void transform(ITestAnnotation testannotation, Class testClass, Constructor testConstructor, Method testMethod) { IRetryAnalyzer retry = testannotation.getRetryAnalyzer(); if (retry == null) { testannotation.setRetryAnalyzer(Retry.class); } } } |
Давайте выполним два простых теста. Проверим неправильный текст, который вернет False и тест упадет. Таким образом, второй тест будет повторно выполнен такое количество раз, которое присваивается переменной maxRetryCount в классе Retry.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
package com.pack.test; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.firefox.FirefoxDriver; import org.testng.Assert; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; public class TestNGExampleTests { WebDriver driver; String baseURL = "https://www.linkedin.com/"; @BeforeClass public void setup() { driver = new FirefoxDriver(); driver.manage().window().maximize(); } @Test(priority=1) public void verifyLoginPageText() { driver.navigate().to(baseURL); System.out.println("Verify login page test started"); WebElement element = driver.findElement(By.cssSelector(".header>h2")); String headerText = element.getText(); Assert.assertEquals(headerText, "Get started – it’s free."); } @Test(priority=2) public void verifyForgotPasswordPage() { driver.navigate().to(baseURL); System.out.println("Verify Forgot password page test started"); WebElement element = driver.findElement(By.linkText("Forgot your password?")); element.click(); WebElement pageTextElement = driver.findElement(By.cssSelector(".flow-login-content>fieldset>h1")); String pageText = pageTextElement.getText(); Assert.assertEquals(pageText, "Wrong text"); //Assert.assertEquals(pageText, "Change your password"); } } |
Также нам понадобится добавить Listener в файл testng.xml.
|
1 2 3 |
<listeners> <listener class-name="com.pack.test.RetryListener"/> </listeners> |
После запуска тестов вывод в консоли примет следующий вид:

Тест verifyForgotPasswordPage будет выполнен дважды, так как мы указали “maxRetryCount = 1″ и первый раз тест упал. Теперь суммарное количество тестов будет иметь значение 3, зафейлиных (Failures) – 2. Но в реальности мы имеем только 2 теста. Кому это не нравится, тот может установить переменную count путем внедрения интерфейса ITestListenerand и обновить количество в методе onFinish. Напишу об этом в следующей статье.
Спасибо за прочтение и подписывайтесь на рассылку!