iOS自動化測試包括 UI測試 和數(shù)據(jù)測試兩個(gè)方面。
UI測試:
UITest介紹
XCUIApplication *app = [[XCUIApplication alloc] init];
XCUIElement *element = [[[[app.otherElements containingType:XCUIElementTypeNavigationBar identifier:@"View"] childrenMatchingType:XCUIElementTypeOther].element childrenMatchingType:XCUIElementTypeOther].element childrenMatchingType:XCUIElementTypeOther].element;
XCUIElement *textField = [[element childrenMatchingType:XCUIElementTypeTextField] elementBoundByIndex:0];
[textField tap];
[textField typeText:@"Blank_佐毅"];
XCUIElement *textField2 = [[element childrenMatchingType:XCUIElementTypeTextField] elementBoundByIndex:1];
[textField2 tap];
XCUIElement *moreNumbersKey = app/*@START_MENU_TOKEN@*/.keys[@"more, numbers"]/*[[".keyboards.keys[@\\\\"more, numbers\\\\"]",".keys[@\\\\"more, numbers\\\\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/;
[moreNumbersKey tap];
[textField2 typeText:@"123"];
[app.buttons[@"Login"] tap];
XCUIApplication痴荐。這是你正在測試的應(yīng)用的代理。它能讓你啟動應(yīng)用,這樣你就能執(zhí)行測試了。它每次都會新起一個(gè)進(jìn)程促王,這會多花一些時(shí)間,但是能保證測試應(yīng)用時(shí)的狀態(tài)是干凈的,這樣你需要處理的變量就少了些而晒。
XCUIElement蝇狼。這是你正在測試的應(yīng)用中UI元素的代理。每個(gè)元素都有類型和標(biāo)識符倡怎,結(jié)合二者就能找到應(yīng)用中的UI元素迅耘。所有的元素都會嵌套在代表你的應(yīng)用的樹中。
XCUIElementQuery监署。 當(dāng)你想要找到某個(gè)元素時(shí)颤专,就會用到 element query。每個(gè) XCUIElement 里都包含一個(gè)query钠乏。這些query搜索 XCUIElement 樹栖秕, 必須要找到一個(gè)匹配的。否則當(dāng)你視圖訪問該元素時(shí)晓避,測試就會失敗累魔。 例外是exists 屬性,你可以使用這個(gè)屬性來檢查一個(gè)元素是否展示在樹中够滑。 這對于斷言很有用。 更一般地你可以使用 XCUIElementQuery 來找到對accessibility可見的元素吕世。Query會返回結(jié)果的集合彰触。
數(shù)據(jù)測試(行為驅(qū)動測試)
BDD DSL 測試
【行為驅(qū)動測試-Objc中國】(http://objccn.io/issue-15-1/)
SpecBegin 聲明了一個(gè)名為StalkerSpec 測試類. SpecEnd 結(jié)束了類聲明。
describe 塊聲明了一組實(shí)例命辖。
context 塊的行為類似于 describe 况毅。
it 是一個(gè)單一的例子 (單一測試)。
beforeEach 是一個(gè)運(yùn)行于所有同級塊和嵌套塊之前的塊尔艇。
可能你已經(jīng)注意到尔许,幾乎在這種 DSL 中定義的所有組件由兩部分都組成:一個(gè)字符串值定義了什么被測試,以及一個(gè)包含了測試其本身或者更多組件的塊终娃。這些字符串有兩個(gè)非常重要的功能味廊。
首先,在 describe 塊內(nèi),這些字符串將聯(lián)系緊密的被測試的一部分特性的行為進(jìn)行分組描述 余佛。因?yàn)槟憧梢园匆庠钢付ㄈ我舛嗟那短讐K柠新,你可以基于對象或者它們的依賴關(guān)系的上下文來編寫的不同的測試。
#define EXP_SHORTHAND
#import "Expecta.h"
#import "Specta.h"
#import "NSObject+BPStalker.h"
SpecBegin(Stalker)
describe(@"objectWithStalker", ^{
__block NSMutableDictionary *objectToBeObserved;
__block NSObject *objectWithStalker;
__block NSString *testNotification;
beforeEach(^{
//
objectWithStalker = [[NSObject alloc] init];
objectToBeObserved = [@{ @"one" : @1,@"two" : @2 } mutableCopy];
testNotification = @"TEST_NOTIFICATION";
});
it(@"should have a stalker", ^{
expect(objectWithStalker.stalker).toNot.beNil;
});
it(@"should be able to observer changes", ^{
__block BOOL objectChanged = NO;
__block NSInteger blockCalled = 0;
[objectWithStalker.stalker whenPath:@"one"
changeForObject:objectToBeObserved
options:(NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew |
NSKeyValueObservingOptionOld)
then:^(NSMutableDictionary *object, NSDictionary *change) {
expect(object[@"one"]).to.equal(@1);
blockCalled++;
}];
[objectWithStalker.stalker whenPath:@"two"
changeForObject:objectToBeObserved
options:(NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew |
NSKeyValueObservingOptionOld)
then:^(NSMutableDictionary *object, NSDictionary *change) {
blockCalled++;
if (objectChanged)
expect(object[@"two"]).to.equal(@3);
else
expect(object[@"two"]).to.equal(@2);
}];
objectChanged = YES;
objectToBeObserved[@"two"] = @3;
expect(blockCalled).to.equal(3);
});
it(@"s stalker KVO shoud be removed when it is deallocated", ^{
__block NSInteger blockCalled = 0;
@autoreleasepool
{
NSObject *objectWithStalker = [[NSObject alloc] init];
[objectWithStalker.stalker whenPath:@"one"
changeForObject:objectToBeObserved
options:(NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew |
NSKeyValueObservingOptionOld)
then:^(NSMutableDictionary *object, NSDictionary *change) {
blockCalled++;
}];
expect(blockCalled).to.equal(1);
objectToBeObserved[@"one"] = @3;
expect(blockCalled).to.equal(2);
}
objectToBeObserved[@"one"] = @4;
objectToBeObserved[@"one"] = @10;
expect(blockCalled).to.equal(2);
});
it(@"should be able to listen to notifications", ^{
__block NSInteger blockCalled = 0;
[objectWithStalker.stalker when:testNotification
then:^(NSNotification *notification) {
expect(notification.object).to.equal(@1);
blockCalled++;
}];
expect(blockCalled).to.equal(0);
[objectWithStalker.stalker.notificationCenter postNotificationName:testNotification object:@1];
expect(blockCalled).to.equal(1);
});
it(@"s stalker notification observing shoud be removed when it is deallocated", ^{
__block NSInteger blockCalled = 0;
@autoreleasepool
{
NSObject *objectWithStalker = [[NSObject alloc] init];
[objectWithStalker.stalker when:testNotification
then:^(NSNotification *notification) {
blockCalled++;
}];
expect(blockCalled).to.equal(0);
[objectWithStalker.stalker.notificationCenter postNotificationName:testNotification object:@1];
expect(blockCalled).to.equal(1);
}
[objectWithStalker.stalker.notificationCenter postNotificationName:testNotification object:@1];
expect(blockCalled).to.equal(1);
}); });
SpecEnd
如果界面UI元素中出現(xiàn)中文辉巡,UITest腳本報(bào)錯(cuò)恨憎,使用下邊方法解決:
You can use the following workaround as this seems to be a bug in xcode: replace all \U to \u and it should work.