一. iOS單元測試遭商,UI測試基本介紹
二. KIF簡介
三. KIF集成
四. 測試用例編寫
五. jenkins集成步驟
六. 總結(jié)
一 iOS單元測試,UI測試基本介紹
1.1 簡單介紹
iOS有兩個層次的測試:單元測試捅伤,UI測試劫流。
單元測試:XCTest,XCTest最后生成的是一個bundle丛忆。bundle是不能直接執(zhí)行的祠汇,必須依賴于一個宿主進程。XCTest主要基礎(chǔ)功能:異步測試熄诡,性能測試饭尝,代碼覆蓋率等串前。
UI測試:UI Testing,UI測試是模擬用戶操作,進而從業(yè)務(wù)處層面測試负敏,iOS UI測試還有一個核心功能是UI Recording亮隙。選中一個UI測試用例爪瓜,然后點擊圖中的小紅點既可以開始UI Recoding悠栓,錄制完成之后,會自動生成一段測試代碼惫周。
1.2 項目中如何集成
如果是一個新項目尘惧,在創(chuàng)建項目的時候,直接勾選 include Unit Tests,和include UI Tests 即可递递,如下圖:
1.2 已有項目中如何集成
如果我們有一個已有項目喷橙,可能前期沒有加入測試框架啥么,那么后期我們?nèi)绾我肽兀襟E如下圖:
步驟一 :點擊項目工程贰逾,在配置文件右下角點擊+號會彈出一個選擇框
步驟二 :下滑到test一欄悬荣,這里就找到了單元測試和UI測試,這里我們選擇iOS UnitTesing Bundle
步驟三 :填寫一些基本信息疙剑,
步驟四 :添加成功的頁面氯迂,Testable SwiftTests目錄就是就是我們剛生成的,今后的測試用例也都是在這個目錄下面寫言缤。
總結(jié):這里只是簡單的介紹iOS測試方面的一些東西嚼蚀,我們今天的主要目的是講一個第三方的UI測試框架,以及如何結(jié)合jenkins做自動化測試管挟,所以這里就不詳細介紹了轿曙,下面開始介紹我們的主題。
二. KIF簡介
2.1 簡要說明
KIF代表Keep It Functional僻孝,是一款iOS集成測試框架导帝。 通過利用操作系統(tǒng)為具有視覺障礙的用戶提供的輔助功能屬性,可以輕松實現(xiàn)iOS應(yīng)用程序的自動化穿铆。
KIF使用標(biāo)準(zhǔn)的XCTest測試目標(biāo)來構(gòu)建和執(zhí)行測試您单。 測試在主線程中同步進行(運行運行循環(huán)以強制時間流逝),從而允許更復(fù)雜的邏輯和組合荞雏。 這也使得KIF能夠利用Xcode Test Navigator虐秦,命令行構(gòu)建工具和Bot測試報告。
KIF使用未公開的Apple API讯檐。 大多數(shù)iOS測試框架都是如此羡疗,并且對于測試目的而言是安全的染服,但重要的是KIF不會將其轉(zhuǎn)換為生產(chǎn)代碼别洪,因為它會讓您的應(yīng)用程序提交被Apple拒絕。 按照下面的說明確保KIF為您的項目配置正確柳刮。
KIF是基于XCTest的一個第三方UI測試框架挖垛,XCTest是iOS的單元測試框架,所以項目中加入XCTest框架可以做單元測試秉颗,又通過引入KIF框架做UI集成測試痢毒。
2.2 功能特性
1 最小化間接性
所有的KIF測試都是用Objective-C編寫的。 這可以最大程度地集成代碼蚕甥,同時最大限度地減少必須構(gòu)建的圖層數(shù)量哪替。
2 簡單的配置
KIF直接集成到您的Xcode項目中,因此無需運行其他Web服務(wù)器或安裝任何其他軟件包菇怀。
3 寬操作系統(tǒng)和Xcode覆蓋
KIF的測試套件正在針對iOS 8+和Xcode 7+運行凭舶。 較低的版本可能仍然有效晌块,但你的里程可能會有所不同。 我們盡最大努力保留向后兼容性帅霜。
4 像用戶一樣測試
KIF試圖模仿實際的用戶輸入匆背。 盡可能使用觸摸事件來完成自動化。
5 與Xcode測試工具自動集成
您可以使用測試導(dǎo)航器輕松運行單個KIF測試身冀,或者使用機器人啟動每晚驗收測試钝尸。
三. KIF集成
我們通過cocopod來進行引入
步驟一
項目中要先引入XCTest,引入步驟和方法搂根,可以參考本文上面(1.2 已有項目中如何集成 )章節(jié)
步驟二
打開工程里的Podfile文件加入以下代碼:
target 'MyApp' do
pod 'Alamofire'
pod 'SwiftProgressHUD'
pod 'WechatOpenSDK'
pod 'Bugly'
end
target 'MyAppTests' do
pod 'KIF'
end
這里要注意target是項目的Tests珍促,不要加錯位置了,當(dāng)初我就加錯了加到target "MyApp",然后在寫測試用例是引入KIF.h,總是報錯剩愧,可能當(dāng)時沒太注意這個細節(jié)踢星,結(jié)果掉坑里了。編輯完成隙咸,pod install 一下沐悦。
步驟三
1: 項目名Tests對象 (項目名+Tests)---> Build Phase ---> Target Dependencies ---> "+" --->"項目的Tests文件"(去百度一下這個 tests 文件 和UItests 文件有什么區(qū)別)
2: 項目名Tests對象 ---> Build Settings ---> Linking(直接搜)---> Bundle Loader 填寫"$(BUILT_PRODUCTS_DIR)/項目名稱.app/項目名稱"
3: 項目名Tests對象 ---> Build Settings ---> Wrapper Extension (直接搜)設(shè)置成 "xctest"
4: 點擊你 RUN 按鈕前面的前面的項目target ---> Edit Scheme... ---> Test 看看里面有沒有你要測試的項目,沒有就添加
步驟四
在Tests目錄下創(chuàng)建一個橋接文件(創(chuàng)建橋接文件五督,可以在當(dāng)前目錄下新建一個oc文件藏否,xcode中途會提示是否創(chuàng)建橋接文件,橋接文件創(chuàng)建完成后充包,再把oc文件刪除就行了)副签,KIF是OC寫的,用swift寫測試用例就要創(chuàng)建一個橋接文件基矮,oc的話就不用了淆储。
總結(jié):自此,KIF我們就已經(jīng)集成完畢了家浇,下面就開始我們測試用例的編寫了本砰。
四. 測試用例編寫
我們寫了一個登陸流程的示例:新建一個LoginTest.swift文件有幾個注意點:
1 要導(dǎo)入KIF頭文件 import KIF
2 底層沒有提供tester方法,所以要加一個擴展
3 類要繼承 KIFTestCase類
4 tester().usingLabel("login_phone"),使用usingLabel獲取控件钢悲,前提是項目中這個控件的要設(shè)置accessibilityLabel 屬性
LoginTests.swift
import XCTest
import KIF
extension XCTestCase {
func tester(_ file : String = #file, _ line : Int = #line) -> KIFUIViewTestActor {
return KIFUIViewTestActor(inFile: file, atLine: line, delegate: self)
}
func system(_ file : String = #file, _ line : Int = #line) -> KIFSystemTestActor {
return KIFSystemTestActor(inFile: file, atLine: line, delegate: self)
}
}
class LoginTests: KIFTestCase {
func testLogin(){
noInputLogin()
noValidateLogin()
validateLogin()
agreeValidateLogin()
}
func testAdd() {
let a = 3
let b = 4
XCTAssert(a+b == 7, "計算正確")
}
func testnoValidateLogin(){
let userNameInput = tester().usingLabel("login_phone")
userNameInput?.enterText("15856885688")
let loginBtn = tester().usingLabel("登錄")
loginBtn?.tap()
tester().wait(forTimeInterval: 2)
}
func noInputLogin(){
let loginBtn = tester().usingLabel("登錄")
loginBtn?.tap()
tester().wait(forTimeInterval: 2)
}
func noValidateLogin(){
let userNameInput = tester().usingLabel("login_phone")
userNameInput?.enterText("15856885688")
let loginBtn = tester().usingLabel("登錄")
loginBtn?.tap()
tester().wait(forTimeInterval: 2)
}
func validateLogin(){
let invalicaodeInput = tester().usingLabel("login_input_invlicode")
invalicaodeInput?.enterText("123456")
let valicodeBtn = tester().usingLabel("獲取驗證碼")
valicodeBtn?.tap()
let loginBtn = tester().usingLabel("登錄")
loginBtn?.tap()
tester().wait(forTimeInterval: 2)
}
func agreeValidateLogin(){
let login_agree = tester().usingLabel("login_agree")
login_agree?.tap()
let loginBtn = tester().usingLabel("登錄")
loginBtn?.tap()
let firstPage = tester().usingLabel("首頁").waitForView()
if (firstPage != nil) {
loginOut()
} else {
XCTAssert(false, "未找到頁面")
}
}
func loginOut(){
let meBtn = tester().usingLabel("我")
meBtn?.tap()
let setUpBtn = tester().usingLabel("設(shè)置")
setUpBtn?.tap()
let outBtn = tester().usingLabel("退出登錄")
outBtn?.tap()
tester().wait(forTimeInterval: 5)
}
}
所有的測試方法要以test頭点额,不以test開頭的方法,測試是不會執(zhí)行的莺琳,但可以作為內(nèi)置方法还棱,其他的測試方法可以調(diào)用。這里只做一個示例具體使用請參考官方文檔:https://github.com/kif-framework/KIF惭等,官方demo它提供了如下一些操作示例:
到此KIF集成焙蹭,使用流程晒杈,我們基本介紹完了。下面我們看下如何結(jié)合jenkins做自動化測試
五. jenkins集成步驟
步驟一
首先我們要把已經(jīng)完成的測試用例的項目上傳到一個git倉庫里孔厉。
步驟二
1 啟動jenkins,新建item,構(gòu)建一個自由風(fēng)格的項目拯钻,輸入名稱點擊確定,接下來就是job配置撰豺。
2 主要配置后五項粪般,源碼管理,構(gòu)建觸發(fā)器污桦,構(gòu)建環(huán)境亩歹,構(gòu)建,構(gòu)建后操作凡橱。
3 源碼管理
這里就是填寫你的倉庫路徑小作,授權(quán)賬戶,分支稼钩。
4 構(gòu)建觸發(fā)器
這里根據(jù)不同的需求顾稀,可以自定義觸發(fā)腳本運行時機。這里設(shè)置構(gòu)建觸發(fā)器*/2 * * * *坝撑,每2分鐘檢查一次源碼變化静秆。
5 構(gòu)建環(huán)境
此項可不用配置
6 構(gòu)建
增加構(gòu)建步驟,選擇Execute 腳本
輸入腳本:
#!/bin/bash -l
#新建目錄用于保存報告
mkdir test-reports
#pod可能失敗的全局參數(shù)設(shè)置
export LANG=en_US.UTF-8
export LANGUAGE=en_US.UTF-8
export LC_ALL=en_US.UTF-8
pod install
#xcodebuild test -workspace XXX.xcworkspace -scheme XXXTests -destination 'platform=iOS Simulator,name=iPhone 6s'跑[<u style="margin: 0px auto; padding: 0px; font-family: "microsoft yahei";">**測試用例**</u>](javascript:;)
#-enableCodeCoverage YES 收集[<u style="margin: 0px auto; padding: 0px; font-family: "microsoft yahei";">**測試覆蓋率**</u>](javascript:;)
#ocunit2junit 輸出報告轉(zhuǎn)換為jenkins可讀的[<u style="margin: 0px auto; padding: 0px; font-family: "microsoft yahei";">**junit**</u>](javascript:;)報告
xcodebuild test -workspace XXX.xcworkspace -scheme XXXTests -destination 'platform=iOS Simulator,name=iPhone 6s' -configuration Debug -enableCodeCoverage YES 2>&1 | ocunit2junit
#slather coverage轉(zhuǎn)換覆蓋率報告為html文件巡李,jenkins可讀
#--input-format profdata xcode生成的為profdata格式的文件抚笔,轉(zhuǎn)換為html以便jenkins顯示
#--ignore 排除篩選需要計算的文件,多個格式寫多個ignore表達式
slather coverage --html --input-format profdata --binary-basename XXXApp --scheme XXXTests --workspace XXX.xcworkspace --configuration Debug --ignore **View** --ignore **AppText** --output-directory reports XXX.xcodeproj
這里用到兩個工具侨拦, ocunit2junit 以及slather.
打開mac終端安裝
sudo gem install ocunit2junit
sudo gem install slather
7 構(gòu)建后操作
讀取顯示junit和覆蓋率html報告
這里用到兩個jenkins插件殊橙,jenkins->系統(tǒng)管理-> 管理插件,找到JUnit Plugin和HTML Publisher plugin,安裝重啟jenkins,如果沒安裝這兩個插件的話阳谍,構(gòu)建后操作步驟是沒有這兩個選項的
選擇Publish Junit test result report,配置xml文件路徑為第三步配置的test-reports/*.xml蛀柴。
再增加一個構(gòu)建后操作螃概,選擇Publish HTML reports, 配置html路勁為第三步配置的reports矫夯,Index文件為index.html,可以設(shè)置標(biāo)題Reports title為Coverage Report。
保存返回吊洼,點擊立即構(gòu)建训貌,等待構(gòu)建完成,返回job主頁,可以看到j(luò)unit測試結(jié)果報告和覆蓋率的圖表了递沪。
到此整個jenkins集成完畢了豺鼻,以后就可以愉快的跑UI測試了
六. 總結(jié)
項目中對于單元測試,UI測試我們可以單獨拉取一個分支款慨,專門作為測試分支儒飒,每次代碼提交前,先合并到這個測試分支檩奠,然后jenkins就會開始跑你所有的測試用例桩了,如果我們寫了很多測試用例,有很多個測試用例文件埠戳,我們要指定跑哪幾個怎么辦井誉,看下圖:
EditScheme->Test
把你不想跑的測試用例直接勾掉就行了,然后保存推送到git倉庫就行了整胃,這里還有一個注意的颗圣,上文講的覆蓋率報告的生成,這里有個Code Coverage選項要勾上才行屁使。