如果测试失败,则重试 TestNG 代码中的特定代码段,而不是整个测试
Retry a specific piece of code in a TestNG code if the test fails, not the whole test
如果 TestNG 测试失败,我想重试一些特定于方法的代码,而不是重试整个测试。
我从这里 https://github.com/haojiwu/testng-retry-example 研究了自定义测试监听器和重试分析器。如果失败,这将重新运行整个测试我想要一些特定于方法的代码。
@Test()
public void testStuff() {
String var1;
String var2;
/* Code specific to this test and should only be ran once. */
doSomething(param1)
/* Contains code looking for files that may or not be ready by the time the code is ran. */
/* I want to try this code then wait and retry up to a max of 3 retries. */
assertStuff(var1, var2);
}
我想在 doSomething(param1) 中执行代码,尝试 assertStuff(var1, var2) 中的内容,如果断言失败,我想等待 5 秒,然后重试 assertStuff(var1, var2) ) 代码,如果断言通过则测试通过,否则重试最多 2 次。
您可能想使用 TestNG retryAnalyzer 功能,但仅限于 assertStuff(var1, var2)
部分。
因此您应该将 doSomething(param1)
移动到一个单独的方法中,用 @BeforeClass
(或 @BeforeMethod
)注释:
...
@BeforeClass
public void initSomething() {
doSomething(param1);
}
@Test(retryAnalyzer = ThreeRetries.class)
public void testStuff() {
String var1;
String var2;
assertStuff(var1, var2);
}
或者你可以使用@Test
注解强制部分并声明测试之间的依赖关系,例如:
...
@Test
public void initSomething() {
doSomething(param1);
}
@Test(retryAnalyzer = ThreeRetries.class, dependsOnMethods = "initSomething")
public void testStuff() {
String var1;
String var2;
assertStuff(var1, var2);
}
无需依赖 RetryAnalyzer 即可完成此操作的更简单方法(如果您未使用最新的 Beta 版本,即 7.0.0-beta5
或更高版本,RetryAnalyzer 的一个问题是您需要承担责任修剪重试产生的重复测试结果)。
您可以围绕您的 assertStuff()
方法构建一个简单的轮询机制,并让它 return true
或 false
您可以断言。
举个例子。为了方便起见,我使用了 org.openqa.selenium.support.ui.FluentWait
因为它的 API 非常简洁
import java.time.Duration;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.function.Supplier;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.support.ui.FluentWait;
import org.testng.Assert;
import org.testng.annotations.Test;
public class TestClass {
private static final int max = 5;
@Test
public void testStuff() {
doSomething();
boolean wasAsserted = assertStuff(2);
Assert.assertTrue(wasAsserted);
}
@Test
public void testStuffThatFails() {
doSomething();
boolean wasAsserted = assertStuff(10);
Assert.assertTrue(wasAsserted);
}
private boolean assertStuff(int retries) {
final AtomicInteger integer = new AtomicInteger(0);
Supplier<Integer> input = integer::getAndIncrement;
FluentWait<Supplier<Integer>> checker =
new FluentWait<>(input)
.pollingEvery(Duration.ofSeconds(2))
.withTimeout(Duration.ofSeconds(10));
try {
return checker.until(getCondition(retries));
} catch (TimeoutException e) {
return false;
}
}
private Function<Supplier<Integer>, Boolean> getCondition(int retries) {
return integerSupplier -> {
int current = integerSupplier.get();
return current == retries || current > max;
};
}
private void doSomething() {
System.err.println("I did something");
}
}
简单来说,我们也这样试试
int iterate=5;
boolean status=false;
while(iterate >=1 && status ==false) {
try {
assertEquals("false", "true");
status=true;
}catch (AssertionError e) {
iterate--;
Thread.sleep(500);
}
}
如果 TestNG 测试失败,我想重试一些特定于方法的代码,而不是重试整个测试。
我从这里 https://github.com/haojiwu/testng-retry-example 研究了自定义测试监听器和重试分析器。如果失败,这将重新运行整个测试我想要一些特定于方法的代码。
@Test()
public void testStuff() {
String var1;
String var2;
/* Code specific to this test and should only be ran once. */
doSomething(param1)
/* Contains code looking for files that may or not be ready by the time the code is ran. */
/* I want to try this code then wait and retry up to a max of 3 retries. */
assertStuff(var1, var2);
}
我想在 doSomething(param1) 中执行代码,尝试 assertStuff(var1, var2) 中的内容,如果断言失败,我想等待 5 秒,然后重试 assertStuff(var1, var2) ) 代码,如果断言通过则测试通过,否则重试最多 2 次。
您可能想使用 TestNG retryAnalyzer 功能,但仅限于 assertStuff(var1, var2)
部分。
因此您应该将 doSomething(param1)
移动到一个单独的方法中,用 @BeforeClass
(或 @BeforeMethod
)注释:
...
@BeforeClass
public void initSomething() {
doSomething(param1);
}
@Test(retryAnalyzer = ThreeRetries.class)
public void testStuff() {
String var1;
String var2;
assertStuff(var1, var2);
}
或者你可以使用@Test
注解强制部分并声明测试之间的依赖关系,例如:
...
@Test
public void initSomething() {
doSomething(param1);
}
@Test(retryAnalyzer = ThreeRetries.class, dependsOnMethods = "initSomething")
public void testStuff() {
String var1;
String var2;
assertStuff(var1, var2);
}
无需依赖 RetryAnalyzer 即可完成此操作的更简单方法(如果您未使用最新的 Beta 版本,即 7.0.0-beta5
或更高版本,RetryAnalyzer 的一个问题是您需要承担责任修剪重试产生的重复测试结果)。
您可以围绕您的 assertStuff()
方法构建一个简单的轮询机制,并让它 return true
或 false
您可以断言。
举个例子。为了方便起见,我使用了 org.openqa.selenium.support.ui.FluentWait
因为它的 API 非常简洁
import java.time.Duration;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.function.Supplier;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.support.ui.FluentWait;
import org.testng.Assert;
import org.testng.annotations.Test;
public class TestClass {
private static final int max = 5;
@Test
public void testStuff() {
doSomething();
boolean wasAsserted = assertStuff(2);
Assert.assertTrue(wasAsserted);
}
@Test
public void testStuffThatFails() {
doSomething();
boolean wasAsserted = assertStuff(10);
Assert.assertTrue(wasAsserted);
}
private boolean assertStuff(int retries) {
final AtomicInteger integer = new AtomicInteger(0);
Supplier<Integer> input = integer::getAndIncrement;
FluentWait<Supplier<Integer>> checker =
new FluentWait<>(input)
.pollingEvery(Duration.ofSeconds(2))
.withTimeout(Duration.ofSeconds(10));
try {
return checker.until(getCondition(retries));
} catch (TimeoutException e) {
return false;
}
}
private Function<Supplier<Integer>, Boolean> getCondition(int retries) {
return integerSupplier -> {
int current = integerSupplier.get();
return current == retries || current > max;
};
}
private void doSomething() {
System.err.println("I did something");
}
}
简单来说,我们也这样试试
int iterate=5;
boolean status=false;
while(iterate >=1 && status ==false) {
try {
assertEquals("false", "true");
status=true;
}catch (AssertionError e) {
iterate--;
Thread.sleep(500);
}
}