什么是单元测试?
单元测试(英语:Unit Testing)又称为模块测试, 是针对程序模块(软件设计的最小单位)来进行正确性检验的测试工作。程序单元是应用的最小可测试部件.
在过程化编程中,一个单元就是单个程序、函数、过程等;对于面向对象编程,最小单元就是方法,包括基类(超类)、抽象类、或者派生类(子类)中的方法.
为什么需要单元测试?
优点:避免低级错误,保证代码的质量;
减少调试时间;
增加可维护性、可扩展性;
帮助改善设计
缺点:
不能减少研发的代码量,反而会花费很多精力在编写单元测试上,增加了开发成本,而且对开发人员的要求也会更高;
对于小项目来说,是否执行单元测试意义不大;
单元测试聚焦的是一个模块单元的功能完整性和健壮性,但是模块间互动可能带来的问题并不属于单元测试的范畴,同时也有很大部分的界面测试和功能测试仍旧离不开测试工程。
哪些需要单元测试?
1、网络数据层;
2、公共类中的公开方法;
3、业务逻辑层;
4、修复Bug的测试
选型:
XCTest + OCMock + OCHamcrest是我认为比较好的框架方案

XCTest
1. 创建工程时选择Unit Tests 对于已经创建的工程但未引入Unit Tests的工程,可以在File -> New -> Target中创建单元测试Target
2.创建之后可以看到工程下面多了一个叫XXXXTests和XXXXUITests的部分,Targets也多了一个XXXXTests。
我们可以看到有四个函数。
- (void)setUp
初始化的代码,在测试方法调用之前调用
- (void)tearDown
释放测试用例的资源代码,每个方法在每个测试用例执行后调用。测试失败不调用。
- (void)testExample
测试用例
- (void)testPerformanceExample
性能测试用例
XCode 的 UI 测试
从 Xcode 7 开始引入了 UI 测试,允许你通过记录 UI 上的交互来创建 UI 测试。UI 测试通过查询来找到 app 的 UI 对象,同步事件,然后将事件发送给这些对象。这个 API 允许你检索 UI 对象的属性和状态,并和预期值进行比对.
OCMock
对于这个方法的测试,依赖Student对象,并且在方法的实现中调用了Student中属性的get方法。这个时候我们就需要用到OCMock
1、安装
接来下说一下framework的安装。 最好使用cocoapods安装
解压缩dmg得到OCMock.framework;
将OCMock.framework添加到工程中;
General->Embedded Binaries添加OCMock.framework;
Build Setting->Framework Search Paths 填入$(PROJECT_DIR)/$(TARGET_NAME);
Build Setting->Other Link Flags 填入-ObjC
2、用法
1>创建对象
id classMock = OCMClassMock([SomeClass class]);
id protocolMock = OCMProtocolMock(@protocol(SomeProtocol));
id observerMock = OCMObserverMock();
2>置换方法
OCMStub([mock someMethod]).andReturn(anObject);
OCMStub([mock someMethod]).andCall(anotherObject, @selector(aDifferentMethod));
OCMStub([mock someMethodWithBlock:([OCMArg invokeBlockWithArgs:@"First arg", nil])]);
3>验证作用
id mock = OCMClassMock([SomeClass class]);
/* run code under test */
OCMVerify([mock someMethod]);
id mock = OCMClassMock([SomeClass class]);
OCMStub([mock someMethod]).andReturn(myValue);
/* run code under test */
OCMVerify([mock someMethod]);
引入单元测试遇到的问题:
问题1:
测试Target Build Setting中对应的Library Search Paths未添加对应的第三方框架
解决方法:
我们可以选择在测试Target的Search Paths中一个一个添加所有由cocoapods管理所有第三方框架。更简单的方式我们可以通过cocoapods帮我们自动生成Search Paths
问题2:
No type or protocol named 'YYModel';Unknown type name 'XXXXXXXType'。无法识别某些协议、类型、宏定义
解决方法:
在测试target 的 prefix header中添加pch文件路径
LLDB
expression命令
expression的简写有exp, e。可以用expression来声明新的变量,也可以改变已有变量的值。我们看到e声明的都是$开头的变量。我们在使用时也需要加上$符号。
print指令
print命令会打印出对象的类型和相关属性.
print命令的别名有prin, pri, p,
po命令对于继承自NSObject的对象,会打印出description中的内容,类似于print函数, 对于struct, 会打印出属性
image命令
image命令可以用来寻找栈地址对应的代码位置

一 静态检测方法
使用XCode分析功能,Product->Analyze
使用静态检测可以检查出一些明显的没有释放的内存,包括NSObject和CF开头的内存泄漏.
缺点: 不能检测block导致的内存泄漏问题
二 动态检测方法
使用 instruments ------leaks
po:print object的缩写,表示显示对象的文本描述,如果对象不存在则打印nil。
p:可以用来打印基本数据类型。
call:执行一段代码 如:call NSLog(@"%@", @"yang")
expr:动态执行指定表达式
bt:打印当前线程堆栈信息 (bt all 打印所有线程堆栈信息)
image:常用来寻找栈地址对应代码位置 如:image lookup --address 0xxxx
答案和其他问题待更新!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
网友评论