当你在工程中通过测试导航栏添加了一个测试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 2for (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中的单元测试:编写测试类和方法(内容意译自苹果官方文档)相关推荐

  1. pyecharts中折线图Line参数大全(内附优秀范例和官方文档)

    优秀范例:https://blog.csdn.net/weixin_44146276/article/details/102705998 关于折线的参数 def add_yaxis(# 系列名称,用于 ...

  2. 编写类的步骤编写测试类

    目录 1,编写类的步骤 1,编写类 2,编写属性,也叫做成员变量 3,编写方法 2,编写测试类就是含有main方法的类 3.编写对象 1,编写类的步骤 1,编写类 编写类的格式:修饰符 class 类 ...

  3. 怎样编写测试类测试分支_编写干净的测试–天堂中的麻烦

    怎样编写测试类测试分支 如果我们的代码有明显的错误,我们很有动力对其进行改进. 但是,在某些时候,我们认为我们的代码"足够好"并继续前进. 通常,当我们认为改进现有代码的好处小于所 ...

  4. 怎样编写测试类测试分支_编写干净的测试-被认为有害的新内容

    怎样编写测试类测试分支 很难为干净的代码找到一个好的定义,因为我们每个人都有自己的单词clean的定义. 但是,有一个似乎是通用的定义: 简洁的代码易于阅读. 这可能会让您感到有些惊讶,但我认为该定义 ...

  5. 怎样编写测试类测试分支_编写干净的测试–从配置开始

    怎样编写测试类测试分支 很难为干净的代码找到一个好的定义,因为我们每个人都有自己的单词clean的定义. 但是,有一个似乎是通用的定义: 简洁的代码易于阅读. 这可能会让您感到有些惊讶,但我认为该定义 ...

  6. 怎样编写测试类测试分支_测试技巧–不编写测试

    怎样编写测试类测试分支 对此没有太多疑问,测试代码的方式是一个有争议的问题. 不同的测试技术由于各种原因(包括企业文化,经验和总体心理观点)而受到不同开发人员的青睐. 例如,您可能更喜欢编写经典的单元 ...

  7. php 单例类 mysql pdo_PHP实战:PHP基于单例模式编写PDO类的方法

    <PHP实战:PHP基于单例模式编写PDO类的方法>要点: 本文介绍了PHP实战:PHP基于单例模式编写PDO类的方法,希望对您有用.如果有疑问,可以联系我们. 一.单例模式简介 简单的说 ...

  8. java面试题27 java中下面哪些是Object类的方法()

    java面试题27 java中下面哪些是Object类的方法() A notify() B notifyAll() C sleep() D wait() 蒙蔽树上蒙蔽果,蒙蔽树下你和我.遇到这种题,我 ...

  9. 编写一个类的方法,其输入参数为一个整数,输出为该整数各个位上的最大数字

    1. 编写一个类的方法,其输入参数为一个整数,输出为该整数各个位上的最大数字. import java.util.*;public class Main {public static int s(in ...

最新文章

  1. Seaborn使用violinplot函数可视化多分组小提琴图(violin plot)、每个小提琴图内部包含两个分组、使用inner函数设置在小提琴图中使用虚线显示分位数位置
  2. CYQ.Data 轻量数据访问层(一) 概述
  3. Openssl:构建CA的过程并实现web服务基于https访问的网络架构
  4. 配置 Spring.NET
  5. MATLAB从入门到精通-MATLAB零矩阵eye()函数的几种应用场景
  6. VC中怎么读取.txt文件
  7. promise 是什么?有哪些状态和参数?如何使用?
  8. python queue windows_python Queue模块
  9. ddt python_python-ddt实践
  10. 初识exe程序反汇编小感
  11. Android FrameWork——ActivityManager框架
  12. 学python要多久-目前Python学习需要多长时间?老男孩Python入门培训
  13. 完整的【ArcGIS地理信息系统空间分析实验教程】(包括光盘数据)
  14. Gliffy Diagrams(在线绘图)
  15. 面试的准备——公子禹
  16. 如何使用GoldWave中文版进行声道分离?
  17. Django 表单 AuthenticationFrom自动检测user的name 和 password , has no attributes cleaned_data
  18. python获取现在的日期和时间
  19. 城市大脑从起源到终极状态的7个阶段
  20. CAD画图软件测试初学者,CAD制图初学入门:基础操作 平面绘图练习100题,新手必备...

热门文章

  1. Practical Go: Real world advice for writing maintainable Go programs
  2. js模块化编程之彻底弄懂CommonJS和AMD/CMD
  3. java单元测试面试,Java必备!JUnit面试题和答案汇总
  4. 【MyBatis框架】Mybatis开发dao方法第一部分
  5. 计算机网络引言,[计算机网络]Ch.1引言
  6. IO多路复用中select、poll、epoll之间的区别
  7. python来进行图的深度遍历和广度遍历
  8. Spring核心技术原理-(2)-通过Web开发演进过程了解一下为什么要有Spring AOP?
  9. 维信小程序button样式重写
  10. [BZOJ2818][P2568]Gcd[欧拉函数]