XCode中的单元测试:编写测试类和方法(内容意译自苹果官方文档)
当你在工程中通过测试导航栏添加了一个测试target之后, xcode会在测试导航栏中显示该target所属的测试类和方法。
这一章演示了怎么创建测试类,以及如何编写测试方法。
测试targets, 测试bundles, 以及测试导航栏
在开始创建测试类之前,测试导航栏值得多看上一眼。对于创建测试和完善测试工作来说,如何使用好它是很关键的。
将一个测试target加到工程会创建一个测试bundle.测试导航栏会展开测试bundles里面所有的源代码组成部分(在一个层级列表中展示了测试类和测试方法)。下面是一个工程的测试导航页面,该工程中有两个测试targets,该图展示了测试bundles、测试类、测试方法之间的嵌套层次关系。
测试bundles可以包含多个测试类。你可以使用测试类来将相关的测试分组,分组的方式可以通过功能或者其他的组织目的。例如,对于计算器例子工程,你可能会创建BasicFunctionsTests类、AdvancedFunctionsTests类、DisplayTests类,都包含在Mac_Calc_Tests测试bundle里(如下图)。
有些类型的测试可能会共享一些类型的setup或是teardown的需求,将它们合理的聚集在一起可以复用setup和teardown方法;如此一来会大大减少你的工作量,不失为一个机智的策略。
创建一个测试类
你可以使用测试导航栏中的+按钮来创建新的测试类。
你可以选择添加一个单元测试类或是一个UI测试类。选完以后,xcode会显示一个包含了一些文件模板项的选择页。该页面此时会默认选中一个Unit test case class。按下一步继续。
(此处截图省略)
所有的测试类都应该是XCTestCase的子类(由xctest框架提供)。
尽管xcode默认会将测试类的文件加到你的测试target的group中,你仍然可以自由的组织你的测试类文件(比如同时添加到多个targets中)。
测试类的结构
这里是OC编写的,想用swift来写也可以。
注意:setup 和 teardown不是必须的。如果一个类里的所有测试方法都需要相同的初始化和销毁代码,那么可以在setup 和 teardown中实现它们。这两个方法分别会在测试方法调用前和调用后被执行。你也可以实现同名的类方法(setup和teardown),它们会在所有测试方法执行前和执行后被调用(也就是说只执行一次,对象方法会根据测试方法的多少被执行多次)。
测试执行的流程
XCTest会找到所有的测试类并且运行每个类中所包含的所有测试方法。
注意:你也可以选择指定运行哪些XCTest测试。你可以使用test navigator禁用测试或者通过edit scheme来达到类似的目的。你也可以通过测试导航栏或代码编辑器的运行按钮来只运行一个测试或测试的子集。
对于每个类,测试开始时会先运行setup方法。对于每个测试方法,类的一个新对象被分配;其对象setup方法会被执行。在那之后它运行测试方法, 然后运行对象的teardown方法。当最后一个测试方法的teardown被调用以后,xcode会调用类的teardown方法,然后移动到下一个类。 这些步骤就这样机械化的被xcode来重复执行,直到所有类的所有测试方法都执行完毕。
编写测试方法
我们通过在测试类中编写测试方法来添加测试。测试方法是一个对象方法,其前缀是test,没有参数也没有返回值。我们通过测试方法来检查你的项目中得代码,观察其执行结果是否符合预期。如果代码不能产生预期的结果,我们通过一组断言api来报告故障。
要测试相应的项目代码,请先将对应的头文件加到你的测试类中。
当xcode运行测试时,它会独立调用每个测试方法。因此,每个方法必须准备和清理任何需要与主题API进行交互所需要的辅助变量,结构,和对象。如果这段代码是类中的所有测试方法都需要的,那你可以将其添加到setUp和tearDown对象方法中。
为异步操作编写测试
因为每个测试都是一个接一个独立的执行,所以测试方法都是同步执行的。但是越来越多的代码需要异步执行。为了应对异步方法和函数的测试需求,xctest在xcode6被大大增强了——在测试方法中支持序列化执行异步方法,具体实现是通过等待异步操作执行完毕或超时来达到这个目的。
示例代码如下图:
要了解更多关于编写异步测试的内容,请重点查看XCTest.framework中的XCTestCase+AsynchronousTesting.h头文件。
编写性能测试
性能测试通过重复运行一个你需要评估执行时间的代码block十次并收集的平均执行时间和标准差来完成。最后得到的平均值可以用来和一个参考基准来对比,以此得出成功或是失败的结论。
代码非常简单:
- (void)testPerformanceExample {
// This is an example of a performance test case.
[self measureBlock:^{
// Put the code you want to measure the time of here.
}];
}
一个实际应用的例子:
- (void) testAdditionPerformance {
[self measureBlock:^{
// set the initial state
[calcViewController press:[calcView viewWithTag: 6]]; // 6
// iterate for 100000 cycles of adding 2
for (int i=0; i<100000; i++) {
[calcViewController press:[calcView viewWithTag:13]]; // +
[calcViewController press:[calcView viewWithTag: 2]]; // 2
[calcViewController press:[calcView viewWithTag:12]]; // =
}
}];
}
性能测试运行时,可以展开代码编辑器中得选项来查看具体每次运行的结果。其中的基准线也是可以设置的。同时,性能测试还可以针对不同的设备来设置不同的基准线(根据设备的性能不同来制定)。该设定是非常合理也非常实用。
今天先写这么多,关键在实践。单元测试作为一个非常有用的工具,实在不应该将其束之高阁。大家可以对底层的基础代码多多编写单元测试来保证代码的可靠性和健壮性;同时单元测试也是重构过程中的一个得力武器,有了它的保证,代码的重构之路才能走的更加坦荡。
让我们拥抱变化。
To be continued… (未完待续)
待翻译的续篇:(执行测试,查看结果)
Running Tests and Viewing Results
XCode中的单元测试:编写测试类和方法(内容意译自苹果官方文档)的更多相关文章
- 编写测试类,了解ArrayList的方法
这篇文章主要介绍了C#中动态数组用法,实例分析了C#中ArrayList实现动态数组的技巧,非常具有实用价值,需要的朋友可以参考下 本文实例讲述了C#中动态数组用法.分享给大家供大家参考.具体分析如下 ...
- 在C++中使用C#编写的类2
在那篇<在C#中使用C++编写的类>中我介绍了如何在C#中使用C++编写的类.可是由于C#在用户界面设计.数据库存储和XML文件读取等方面的优势,有时候也会出现要在C++中使用C#编写的类 ...
- Javacard 解释器怎样在API类库中找到源文件调用的类、方法或者静态域?
申明:本篇非本人原创,是在阅读各种论文文献之后,对论文文献的一种梳理. 主要参考文献为: ------------------------------------------------------- ...
- Randoop测试类和方法(用例自动生成)
详细使用方法见randoop官网: https://randoop.github.io/randoop/manual/index.html 测试程序之前,先检测下你的Randoop是否配置好: 打开c ...
- Hutool中那些常用的工具类和方法
Hutool中那些常用的工具类和方法 Hutool是一个Java工具包,它帮助我们简化每一行代码,避免重复造轮子.如果你有需要用到某些工具方法的时候,不妨在Hutool里面找找,可能就有.本文将对Hu ...
- 006-基于hyperledger fabric1.4( 官方文档)编写第一个应用【外部nodejs调用】
一.概述 官方原文地址 Writing Your First Application如果对fabric网络的基本运行机制不熟悉的话,请看这里. 注意:本教程是对fabric应用以及如何使用智能合约的简 ...
- 【AutoMapper官方文档】DTO与Domin Model相互转换(中)
写在前面 AutoMapper目录: [AutoMapper官方文档]DTO与Domin Model相互转换(上) [AutoMapper官方文档]DTO与Domin Model相互转换(中) [Au ...
- java中的方法引用(method reference)官方文档总结
2017/7/5 转载写明出处:http://www.cnblogs.com/daren-lin/p/java-method-reference.html 今天要说的是java中的一项新特性,方法引用 ...
- 【采坑小计】thanos receiver的官方文档中,并未说明tsdb落盘的配置方式
官方文档的地址在:https://thanos.io/tip/components/receive.md/ 一开始以为落盘的时间间隔是:--tsdb.retention=15d 实际测试中发现,tha ...
随机推荐
- helpDB
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Da ...
- 模拟 ZOJ 3736 Pocket Cube
题目传送门 题意:魔方最多旋转n次,问最多能使多少面颜色相同 分析:6种状态(3种旋转方式*顺逆方向,其他对称的!),首先先打个表,然后很愉快的DFS.自己写的时候费劲脑汁,代码很长,还TLE了... ...
- 【随笔】android开发的学习路线
第一阶段:Java面向对象编程 1.Java基本数据类型与表达式,分支循环. 2.String和StringBuffer的使用.正则表达式. 3.面向对象的抽象,封装,继承,多态,类与对象,对象初始化 ...
- BZOJ3748 : [POI2015]Kwadraty
打表可得结论: 1.只有2,3,6,7,8,11,12,15,18,19,...,108,112,128这31个数的k值是无穷大 2.当n足够大的时候,即当n>506时,设$f(x)=1^2+2 ...
- BZOJ3356 : [Usaco2004 Jan]禁闭围栏
首先将坐标离散化,考虑从左往右扫描线 碰到插入操作则插入 碰到删除操作的: 当前包含i的矩形数=y1在[1,y2[i]]之间的矩形数-y2在[1,y1[i]-1]之间的矩形数 用两棵树状数组维护即可, ...
- CSS:权重和层叠规则决定了其优先级
首先,给大家看一篇关于CSS优先级的示例:http://www.ido321.com/76.html 一.基本的优先级规则 比较同一级别的个数,数量多的优先级高,如果相同即比较下一级别的个数,至于各级 ...
- 地球上最大的PHP站点 后端技术解密
Facebook的扩展性挑战 在我们讨论细节之前,这里有一些Facebook已经做的软件规模: ◆Facebook有570000000000每月页面浏览量 (据Google Ad Planner) ◆ ...
- HDU 1058 优先队列or堆
本来应当是一道优先队列或者堆的题 因为每个数都应该是已经得到的数*2 *3 *5 *7而得到的 但是 2*7 大于 3*2 这就必须保证每次取得都是没有拿过的最小的数 但是它主动降低难度在样例里卖了个 ...
- [IT学习]关于minidump
windows debug里面需要用到数据分析. 很重要的一个工具就是dump. 什么事minidump,就是windows在蓝屏或其他故障时,转存的内存数据.(我现在是这么理解的) Applicat ...
- 每天学点GDB 13
ptrace是gdb实现的基石,本文简要介绍一下ptrace. ptrace linux提供的系统调用ptrace,使得一个进程可以attach到另一个进程并进而完整的控制被attach上的进程. 被 ...