TDD (测试驱动开发)
测试驱动开发不是新鲜的概念,但是在国内的客户端开发,甚至有些服务端开发中并没有盛行,其原因也多。我们在写程序时,最喜欢或习惯做的事情,就是编写一段代码,然后运行观察结果是否正确,如果不正确就检查错误,或者打断点、print跟踪调试程序并找出错误,然后再次运行查看是否与预期一致。
TDD 是一种与普通逻辑思维相反的做法, 我们一般能想到的是先编写业务代码,然后再针对业务代码编写测试代码,来验证最终结果。而TDD 正好与之相反,在TDD 的世界中,我们应该首先根据需求编写测试代码,然后再根据测试来编写业务代码,而这也是违反传统软件开发中的先验认知的。但是我们可以举一个生活中的例子来说明TDD的必然性:我们在定制合身的西服和婚纱的时候都会对身体的尺寸来进行测量,然后再根据合适的尺寸进行制作,最终制作出最合身的衣服。而如果直接根据某一个标准码来进行制作,可能由于身高或一些因素,最后还需要重新测量并且对衣服进行修改。TDD 的好处不言而喻。因为总是先测试,再编码,所以你的所有代码的公共部分都应该含有必要的测试。还有,在测试代码中是需要引入使用业务代码的,因此在编写业务代码之前你有一次可以深入思考和实践如何使用这些代码的机会,这对提高设计和可扩展性有很好的帮助。试想一下如果是你测试都很难写的接口,别人在使用起来是不是会很纠结。在有测试的前提下,你可以有目的有方向的编写业务代码。还有,因为有测试的保护,你可以放心的对原有代码进行重构,而不必担心破坏这些逻辑。
BDD (行为驱动开发)
在iOS 中有专属的传统测试框架 XCTest,使用简单,但是在书写性和可读性上都不太好。在测试用例太多的时候,很难搞清楚某个测试到底是做什么,因为所有的测试都是由断言来完成,很多时候断言的意义也并不是特别的明确,还有,每一个测试的描述结果都是被写在断言之后,夹杂在测试逻辑中,很难寻找,并且使用XCTest 难以将对象或方法进行 mock 或者stub, 这是在测试中很重要的。BDD 提倡是通过将测试语句转换为类似自然语言的描述,开发人员可以使用更符合大众语言的习惯来编写测试,这样我们在可读性会高很多,并且便于修改。
一个典型的BDD 的测试用例包括完整的三段式上下文, Given..When..Then,或者说是一个 Arrange.. Act.. Assert 三部曲。BDD 在很多语言中都有支持的库,使用规则和语法都大同小异,在Swift 中我们可以使用Quick 和 Nimble 结合来编写测试。
如何编写测试
如何通过Quick 和Nimble 来编写Swift 的单元测试,这里有比较详细的文档说明。
测试覆盖率
在Xcode中集成了很多有用的工具,测试相关的也不例外,我们可以通过设置,在每次测试完成之后,就可以直接查看测试覆盖率的统计。
在运行测试Cmd+U
之后,我们可以看到测试覆盖率的统计。