单元测试最佳实践

2023-08-12  本文已影响0人  JJNile

原则

Fast 快速

单元测试应该尽量保持简单和快速,应该做到毫秒级

需要考虑输入数据的大小、数量和质量对代码性能的影响,并对测试用例的执行时间进行评估。

Isolate 隔离

测试用例应该是独立的,不受其他测试用例的影响,不依赖其他单元测试的执行顺序,不依赖外部资源。

多关注单测的隔离性,同时也会驱动类、方法实现单一职责(SRP)

Repeatabel 可重复性

每次都是重复的入参和结果,运行都是固定不变的

不受外界的影响,如:

Self-Validating 自验证性

必须使用断言 Assert 方式来进行正确性验证,而不是 var_dump、System.out、Println 等输出进行人肉校验。

单测必须走持续集成&自动化测试,而不是人工上线运行。

Timely 及时性

单元测试应该具有及时性,先于开发而不是后续开发完在补充。

如何限制后续补充单元测试的坏习惯:

除了 FIRST 原则还有 AIR 原则、ASCII 原则等,具体都没啥大区别,可参考那些年,我们写过的无效单元测试_阿里云云栖号的博客-CSDN 博客

其他准则

BCDE 原则,以保证被测试模块的交付质量。

用例结构

一般都是一个三段式的用例结构,目前较常见的就是 AAA 和 GWT,整体测试结构时相同的。如果说两者有什么区别的话,那区别在于 AAA 的构思更倾向于技术实现,GWT 更倾向于业务流程。

与其说 AAA 与 GWT 区别,不如说 TDD(Test-Driven Development) 和 BDD(Behavior-Driven Development),区别。

AAA

Arrange-Act-Assert 是单元测试时的常见模式。顾名思义,它由三个主要操作组成:

例如,对于以下方法的测试:

public int add(int x, int y) {
    return x + y;
}

使用 AAA 方法的测试代码如下:

@Test
public void testAdd() {
    // Arrange
    int x = 3;
    int y = 4;
    MyClass myClass = new MyClass();

    // Act
    int result = myClass.add(x, y);

    // Assert
    assertEquals(7, result);
}

GWT

Given-When-Then

例如,对于以下方法的测试:

public String greeting(String name) {
    if (name == null) {
        throw new IllegalArgumentException("Name cannot be null");
    }
    return "Hello, " + name + "!";
}

使用 GWT 方法的测试代码如下:

@Test
public void testGreeting() {
    // Given 准备用例所需的上下文
    String name = "Alice";
    MyClass myClass = new MyClass();

    // When 调用待测的函数
    String result = myClass.greeting(name);

    // Then 断言
    assertEquals("Hello, Alice!", result);
}

@Test(expected = IllegalArgumentException.class)
public void testGreetingWithNullName() {
    // Given
    String name = null;
    MyClass myClass = new MyClass();

    // When
    myClass.greeting(name);

    // Then (expecting exception)
}

参考

二、优秀单元测试的五个特征 FIRST - 纪玉奇 - 博客园
单元测试准则
要对自己写的代码负责 | 蓝士钦
有效的单元测试之一--代码坏味道(读书笔记精华带源码)
unit-test-specification/README.md at master · cyneck/unit-test-specification · GitHub

上一篇下一篇

猜你喜欢

热点阅读