養(yǎng)一只”無限猴子”幫你測試

在上線之后發(fā)生了幾次崩潰閃退, 需要緊急修復(fù)的情況之后, 我決定我要動手了...

分析了這幾次情況之后, 發(fā)現(xiàn)其實大的邏輯都沒有錯, 但是細(xì)的東西特別容易出簍子, 例如說布爾條件寫反了, 某個 @IBOutlet 的控件改名了, 刪掉了, 忘了去 storyboard 里處理掉它, 就會發(fā)生 setValue: forUndefinedKey: 的錯誤, 本來我是想直接 swizzle 掉這個方法, 不讓它拋出錯誤, 但是想想又覺得不值得. 難道終于要開始學(xué)一下怎么寫測試了嗎?

然后突然想起了之前好像看到過一個 UI 測試的框架, 可以自動幫忙測試 UI, 找到之后就開始用, 然后一發(fā)不可收拾.

倉庫的位置在這里 GitHub - zalando/SwiftMonkey: A framework for doing randomised UI testing of iOS apps

簡介

這個庫讓我想起了無限猴子理論, 其實也類似, 就是產(chǎn)生間隔一段事件就產(chǎn)生一個隨機操作事件, 例如點擊拖拽, 閃退的話是最容易發(fā)現(xiàn)的, 或者是你看到一些錯誤的數(shù)據(jù)和 UI 呈現(xiàn).(效果圖是張 gif, 手機端加載可能會比較慢)

68747470733a2f2f7468756d62732e6766796361742e636f6d2f496e646f6c656e7454616c6c466f78746572726965722d73697a655f726573747269637465642e676966.gif

這個庫分成兩部分:

  1. 主體是 SwiftMonkey, 依賴于 XCUITest, 調(diào)用了一些私有方法去發(fā)起操作事件
  2. SwiftMonkeyPaws, 負(fù)責(zé)呈現(xiàn)操作事件的視覺效果, 上面的動圖里, 那些小手掌就是 SwiftMonkeyPaws 制造出來的, 需要直接接入到 app 里面

接入流程

官方文檔目前還不是很詳細(xì), 我花了一點時間才把這個庫給搞明白, 所以大概介紹一下接入流程.

包管理, 很簡單嘛, 支持 Carthage 和 Cocoapods 兩種方式, 想用哪個用哪個.

但使用 Cocoapods 的同學(xué)有一點事情要注意, 作者忘了 push podspec 到主倉庫了, 所以我們 pod 里搜索和安裝的都是 1.0.0 版本, 最低支持 iOS 9.0, 而最新的 1.0.1 版本最低支持 8.0.

Screen Shot 2017-03-16 at 8.34.06 PM.png

解決方法也很簡單, pod 的時候指定倉庫就行了, 就像這樣:

pod 'SwiftMonkey', :git => 'https://github.com/zalando/SwiftMonkey.git'

安裝完之后, 在 AppDelegate 里面我們需要初始化一下 SwiftMonkeyPaws, 有視覺效果畢竟會更好一點

import SwiftMonkeyPaws

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var paws: MonkeyPaws?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        #if DEBUG
            if CommandLine.arguments.contains("--MonkeyPaws") {
                paws = MonkeyPaws(view: window!)
            }
        #endif
        
        return true
    }
}

記得要在 AppDelegate 里聲明一個 paws 去維持引用計數(shù), 然后 MonkeyPaws 就會 swizzle 掉 UITouch 的方法, 讓每次點擊, 拖拽都會有相應(yīng)的視覺效果.

這里我們看到一個 CommandLine.argments.contains(“—MonkeyPaws”) 可能會比較奇怪, 這段代碼是為了區(qū)分開 app 是否跑在測試模式下的, 然后為了不在正式版里加入這段代碼, 我們還加上了 compile flag 去判斷是否編譯這段代碼. 直接加一個 ConfiguationSet 也行, 但不優(yōu)雅, 也沒必要...

接下里我們就去處理 UI 測試的代碼:

import SwiftMonkey

class UITest: XCTestCase {
        
    override func setUp() {
        super.setUp()
        
        continueAfterFailure = false

        let app = XCUIApplication()
        app.launchArguments.append("--MonkeyPaws")
        app.launch()
    }
}

在 setup 方法里, 需要注意的就是最好把 continueAfterFailure 設(shè)為 false, 讓代碼出錯時能夠停留在出錯的位置那里, 方便我們 DEBUG, 畢竟我們使用的不是常規(guī)的測試方法, 測試用例跟代碼之間沒有一一對應(yīng)的關(guān)系.

還有一個就是加上參數(shù) —-MonkeyPaws 去區(qū)分運行和測試狀態(tài), 不加的話 paws 就不會運行了.

那么久該開始寫用例了, 我用的方式比較粗暴.

func testMonkey() {
    let application = XCUIApplication()

    // Workaround for bug in Xcode 7.3. Snapshots are not properly updated
    // when you initially call app.frame, resulting in a zero-sized rect.
    // Doing a random query seems to update everything properly.
    // TODO: Remove this when the Xcode bug is fixed!
    _ = application.descendants(matching: .any).element(boundBy: 0).frame

    let monkey = Monkey(frame: application.frame)
 
    monkey.addXCTestTapAction(weight: 25)
    monkey.addXCTestDragAction(weight: 200)
    monkey.addXCTestTapAction(weight: 100)
    monkey.addXCTestDragAction(weight: 30)
        
    monkey.monkeyAround(iterations: 360000)
}

前面的代碼是我照抄官方給的例子的, 不加的話會有 bug.

接著我們初始化一只 Monkey, 然后給它添加一些動作, 其實還有什么各種 pinch, peek, pop 之類的, 但我的項目比較簡單, 所以我就只加了點擊和拖拽動作, weight 是間隔. monkeyAround 就是開始隨機操作, iteration 是操作的次數(shù), 操作滿 360000 次就會停止.

這基本上就是我的用法, 里面還有一些挺有趣的東西, 之后有空的話我還會再探索一下, 例如添加多幾個用例, 然后先跳轉(zhuǎn)到新寫的 ViewController 那里, 讓這只猴子把里面的東西全都搞亂, 看看有啥 bug.

使用體驗

到目前位置我用了這個庫兩三天, 每天中午去吃飯都會跑一下, 發(fā)現(xiàn)了幾個 bug, 三個是低級錯誤, 兩個比較隱晦, 主要是關(guān)于多次點擊重復(fù)觸發(fā)關(guān)鍵事件, 例如說一秒內(nèi)連續(xù)點了七八次提交訂單, 導(dǎo)致發(fā)出去七八個請求, 實際在網(wǎng)絡(luò)情況不好的時候, 用戶也有可能心急多次點擊, 所以挺好的, 幫我提前預(yù)防了一些問題.

其實覺得無論是哪種情況, 都挺適合用一下這個庫去找到一些低級的明顯的 bug, 強烈推薦大家用一下.

覺得我寫的還不錯的話可以關(guān)注一下我的博客

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

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,643評論 25 708
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,151評論 4 61
  • 作者設(shè)計思路 1.YYMemoryCache YYMemoryCache負(fù)責(zé)管理內(nèi)存緩存。這個類是線程安全的。 L...
    WeiHing閱讀 655評論 0 7
  • 設(shè)置快捷啟動方式在Ubuntu下,每次都要找到 pycharm.sh所在的文件夾,執(zhí)行./pycharm.sh,非...
    張不二01閱讀 293評論 0 0
  • 光陰荏苒,轉(zhuǎn)瞬間的流逝!人生一世,值得謹(jǐn)記于心的人與事能有多少!很多時候你會說:我自私!誰又會懂得自私的緣由!很多...
    承諾詮釋人生閱讀 267評論 0 0