随机化TestNG调用

时间:2018-02-09 23:19:16

标签: unit-testing testing testng

类似于:Run TestNG tests in random order但不同,因为此问题不包括调用。

TestNG将测试本身随机化,但调用将全部连续运行。例如:

@Test(invocation = 2)public void A {}
@Test(invocation = 2)public void B {}

将运行AABB或BBAA 但我希望让它们以真正随机的方式运行(ABAB,BABA等)

有没有用TestNG实现这一点,目前我所能想到的就是将我的测试改为一个控制顺序的测试调用的方法,但我希望我忽略了一些内置于TestNG的内容。

1 个答案:

答案 0 :(得分:0)

你可以建立在利用IMethodInterceptor的相同概念上。

这是你怎么做的。 首先,您构建一个可用于表示调用计数的自定义注释。

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;

@Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@Target({METHOD, TYPE})
public @interface InvocationCount {
    int value() default 1;
}

现在,您可以自定义方法拦截器,以便查找自定义注释,并在此基础上添加更多实例,然后最终随机化生成的集合。

import org.testng.IMethodInstance;
import org.testng.IMethodInterceptor;
import org.testng.ITestContext;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;

public class LocalInterceptor implements IMethodInterceptor {

    @Override
    public List<IMethodInstance> intercept(List<IMethodInstance> methods, ITestContext context) {
        List<IMethodInstance> altered = new ArrayList<>();
        for (IMethodInstance method : methods) {
            InvocationCount count = method.getMethod().getConstructorOrMethod().getMethod().getAnnotation(InvocationCount.class);
            if (count == null) {
                altered.add(method);
            } else {
                if (count.value() > 1) {
                    for (int i = 0; i < count.value(); i++) {
                        altered.add(method);
                    }
                }
            }
        }
        long seed = System.nanoTime();
        Collections.shuffle(altered, new Random(seed));
        return altered;
    }
}

您的测试现在看起来如下

import org.testng.annotations.Listeners;
import org.testng.annotations.Test;

@Listeners(LocalInterceptor.class)
public class SampleTestClass {

    @InvocationCount(2)
    @Test
    public void A() {
        System.err.println("A()");
    }

    @InvocationCount(3)
    @Test
    public void B() {
        System.err.println("B()");
    }
}

这是一个示例输出(记者有一些StringIndexOutOfBoundsException个例外,但我认为这与此无关)

...
... TestNG 6.14.2 by Cédric Beust (cedric@beust.com)
...
B()
A()
B()
B()
A()
PASSED: B
PASSED: A
PASSED: B
PASSED: B
PASSED: A

===============================================
    48715503_test
    Tests run: 5, Failures: 0, Skips: 0
===============================================

===============================================
48715503_Suite
Total tests run: 5, Failures: 0, Skips: 0
===============================================