iOS-SwiftMonkey測試

Android中的Monkey測試極大的幫助Android開發(fā)者保證了開發(fā)質(zhì)量抗果,iOS自身是沒有Monkey測試的,最開始有基于UIAutomation 的 monkey 測試[https://github.com/jonathanpenn/ui-auto-monkey]. xCode7之后麸锉,UIAutomation被棄用道宅,對應(yīng)Monkey也隨之淡化.當(dāng)大家習(xí)慣Monkey測試扫倡,突然消失之后就會懷念豹缀,正所謂有需求就會有市場,老外用Swift基于XCUITesting框架開發(fā)新的Monkey工具SwiftMonkey.

Swift Monkey測試

SwiftMonkey基于Swift語言編寫鼠次,按照SwiftMonkey提供的Demo更哄,運行之后看到效果如下圖所示:


SwiftMonkey.gif

SwiftMonkey實現(xiàn)測試需要SwiftMonkey和SwiftMonkeyPaws兩個框架芋齿,如果我們的項目開始就是Swift語言編寫的,那么使用起來就非常簡單,主要過程如下:
①將Demo中SwiftMonkey和SwiftMonkeyPaws兩個項目拖入自身的Swift項目中.

FlyElephant.png

②SwiftMonkey作為FrameWork加入UITest對應(yīng)的Target文件中:


FlyElephant.png

③SwiftMonkeyPaws作為FrameWork加入App項目對應(yīng)的Target中;


FlyElephant.png

④AppDelegate中加入Paws:

class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    var paws: MonkeyPaws?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        paws = MonkeyPaws(view: window!)
        return true
    }

⑤UITest中加入Monkey測試代碼:

override func setUp() {
        super.setUp()
        
        // Put setup code here. This method is called before the invocation of each test method in the class.
        
        // In UI tests it is usually best to stop immediately when a failure occurs.
        continueAfterFailure = false
        // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
        XCUIApplication().launch()

        // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
    }
    
    override func tearDown() {
        // Put teardown code here. This method is called after the invocation of each test method in the class.
        super.tearDown()
    }
    
    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
        
        // Initialise the monkey tester with the current device
        // frame. Giving an explicit seed will make it generate
        // the same sequence of events on each run, and leaving it
        // out will generate a new sequence on each run.
        //let monkey = Monkey(frame: application.frame)
        let monkey = Monkey(seed: 123, frame: application.frame)
        
        // Add actions for the monkey to perform. We just use a
        // default set of actions for this, which is usually enough.
        // Use either one of these but maybe not both.
        // XCTest private actions seem to work better at the moment.
        // UIAutomation actions seem to work only on the simulator.
        monkey.addDefaultXCTestPrivateActions()
        
        //monkey.addDefaultUIAutomationActions()
        
        // Occasionally, use the regular XCTest functionality
        // to check if an alert is shown, and click a random
        // button on it.
        monkey.addXCTestTapAlertAction(interval: 100, application: application)
        
        // Run the monkey test indefinitely.
        monkey.monkeyAround()
    }

這段代碼是SwiftMonkey的默認(rèn)代碼成翩,addDefaultXCTestPrivateActions是調(diào)用Apple私有手勢方法觅捆,addDefaultUIAutomationActions只在模擬器中有效,內(nèi)部實現(xiàn)如下:

 public func addDefaultXCTestPrivateActions() {
        addXCTestTapAction(weight: 25)
        addXCTestLongPressAction(weight: 1)
        addXCTestDragAction(weight: 1)
        addXCTestPinchCloseAction(weight: 1)
        addXCTestPinchOpenAction(weight: 1)
        addXCTestRotateAction(weight: 1)
        //addXCTestOrientationAction(weight: 1) // TODO: Investigate why this does not work.
    }

默認(rèn)執(zhí)行點擊麻敌,長按栅炒,拖拽,捏合术羔,旋轉(zhuǎn)赢赊,橫豎屏切換操作,Weight代表的是時間間隔聂示,如果覺得系統(tǒng)默認(rèn)的操作過多,可以自行刪減.

monkeyAround代表次數(shù)簇秒,默認(rèn)如果不設(shè)置次數(shù)鱼喉,會一直執(zhí)行下去.

public func monkeyAround() {
        while true {
            actRandomly()
            actRegularly()
        }
    }
FlyElephant.gif

OC Monkey 測試

如果你的項目一開始就是Swift編寫,或者已經(jīng)全面遷移到Swift語言趋观,恭喜你下面這段介紹可以忽略了.鑒于目前大部分App都是OC為主扛禽,如果直接按照Swift的套路去使用SwiftMonkey會遇到一些問題,有興趣可以自行實踐皱坛,以下是本人實戰(zhàn)過程.

① 將Demo中SwiftMonkey和SwiftMonkeyPaws兩個項目拖入自身的Swift項目中.

② 將Always Embed Swift Standard Libraries設(shè)置為YES.


Paste_Image.png

③ 正常的套路直接調(diào)用Moneky,MonkeyPaws類编曼,但是事實上無法調(diào)用,折騰了很久剩辟,中間各種報錯.

④ 簡單粗暴的方式是將SwiftMonkey兩個項目中的Swift拷貝到OC項目中:


FlyElephant.png

⑤ AppDelegate中代碼實現(xiàn):

@interface AppDelegate ()

@property (strong, nonatomic) MonkeyPaws *paws;

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    self.paws = [[MonkeyPaws alloc] initWithView:self.window tapUIApplication:true];

    return YES;
}

⑤ UITest測試代碼:

- (void)setUp {
    [super setUp];
    
    // Put setup code here. This method is called before the invocation of each test method in the class.
    
    // In UI tests it is usually best to stop immediately when a failure occurs.
    self.continueAfterFailure = NO;
    // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
    [[[XCUIApplication alloc] init] launch];
    
    // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
}

- (void)tearDown {
    // Put teardown code here. This method is called after the invocation of each test method in the class.
    [super tearDown];
}

- (void)testExample {
    // Use recording to get started writing UI tests.
    [XCUIDevice sharedDevice].orientation = UIDeviceOrientationPortrait;
    // Use XCTAssert and related functions to verify your tests produce the correct results.
}

- (void)testMonkey {
    
    XCUIApplication *application = [XCUIApplication new];
    CGRect frame = [[application descendantsMatchingType:XCUIElementTypeAny] elementBoundByIndex:0].frame;
    
    Monkey *monkey = [[Monkey alloc] initWithSeed:123 frame:application.frame];
    
    [monkey addDefaultXCTestPrivateActions];
    [monkey addXCTestTapAlertActionWithInterval:100 application:application];
    [monkey monkeyAround];
}
FlyElephant.gif

如果項目中之前沒有進行過Monkey測試掐场,SwiftMonkey會幫我們測出一些以前開發(fā)中沒有注意的問題.SwiftMonkey涉及調(diào)用XCTesting的私有API,不建議包含SwiftMonkey直接上傳到AppStore.

參考資料
SwiftMonkey
SwiftMonkey :iOS 上的 monkey

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末贩猎,一起剝皮案震驚了整個濱河市熊户,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌吭服,老刑警劉巖嚷堡,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異艇棕,居然都是意外死亡蝌戒,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門沼琉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來北苟,“玉大人,你說我怎么就攤上這事打瘪〈饬埽” “怎么了吸祟?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長桃移。 經(jīng)常有香客問我屋匕,道長,這世上最難降的妖魔是什么借杰? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任过吻,我火速辦了婚禮,結(jié)果婚禮上蔗衡,老公的妹妹穿的比我還像新娘纤虽。我一直安慰自己,他們只是感情好绞惦,可當(dāng)我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布逼纸。 她就那樣靜靜地躺著,像睡著了一般济蝉。 火紅的嫁衣襯著肌膚如雪杰刽。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天王滤,我揣著相機與錄音贺嫂,去河邊找鬼。 笑死雁乡,一個胖子當(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
  • 正文 獨居荒郊野嶺守林人離奇死亡侵浸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年旺韭,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片掏觉。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡区端,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出澳腹,到底是詐尸還是另有隱情织盼,我是刑警寧澤杨何,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站沥邻,受9級特大地震影響危虱,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜唐全,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一埃跷、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧邮利,春花似錦弥雹、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至方庭,卻和暖如春厕吉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背二鳄。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工赴涵, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留媒怯,地道東北人订讼。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像扇苞,于是被迫代替她去往敵國和親欺殿。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,901評論 2 345

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

  • 書名:刻意練習(xí) 閱讀時間:60分鐘 頁碼:1-46頁 閱讀收獲: 1鳖敷、以前做很多事脖苏,或看很多書,都是看看停停定踱,做事...
    榮涵閱讀 163評論 0 0
  • 短書集微信公眾號ID:duanshu300 解說詞:當(dāng)幸福來得太快棍潘,你會怎么樣?再進一步崖媚,當(dāng)一切都來得太快亦歉,又會怎...
    Andylee閱讀 690評論 0 1
  • /牙疼1 一到晚上 蛀牙隱隱作痛 連同腦殼后耳 似乎痛無止境 自己 似乎像一條魚 那顆蛀牙 是一把尖刀 把自己牢牢...
    可樂飛冰閱讀 398評論 0 0
  • 我稀稀拉拉的在簡書上寫了幾篇文章荠呐,中間停止了很長時間赛蔫,我去汲取能量去了砂客,我在就業(yè)的閑暇時瘋狂看書,想要有更多的東...
    鹿有年閱讀 146評論 0 0
  • 目前的我的場景是:使用攔截器全局驗證token 上面的辦法只是重新創(chuàng)建了ResponseBody 然后將服務(wù)器返回...
    wodezhuanshu閱讀 5,895評論 0 2