单元测试,XCTestCase的使用与限制

简介: 单元测试,XCTestCase的使用与限制

软件开发工程师们(当然包括你我)最开始学习程序编写时,最喜欢干的事情就是编写一段代码,然后运行观察结果是否正确。如果不对就返回代码检查错误,或者是加入断点或者输出跟踪程序并找出错误,然后再次运行查看输出是否与预想一致。如果输出只是控制台的一个简单的数字或者字符那还好,但是如果输出必须在点击一系列按钮之后才能在屏幕上显示出来的东西呢?难道我们就只能一次一次地等待编译部署,启动程序然后操作UI,一直点到我们需要观察的地方么?而且程序有种习惯就是只测试正常情况,不测试所有情况就认为自己的代码ok了。单元测试就是为减少无谓的体力劳动和方便测试所有场景达到语句覆盖(所有判断分枝测试,无判断的测试也没有任何意义)测试的目的。

在代码中调用我们之前想检查的代码,并将运行的结果与我们的设想结果在程序中进行比较,如果一致,则说明了我们的代码没有问题,是按照预期工作的。单元测试这就是对这种思想一种实现方式。简言就是首先明确你要让函数或方法实现(行为)什么功能(期望),单元测试帮你检查你的行为能不能实现所有情况下的期望。只需要对对应类建立一个测试类,在测试用例只需要在调用函数时传递给它你需要测试的条件参数,就可以对结果进行判断了。工作量很小。本质是函数测试,不能测试UI。

测试驱动开发(Test Driven Development,以下简称TDD)是保证代码质量的不二法则是第一代敏捷方法。生活中类似的例子来说明TDD的必要性:有经验的砌砖师傅总是会先拉一条垂线,然后沿着线砌砖,因为有直线的保证,因此可以做到笔直整齐;而新入行的师傅往往二话不说直接开工,然后在一阶段完成后再用直尺垂线之类的工具进行测量和修补。TDD的好处不言自明,因为总是先测试,再编码,所以至少你的所有代码的public部分都应该含有必要的测试。测试驱动开发的优点是十分贴近源码,又不影响代码,可以边写测试用例边写代码,工作两很较少,对代码质量提高很有效。不像行为驱动开发需要开始抽象出一套系统进行行为和期望的描述。

单元测试的最终目的是:反复测试测试直到各种边界和测试都进行完毕,此时我们便可以得到一个具有测试保证,鲁棒性超强的产品代码。在我们之后的开发中,因为你有这些测试的保证,你可以大胆重构这段代码或者与之相关的代码,最后只需要保证项目处于绿灯状态,你就可以保证代码没重构没有出现问题。所谓断言,就是判断输入的条件是否满足。如果不满足,则抛出错误并输出预先规定的字符串作为提示。XCTestCase测试的函数要在被测试类的.h文件里要有声明。XCTestCase所有的测试都是由断言完成的。

XCode5.0及以后版本在建立工程时会自动建立XCTestCase框架及测试例子。

  XCTestCase真机调试使用,单元测试部分需要的配置:

1.  EditScheme...,设置test为Debug。设置Executable为和run中的名称相同。

2.  设置研发者证书。

3.  设置测试target的和原工程的信息属性一直,特别时Bundle identifier要一致或和配置的证书指定Bundleidentifier一直(若使用两个不同的证书的情况)

只需要在工程的Tests目录下点击新建文件,选择iOS->Souce->Test Case Class就能建立测试类,注意通常测试类以Tests结束,测试用例以test单词开始,一个测试用例可以有多个断言。详细参考文章:http://blog.csdn.net/chaoyuan899/article/details/25779295。

  XCTestCase作为XCode自带的单元测试具有一下特征:

1. 只能通过参数传递参数,测试类方法的返回值是否达到期望的结果。

2. 不能通过测试类方法的调用后对全局变量的影响。

3. 不能通过测试类方法中有直接读取UI元素(如:文本框)并且对结果产生影响的类方法。

4. 不适合直接测试表格UITabeView,若测试UITabeView需要要用到第三方库OCMock,工作量很大,并且源代码修改为表格数据源和控制器分开,这样也不适合大多少OC的习惯。这样写测试用例还不如直接运行UI设置断点调试呢。

5. NSString和char数组的转换及char数组交换不能进行单元测试,否者会产生崩溃。

6. 不能测试无返回值的类函数。

  点XCode工具栏的Product->Test可以启动所有测试用例。带绿勾的时通过的例子,带红叉的时单元测试失败的例子,没有运行过的新测试用例是灰色的菱形图标。测试用例可以点绿勾或红叉直接启动该测试用例。

XCTestCase使用的例子,FLDDLogVerbose是自定义打印日志函数可以去掉:

1. 公有类函数,由于这类函数都是与UI没有直接关系,只是与输入参数有关,通常有输出参数,这类函数是最适合采用单元测试测试的函数。switchNNStringValue函数的功能对NSString字符串的两个指定位置的字符进行交换。简单吧?3行代码测试一个分支,所以工作量很小,对项目进度影响。经过单元测试减少的问题单修改的时间远比使用它所花的时间长。

#import "CGeneralFunction.h"

2. 普通函数测试用例:

#import "LoginViewController.h"

#import "GlobalVariable.h"

#import "UITextFieldValue.h"

 

3. 不能使用测试场景:

3.1建立页面控制器页面(UIViewController及子类)后通过,给它的文本框赋值,当调用函数根本就不能影响类函数的文本框的值,并且是空指针。实际上这样的类函数就不能测试。

 

3.2 实际上就是你给它申请一个文本框也影响不了类函数种所获取到的文本框的值为空。所以单元测试时,只有输入参数才能影响类函数种的处理,就是像要用单元测试就要按照单元测试的规则写函数才能测试。

3.3单元测试用例不能拿全局变量当判断条件,因为类函数再调用完并不能影响测试用例种的全局变量,可见类函数和测试用例应该属于不同的模块,全局变量虽然同名,但是却是两个模块不同的全局变量。

  XCTestCase崩溃的例子:

1. 表格处理函数在控制器里直接实现用OCMock模拟时崩溃。

2. NSString和char数组的转换及char数组交换不能进行单元测试,否者会产生崩溃。


目录
相关文章
|
7月前
|
测试技术
|
2月前
|
安全 Java 测试技术
单元测试一篇汇总
本文详细介绍了软件开发中的单元测试,包括其重要性和好处。单元测试主要用于确保程序模块代码的正确性,常使用的测试框架有JUnit和TestNG。文章重点讲解了JUnit框架,包括其注解、断言方法及JUnit 3.x和4.x的区别。此外,还列举了八大常用的单元测试框架,如Arquillian、JTest、The Grinder、TestNG、JUnit、JWalk、Mockito和PowerMock,帮助读者更好地理解和应用单元测试。
单元测试一篇汇总
|
7月前
|
测试技术
为什么要单元测试
刹⻋是降低了⻋速还是提升了⻋速?我们通常认为写单测费⼒耗时、耽误研发进度,仿佛在给项⽬“踩刹⻋”。⼤家不妨带着这个问题往下看,详细聊聊为什么单元测试可以让软件开发跑得更快。
|
7月前
|
敏捷开发 Java 测试技术
为什么要单元测试(正片)
在如今的互联⽹时代,软件迭代的速度越来越快,研发的职责也越来越多。DevOps的理念是"you build it, you run it",研发/测试合⼆为⼀的趋势也可以理解为对"you build it, you test it"的呼吁。当研发要对⾃⼰写的代码质量和测试负责的时候,好的测试实践就必不可少了。
|
Java 测试技术
单元测试的正确姿势
软件测试是软件质量保证的关键步骤。越早发现软件中存在的问题,修复问题的成本就越低,软件质量也就越高,软件发布后的维护费用越低。为了能更好的保障软件质量,制定统一的系统自测指南,形成统一的流程达到此目标。
378 0
单元测试的正确姿势
|
Java 中间件 测试技术
单元测试都不做,怪不得你没有女朋友
单元测试都不做,怪不得你没有女朋友
单元测试都不做,怪不得你没有女朋友
|
Java 测试技术 容器
还在手动写单元测试?
还在手动写单元测试?
122 0
|
敏捷开发 测试技术 程序员
|
测试技术 C++ 编译器
下一篇
DataWorks