iOS自動化測試的那些干貨

大多數(shù)的iOS App (沒有持續(xù)集成)迭代流程是這樣的:


流程

也就是說眼姐,測試是發(fā)布之前的最后一道關(guān)卡诅迷。如果bug不能在測試中發(fā)現(xiàn),那么bug 就會抵達(dá)用戶众旗,所以測試的完整性可靠性十分重要罢杉。

目前,大多數(shù)App還停留在人工測試階段贡歧,人工測試投入的成本最低滩租,能夠保證核心功能的使用,而且測試人員不需要會寫代碼利朵。

但是律想,在很多測試場景下,人工測試的效率太低绍弟,容易出錯技即。舉兩個常見的例子:

  • 一個App的核心功能,在每一次發(fā)布版本前的測試必定會跑一遍所有的測試用例樟遣,不管對應(yīng)的業(yè)務(wù)在當(dāng)前版本有沒有變化(天知道開發(fā)在做業(yè)務(wù)A的時候而叼,對業(yè)務(wù)B有沒有影響),如果這次測出新的bug豹悬,測試人員在下一次發(fā)版測試中葵陵,又不得不做這些重復(fù)的工作。

  • 開發(fā)在寫API請求相關(guān)代碼的時候沒有做數(shù)據(jù)容錯瞻佛,測試在人工測試的時候都是正常的數(shù)據(jù)脱篙,所以測試通過。上線了之后涤久,后臺配置數(shù)據(jù)的時候出了點(diǎn)小問題,導(dǎo)致大面積崩潰忍弛,boom~响迂。

本文所講解的均是基于XCode 8.2.1,有些概念可能不適用于低版本的XCode细疚。

1蔗彤、自動化測試

自動化測試就是寫一些測試代碼,用代碼代替人工去完成模塊和業(yè)務(wù)的測試疯兼。

其實(shí)不管是開發(fā)還是測試然遏,如果你在不斷的做重復(fù)性工作的時候,就應(yīng)該問自己一個問題:是不是有更高效的辦法吧彪?

自動化測試有很多優(yōu)點(diǎn):

  • 測試速度快待侵,避免重復(fù)性的工作
  • 避免regression,讓開發(fā)更有信心去修改和重構(gòu)代碼(個人認(rèn)為最大的優(yōu)點(diǎn))
  • 具有一致性姨裸。
  • 有了自動化測試秧倾,持續(xù)集成(CI)會變得更可靠怨酝。
  • 迫使開發(fā)人員寫出更高質(zhì)量的代碼。(自動化測試不通過那先,代碼不允許合并)

當(dāng)然农猬,自動化測試也有一些缺點(diǎn):

  • 開發(fā)和維護(hù)成本高。
  • 不能完全替代人工測試售淡。
  • 無法完全保證測試的準(zhǔn)確性 - 讓代碼去判斷一段邏輯是否正確很容易斤葱,但是,讓代碼判斷一個控件顯示是否正確卻沒那么容易揖闸。

所以揍堕,在做自動化測試之前,首先要問自己幾個問題楔壤?

  • 這個測試業(yè)務(wù)的變動是否頻繁鹤啡?
  • 這個測試業(yè)務(wù)是否屬于核心功能?
  • 編寫測試代碼的成本有多少蹲嚣?
  • 自動化測試能保證測試結(jié)果的準(zhǔn)確么递瑰?

通常,我們會選擇那些業(yè)務(wù)穩(wěn)定隙畜,需要頻繁測試的部分來編寫自動化測試腳本抖部,其余的采用人工測試,人工測試仍然是iOS App開發(fā)中不可缺少的一部分议惰。

2慎颗、測試種類

從是否接觸源代碼的角度來分類:測試分為黑盒和白盒(灰盒就是黑盒白盒結(jié)合,這里不做討論)言询。

白盒測試的時候俯萎,測試人員是可以直接接觸待測試App的源代碼的。白盒測試更多的是單元測試运杭,測試人員針對各個單元進(jìn)行各種可能的輸入分析夫啊,然后測試其輸出。白盒測試的測試代碼通常由iOS開發(fā)編寫辆憔。

黑盒測試的時候撇眯,測試人員不需要接觸源代碼。是從App層面對其行為以及UI的正確性進(jìn)行驗(yàn)證虱咧,黑盒測試由iOS測試完成熊榛。

從業(yè)務(wù)的層次上來說,測試金字塔如圖:


測試金字塔

而iOS測試通常只有以下兩個層次:

  • Unit:單元測試腕巡,保證每一個類能夠正常工作
  • UI:UI測試玄坦,也叫做集成測試,從業(yè)務(wù)層的角度保證各個業(yè)務(wù)可以正常工作绘沉。

3营搅、框架選擇

啰里八嗦講的這么多云挟,自動化測試的效率怎么樣,關(guān)鍵還是在測試框架上转质。那么园欣,如何選擇測試框架呢?

框架可以分為兩大類:XCode內(nèi)置的和三方庫休蟹。

選擇框架的時候有幾個方面要考慮:

  • 測試代碼編寫的成本
  • 是否可調(diào)式
  • 框架的穩(wěn)定性
  • 測試報告(截圖沸枯,代碼覆蓋率,…)
  • WebView的支持(很多App都用到了H5)
  • 自定義控件的測試
  • 是否需要源代碼
  • 能否需要連著電腦
  • 是否支持CI(持續(xù)集成)
  • ….

我們首先來看看XCode內(nèi)置的框架:XCTest赂弓。XCTest又可以分為兩部分:Unit Test 和 UI Test绑榴,分別對應(yīng)單元測試和UI測試。有一些三方的測試庫也是基于XCTest框架的盈魁,這個在后文會講到翔怎。由于是Apple官方提供的,所以這個框架會不斷完善杨耙。

成熟的三方框架通常提供了很多封裝好的有好的接口赤套,筆者綜合對比了一些,推薦以下框架:

單元測試:

以下三個框架都是BDD(Behavior-driven development) - 行為驅(qū)動開發(fā)珊膜。行為驅(qū)動開發(fā)簡單來說就是先定義行為容握,然后定義測試用例,接著再編寫代碼车柠。 **實(shí)踐中發(fā)現(xiàn)剔氏,通常沒有那么多時間來先定義行為,不過BDD中的domain-specific language (DSL)能夠很好的描述用例的行為
**竹祷。

  • Kiwi 老牌測試框架
  • specta 另一個BDD優(yōu)秀框架
  • Quick 三個項(xiàng)目中Star最多谈跛,支持OC和Swift,優(yōu)先推薦塑陵。

UI測試:

  • KIF 基于XCTest的測試框架感憾,調(diào)用私有API來控制UI,測試用例用Objective C或Swift編寫猿妈。
  • appium 基于Client - Server的測試框架吹菱。App相當(dāng)于一個Server巍虫,測試代碼相當(dāng)于Client彭则,通過發(fā)送JSON來操作APP,測試語言可以是任意的占遥,支持android和iOS俯抖。

篇幅有限,本文會先介紹XCtest瓦胎,接著三方的Unit框架會以Quick為例芬萍,UI Test框架側(cè)重分析KIF尤揣,appium僅僅做原理講解。

4柬祠、XCTest

對于XCTest來說北戏,最后生成的是一個bundle。bundle是不能直接執(zhí)行的漫蛔,必須依賴于一個宿主進(jìn)程嗜愈。關(guān)于XCTest進(jìn)行單元測試的基礎(chǔ)(XCode的使用,異步測試莽龟,性能測試蠕嫁,代碼覆蓋率等),我在這篇文章里講解過毯盈,這里不再詳細(xì)講解剃毒。

單元測試用例:

比如,我有以下一個函數(shù):

//驗(yàn)證一段Text是否有效搂赋。(不能以空字符開頭赘阀,不能為空)
- (BOOL)validText:(NSString *)text error:(NSError *__autoreleasing *)error{
}

那么,我該如何為這個函數(shù)編寫單元測試的代碼厂镇?通常纤壁,需要考慮以下用例:

  • 輸入以空白字符或者換行符開頭的,error不為空捺信,返回 NO
  • 輸入正確的內(nèi)容酌媒,error為空,返回YES
  • 輸入為nil,error不為空迄靠,返回 NO (邊界條件)
  • 輸入為非NSString類型秒咨,驗(yàn)證不通過,返回NO (錯誤輸入)
  • 特殊輸入字符(標(biāo)點(diǎn)符號掌挚,非英文等等)

UI測試:

UI測試是模擬用戶操作雨席,進(jìn)而從業(yè)務(wù)處層面測試。關(guān)于XCTest的UI測試吠式,建議看看WWDC 2015的這個視頻:

關(guān)于UI測試陡厘,有幾個核心類需要掌握:

UI測試還有一個核心功能是UI Recording。選中一個UI測試用例特占,然后點(diǎn)擊圖中的小紅點(diǎn)既可以開始UI Recoding糙置。你會發(fā)現(xiàn):

隨著點(diǎn)擊模擬器,自動合成了測試代碼是目。(通常自動合成代碼后谤饭,還需要手動的去調(diào)整)


在寫UI測試用例的時候要注意:測試行為而不是測試代碼。比如,我們測試這樣一個case揉抵。

進(jìn)入Todo首頁亡容,點(diǎn)擊add,進(jìn)入添加頁面冤今,輸入文字闺兢,點(diǎn)擊save。

測試效果如下:



對應(yīng)測試代碼:

- (void)testAddNewItems{
    //獲取app代理
    XCUIApplication *app = [[XCUIApplication alloc] init];
    //找到第一個tabeview戏罢,就是我們想要的tableview
    XCUIElement * table = [app.tables elementBoundByIndex:0];
    //記錄下來添加之前的數(shù)量
    NSInteger oldCount = table.cells.count;
    //點(diǎn)擊Add
    [app.navigationBars[@"ToDo"].buttons[@"Add"] tap];
    //找到Textfield
    XCUIElement *inputWhatYouWantTodoTextField = app.textFields[@"Input what you want todo"];
    //點(diǎn)擊Textfield
    [inputWhatYouWantTodoTextField tap];
    //輸入字符
    [inputWhatYouWantTodoTextField typeText:@"somethingtodo"];
    //點(diǎn)擊保存
    [app.navigationBars[@"Add"].buttons[@"Save"] tap];
    //獲取當(dāng)前的數(shù)量
    NSInteger newCount = table.cells.count;
    //如果cells的數(shù)量加一列敲,則認(rèn)為測試成功
    XCTAssert(newCount == oldCount + 1);
}

這里是通過前后tableview的row數(shù)量來斷言成功或者失敗。

等待:

通常帖汞,在視圖切換的時候有轉(zhuǎn)場動畫戴而,我們需要等待動畫結(jié)束,然后才能繼續(xù),否則query的時候很可能找不到我們想要的控件翩蘸。

比如所意,如下代碼等待VC轉(zhuǎn)場結(jié)束,當(dāng)query只有一個table的時候催首,才繼續(xù)執(zhí)行后續(xù)的代碼扶踊。

[self expectationForPredicate:[NSPredicate predicateWithFormat:@"self.count = 1"]
          evaluatedWithObject:app.tables
                      handler:nil];
[self waitForExpectationsWithTimeout:2.0 handler:nil];
//后續(xù)代碼....

Tips: 當(dāng)你的UI結(jié)構(gòu)比較復(fù)雜的時候,比如各種嵌套childViewController郎任,使用XCUIElementQuery的代碼會很長秧耗,也不好維護(hù)。

另外舶治,UI測試還會在每一步操作的時候截圖分井,方便對測試報告進(jìn)行驗(yàn)證。

查看測試結(jié)果:

使用基于XCTest的框架霉猛,可以在XCode的report navigator中查看測試結(jié)果尺锚。



其中:

  • Tests 用來查看詳細(xì)的測試過程
  • Coverage 用來查看代碼覆蓋率
  • Logs 用來查看測試的日志
  • 點(diǎn)擊圖中的紅色框指向的圖標(biāo)可以看到每一步UI操作的截圖

除了利用XCode的GUI,還可以通過后文提到的命令行工具來測試惜浅,查看結(jié)果瘫辩。

Stub/Mock:

首先解釋兩個術(shù)語:

  • mock 表示一個模擬對象
  • stub 追蹤方法的調(diào)用,在方法調(diào)用的時候返回指定的值坛悉。

通常伐厌,如果你采用純存的XCTest,推薦采用OCMock來實(shí)現(xiàn)mock和stub裸影,單元測試的三方庫通常已集成了stub和mock挣轨。

那么,如何使用mock呢空民?舉個官方的例子:

//mock一個NSUserDefaults對象
id userDefaultsMock = OCMClassMock([NSUserDefaults class]);
//在調(diào)用stringForKey的時候刃唐,返回http://testurl
OCMStub([userDefaultsMock 
stringForKey:@"MyAppURLKey"]).andReturn(@"http://testurl");

再比如,我們要測試打開其他App界轩,那么如何判斷確實(shí)打開了其他App呢画饥?

id app = OCMClassMock([UIApplication class]);
OCMStub([app sharedInstance]).andReturn(app);
OCMVerify([app openURL:url] 

使用Stub可以讓我們很方便的實(shí)現(xiàn)這個。

關(guān)于OCMock的使用浊猾,推薦看看objc.io的這篇文章:

5抖甘、Quick

Quick是建立在XCTestSuite上的框架,使用XCTestSuite允許你動態(tài)創(chuàng)建測試用例葫慎。所以衔彻,使用Quick,你仍讓可以使用XCode的測試相關(guān)GUI和命令行工具。

使用Quick編寫的測試用例看起來是這樣子的:

import Quick
import Nimble

class TableOfContentsSpec: QuickSpec {
  override func spec() {
    describe("the 'Documentation' directory") {
      it("has everything you need to get started") {
        let sections = Directory("Documentation").sections
        expect(sections).to(contain("Organized Tests with Quick Examples and Example Groups"))
        expect(sections).to(contain("Installing Quick"))
      }

      context("if it doesn't have what you're looking for") {
        it("needs to be updated") {
          let you = You(awesome: true)
          expect{you.submittedAnIssue}.toEventually(beTruthy())
        }
      }
    }
  }
}

BDD的框架讓測試用例的目的更加明確偷办,測試是否通過更加清晰艰额。使用Quick,測試用例分為兩種:

單獨(dú)的用例 - 使用it來描述

it 有兩個參數(shù)

  • 行為描述
  • 行為的測試代碼

比如,以下測試Dolphin行為椒涯,它具有行為 is friendlyis smart柄沮。

//Swift代碼
class DolphinSpec: QuickSpec {
  override func spec() {
    it("is friendly") {
      expect(Dolphin().isFriendly).to(beTruthy())
    }

    it("is smart") {
      expect(Dolphin().isSmart).to(beTruthy())
    }
  }
}

可以看到,BDD的核心是行為废岂。也就是說祖搓,需要關(guān)注的是一個類提供哪些行為。

用例集合湖苞,用describe和context描述

比如拯欧,驗(yàn)證dolphin的click行為的時候,我們需要兩個用例财骨。一個是 is loud镐作,一個是 has a high frequency,就可以用 describe 將用例組織起來隆箩。

class DolphinSpec: QuickSpec {
  override func spec() {
    describe("a dolphin") {
      describe("its click") {
        it("is loud") {
          let click = Dolphin().click()
          expect(click.isLoud).to(beTruthy())
        }

        it("has a high frequency") {
          let click = Dolphin().click()
          expect(click.hasHighFrequency).to(beTruthy())
        }
      }
    }
  }
}

context可以指定用例的條件:

比如:

describe("its click") {
    context("when the dolphin is not near anything interesting") {
      it("is only emitted once") {
        expect(dolphin!.click().count).to(equal(1))
      }
    }
}

除了這些之外滑肉,Quick也支持一些切入點(diǎn),進(jìn)行測試前的配置:

  • beforeEach
  • afterEach
  • beforeAll
  • afterAll
  • beforeSuite
  • afterSuite

Nimble

由于Quick是基于XCTest摘仅,開發(fā)者當(dāng)然可以收使用斷言來定義測試用例成功或者失敗靶庙。Quick提供了一個更有好的Framework來進(jìn)行這種斷言:Nimble

比如,一個常見的XCTest斷言如下:

XCTAssertTrue(ConditionCode, "FailReason")

在出錯的時候娃属,會提示:

XCAssertTrue failed, balabala

這時候六荒,開發(fā)者要打個斷點(diǎn),查看下上下文矾端,看看具體失敗的原因在哪掏击。

使用Nimble后,斷言變成類似:

expect(1 + 1).to(equal(2))
expect(3) > 2
expect("seahorse").to(contain("sea"))
expect(["Atlantic", "Pacific"]).toNot(contain("Mississippi"))

并且秩铆,出錯的時候砚亭,提示信息會帶著上下文的值信息灯变,讓開發(fā)者更容易的找到錯誤。

6捅膘、讓你的代碼更容易單元測試

測試的準(zhǔn)確性和工作量很大程度上依賴于開發(fā)人員的代碼質(zhì)量添祸。

通常,為了單元測試的準(zhǔn)確性寻仗,我們在寫函數(shù)(方法)的時候會借鑒一些函數(shù)式編程的思想刃泌。其中最重要的一個思想就是

  • pure function(純函數(shù))

何為Pure function?就是如果一個函數(shù)的輸入一樣署尤,那么輸出一定一樣耙替。

比如,這樣的一個函數(shù)就不是pure function曹体。因?yàn)樗蕾囉谕獠孔兞縱alue的值俗扇。

static NSInteger value = 0;

- (NSInteger)function_1{
    value = value + 1;
    return value;
}

而這個函數(shù)就是pure function,因?yàn)榻o定輸入箕别,輸出一定一致狐援。

- (NSInteger)function_2:(NSInteger)base{
    NSInteger value = base + 1;
    return value;
}

所以,如果你寫了一個沒有參數(shù)究孕,或者沒有返回值的方法啥酱,那么你要小心了,很可能這個方法很難測試厨诸。

關(guān)于MVC:

在良好的MVC架構(gòu)的App中:

  • View只做純粹的展示型工作镶殷,把用戶交互通過各種方式傳遞到外部
  • Model只做數(shù)據(jù)存儲類工作
  • Controller作為View和Model的樞紐,往往要和很多View和Model進(jìn)行交互微酬,也是自動化包括代碼維護(hù)的痛點(diǎn)绘趋。

所以,對Controller瘦身是iOS架構(gòu)中比較重要的一環(huán)颗管,一些通用的技巧包括:

邏輯抽離:

  • 網(wǎng)絡(luò)請求獨(dú)立陷遮。可以每個網(wǎng)絡(luò)請求以Command模式封裝成一個對象垦江,不要直接在Controller調(diào)用AFNetworking帽馋。
  • 數(shù)據(jù)存儲獨(dú)立。建立獨(dú)立的Store類比吭,用來做數(shù)據(jù)持久化和緩存绽族。
  • 共有數(shù)據(jù)服務(wù)化(協(xié)議)。比如登錄狀態(tài)等等衩藤,通過服務(wù)去訪問吧慢,這樣服務(wù)提供者之需要處理服務(wù)的質(zhì)量,服務(wù)使用者則信任服務(wù)提供者的結(jié)果赏表。

Controller與View解耦合:

  • 建立ViewModel層检诗,這樣Controller只需要和ViewModel進(jìn)行交互匈仗。
  • 建立UIView子類作為容器,將一些View放到容器后再把容器作為SubView添加到Controller里
  • 建立可復(fù)用的Layout層逢慌,不管是AutoLayout還是手動布局悠轩。

Controller與Controller解耦合:

  • 建立頁面路由。每一個界面都抽象為一個URL涕癣,跳轉(zhuǎn)僅僅通過Intent或者URL跳轉(zhuǎn),這樣兩個Controller完全獨(dú)立前标。

如果你的App用Swift開發(fā)坠韩,那么面向協(xié)議編程和不可變的值類型會讓你的代碼更容易測試。

當(dāng)然炼列,iOS組建化對自動化測試的幫助也很大只搁,因?yàn)椴还苁腔A(chǔ)組件還是業(yè)務(wù)組件,都可以獨(dú)立測試俭尖。組建化又是一個很大的課題氢惋,這里不深入講解了。

7稽犁、KIF

KIF 的全稱是Keep it functional焰望。它是一個建立在XCTest的UI測試框架,通過accessibility來定位具體的控件已亥,再利用私有的API來操作UI熊赖。由于是建立在XCTest上的,所以你可以完美的借助XCode的測試相關(guān)工具(包括命令行腳本)虑椎。

KIF是個人非常推薦的一個框架震鹉,簡單易用。

使用KIF框架強(qiáng)制要求你的代碼支持accessibility捆姜。如果你之前沒接觸過传趾,可以看看Apple的文檔:

簡單來說,accessibility能夠讓視覺障礙人士使用你的App泥技。每一個控件都有一個描述AccessibilityLabel浆兰。在開啟VoiceOver的時候,點(diǎn)擊控件就可以選中并且聽到對應(yīng)的描述珊豹。

通常UIKit的控件是支持accessibility的镊讼,自定定義控件可以通過代碼或者Storyboard上設(shè)置,如圖:


在Storyboard上設(shè)置
  • 上面的通過Runtime Attributes設(shè)置(KVC)
  • 下面的通過GUI來設(shè)置

通過代碼設(shè)置:

[alert setAccessibilityLabel:@"Label"];
[alert setAccessibilityValue:@"Value"];
[alert setAccessibilityTraits:UIAccessibilityTraitButton];

如果你有些Accessibility的經(jīng)驗(yàn)平夜,那么你肯定知道蝶棋,像TableView的這種不應(yīng)該支持VoiceOver的。我們可以用條件編譯來只對測試Target進(jìn)行設(shè)置:

#ifdef DEBUG
[tableView setAccessibilityValue:@"Main List Table"];
#endif

#ifdef KIF_TARGET (這個值需要在build settings里設(shè)置)
[tableView setAccessibilityValue:@"Main List Table"];
#endif

使用KIF主要有兩個核心類:

  • KIFTestCase XCTestCase的子類
  • KIFUITestActor 控制UI忽妒,常見的三種是:點(diǎn)擊一個View玩裙,向一個View輸入內(nèi)容兼贸,等待一個View的出現(xiàn)

我們用KIF來測試添加一個新的ToDo:

- (void)testAddANewItem{
    [tester tapViewWithAccessibilityLabel:@"Add"];
    [tester enterText:@"Create a test to do item" intoViewWithAccessibilityLabel:@"Input what you want todo"];
    [tester tapViewWithAccessibilityLabel:@"Save"];
    [tester waitForTimeInterval:0.2];
    [tester waitForViewWithAccessibilityLabel:@"Create a test to do item"];
}

8、命令行

自動化測試中吃溅,命令行工具可以facebook的開源項(xiàng)目:

這是一個基于 xcodebuild 命令的擴(kuò)展溶诞,在iOS自動化測試和持續(xù)集成領(lǐng)域很有用,而且它支持 -parallelize 并行測試多個bundle,大大提高測試效率决侈。

安裝XCTool:

brew install xctool

使用:

path/to/xctool.sh \
  -workspace YourWorkspace.xcworkspace \
  -scheme YourScheme \
  -reporter plain:/path/to/plain-output.txt \
  run-test

并且螺垢,xctool對于持續(xù)集成很有用,iOS常用的持續(xù)集成的server有兩個:

  • Travis CI 對于公開倉庫(比如github)免費(fèi)赖歌,私有倉庫收費(fèi)
  • Jenkins 免費(fèi)

9枉圃、優(yōu)化你的測試代碼

準(zhǔn)確的測試用例:

通常,你的你的測試用例分為三部分:

  • 配置測試的初始狀態(tài)
  • 對要測試的目標(biāo)執(zhí)行代碼
  • 對測試結(jié)果進(jìn)行斷言(成功 or 失斅搿)

測試代碼結(jié)構(gòu):

當(dāng)測試用例多了孽亲,你會發(fā)現(xiàn)測試代碼編寫和維護(hù)也是一個技術(shù)活。通常展父,我們會從幾個角度考慮:

  • 不要測試私有方法(封裝是OOP的核心思想之一返劲,不要為了測試破壞封裝)
  • 對用例分組(功能,業(yè)務(wù)相似)
  • 對單個用例保證測試獨(dú)立(不受之前測試的影響栖茉,不影響之后的測試)篮绿,這也是測試是否準(zhǔn)確的核心。
  • 提取公共的代碼和操作吕漂,減少copy/paste這類工作搔耕,測試用例是上層調(diào)用,只關(guān)心業(yè)務(wù)邏輯痰娱,不關(guān)心內(nèi)部代碼實(shí)現(xiàn)弃榨。

一個常見的測試代碼組織如下:


測試代碼組織

10、appium

appium采用了Client Server的模式梨睁。對于App來說就是一個Server鲸睛,基于 WebDriver JSON wire protocol 對實(shí)際的UI操作庫進(jìn)行了封裝,并且暴露出RESTFUL的接口坡贺。然后測試代碼通過HTTP請求的方式官辈,來進(jìn)行實(shí)際的測試。其中遍坟,實(shí)際驅(qū)動UI的框架根據(jù)系統(tǒng)版本有所不同:

  • < 9.3 采用 UIAutomation
  • >= 9.3 XCUITest

原因也比較簡單:Apple在10.0之后拳亿,移除了UIAutomation的支持,只支持XCUITest愿伴。

對比 KIF肺魁,appium 有它的優(yōu)點(diǎn):

  • 跨平臺,支持iOS隔节,Android
  • 測試代碼可以由多種語言編寫鹅经,這對測試來說門檻更低
  • 測試腳本獨(dú)立與源代碼和測試框架

當(dāng)然寂呛,任何框架都有缺點(diǎn):

  • 自定義控件支持不好
  • WebView的支持不好

總結(jié)

由于我不是專業(yè)的iOS測試,關(guān)于測試的一點(diǎn)見解如下:

  • 單元測試還是選擇BDD框架瘾晃,畢竟可讀性高一些贷痪,推薦 Quick(Swift),Kiwi(Objective C)

  • UI測試優(yōu)先推薦 KIF蹦误,如果需要兼顧安卓測試劫拢,或者測試人員對OC/Swift很陌生,可以采用 appium


參考資料

轉(zhuǎn)載出處:iOS自動化測試的那些干貨

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末狗唉,一起剝皮案震驚了整個濱河市初烘,隨后出現(xiàn)的幾起案子涡真,更是在濱河造成了極大的恐慌,老刑警劉巖肾筐,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件哆料,死亡現(xiàn)場離奇詭異,居然都是意外死亡吗铐,警方通過查閱死者的電腦和手機(jī)东亦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來唬渗,“玉大人典阵,你說我怎么就攤上這事∧魇牛” “怎么了壮啊?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長撑蒜。 經(jīng)常有香客問我歹啼,道長,這世上最難降的妖魔是什么座菠? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任狸眼,我火速辦了婚禮,結(jié)果婚禮上浴滴,老公的妹妹穿的比我還像新娘拓萌。我一直安慰自己,他們只是感情好升略,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布司志。 她就那樣靜靜地躺著甜紫,像睡著了一般。 火紅的嫁衣襯著肌膚如雪骂远。 梳的紋絲不亂的頭發(fā)上囚霸,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天,我揣著相機(jī)與錄音激才,去河邊找鬼拓型。 笑死,一個胖子當(dāng)著我的面吹牛瘸恼,可吹牛的內(nèi)容都是我干的劣挫。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼东帅,長吁一口氣:“原來是場噩夢啊……” “哼压固!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起靠闭,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤帐我,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后愧膀,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拦键,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年檩淋,在試婚紗的時候發(fā)現(xiàn)自己被綠了芬为。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡蟀悦,死狀恐怖媚朦,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情日戈,我是刑警寧澤询张,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站涎拉,受9級特大地震影響瑞侮,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜鼓拧,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一半火、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧季俩,春花似錦钮糖、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽阎抒。三九已至,卻和暖如春消痛,著一層夾襖步出監(jiān)牢的瞬間且叁,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工秩伞, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留逞带,地道東北人。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓纱新,卻偏偏與公主長得像展氓,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子脸爱,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容