【译】Testing Basics
文章导读
本文是纯理论篇,介绍了测试的基础概念。
声明
文章翻译自Apple官方文档《Testing with Xcode》,不保证每个字都能翻译的精准,如有翻译错误,请留言指出,不胜感激。
Testing Basics(测试基础)
测试是把你写的代码放到你的app和库代码中运行,结果成功或者失败,对照预期进行评价。测试需要检查经过一系列运算后,变量变化的情况。当被边界条件等情况限制的时候,验证你的代码能否跑出一个特定的结果。对于性能测试,衡量标准就是你所预计完成一系列运行的最大次数。
Defining Test Scope(定义测试范围)
一个软件是由很多部分构成的,意味着小的元素放在一起组成一个更大更高层次带有更强功能的元素。直到项目的目标和需求都被满足了,高等级的元素有着非常实用性的意义。好的测试用例需要覆盖程序所有等级的各个功能。XCTest允许你为程序任意等级的元素编写测试用例。
测试用例的构成由你定义。可以是一个类中的方法,或者是一系列方法来实现一个必须的目的。例如,它可以是一个算术运算,就像在第一章QuickStart中例子介绍的计算类型的app那样。它可以包含不同的方法来处理TableView
的内容和你的代码数据结构中一系列名字的相互作用。它们中的每一个方法都隐含app中的一个功能以及一项测试来检验它。元素测试的行为应该是完全确定的,成功或者失败。
app元素的行为你细分的越多。在你的项目增长和变化过程中,就能越有效的测试代码的行为是否符合标准。在有非常多的元素的大型项目中,你需要运行非常大量的测试代码去完全地测试程序。如果可能,测试用例需要被设计的执行非常快速。但是某些测试用例必须要非常大而且执行的很慢。小而快速的执行测试可以经常的执行,很简单的定位,帮忙诊断和修复问题失败的地方。
为一个项目项目构建的测试设计是测试驱动开发的基础——一种写代码的方式,在代码被测试前让你用现有的逻辑的写测试。你带着成功通过测试的目标写完测试后,会完善你的运算法则(逻辑)。你的代码通过测试后。当你下次执行测试的时候,你可以很自信的修改你的代码,因为预期(在你的产品中产生故障)之外任何变化都是可被辨别的。
即便你不使用测试驱动开发的方式,测试也能帮你减少开发新功能时引入新的bug。你把测试写到app中来确保未来app的行为变化都是在计划中的。当你修复bug时,你可以增加测试用例来证实缺陷被修复了。测试需要执行你的代码。寻找成功或者失败的情况,来覆盖所有的边界情况。
注意: 如果原来没有测试的项目增加测试用例,可能需要重新设计部分代码来让测试更容易实施。 Appendix A: Writing Testable Code为你编写测试代码提供了简单的指南,你可能会找到一些有用的东西
你的app的任意两个不同的单元可能会互相影响,由于一些类型的测试需要执行很长的时间,你可能只想周期性的运行他们或者只在一个服务商运行。稍后你会看到下一章,你可以安排你的测试用例,使用不同方式执行来适应不同的需求。
Performance Testing(性能测试)
单元测试可以在测试自然环境下的功能,或者性能。XCTest提供了API来衡量基于时间的性能指标。让你能够和功能测试一样的跟踪性能改善和回归分析的情况。
当执行性能测试的时候,需要提供一个成功或者失败的结果,一个测试用例需要有一个基线进行来评估。基线市值程序运行十次结果的时间平均值,每次运行都带有一个标准差。测试结果低于基线时间很多或者各结果之间差异明显的用例要被报告为失败。
注意:你第一次运行性能测试的时候,XCTest总会给一个失败的结果,是由于基线未知。一旦你接受了某一个确定的性能指标当成基线,XCTest会在报告中评估结果是成功或者失败,然后提供给你测试结果的细节。
User Interface Testing(界面测试)
到目前为止,讨论的功能和性能测试,通常被称为单元测试。其中的“单元”取决于你对功能细分的颗粒度和层次。单元测试主要关心的是符合预期的组件,或者与其他组件交互行为也符合预期的。从设计的角度来看,单元测试从项目内部开始着手整个开发过程,审查各组件的配合,实现你的意图。
用户通过界面来与你的代码的内部构建进行交互。用户界面的交互行为一般来说是粗颗粒度的、比较高级的行为。使用外部的界面来操作几个组件(或附属系统)来实现app的功能。如果没有特殊的设计能够从app外部环境来进行操作的话,要想通过单元测试来测试用户通过界面执行的方法是非常困难的。这些特殊的设计被称为“UI测试”。
UI测试就像用户操作一样,从外部表层对app进行测试。他们让你写测试用例,发送模拟的事件给系统和定制的UI对象,捕捉这些对象的响应,然后就像你做内部原生单元测试一样测试响应的正确性是否符合预期。
App and Library Tests(App和库测试?)
Xcode提供了两种单元测试的会话,App测试和库测试。
- app测试
App测试检查app中代码行为的正确性,就像例子中计算器app的计算操作一样。
- 库测试
库测试在动态库和框架中检查代码行为的正确性,此检测在运行时间内独立于系统。进行库测试,你可以构建单元测试来测试库的组件。
XCTest——the Xcode Testing Framework(Xcode测试框架)
从Xcode5开始包含该了XCTest,是提供给你的测试框架。
考虑到版本的一致性:
In Xcode 5, XCTest is compatible with running on OS X v10.8 and OS X v10.9, and with iOS 7 and later.
In Xcode 6, XCTest is compatible with running on OS X v10.9 and OS X v10.10, and with iOS 6 and later.
In Xcode 7, XCTest is compatible with running on OS X v10.10 and OS X v10.11, and with iOS 6 and later.
UI测试在OS X v10.11和IOS9之后支持运行,可以运行在模拟器和设备上。
更多详细的版本信息,请看 Xcode Release Notes.
Xcode把XCTest.framework
收入在你的项目中。这个框架提供了让你设计测试并且在你的代码中运行他们的接口。获取更多有关于XCTest测试框架的信息,请看XCTest Framework Reference。
注意:Xcode包含了已经存在OCUnit test项目的更新迁移方法,获取更多信息请看Appendix B: Transitioning from OCUnit to XCTest。
Where to Start When Testing(当测试的时候从哪里开始)
当你开始创建测试的时候,记住下列几个建议:
- 当创建单元测试的时候,重点测试你代码中最基础的功能,模型中与控制器交互的类和方法。
一个高级的程序框架,通常会有模型,视图和控制器类。这是对每个经常使用Cocoa和Cocoa Touch工作的人来说最熟悉的设计模式。如果你需要写的测试要覆盖所有的模型类,在你为控制器类写代码测试之前,对于你的app基层是否良好要有一个明确的认知。控制器类包含app中其他许多复杂的部分,例如,一个通向网络服务所基于的数据库的连接。
作为一个起点,如果你正在编写一个测试框架或者库,你最好从你API的表面开始,从那里,你的工作方式就是从内部类开始创建。
- 当创建UI测试的时候,要考虑大部分常见的工作流。考虑当用户开始使用app的时候会做些什么,UI层会马上执行哪些进程。使用UI录制是一个很好的方式来捕获用户一些列行为到测试方法中,这些测试方法可以扩展到正确性测试和性能测试。
这种UI测试倾向于一个粗颗粒度的测试,每个测试可能会跨越多个子系统。他们会返回很多信息让你在开始的时候难以分析。所以你和你的UI测试套件工作的时候,你最要细分每个测试,以便更清晰的反映某个子系统的行为。
感谢
感谢小强在百忙之中抽空帮忙校验