Skip to content

JUnit 4 测试方法执行顺序

🏷️ JUnit

在 JUnit 5 中可以通过 @TestMethodOrder@Order 自定义测试用例的执行顺序[1],但在 JUnit 4 中没有 @TestMethodOrder 注解,对应的是 @FixMethodOrder 注解,不过不如前者使用方便。

@FixMethodOrder 注解的配置项是一个 MethodSorters 类型的枚举,共有三种排序方式(英文是代码中的备注):

  • NAME_ASCENDING

    Sorts the test methods by the method name, in lexicographic order, with {@link Method#toString()} used as a tiebreaker

  • JVM

    Leaves the test methods in the order returned by the JVM. Note that the order from the JVM may vary from run to run

  • DEFAULT

    Sorts the test methods in a deterministic, but not predictable, order

要实现按指定的固定顺序执行的话,只能使用 NAME_ASCENDING 类型的排序。这种方式需要测试方法按照固定的规则命名(如以 testNNN 开头[2]),对代码有一定的侵入。

下面示例代码中的测试方法会以如下顺序执行:

  1. test_001_save
  2. test_002_update
  3. test_003_detail
  4. test_004_page
  5. test_005_delete

示例代码:

java
package me.liujiajia.junit4.controller;

import com.alibaba.fastjson.JSONObject;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;

@AutoConfigureMockMvc
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class TestMethodExecutionOrderControllerTests {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void test_001_save() throws Exception {
        ResultActions resultActions = mockMvc.perform(MockMvcRequestBuilders
                .post("/test-method-execution-order/save")
                .content(JSONObject.toJSONString(param))
                .contentType(MediaType.APPLICATION_JSON)
        );
        resultActions.andExpect(MockMvcResultMatchers.status().isOk())
                .andDo(MockMvcResultHandlers.print());
    }

    @Test
    public void test_002_update() throws Exception {
        ResultActions resultActions = mockMvc.perform(MockMvcRequestBuilders
                .post("/test-method-execution-order/update")
                .content(JSONObject.toJSONString(param))
                .contentType(MediaType.APPLICATION_JSON)
        );
        resultActions.andExpect(MockMvcResultMatchers.status().isOk())
                .andDo(MockMvcResultHandlers.print());
    }

    @Test
    public void test_003_detail() throws Exception {
        ResultActions resultActions = mockMvc.perform(MockMvcRequestBuilders
                .get("/test-method-execution-order/detail")
                .param("code", "a code")
                .contentType(MediaType.APPLICATION_JSON)
        );
        resultActions.andExpect(MockMvcResultMatchers.status().isOk())
                .andDo(MockMvcResultHandlers.print());
    }

    @Test
    public void test_004_page() throws Exception {
        ResultActions resultActions = mockMvc.perform(MockMvcRequestBuilders
                .post("/test-method-execution-order/page")
                .content(JSONObject.toJSONString(param))
                .contentType(MediaType.APPLICATION_JSON)
        );
        resultActions.andExpect(MockMvcResultMatchers.status().isOk())
                .andDo(MockMvcResultHandlers.print());
    }

    @Test
    public void test_005_delete() throws Exception {
        ResultActions resultActions = mockMvc.perform(MockMvcRequestBuilders
                .post("/test-method-execution-order/delete")
                .content(JSONObject.toJSONString(param))
                .contentType(MediaType.APPLICATION_JSON)
        );
        resultActions.andExpect(MockMvcResultMatchers.status().isOk())
                .andDo(MockMvcResultHandlers.print());
    }
}

  1. JUnit5 指定 @Test 的执行顺序 ↩︎

  2. Junit 单元测试 | 注解和执行顺 ↩︎