6.单元测试对重构的帮助不如预期

  正如前面所说,我目前负责的项目中,较大的重构发生次数并不多。小规模的重构中确实有单元测试帮助我发现问题的情况。但是,远不像我的预期那么多。这一点,应该说和单元测试的覆盖率较低有关。

  7.目前的现状下,很多平台的限制,使能够单元测试的部分很少。

  虽然我很有意识的推动单元测试,并且在实际开发中使用单元测试。但是,目前的情况,在WinForm平台下的开发中进行单元测试的桎梏还是很多。也许和我们的产品特性有关,实际过程中,我经常发现,能够测试的代码不是那些经常出问题的代码。而经常出问题的代码,往往因为和平台关系太密切,而无法切割出来进行单元测试。

  ASP.NETMVC在一开始设计的时候考虑了可测试性,因此,这一方面应该更好一些。但是,至少我目前没有看到微软在其他平台下的可单元测试方面的努力。这是我在使用单元测试过程中郁闷的地方。

  以下后两点属于我的想法,目前的项目中因为前面的一些约束,导致我还无法证明我的想法是正确的或错误的。列在这里也仅供大家参考了。

  8.单元测试可以作为开发Leader掌控设计的一种工具

  和聪明的人在一起工作的大困难是你没有办法控制项目的设计。聪明人并不一定出好的设计。但是,你又没有办法说服他采用你的设计。我觉得,单元测试是一个开发Leader掌控设计质量的很好的工具。因为它可以成为一个简单的指标:“你别给我说你的设计有多么好,如果你的设计不可测试,那么抱歉,你不能放入产品代码。”,反过来说,如果你的设计可测试,那么意味着,即使你的设计再烂,它也是可以替换的。总有,我会把它从产品里面干掉的。

  说说而已,其实大多时候,我也不确定我的设计是好的。但是,我相信,可测试≈低耦合≈好的设计。我相信,当项目复杂到一定程度的时候,建立一些这样简单粗暴可测量的规矩,对产品的健康发展很有帮助。

  9.单元测试可以帮助开发人员设计出更好的结构

  因为那个简单粗暴可测量的规矩,迫使开发人员降低自己设计的耦合度。从而产生更好的设计。

  后,来和老赵探讨一下他的问题。我的观点是:

  10.单元测试不需要对private成员进行。如果需要,那么抽象Strategy类。并对Strategy类进行测试。这个不属于过度设计。

  因为,我认为需要测试的方法一定具有以下几个特点中的至少一个:

  它有出错的可能。

  它具有的复用的可能。

  它具有变化的可能。

  对于第一点,我认为应该是可以通过对public成员的测试来完成对该private方法的测试的。而二三两点,正是抽象的用武之地。抽象的重要目的是在封装变化和复用。如果这个函数具有了变化和复用的可能性,我们应该将它抽象为一个独立的对象,并且对他进行测试。这是一个更好的设计,而不应该归入过度设计的范畴。

  如果不符合上面的二三两点,我觉的对这个private成员的测试属于过度测试的范畴了。是应该杜绝的。因为,你的测试代码很可能没有起到保证质量的作用,而是成为了将来重构的桎梏。因为,理论上重构的过程不需要保持私有成员的行为不变。但是,你的单元测试又要求私有成员的行为不变。这个其实是我上文中提到的“单元测试影响了重构进行”的情况。