ios 自动化测试的简单运用

自动化测试就是编写测试代码,代替人工去完成业务与模块的测试。目前人工在测试中还是占比很重的,毕竟代码无法验证非逻辑问题,比如UI控件的显示问题等。

测试框架

XCTest 是Apple 官方提供的测试工具框架。Xcode4.x 时代集成了OCUnit,Xcode5.x 时代升级为 XCTest,Xcode7时代增加了UITest工具。当新建一个项目时,勾选了 Unit Tests 和 UI Tests 选项,我们可以到工程里看到多了两个目录:项目名+Tests项目名+UITests

1.png

2.png

如果没有上述说的两个文件,可以添加相应的 target。操作路径为:File —> New —> Target —> Test,缺哪个选哪个了,都缺都选。
项目名+Tests.m文件里有四个方法,这个文件主要做一些逻辑的测试。项目名+UITests.m文件里有三个方法,这个文件主要做一些UI的测试。
XCTest 中的测试类都是继承自 XCTestCase,测试用例方法名自定义以test开头。

单元测试

单元测试最显著最简单的用途就是测试某些小功能等,例如,我们写了一个验证一串字符串是否是手机号格式的方法,我们又不能运行整个工程去验证此方法的正误,因为这样太耗时间了,所以我们用到了单元测试,只需要运行一个测试用例即可。
首先我们新建一个NSString的分类NSString+String文件,在.m文件里实现方法:

//验证手机号
-(BOOL)isPhone{
    if (self.length != 11) {
        return NO;
    }
    
    NSString *shuzi = @"^(11[0-9])";
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"self matches %@",shuzi];
    BOOL flag = [pred evaluateWithObject:self];
    return flag;
}

这样我们可以在单元测试文件XXXTests.m里的编写测试用例了。
首先引入分类的头文件
#import "NSString+String.h"
接着在方法testExample里可以验证isPhone是否正确了:

3.png

如图,可以点击目录右侧的三角形或者测试方法左侧的菱形,都可以单独运行此测试用例来验证你所写的 isPhone 方法

当然了,也可以再写个测试用例

- (void)testIsPhone{
    NSString *phone = @"12345678901";
    BOOL flag = [phone isPhone];
    XCTAssertTrue(flag,@"是手机号");
}

上面的测试用例验证了验证手机号的方法是错误的,所以我们回到 isPhone 方法里看看,判断正则不对,修改如下:

-(BOOL)isPhone{
    if (self.length != 11) {
        return NO;
    }
    
    NSString *shuzi = @"^([1][0-9]{10})";
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"self matches %@",shuzi];
    BOOL flag = [pred evaluateWithObject:self];
    return flag;
}

再次运行测试用例,显示绿色对勾表示测试通过,若是红色叉号表示测试失败。

5.png

一般用断言去处理测试结果,不然的话测试运行通过后,不知道最终验证的结果是否是正确的是想要的。
还可以建一个测试类,例如网络接口调试类:

#import <XCTest/XCTest.h>
#import "AFNetworking/AFNetworking.h"
@interface NetworkingTest : XCTestCase
@property (nonatomic, strong) AFHTTPSessionManager *AFHTTPManager;
@end
@implementation NetworkingTest
- (void)setUp {
    [super setUp];
    //初始化    
    _AFHTTPManager = [AFHTTPSessionManager manager];
    _AFHTTPManager.requestSerializer.timeoutInterval = 50;
    _AFHTTPManager.securityPolicy.allowInvalidCertificates = YES;
    _AFHTTPManager.requestSerializer = [AFJSONRequestSerializer serializer];
    [_AFHTTPManager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Accept"];
    _AFHTTPManager.responseSerializer.acceptableContentTypes=[NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html", nil];
}
- (void)testRequest{
    [self.AFHTTPManager GET:@"http://www.weather.com.cn/data/sk/101010100.html" parameters:nil progress:^(NSProgress * _Nonnull downloadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
        NSLog(@"返回数据:%@",responseObject);
        [[NSNotificationCenter defaultCenter]postNotificationName:@"Test" object:nil];
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
        NSLog(@"hehehe");
        XCTAssertFalse(0,@"服务器连接失败");
        [[NSNotificationCenter defaultCenter]postNotificationName:@"Test" object:nil];
    }];
    
    //该方法监听一个通知,如果在规定时间内正确收到通知则测试通过。
    [self expectationForNotification:@"Test" object:nil handler:nil];
    //waitForExpectationsWithTimeout是等待时间,超过时间而没等到expectationForNotification方法收到“Test”通知就报错。
    [self waitForExpectationsWithTimeout:3 handler:nil];
}
- (void)tearDown {
    // Put teardown code here. This method is called after the invocation of each test method in the class.
    [super tearDown];
}
- (void)testExample {
    // This is an example of a functional test case.
    // Use XCTAssert and related functions to verify your tests produce the correct results.
}
- (void)testPerformanceExample {
    // This is an example of a performance test case.
    [self measureBlock:^{
        // Put the code you want to measure the time of here.
    }];
}
@end

需要注意的是测试方法主线程执行完就结束,想要查看异步方法返回结果,就要有一些异步测试的特殊方法,这里用到了expectationForNotification:方法。
这个NetworkingTest测试类只是简单说明了一下用法,我们可以建新的测试类来调试不同用途的模块或者功能。具体情况具体应对,一切都是为了清晰化而已。

UI测试

用代码写UI测试代码很麻烦,若非特别情况估计没人费劲去手写,还好Xcode为我们提供了录制功能,这里简单介绍一个登录模块测试例子。

7.gif

8.gif

图7是录制演示,当我们启动录制功能后,点击操作界面,随之形成相应的代码,这样就省去了手动写代码的费劲,之后我们可以点击菱形启动测试方法来测试这段UI操作过程。

UI Testing API

  • XCUIApplication
    当前测试应用Target
  • XCUIElement
    UI测试中任何一个元素都被抽象成一个XCUIElement类型
  • XCUIElementQuery
    定位查询当前UI中XCUIElement的一个类
- (void)testExample {
    XCUIApplication *app = [[XCUIApplication alloc] init];
    XCUIElement *phoneTextField = app.textFields[@"phone"];
    [phoneTextField tap];
    [phoneTextField typeText:@"15312345678"];
    
    XCUIElement *passwordTextField = app.textFields[@"password"];
    [passwordTextField tap];
    [passwordTextField tap];
    [passwordTextField typeText:@"1234"];
    
    XCUIElement *loginButton = app.buttons[@"login"];
    [loginButton tap];
    [app.alerts[@"\u63d0\u793a"].buttons[@"\u597d\u7684"] tap];
    [passwordTextField typeText:@"123"];
    [loginButton tap];
}

我们也可以通过identifier获取当前元素XCUIElement类型,例如:

XCUIElement *phoneTextField = [app.textFields elementMatchingType:XCUIElementTypeTextField identifier:@"phone"];

需要手动设置identifier:

9.png

本文Demo

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,634评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,951评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,427评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,770评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,835评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,799评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,768评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,544评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,979评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,271评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,427评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,121评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,756评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,375评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,579评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,410评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,315评论 2 352

推荐阅读更多精彩内容