测试代码是用于检测你的应用程序和库代码,根据预期返回一个通过或失败结果。测试可能会检查某个对象在执行某些操作后实例变量的状态,验证你的代码在边界条件的情况下抛出的特定异常,等等。对于一个性能测试,参考标准可能是在最大的时间内完成你希望运行的程序。
定义测试范围
所有软件都是由组件构建,也就是说,小组件在一起形成大组件,高级别组件有更多的功能直到项目需求被满足。最佳测试实践是所有测试覆盖这个组件的所有层次功能。XCTest允许你为组件的任何层次编写测试代码。
它取决于你测试组件的哪一部分,它可以是一个类或一组完成基本目标的一组方法。例如,它可以是算术运算,如快速入门章节的计算器应用。可能有不同方法处理TableView内容和数据结构之间的交互。这些方法和运算每一个都意味着应用程序的功能组成部分,都可以测试。测试组件的行为完全是确定的,要么测试通过要么失败。
当你的项目在不断的增长和变化时,可以把应用行为划分为组件,可以更有效的测试你的代码行为是否符合所有细节的参考标准。对于有许多组件的大项目,你需要运行大量的测试来对项目进行彻底的测试。尽量设计测试可以快速运行,但不可避免有些测试很大并且执行的缓慢。小的快速运行的测试可以经常使用,当返回失败时有助于诊断和解决问题。
为项目组件设计测试时测试驱动开发的基础,在编写要测试的代码前先编写测试代码。这种开发方式让你在实现功能前考虑代码的要求和边界情况。在编写完测试代码后,你开发你的算法通过测试。在你的代码通过测试后,你对代码的改进有一个基础,在下次运行测试时,对预期行为的任何变化(这通常导致产品中的bug)都有信心。
即使你没有使用测试驱动开发,测试可以帮助你减少在代码中引入的bug,提高功能和性能。你可以在工作的应用中引入测试确保未来的变更不会修改应用现有行为。当你修复bug时,添加测试确认测试被修复。测试应该检查你的代码,覆盖所有的边界条件,查找预期失败或预期通过。
注意:添加测试到没有设计测试的项目中可能需要重新设计或重构部分代码使之更容易测试。附录A:编写可测试代码( Appendix A: Writing Testable Code)包含编写可测试代码的简单指南。
组件可以包含应用不同部分的交互。因为某些测试需要更长的时间允许,你可能希望定期或在某个服务器上运行测试。正如你在下一章中看到的,你可以组织你的测试并用许多不同的运行方式来满足不同需求。
性能测试
测试组件可以是功能测试或性能测试。XCTest提供API衡量时间性能,使你可以跟踪性能改进和回归测试。
为了让性能测试返回成功或失败,测试必须提供一个基准来评估。基准是十次运行测试方法与衡量标准偏差的平均时间。低于时间基准或多次运行相差太大均为失败。
注意:当你第一次运行性能测试时,XCTest总是会失败,是因为基准未知。一旦你设置特定的值为基准时,XCTest会评估并返回成功或失败,并为你提供测试结果的详情。
用户界面测试
到目前为止讨论的功能和性能测试通常被称为单元测试,其中单元是你决定测试功能的粒度和级别。单元测试主要关心组件是否是预期的行为,及与其他组件进行预期交互行为。从设计的角度来看,单元测试是从开发项目的内部审查满足你需求的组件。
用户通过用户界面与你的代码交互。用户界面的交互通常都是粗粒度更加高层次的行为,使用外部活动、集成的几个组件(子系统)来调用你的应用程序功能。没有专门为用户界面设计的组件,并在程序之外操作用户界面,很难编写单元测试用来检查用户界面的用户体验。这些特殊的组件叫做“UI测试”。
UI测试在应用外部测试应用,作为用户来体验它。让你可以编写测试并发送模拟事件给系统提供的和自定义的UI对象,捕获这些对象的响应,然后测试响应的正确性或想,就像你在单元测试中那样。
应用和库测试
Xcode提供两种类型的单元测试环境:应用测试和库测试
- 应用测试。应用测试检查应用代码行为是否正确,例如计算器应用的算术运算。
- 库测试。库测试检查动态库和不依赖于应用程序运行时使用的框架代码行为是否正确。使用库测试你可以构建单元测试检查库组件。
适当的使用这些环境测试你的项目,帮助你保持代码与预期的行为一致。
XCTest——Xcode测试框架
提供给你的测试框架是XCTest,从Xcode5开始。
关于版本和兼容性
- 在Xcode5中,XCTest兼容运行于OS X v10.8和OS X v10.9及iOS7及更高版本。
- 在Xcode6中,XCTest兼容运行于OS X v10.9和OS X v10.10及iOS6及更高版本。
- 在Xcode7中,XCTest兼容运行于OS X v10.10和OS X v10.11及iOS6及更高版本。
- UI测试支持运行于OS X v10.11和iOS9的设备和模拟器。
版本兼容性的更详细信息,参见Xcode版本说明( Xcode Release Notes)。
Xcode集成 XCTest.framework
到你的项目。该框架提供设计测试并在代码上运行测试的API。XCTest框架的详细信息,参见XCTest 框架参考(XCTest Framework Reference)。
注意:Xcode包含OCUint测试更新项目迁移。关于OCUint迁移到XCTest的信息,参见附录B:从OCUnit迁移到XCTest( Appendix B: Transitioning from OCUnit to XCTest)。
何时开始测试
当你开始创建测试时,记住以下几点:
- 在创建单元测试时,专注于测试代码的最基础功能,与controller交互model类和方法。
- 应用的高层次代码如Model,View和Controller类,使用Cocoa和Cocoa Touch的程序员都熟悉该设计模式。当你编写测试覆盖所有的Model类,在编写Controller类测试代码前,要确认你的应用很好的测试过。从Controller开始会接触到应用更复杂的部分,例如,连接到网络,web服务连接的数据库。
- 如果你正在编写一个框架或库,你可能希望从API开始,从这里,可以开始测试内部类。
- 当创建UI测试,首先考虑最常见的工作流。思考用户开始使用app会做什么,以及在这个过程中用户希望立即看到什么UI。使用UI记录功能是捕获用户动作的最好方式,可以扩展UI测试方法实现测试准确性或性能。
- 这种类型的UI测试相对来说是粗粒度的,可能会跨越几个子系统;他们可能返回很多信息,最初会很难分析。当你使用UI测试组件,你可以细化测试粒度并聚焦UI测试,更清楚的反映子系统行为。