我在 v 站的回复还真没怎么复制粘贴过别人的东西。昨天吃饭的时候看到这个问题,用手机打了一点字,吃完回来在电脑上编辑了一下,删掉了附图,因为是项目的测试代码不应该发出来
我的回复里一直在强调测试代码的可维护性,因为这是切身的体会,我们团队早期对单元测试也不熟悉,照着文档就开写,追求 100%的覆盖率,每个 private 方法都用反射搞出来把测试写了,这样做了之后覆盖率报告 x 是很好看了,全是绿色,但是到了之后需求来了要修改代码的时候就很难过了,不仅要改业务代码,还要修改大量的测试代码,这对开发来说是个很大的负担,并且由于每个测试代码写得也很庞杂,导致理解和维护这些测试代码变得比维护业务代码还麻烦,进而就导致了开发人员消极对待单元测试
因为我们项目在上升期,每期迭代都有很多需求要做,也发生过新需求的修改影响到别的业务的正常使用的问题。所以我们团队对于单元测试最大的期望就是能及时发现新的代码修改对整个系统的影响,同时尽量减少开发人员的负担,所以我们现在基本只测试 public 方法,虽然如此,因为类写得比较内聚,对 public 方法完善的测试其实也已经覆盖到了大部分代码
关于 DataProvider ,为什么我烦它呢?也是在早期,大家基本上就是按照一个业务方法对应一个测试方法这样来写,对于复杂的业务方法,有很多异常情况处理,这些都需要测试,于是就在 DataProvider 里面弄上十几条各种数据,然后在一个测试方法里面对所有这些场景编测试代码,一堆的 if ,等于是把十几种测试用例一股脑地揉在一个方法里面,你可以想见这种测试代码在维护的时候是什么感觉。所以之后我们一般就按照一个测试用例一个测试方法这样来组织测试,很少用 DataProvider 了
关于为什么追求测试代码的简洁性,因为我改过几个之前我自己写的测试,这些测试方法或者是依赖于一些外部接口,或者是会调用一些重型操作,我们测试的时候是通过向被测试方法注入 MockObjectBuilder 构造出来的 Mock 对象来做的,于是出现了一个测试方法前面几十行都在构造测试环境,后面几十行各种 assert 检查数据细节是否达到了要求,很不好看,一眼看不出测试,所以基本上现在测试代码就写成这个样子:
/**
* 成功调用 add 方法后,应该持久化消息数据
*
* @
return void
*/
public function testShouldPersistMessage_afterAdd()
{
$this->assertMessageNotExist($this->message);
$this->service->add($this->message, new SampleDataProvider());
$this->assertMessageExist($this->message);
}
所以上一条的回复都是我近些日子里实际的一些体会,不一定对,也不适合所有人,权且当作一个参考吧