美文网首页程序员
如何写出好的单元测试

如何写出好的单元测试

作者: PageThinker | 来源:发表于2019-12-20 18:56 被阅读0次

我们知道编写测试能够带来很多好处。那么除了只是停留在编写测试上,我们应该如何编写好的测试呢?

这里翻译了一篇2012年Eric Lewis的一篇文章《How to write good tests》

提交历史显示,这篇内容还在一直维护。

文章变更历史

正文开始

01 保持测试代码的短小可读

要实现这一点就必须产品代码进行重构。否则测试端就会因遗留代码而变得腐败。如果测试代码不能很容易的进行重构,那么产品代码同样不容易重构,从而导致了遗留代码。永远都要勇敢的进行重构。

02 避免编写重复的代码

下面这个场景:

一个将参数放置到模版中的方法,代码如下:

public void format(String dateString) {
   return String.formate("Update date is %s", dateString);
}

我们对这个测试的代码不应该是这样

@Test
void should_format_date_label_when_format_given_a_date_string() {
    String dateString = "2019/12/20";

    String formatedDate = DateUtils.format(dateString);

    assertThat(formatedDate).isEquals(String.formate("Update date is %s", dateString))
}

一般而言,不应该在测试和代码之间重复逻辑。因此,上面测试断言中,将业务代码中的实现复制到测试代码中并不可取。在这种情况下,我们应该关注输入/输出,应该使用一个固定期望的结果。

@Test
void should_format_date_label_when_format_given_a_date_string() {
    String dateString = "2019/12/20";

    String formatedDate = DateUtils.format(dateString);

    assertThat(formatedDate).isEquals("Update date is 2019/12/20");
}

ps:当然既然String.formate()方法能够提供实现,没有必要在封装一个方法,所以上面的例子不是一个好例子,但是意图在说明应该如何验证结果。

03 除了覆盖正向测试,测试用例应该尽可能多的错误代码的路径

通常,这也是练习TDD最好的实现方式。使用TDD可以在设计的时候辨别出造成破坏的地方。不要认为为一个小的代码片段编写简单的测试不值得,你永远不知道什么时候、因为什么而修改这段代码。

可与使用PIT(突变检测系统 http://pitest.org/)来对测试代码的有效性进行检测。

04 不要Mock一个你不拥有的类型

TDD既涉及到测试,也涉及到设计。这不是一个硬性要求,但是如果真的这样做了,很可能会带来一些影响。

场景:假设你在使用一个第三方提供的工具API时。如果对API进行了mock,那么会有什么杨的结果?

  1. 你的测试当时是通过的。
  2. 如果第三方API进行了升级,会有什么结果?会造成单元测试通过,但是实际调用的时候却失败或者并没有返回自己想要的结果。
  3. 这样的设计也表明和第三方API的紧密度不够。
  4. 如果第三方API非常复杂,也会导致当前测试代码必须在大量mock之后才能正常工作。这本身也损害了短小易读的目的。

取而代之,我们应该也是到使用底层这些API的风险,我们应该为第三方库和API编写封装器。为了验证第三方提供API的可用性,我们需要编写集成测试,并让这些测试保持短小、易读。

还有一些人记录了当mock一个不是自己代码库的类型的时候,遇到的痛:

  1. http://davesquared.net/2011/04/dont-mock-types-you-dont-own.html
  2. http://www.markhneedham.com/blog/2009/12/13/tdd-only-mock-types-you-own
  3. http://blog.8thlight.com/eric-smith/2011/10/27/thats-not-yours.html
  4. http://stackoverflow.com/questions/1906344/should-you-only-mock-types-you-own

05 反模式:Mock一切对象

如果所有的代码都mock了,那么我们怎么测试业务代码?不要害怕不使用Mock的方法。

06 不要Mock值对象

为什么有的人会Mock只值对象呢?

因为实例化对方是一件很痛苦的事情。

如果创建一个对象很复杂,那么很可能意味着我们需要进行认真的重构。不Mock的话应该怎么处理?可以使用一些IDE插件、Lombok等,让构造值对象变的简单,也可以在测试类中创建有意义的工厂方法。

abstract class CustomerCreations {
   public static Customer customer_with_a_single_item_in_the_basket() {
       // long init sequence
   }
}

Mockito更加关注对象之间的交互。

07 读读书籍,做做刻意练习

原文中推荐阅读这本书:"Growing Object Oriented Software Guided by Tests"。

但是这本书现在市场已经无法找到了,留在我么身边的还有Code Dojo或者一些其他TDD实践练习,通过反复练习一些场景,思考分析,能够帮助我们写出好的测试。

原文

How to write good tests--Eric Lewis edited this page on Mar 22 · 11 revisions

相关文章

  • 如何写出好的单元测试

    我们知道编写测试能够带来很多好处。那么除了只是停留在编写测试上,我们应该如何编写好的测试呢? 这里翻译了一篇201...

  • 上手unittest读这篇文章就够了

    引言 本文主要介绍了如下内容 单元测试的定义; python中如何写基础的unittest单元测试; 详解unit...

  • 6.18日记

    6.18上午阅读了卡普斯标题文案,如何写出好的标题,关于诉求,如何写出好的开头,一边阅读,一边用笔记本做学习线索。...

  • 单元测试

    本文将介绍以下内容: iOS开发中添加单元测试的方法。 如何写单元测试用例及用例组。 介绍单元测试的一些基础概念。...

  • 小白如何写出好文章清单

    近期读了一篇关于小白如何写出好文章的短文,结合以前读过的文章,心有所感,遂整理了一份小白如何写出好文章的清单(以下...

  • 怎样写出好代码

    怎样写出好代码 【指南】如何写出好代码 代码就是设计(Jack W.Reeves, 1992) 代码是最有价值的交...

  • React单元测试策略及落地

    单元测试是现代软件开发最基本,也普遍落地不力的实践。市面关于React单元测试的文章,普遍停留在“可以如何写”和介...

  • 如何写出个惊爆人眼球的网络小说开篇【网文写作技巧】

    我是老司机讲如何写出赚钱的网文。 今天讲如何写出个惊爆人眼球的开篇。 在讲如何写出好开篇之前,先讲什么是不好的开篇...

  • 笔上那点事

    你还在写简书吗? 如何写简书? 如何写文字? 如何写小说? 如何用生动的文字写出好的故事? 无非两点 1.多学熟练...

  • 马上写出好文章

    【书籍】马上写出好文章 【标题】如何写出好文章 【字数】719 【正文】 001激励读者 以激励他人的方式去写作,...

网友评论

    本文标题:如何写出好的单元测试

    本文链接:https://www.haomeiwen.com/subject/dlwinctx.html