UT单元测试总结基础篇

最近需要在团队中引入单元测试实践,特地买了《单元测试的艺术》这本书来学习,在单元测试领域这本书写得相当好,非常系统和完善,对单元测试希望有一个更深入的认识的同学可以找来读一读。

这篇文章对UT基础概念做了一个简单的总结,下一篇提高篇中再总结一下在Java项目中如何使用PowerMock和Mockito进行测试桩和模拟对象的创建,以规避测试时代码对外部模块的依赖问题。

什么是单元测试

一个单元测试是一段代码,这段代码调用一个工作单元,并检验该工作单元的最终结果是否与期望的一致。

工作单元可以是一个方法,类或者功能单元。

为了增强测试代码的可维护性,我们通常针对用户更可见的功能单元编写测试用例。

单元测试具有什么特性

  • 可以被自动化运行
  • 很容易实现
  • 运行速度很快
  • 测试结果是稳定的
  • 能完全控制被测试的单元,不包含外部依赖
  • 各测试用例相互独立,无依赖关系

单元测试的价值

  • 帮助发现代码缺陷
  • 将缺陷发现的时间提前,开发人员可在本地频繁运行测试代码
  • 修改或者重构代码时确保没有影响现有功能
  • 使得开发人员提交代码更有信心

虽然在一定程度上单元测试增加了需求开发所需的时间,但是单元测试大大提升了代码的质量和可维护性,使得产品的整体交付周期缩短了。

什么时候写单元测试

为了最大化单元测试的价值,需要引入TDD(测试驱动开发),在产品代码编写之前写单元测试。

TDD流程: 首先编写一个会失败的测试,然后编写产品代码,接着调试用例确保通过,接下来重构代码或者创建另一个测试。

怎么写单元测试

使用单元测试框架编写测试代码,Java项目中推荐使用Junit或者TestNG框架。

一个简单的单元测试代码结构如下:

public class AppTest {
    @Before
    public void setUp() {
        // 执行运行前准备工作
    }

    @After
    public void tearDown() {
        // 执行运行后销毁工作
    }

    @Test
    public void unitOfWorkName_Scenario_ExpectedBehavior() {
        // 准备阶段

        // 执行阶段

        // 验证阶段
    }
}

每一个测试用例需要包括准备阶段,执行阶段和最后的验证阶段。

伪造对象

在编写测试代码的过程中会发现,被测代码通常会与一些不能控制的外部依赖项或者尚未实现的模块进行交互,我们通常会使用伪造对象来规避依赖项问题。

伪造对象通常包括Stub和Mock,区别如下:
Stub: 测试桩或者存根,在测试时提前定义好接口的请求和响应,作为伪造的对象使得被测代码能够屏蔽掉依赖顺利地执行。
Mock: 模拟对象,也是伪造对象,在测试用例中进行断言时使用,以验证代码与其他依赖项之间的交互行为。

Java项目中推荐使用PowerMock或者JMockit框架进行测试桩和模拟对象的创建。

如何组织和运行单元测试

为方便管理,测试代码和产品代码放在同一个项目中的不同文件夹下,使用Maven工具管理的Java项目产品代码位于src/main目录下,单元测试代码位于src/test目录下。为了增强测试代码的可读性,每一个测试用例应该与被测工作单元位于同一个package下,每个测试用例的命名规范为: unitOfWorkName_Scenario_ExpectedBehavior,需要描述清楚被测工作单元,测试场景和期待的行为。

任何开发或者测试人员可在本地非常快速地运行单元测试代码。

开发人员在提交代码之前需要在本地运行单元测试,当所有测试用例通过后才能提交代码。

单元测试需要集成到CI平台上,每次构建代码都需要自动运行单元测试,如果有用例不能通过,需要尽快修复。

参考资料:《单元测试的艺术》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章