一、测试思想
测试驱动开发(Test-driven development,TDD)是一种软件开发过程中的应用方法,由极限编程中倡导,以其倡导先写测试程序,然后编码实现其功能得名。测试驱动开发是戴两顶帽子思考的开发方式:先戴上实现功能的帽子,在测试的辅助下,快速实现其功能;再戴上重构的帽子,在测试的保护下,通过去除冗余的代码,提高代码质量。测试驱动着整个开发过程:首先,驱动代码的设计和功能的实现;其后,驱动代码的再设计和重构。
行为驱动开发(Behavior-driven development,BDD)是一种敏捷软件开发的技术,BDD的重点是通过与利益相关者的讨论取得对预期的软件行为的清醒认识。它通过用自然语言书写非程序员可读的测试用例扩展了 测试驱动开发方法(TDD)
。这让开发者得以把精力集中在代码应该怎么写,而不是技术细节上,而且也最大程度的减少了将代码编写者的技术语言与商业客户、用户、利益相关者、项目管理者等的领域语言之间来回翻译的代价。
二、测试框架
OCUnit(即用XCTest进行测试
)其实就是苹果自带的测试框架。
GHUnit是一个可视化的测试框架。
有了它,你可以点击APP来决定测试哪个方法,并且可以点击查看测试结果等。
OCMock就是模拟某个方法或者属性的返回值,你可能会疑惑为什么要这样做?使用用模型生成的模型对象,再传进去不就可以了?答案是可以的,但是有特殊的情况。比如你测试的是方法A,方法A里面调用到了方法B,而且方法B是有参数传入,但又不是方法A所提供。这时候,你可以使用OCMock来模拟方法B返回的值。(在不影响测试的情况下,就可以这样去模拟。)除了这些,在没有网络的情况下,也可以通过OCMock模拟返回的数据。
UITests就是通过代码化来实现自动点击界面,输入文字等功能。靠人工操作的方式来覆盖所有测试用例是非常困难的,尤其是加入新功能以后,旧的功能也要重新测试一遍,这导致了测试需要花非常多的时间来进行回归测试,这里产生了大量重复的工作,而这些重复的工作有些是可以自动完成的,这时候UITests就可以帮助解决这个问题了。
三、测试案例
- 案例 1:简单测试
1、创建一个新的项目:

2、点开测试文件,进入到这个类
setUp :每个测试方法调用前执行
tearDown :每个测试方法调用后执行
testExample :是测试方法,和我们新建的没有差别。
测试方法必须testXXX的格式,且不能有参数,不然不会识别为测试方法
测试方法的执行顺序: 字典序排序。
快捷键:Command + U进行单元测试,这个快捷键是全部测试。

3、在testExample方法中输入如下
NSLog(@"自定义测试testExample");
int a= 3;
XCTAssertTrue(a == 0,"a 不能等于 0");

备注:红色的叉子:代表测试未通过。绿色叉子:代表测试通过。
- 案例 2:网络测试
iOS9的http安全问题:现在进行异步请求的网络测试,由于测试方法主线程执行完就会结束,所以需要设置一下,否则没法查看异步返回结果。
也可以在方法结束前设置等待,调回回来的时候再让它继续执行。(另一种异步函数的单元测试)定义宏如下:
//waitForExpectationsWithTimeout是等待时间,超过了就不再等待往下执行。
#define WAIT do {\
[self expectationForNotification:@"RSBaseTest" object:nil handler:nil];\
[self waitForExpectationsWithTimeout:30 handler:nil];\
} while (0);
#define NOTIFY \
[[NSNotificationCenter defaultCenter]postNotificationName:@"RSBaseTest" object:nil];
测试方法
-(void)testRequest{
// 1.获得请求管理者
AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
mgr.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/html",nil];
// 2.发送GET请求
[mgr GET:@"http://www.weather.com.cn/adat/sk/101110101.html" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"responseObject:%@",responseObject);
XCTAssertNotNil(responseObject, @"返回出错");
NOTIFY //继续执行
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"error:%@",error);
XCTAssertNil(error, @"请求出错");
NOTIFY //继续执行
}];
WAIT //暂停
}
-
测试3 :异步测试
func test12() { let ex = XCTestExpectation(description: "ss") DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 10) { print("ss") ex.fulfill() } self.wait(for: [ex], timeout: 30) }
四、测试原理
-
测试的执行顺序
2156697-c7e4c66796b33871.png
通过上述测试得出结论:
可以看到无论我们怎样调换test方法的书写顺序,其测试顺序都是不变的。
目前初步的结论:测试方法执行的顺序与方法名中test后面的字符大小有关,小者优先,例如testA,testB1,testB2三个方法相继执行。
网友评论