自动化测试

2022-08-04  本文已影响0人  bowen_wu

概述

测试类型

测试形态

测试的基本形态

surefire plugin

jacoco

测试的生命周期

对于每一个测试用例都会创建全新的测试类实例

测试类的生命周期

  1. 调用 @BeforeClass/@BeforeAll
    @BeforeAll // @BeforeAll 必须放置在静态方法上
    public static void setUpAll() {}
    
  2. 创建测试类对象实例
  3. @Before/@BeforeEach
    @BeforeEach
    public void setUp() {}
    
  4. @Test
  5. @After/@AfterEach
    @AfterEach
    public void cleanUp() {}
    
    @AfterEach
    public void tearUp() {}
    
    @AfterEach
    public void tearDown() {}
    
  6. 调用 @AfterClass/@AfterAll

断言 & 假设

单元测试

Mockito

Mock 实现

集成测试

Mock 数据库

H2 数据库

内存数据库

public class IntegrationTest {
    @BeforeEach
    public void setUp() {
        // 初始化内存数据库,以备测试
        ClassicConfiguration configuration = new ClassicConfiguration();
        configuration.setDataSource(
                "jdbc:h2:mem:test",
                "test",
                "test"
        );

        Flyway flyway = new Flyway(configuration);
        flyway.clean();
        flyway.migrate();

        // 注册一个测试用户,以备测试
        registerUser("test", "test");
    }
}

Docker 启动数据库

Mock Redis

  1. 使用 Redis 的 Mock 第三方库
  2. 使用 Redis Docker 容器

Mock Bean

Mock 第三方服务 => @MockBean => 将某些 Bean Mock

黑盒测试

  1. 在测试 JVM 中启动 Spring 容器
  2. 向容器发送 HTTP 请求进行测试

白盒测试

  1. 在测试 JVM 中启动 Spring 容器
  2. 其中的部分 Bean 进行 Mock 替换
  3. 向集成环境(待测容器)中注入 Mock 的 Bean 实例
  4. 写 Java 代码进行测试

JUnit 4

JUnit4 扩展性太差

  1. 每个类只能有一个 Runner
  2. 每个类只能有一个 Rule => 多个 Rule 使用 RuleChain,将多个 Rule 组合在一起

@RunWith 与自定义 Runner

@Rule

// 不推荐这么操作,每个测试太重了
public class JUnit4Test {
    @Rule
    public PrepareTestDockerMySqlRule prepareTestDockerMySqlRule = new PrepareTestDockerMySqlRule();

    @Test
    public void test() {
    }

    @Test
    public void test2() {
    }
}

class PrepareTestDockerMySqlRule extends ExternalResource {
    protected void before() throws Throwable {
        System.out.println("Before!");
        new ProcessBuilder("docker", "run", "-d", "--name", "test-mysql", "mysql:5.7.27")
                .inheritIO().start().waitFor();

        // 1. 可以使用定时器监控 docker 容器状态,docker 容器启动之后再进行下一个任务
        // 2. 可以使用 docker inspect 命令检查 docker 容器状态是否可用
        Thread.sleep(20 * 1000);
    }

    protected void after() {
        try {
            new ProcessBuilder("docker", "rm", "-f", "test-mysql")
                    .inheritIO()
                    .start()
                    .waitFor();
        } catch (InterruptedException | IOException e) {
            throw new RuntimeException(e);
        }
        System.out.println("After!");
    }
}

JUnit 5

JUnit5

JUnit5 扩展机制

可以同时应用多个 Extension => JUnit5 Third party Extensions

  1. ExecutionCondition => ExecutionCondition defines the Extension API for programmatic, conditional test execution.
  2. TestInstanceFactory => TestInstanceFactory defines the API for Extensions that wish to create test class instances.
  3. TestInstancePostProcessor => TestInstancePostProcessor defines the API for Extensions that wish to post process test instances.
  4. ParameterResolver => ParameterResolver defines the Extension API for dynamically resolving parameters at runtime.
  5. TestWatcher => TestWatcher defines the API for extensions that wish to process the results of test method executions. Specifically, a TestWatcher will be invoked with contextual information for the following events.
  6. Test Lifecycle Callbacks
public class PrepareMemoryDatabaseExtension implements BeforeEachCallback, AfterEachCallback {
    @Override
    public void afterEach(ExtensionContext extensionContext) throws Exception {
        System.out.println("After!");
    }

    @Override
    public void beforeEach(ExtensionContext extensionContext) throws Exception {
        // 初始化内存数据库,以备测试
        System.out.println("Before!");
        ClassicConfiguration configuration = new ClassicConfiguration();
        configuration.setDataSource(
                "jdbc:h2:mem:test",
                "test",
                "test"
        );

        Flyway flyway = new Flyway(configuration);
        flyway.clean();
        flyway.migrate();
    }
}

@ExtendWith(PrepareMemoryDatabaseExtension.class)
class XxxIntegrationTest {
    @Test
    public void test() {
    }
}

知识点

  1. mvn clean test -Dtest=XxxTest => 仅仅执行 XxxTest 这个测试
  2. 当运行测试时 => 一个新的 JVM 会被创建 => 隔离测试的环境,避免互相影响
  3. ** => ant path pattern
  4. flaky test
  5. 将 suspend 设为 y
    Remote JVM Debug
上一篇下一篇

猜你喜欢

热点阅读