做开发的时候经常听到一个词“单元测试”,很多人听到这个词就觉得是个测试,功能开发完了就在模拟器或者真机上跑一次,点点就好了,也没有用过这个所谓的单元测试。
百度百科 对于单元测试 的定义 如下
单元测试(unit testing),是指对软件中的最小可测试单元进行检查和验证。对于单元测试中单元的含义,一般来说,要根据实际情况去判定其具体含义,如C语言中单元指一个函数,Java里单元指一个类,图形化的软件中可以指一个窗口或一个菜单等。总的来说,单元就是人为规定的最小的被测功能模块。单元测试是在软件开发过程中要进行的最低级别的测试活动,软件的独立单元将在与程序的其他部分相隔离的情况下进行测试。
为什么要使用单元测试?
1.一般开发人员做完了某个小功能或者模块是需要测试一下是否好用的,比如在程序里添加了一个算法,怎么测试这个算法在工程里是否好用呢?把整个工程编译一遍?别逗了。这时候使用单元测试就可以只运行需要测试的方法,速度非常快。
2.我们可以使用单元测试测 某个方法的耗时和性能,单次 和 多次运行的整体对比的。当然你可以在 方法执行前 获取时间 ,方法结束 后获取时间等方式 获取时间消耗 姑且这样写 麻烦不说 但是如何 计算 CPU占用这些消耗呢?当然我们可以使用instrument 来做更专业的测试。 相对而言 单元测试更加便捷 和 方便使用给我们省不少事。
如何添加单元测试
1.0 新建工程时 勾选这两个选项。Unit Test是代码的单元测试,UITests是UI测试。
2.0 在现有的 工程中 添加单元测试 File ->New ->Target 在选项卡中 选择 iOS UI Testing Bundle 和 iOS Unit Testing Bundle 这两个 任选一个添加给 指定的工程就可以了。
iOS Unit Tests Bundle
1.打开 UnionTestTests.swift 文件
如下图所示 鼠标光标选中菱形区域 就会 显示这个播放的状态,然后点击 这个播放的状态 就会测试这个方法。 或者 选择左边 testExample 右边也会出现 黑色的小播放按钮 点击也可以测试。2 添加测试方法
override func setUp() {
// 每个类中 测试方法调用前 先调用这个方法 以方便 开发者 做些 测试前的准备
}
override func tearDown() {
// 当这个 类中的 所有的 测试 方法 测试完后 会调用这个方法
// Put teardown code here. This method is called after the invocation of each test method in the class.
}
//这是需要测试的方法,方法名字必须以test开头,后面的可以自定义
func testExaple(){
}
//这是 我们做性能测试的方法 把要测试的方法 放进Block 就可以了 。
func testPerformanceExample() {
// This is an example of a performance test case.
self.measure {
// Put the code you want to measure the time of here.
}
}
注意!! 所有需要测试的方法名以 test 开头 。 刚添加进去的方法可能左上角的 菱形按钮 不会立即显示 ,你可以 Comand + U Build 这个测试文件一下 就可以了 或者 选中 - (void)testPerformanceExample 测下这个方法就可以了
上面的testExample方法可以这么写
func testExample() {
debugPrint("自定义测试testExample");
let a = 3;
XCTAssertEqual(a, 20)
}
以下是各种断言调试的条件
// XCTFail(@"this is a fail test"); // 生成一个失败的测试
// XCTAssertNil(@"not a nil string",@"string must be nil"); // XCTAssertNil(a1, format...) 为空判断, a1 为空时通过,反之不通过;
// XCTAssertNil(@"",@"string must be nil"); // 注意@"" 一样无法通过
XCTAssertNil(nil,@"object must be nil");
// XCTAssertNotNil(a1, format…) 不为nil 判断,a1不为 nil 时通过,反之不通过;
// 注意空 和 nil 还是有区别的
XCTAssertNotNil(@"not nil string", @"string can not be nil");
// XCTAssert(expression, format...) 当expression求值为TRUE时通过; expression 为一个表达式
// XCTAssert((2 > 2), @"expression must be true");
XCTAssert((3>2),@"expression is true");
// XCTAssertTrue(expression, format...) 当expression求值为TRUE时通过;>0 的都视为 true
XCTAssertTrue(1, @"Can not be zero");
// XCTAssertFalse(expression, format...) 当expression求值为False时通过;
XCTAssertFalse((2 < 2), @"expression must be false");
// XCTAssertEqualObjects(a1, a2, format...) 判断相等, [a1 isEqual:a2] 值为TRUE时通过,其中一个不为空时,不通过;
XCTAssertEqualObjects(@"1", @"1", @"[a1 isEqual:a2] should return YES");
// XCTAssertEqualObjects(@"1", @"2", @"[a1 isEqual:a2] should return YES");
// XCTAssertNotEqualObjects(a1, a2, format...) 判断不等, [a1 isEqual:a2] 值为False时通过,
// XCTAssertNotEqualObjects(@"1", @"1", @"[a1 isEqual:a2] should return NO");
XCTAssertNotEqualObjects(@"1", @"2", @"[a1 isEqual:a2] should return NO");
// XCTAssertEqual(a1, a2, format...) 判断相等(当a1和a2是 C语言标量、结构体或联合体时使用,实际测试发现NSString也可以);
// 1.比较基本数据类型变量
// XCTAssertEqual(1, 2, @"a1 = a2 shoud be true"); // 无法通过测试
XCTAssertEqual(1, 1, @"a1 = a2 shoud be true"); // 通过测试
// 2.比较NSString对象
NSString *str1 = @"1";
NSString *str2 = @"1";
// NSString *str3 = str1;
XCTAssertEqual(str1, str2, @"a1 and a2 should point to the same object"); // 通过测试
// XCTAssertEqual(str1, str3, @"a1 and a2 should point to the same object"); // 通过测试
// 3.比较NSArray对象
NSArray *array1 = @[@1];
NSArray *array2 = @[@1];
NSArray *array3 = array1;
// XCTAssertEqual(array1, array2, @"a1 and a2 should point to the same object"); // 无法通过测试
XCTAssertEqual(array1, array3, @"a1 and a2 should point to the same object"); // 通过测试
// XCTAssertNotEqual(a1, a2, format...) 判断不等(当a1和a2是 C语言标量、结构体或联合体时使用);
// XCTAssertEqualWithAccuracy(a1, a2, accuracy, format...) 判断相等,(double或float类型)提供一个误差范围,当在误差范围(+/- accuracy )以内相等时通过测试;
// XCTAssertEqualWithAccuracy(1.0f, 1.5f, 0.25f, @"a1 = a2 in accuracy should return NO"); // 测试没法通过
// XCTAssertNotEqualWithAccuracy(a1, a2, accuracy, format...) 判断不等,(double或float类型)提供一个误差范围,当在误差范围以内不等时通过测试;
XCTAssertNotEqualWithAccuracy(1.0f, 1.5f, 0.25f, @"a1 = a2 in accuracy should return NO"); // 测试通过
// XCTAssertThrows(expression, format...) 异常测试,当expression发生异常时通过;反之不通过;(很变态)
// XCTAssertThrowsSpecific(expression, specificException, format...) 异常测试,当expression发生 specificException 异常时通过;反之发生其他异常或不发生异常均不通过;
// XCTAssertThrowsSpecificNamed(expression, specificException, exception_name, format...) 异常测试,当expression发生具体异常、具体异常名称的异常时通过测试,反之不通过;
// XCTAssertNoThrow(expression, format…) 异常测试,当expression没有发生异常时通过测试;
// XCTAssertNoThrowSpecific(expression, specificException, format...)异常测试,当expression没有发生具体异常、具体异常名称的异常时通过测试,反之不通过;
// XCTAssertNoThrowSpecificNamed(expression, specificException, exception_name, format...) 异常测试,当expression没有发生具体异常、具体异常名称的异常时通过测试,反之不通过
3.新建 自定义的 测试文件
Command + N 选中Unit Test Case Class 不是 Cocoa Touch Class !!!!
4性能测试
在testPerformanceExample()方法中写入如下代码
func testPerformanceExample() {
// This is an example of a performance test case.
self.measure {
for i in 0...1000{
debugPrint("循环到第\(i)次")
}
}
}
运行之后没有任何反应,是因为没有设置性能测试的基准时间,按如图所示设置基准时间,就能看到性能测试的效果。
性能测试效果: