Realize source code analysis of junitperf based on junit5



The previous section introduced the implementation of junitperf based on junit4, but it can be found that the way of defining variables is still not elegant enough.

Can that make it more natural for users?

Yes, junit5 brings us more powerful functions.

Further reading:

Talking about performance testing

analyzes the source code of junitperf based on junit4, a secret that 99% of people don’t know about junit4!


No comparison, no harm

Let's first review the writing of junit4:

public class HelloWorldTest {

    public JunitPerfRule junitPerfRule = new JunitPerfRule();

     * 单一线程,执行 1000ms,默认以 html 输出测试结果
     * @throws InterruptedException if any
    @JunitPerfConfig(duration = 1000)
    public void helloWorldTest() throws InterruptedException {
        System.out.println("hello world");


Let's take a look at the writing of junit5:

public class HelloWorldTest {

    @JunitPerfConfig(duration = 1000)
    public void helloTest() throws InterruptedException {
        System.out.println("Hello Junit5");


JunitPerfRule magically disappeared? How did all this happen?

Let us uncover the mystery of junit5 together.

Junit5 more powerful features


We just specified a simple @JunitPerfConfig annotation, then the problem must lie in this annotation.

It is defined as follows:

import java.lang.annotation.*;

 * 执行接口
 * 对于每一个测试方法的条件配置
 * @author bbhou
 * @version 1.0.0
 * @since 1.0.0
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD})

public @interface JunitPerfConfig {

    // 属性省略


@Retention and @Target are regular annotations in java, so I won’t repeat them here.

Let's focus on the remaining two notes.


When we used to write unit tests, we always wrote a @Test annotation. You will find that even this annotation is omitted in junit5.

So, where did he go?

The answer is @TestTemplate statement, which is used to identify that this method is a unit test method, and idea will recognize it, which is very flexible and powerful.


This annotation empowers our annotation.

Look at the name, it is an extension, the implementation of extension is the class PerfConfigProvider we specify


Let's take a look at the implementation of PerfConfigProvider.

public class PerfConfigProvider implements TestTemplateInvocationContextProvider {

    public boolean supportsTestTemplate(ExtensionContext context) {
        return context.getTestMethod()
                .filter(m -> AnnotationSupport.isAnnotated(m, JunitPerfConfig.class))

    public Stream<TestTemplateInvocationContext> provideTestTemplateInvocationContexts(ExtensionContext context) {
        return Stream.of(new PerfConfigContext(context));


The implementation is very simple, the first is a filter.

Only @JunitPerfConfig annotations will take effect.

The following is the context PerfConfigContext of our custom implementation.


PerfConfigContext implements TestTemplateInvocationContext and simply encapsulates the native ExtensionContext.

public class PerfConfigContext implements TestTemplateInvocationContext {

    // 省略内部属性

    public List<Extension> getAdditionalExtensions() {
        return Collections.singletonList(
                (TestInstancePostProcessor) (testInstance, context) -> {
                    final Class clazz = testInstance.getClass();
                    // Group test contexts by test class
                    ACTIVE_CONTEXTS.putIfAbsent(clazz, new ArrayList<>());

                    EvaluationContext evaluationContext = new EvaluationContext(testInstance,
                    StatisticsCalculator statisticsCalculator = perfConfig.statistics().newInstance();
                    Set<Reporter> reporterSet = getReporterSet();
                    try {
                        new PerformanceEvaluationStatement(evaluationContext,
                    } catch (Throwable throwable) {
                        throw new JunitPerfRuntimeException(throwable);

After writing this, we will find that it has returned to the similarity with junit4.

Friends who don't understand can go to see the original implementation, so I won't go into details here.

The rest is the same as the original junit4 implementation.


It can be found that the expansion capabilities provided by junit5 are more powerful and flexible. It allows us to define our own annotations.

This annotation is used to make the user no different from using the original junit5 annotation.

I have to sigh with emotion that the back wave of the Yangtze River pushed the front wave, and the front wave died on the beach.


阅读 190

java 工具
整理 java 开发过程中有用的工具
120 声望
14 粉丝
0 条评论

120 声望
14 粉丝