单元测试中的 FIRST 原则

单元测试在软件测试中是最基础的测试,它通常在程序员完成编码以后完成,如果是测试驱动的开发 (TDD) 那么更需要在编码完成之前就写好单元测试。单元测试是白盒测试,它只测试软件中的某块代码,而不像集成测试那样需要和软件组件之外的其他组件联合测试,在持续集成 (CI/CD) 中,软件构建 (build) 完成以后的第一个测试可能就是单元测试。

那么程序员在写单元测试的时候要达到什么要求呢? FIRST 原则就是一个指导编写单元测试的原则。FIRST 是下面几个单词的缩写:
Fast,
Isolated/Independent,
Repeatable,
Self-Validating,
Timely/Thorough.

和 SOLID 设计原则一样, FIRST 经常会在程序员之间的交流中被引用到。下面我们简要介绍一下什么是 FIRST。

Fast 快

程序员的每个单元测试应该很快能够被执行完,如果要给一个标准的话,应该是秒级的。单元测试只测试自己的代码,不应该像集成测试那样,连接外部的组件。如果是和时间相关的测试,不应该真的等待时间流逝再看结果,而应该使用 Mock 来模拟时间。

比如下面的代码,我们通过 IDateTimeProvider 接口,模拟了时间,就不用等一个小时才能拿到结果。这个测试显然能够在 1 秒之内结束。

public interface IDateTimeProvider
{
    /// 
    /// Get current date time.
    /// 
    DateTime Now { get; }
}

[TestClass]
public class DateTest {
	[TestMethod]
	void Weekday_should_be_Monday_after_sunday(){		
		var datetimeMock = new Mock<IDateTimeProvider>();
		var car = new MyCar(dateTimeMock) // 
		
		car.Speed = 30; // 30千米/小时
		var now = DateTime.Now;
		datetimeMock.Setup(o => o.Now).Returns(now);
		car.Start();
		datetimeMock.Setup(o => o.Now).Returns(now.AddHours(1));
		int d1 = car.Distance;
		
		Assert.AreEqual(30, d1);
	}
}
Isolated / Independent 隔离 / 独立

每个单元测试不应该依赖于其他的单元测试结果。它应该能够独立运行,而不是要求某些单元测试完成以后才能完成这个单元测试。同样的某个单元测试的结果,也不应该影响其他单元测试的运行结果。如果需要一些配置,这些配置应该在本单元测试的初始化阶段完成。

Repeatable 可重复

单元测试无论在任何环境下都应该得到相同的结果,而不应该受到数据库,网络等环境因素的影响。单元测试的结果只跟我们的代码有关,而不应该和环境有关。如果单元测试失败,它应该是我们代码的某个地方有问题,或者是初始值设置的问题。这样在拿到单元测试的结果的时候,我们就可以专注于我们的代码,而不是环境因素。

Self-Validating 自我校验

单元测试只会返回一个布尔结果,要么成功,要么失败,而不是要程序员自己检查运行结果以后才能判断是否成功。在单元测试中,我们应该加上断言,比如 Assert.IsTrue, Assert.AreEqual等,这些断言直接决定测试结果是否成功。

Timely / Thorough 及时/完整

如果我们的开发方式是测试驱动开发 (TDD) ,那么这一条指的是单元测试应该在生产代码 (production code) 完成前完成。如果你不用 TDD,这一条指的是单元测试要达到下面的标准

  • 覆盖所有基本路径 (Happy Path)
  • 边界条件
  • 安全问题
  • 覆盖所有可能的功能性用例,而不只是应付 100% 代码覆盖率的要求
结论

单元测试是代码测试中的基础测试,FIRST是写好单元测试的重要原则,它要求我们的单元测试快速,独立,可重复,自我校验,及时/完整。

本文是程序员经常用到的原则之一,下面我们还会介绍 AAA 和 DRY。

下面的链接中,有我写的软件设计之 SOLID 原则,欢迎阅读。

参考链接:

软件设计中的 SOLID 原则
编写代码中的 DRY 原则
单元测试中的 AAA 规则
F.I.R.S.T principles of testing
Writing Your F.I.R.S.T Unit Tests

你可能感兴趣的:(架构,领导力,单元测试,软件测试)