是否有可能在测试类中的测试级套件级别创建一个超时,而不是单个方法



我正在研究我们在testng中遇到的问题。我想知道是否有一种方法可以在测试类级别上指定超时,而不是单个方法。我知道在套件XML级别上的"超时",但这然后适用于每个测试类中的每种测试方法。

我真的可以指定适用于XML中每个类的超时,因此我们可以考虑改进这些类。

这是不支持的。但是Testng确实为您提供了使用功能,您应该能够在很少的努力中自行构建它。[我正在使用testng 7.0.0-beta7为此,这是发布此答案时最新发布的testng版本]

  1. 您首先需要创建一个自定义注释,该注释可用于在班级级别定义超时。
  2. 然后,您构建了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

超时只能以两种方式配置。

  1. 在套房级别。
  2. 在每种测试方法中。

基本上测试类中的测试类包含您的测试方法,这是您对测试条件的主张(在您的情况下,基于超时(,因此它们只是正常的Java类。

您可以尝试将单个测试方法保留为每个测试ng类,并将超时添加到该方法中,也可以创建一个外部方法,该方法将根据方法执行时间进行通过或失败决定。

最新更新