我正在研究我们在testng中遇到的问题。我想知道是否有一种方法可以在测试类级别上指定超时,而不是单个方法。我知道在套件XML级别上的"超时",但这然后适用于每个测试类中的每种测试方法。
我真的可以指定适用于XML中每个类的超时,因此我们可以考虑改进这些类。
这是不支持的。但是Testng确实为您提供了使用功能,您应该能够在很少的努力中自行构建它。[我正在使用testng 7.0.0-beta7
为此,这是发布此答案时最新发布的testng版本]
- 您首先需要创建一个自定义注释,该注释可用于在班级级别定义超时。
- 然后,您构建了
org.testng.IAnnotationTransformer
的实现,该实现可以从测试方法的声明类中读取此自定义注释的值,如果存在注释,则它将更改@Test
注释的timeout
属性。
。
这是一个完整的fled示例,显示了这一点。
自定义注释如下所示:
import static java.lang.annotation.ElementType.TYPE;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@Target({TYPE})
public @interface Timeout {
long inMs() default 0;
}
消耗上述自定义注释的测试类看起来像
import java.util.concurrent.TimeUnit;
import org.testng.annotations.Test;
@Timeout(inMs = 15)
public class TestClass1 {
@Test
public void sleepFor10Ms() throws InterruptedException {
TimeUnit.MILLISECONDS.sleep(10);
}
@Test
public void sleepFor20Ms() throws InterruptedException {
TimeUnit.MILLISECONDS.sleep(20);
}
}
import java.util.concurrent.TimeUnit;
import org.testng.annotations.Test;
@Timeout(inMs = 5)
public class TestClass2 {
@Test
public void sleepFor10Ms() throws InterruptedException {
TimeUnit.MILLISECONDS.sleep(10);
}
@Test
public void sleepFor20Ms() throws InterruptedException {
TimeUnit.MILLISECONDS.sleep(20);
}
}
注释变压器看起来像
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import org.testng.IAnnotationTransformer;
import org.testng.annotations.ITestAnnotation;
public class TimeoutSetter implements IAnnotationTransformer {
@Override
public void transform(
ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) {
if (testMethod == null) {
return;
}
Timeout timeout = testMethod.getDeclaringClass().getAnnotation(Timeout.class);
if (timeout == null) {
return;
}
annotation.setTimeOut(timeout.inMs());
}
}
这是套件文件的样子
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" verbose="2">
<listeners>
<listener class-name="com.rationaleemotions.stackoverflow.qn57307245.TimeoutSetter"/>
</listeners>
<test name="Test">
<classes>
<class name="com.rationaleemotions.stackoverflow.qn57307245.TestClass1"/>
<class name="com.rationaleemotions.stackoverflow.qn57307245.TestClass2"/>
</classes>
</test>
</suite>
执行输出
... TestNG 7.0.0-beta7 by Cédric Beust (cedric@beust.com)
...
org.testng.internal.thread.ThreadTimeoutException: Method com.rationaleemotions.stackoverflow.qn57307245.TestClass1.sleepFor20Ms() didn't finish within the time-out 15
at java.util.concurrent.ThreadPoolExecutor$Worker.unlock(ThreadPoolExecutor.java:652)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
org.testng.internal.thread.ThreadTimeoutException: Method com.rationaleemotions.stackoverflow.qn57307245.TestClass2.sleepFor10Ms() didn't finish within the time-out 5
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:132)
at org.testng.internal.InvokeMethodRunnable.runOne(InvokeMethodRunnable.java:51)
at org.testng.internal.InvokeMethodRunnable.run(InvokeMethodRunnable.java:41)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
org.testng.internal.thread.ThreadTimeoutException: Method com.rationaleemotions.stackoverflow.qn57307245.TestClass2.sleepFor20Ms() didn't finish within the time-out 5
at sun.misc.Unsafe.compareAndSwapInt(Native Method)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.compareAndSetWaitStatus(AbstractQueuedSynchronizer.java:2303)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.transferForSignal(AbstractQueuedSynchronizer.java:1674)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.doSignalAll(AbstractQueuedSynchronizer.java:1888)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.signalAll(AbstractQueuedSynchronizer.java:1957)
at java.util.concurrent.ThreadPoolExecutor.tryTerminate(ThreadPoolExecutor.java:716)
at java.util.concurrent.ThreadPoolExecutor.processWorkerExit(ThreadPoolExecutor.java:1014)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
PASSED: sleepFor10Ms
FAILED: sleepFor20Ms
org.testng.internal.thread.ThreadTimeoutException: Method com.rationaleemotions.stackoverflow.qn57307245.TestClass1.sleepFor20Ms() didn't finish within the time-out 15
at java.util.concurrent.ThreadPoolExecutor$Worker.unlock(ThreadPoolExecutor.java:652)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
FAILED: sleepFor10Ms
org.testng.internal.thread.ThreadTimeoutException: Method com.rationaleemotions.stackoverflow.qn57307245.TestClass2.sleepFor10Ms() didn't finish within the time-out 5
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:132)
at org.testng.internal.InvokeMethodRunnable.runOne(InvokeMethodRunnable.java:51)
at org.testng.internal.InvokeMethodRunnable.run(InvokeMethodRunnable.java:41)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
FAILED: sleepFor20Ms
org.testng.internal.thread.ThreadTimeoutException: Method com.rationaleemotions.stackoverflow.qn57307245.TestClass2.sleepFor20Ms() didn't finish within the time-out 5
at sun.misc.Unsafe.compareAndSwapInt(Native Method)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.compareAndSetWaitStatus(AbstractQueuedSynchronizer.java:2303)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.transferForSignal(AbstractQueuedSynchronizer.java:1674)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.doSignalAll(AbstractQueuedSynchronizer.java:1888)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.signalAll(AbstractQueuedSynchronizer.java:1957)
at java.util.concurrent.ThreadPoolExecutor.tryTerminate(ThreadPoolExecutor.java:716)
at java.util.concurrent.ThreadPoolExecutor.processWorkerExit(ThreadPoolExecutor.java:1014)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
===============================================
Test
Tests run: 7, Failures: 3, Skips: 0
===============================================
===============================================
Suite
Total tests run: 4, Passes: 1, Failures: 3, Skips: 0
===============================================
Process finished with exit code 0
超时只能以两种方式配置。
- 在套房级别。
- 在每种测试方法中。
基本上测试类中的测试类包含您的测试方法,这是您对测试条件的主张(在您的情况下,基于超时(,因此它们只是正常的Java类。
您可以尝试将单个测试方法保留为每个测试ng类,并将超时添加到该方法中,也可以创建一个外部方法,该方法将根据方法执行时间进行通过或失败决定。