Functional Testing in iOS

什么是Function Testing(摘自wikipedia

Functional testing is a quality assurance (QA) process and a type of black-box testing that bases its test cases on the specifications of the software component under test. Functions are tested by feeding them input and examining the output, and internal program structure is rarely considered (not like in white-box testing). Functional testing usually describes what the system does.

為什么需要Functional Testing

在討論這個(gè)問題前先來一些對比:

  1. Functional Tesing vs Unit Testing

    Unit Testing關(guān)注點(diǎn)在于單獨(dú)的代碼片段,可信度較高且易擴(kuò)展,是從開發(fā)者的視角來編寫的。相對Functional Testing來說更快,你可以很快地為某段代碼編寫測試,執(zhí)行速度快,能夠更快的定位bug。但是它并不關(guān)心產(chǎn)品的業(yè)務(wù)邏輯,所以當(dāng)單元測試通過并不能保證你的產(chǎn)品能夠滿足業(yè)務(wù)需求。

  2. Functional Testing vs Integration Testing

    Integration Testing主要用于不同module、system等之間的集成測試。Unit Testing用于保證每個(gè)代碼片段能夠獨(dú)立地正確工作,但是并不能保證他們集成在一起能夠正確工作。你需要集成測試將不同的功能模塊集成在一起來進(jìn)行測試。但是相對Functional Testing來說它還是不能保證某個(gè)feature能夠得到預(yù)期的結(jié)果。

下面的Test Pyramid摘自Martin Fowler的 文章,越高層次產(chǎn)生的用戶價(jià)值會(huì)更高且更慢,越低層次的產(chǎn)生的價(jià)值更低且更快,你所寫的任何一行單元測試代碼對于你的用戶來說都是不可見的,他能感知到的只能通過UI來體現(xiàn)。可以看出我們需要很多的單元測試來保證我們的代碼質(zhì)量,這對開發(fā)人員來說是有巨大價(jià)值的,它能夠幫開發(fā)人員快速發(fā)現(xiàn)且定位問題。

Test Pyramid

Funtional testing 屬于UI測試,UI測試包含行為和外觀。Functional testing從用戶行為這個(gè)維度來保證了代碼的質(zhì)量。比如我需要對用戶登錄進(jìn)行測試,我需要測試的點(diǎn)就可能涵蓋用戶點(diǎn)擊了登錄,需要看到界面上有相應(yīng)的提示,成功之后需要到達(dá)主界面等。

BDD 與 Functional Testing

在敏捷實(shí)踐中我們通過BDD(Behavior-driven development)來幫助我們完成Functional testing。BDD鼓勵(lì)軟件項(xiàng)目中的開發(fā)者、QA和非技術(shù)人員或商業(yè)參與者之間的協(xié)作,讓其能夠在一個(gè)共同的基礎(chǔ)上達(dá)成共識(shí)。

BDD的框架很多,下面簡單的羅列了一下:

框架 語言
Cucumber Ruby
JBehave Java
RBehave Ruby
Specflow C#

它們基本上都是基于Gherkin作為DSL在不同語言上的實(shí)現(xiàn),讓我們可以用自然語言去書寫我們的代碼。

用BDD來為某個(gè)feature書寫測試通常包含以下幾個(gè)部分:

  • 一個(gè)簡單的Title
  • 對測試場景進(jìn)行簡單描述
  • 驗(yàn)收步驟以及預(yù)期行為的描述

在對驗(yàn)收步驟進(jìn)行描述的時(shí)候通常會(huì)用到這樣的格式"Given ... When ... Then ",各自的含義如下

  1. Given: 測試的前置條件
  2. When: 指定用戶的行為
  3. Then: 驗(yàn)證結(jié)果

因此,如果用這樣的格式去描述用戶登錄的場景就大概應(yīng)該是:

  1. Given 用戶打開登錄界面
  2. When 用戶填寫賬號和密碼后點(diǎn)擊登錄按鈕
  3. Then 用戶登錄成功來到主界面。

當(dāng)然除了這幾個(gè)關(guān)鍵字,可能你還會(huì)接觸到And、But、Or等,使用它們可以增加代碼的可讀性。
通過自然語言的描述,業(yè)務(wù)專家、QA或者其他沒有技術(shù)背景的人也可以很明確地明白這個(gè)測試是在干什么。

針對于iOS開發(fā),蘋果本身的XCTest不能很好的支持我們寫Functional testing。它基于assert來完成測試,而很多時(shí)候assert所表達(dá)的含義也很難理解,同時(shí)它相對來說也比較難mock。所以我們可能還需要一些工具來方便我們寫Functional Testing。

下面簡單的列了一些iOS開發(fā)中能夠用來UI Testing的框架:

框架 語言 支持平臺(tái)
Calabash Gherkin \ Ruby iOS \ Android
EarlGrey OC \ Swift iOS
Frank Gherkin \ Ruby iOS \ MAC
KIF OC \ Swift iOS
UI Test OC \ Swift iOS

Calabash和Frank都是基于Cucumber,但是Calabash有著更豐富的特性,比如更豐富的內(nèi)建步驟、更多的手勢支持等,支持的平臺(tái)也更加豐富,使用范圍更廣。

EarlyGrey是google推出的,內(nèi)建同步機(jī)制,測試會(huì)在與UI進(jìn)行交互前自動(dòng)等待動(dòng)畫、網(wǎng)絡(luò)請求等事件,當(dāng)然它還是允許你手動(dòng)處理同步。它會(huì)確保執(zhí)行動(dòng)作前,UI處于穩(wěn)定的狀態(tài)。EarlGrey基于XCTest,因此在Xcode中你可以很容易的建立一個(gè)測試用例類。當(dāng)然在我寫下這篇文章的時(shí)候它還存在一些問題,比如不支持3D Touch,不能和Address Sanitizer一起工作等,完整的列表在這里。

具體使用哪種工具大家可以根據(jù)自己項(xiàng)目的實(shí)際情況來考慮,我目前的項(xiàng)目中使用的是Calabash。

使用Calabash-iOS寫Functional Testing

要想在你的iOS工程中使用Calabash你需要一定的步驟安裝依賴包以及配置工程,可以移步到Calabash查看具體的步驟。

一切都設(shè)置好了之后,工程目錄下會(huì)多一個(gè)叫features的目錄,顧名思義里面會(huì)包含你需要測試的feature。
比如我需要對登錄進(jìn)行測試。我在目錄下新建一個(gè)叫做login.feature的文件,然后開始描述測試的用戶場景:

Feature: User login flow

  Scenario: User can login with correct account number and password
    Given I can open the login page
    When I type "myname" into the account number input field
    And I type "mypassword" into the password input field
    And I click then login button
    Then I can login successful and see home page
 

另外,Calabash內(nèi)建了很多的steps,但是不一定額能夠完全滿足你的需求,你可能還需要一些自定義的步驟,自定義的步驟都放在step_definitions里面。
比如我需要定義輸入賬號這個(gè)步驟:

When(/^I type "(.*?)" i into the account number input field$/) do |value|
  @login_page.touch_account_field
  keyboard_enter_text value
end

當(dāng)描述好feature,并且定義好了步驟之后,這樣一個(gè)用例測試就完成了,接下來你可以通過cucumber命令來執(zhí)行它。

為了方便調(diào)試,Calabash還提供一個(gè)的命令行工具,通過命令calabash-ios console來使用。
比如你要查找出當(dāng)前成為焦點(diǎn)的輸入框,然后讓它停止輸入狀態(tài),你可以像下面這個(gè)樣子

query "textField isFirstResponder:1", :resignFirstResponder

在這里支持的命令和在step定義里支持的命令是一樣的,所以在你不確定的時(shí)候,可以通過命令行工具快速的檢驗(yàn)一下。

最后

在CI中加入U(xiǎn)I的自動(dòng)化測試,可以的降低時(shí)間成本提升生產(chǎn)力。但是這并不是銀彈,還得結(jié)合自身項(xiàng)目,用多少,怎么用都得仔細(xì)去考慮。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,250評論 6 530
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 97,923評論 3 413
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 175,041評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,475評論 1 308
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,253評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,801評論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,882評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,023評論 0 285
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,530評論 1 331
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,494評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,639評論 1 366
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,177評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 43,890評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,289評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,552評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,242評論 3 389
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,626評論 2 370

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