Macaca-iOS入門那些事2

Macaca-iOS入門那些事2

一. 前言

上文《Macaca-iOS入門那些事》講到Macaca環境部署及運行了第一個案例,本文將講解其案例編寫。html

二. 測試案例解析

iOS案例:macaca-mobile-sample.test.js,由2部分組成:ios

  1. 配置
  2. 測試案例

以上代碼兼顧了Android,因此會有冗餘,簡化以下:git

1. 配置

var iOSOpts = {
    platformName: 'iOS',
    platformVersion: '9.3',         
    deviceName: 'iPhone 5s',
    app: '/Users/chenximing/workspace/ios/macaca-test2/macaca-test-sample/app/ios-app-bootstrap.zip'
};
/*
    platformName:平臺名稱
    platformVersion:iOS系統版本,框架好像沒用到這個參數,因此這玩意不重要
    deviceName:設備名稱
    app:被測app路徑
*/

2. 測試案例

var wd = require('webdriver-client')(iOSOpts);
describe('macaca mobile sample', function() {
    this.timeout(5 * 60 * 1000);
    var driver = wd.initPromiseChain();
    driver.configureHttp({
        timeout: 600000
    });

    before(function() {
        return driver
            .initDriver();
    });

    after(function() {
        return driver
            .sleep(1000)
            .quit();
    });

    it('#1 should login success', function() {
        return driver
            .login('12345678', '111111')
            .sleep(1000);
    });

...

});

這裏能夠細分爲:github

(1). driver初始化
var wd = require('webdriver-client')(iOSOpts);
......
var driver = wd.initPromiseChain();
driver.configureHttp({
    timeout: 600000
});

webdriver-client是什麼?web

上篇說到macaca是c-s模式的測試框架,client負責被案例端調用的API,server負責調起instruments以及控制其執行測試。webdriver-client就是上面說到的client端,提供控制操做的API,《Macaca的API文檔》編程

(2). 測試框架
describe('macaca mobile sample', function() {
    this.timeout(5 * 60 * 1000);

    ......

    before(function() {
        return driver
            .initDriver();
    });

    after(function() {
        return driver
            .sleep(1000)
            .quit();
    });

    it('#1 should login success', function() {
        return driver
            .login('12345678', '111111')
            .sleep(1000);
    });

    ...

});

在這裏,Macaca使用一個第三方的測試框架Mocha,macaca-cli在run的時候加載該框架。bootstrap

describe、before、after、it等關鍵字均爲Mocha提供,和傳統XUnit框架功能相似(Mocha默認是BDD模式,而XUnit是TDD模式),想了解更多,見Mocha主頁api

(3). 測試案例
...

it('#1 should login success', function() {
    return driver
        .login('12345678', '111111')
        .sleep(1000);
});

...

it部分就是測試案例。app

三. 進階

1. BDD(Behavior-driven development)

爲何我會介紹BDD? 由於Mocha就基於BDD思想的測試框架,而且我估計會有人把 BDD鏈式調用 的概念搞混。框架

BDD(Behavior Driven Development:行爲驅動開發),是基於TDD發展的一種解決問題的思想,經過用相似天然語言方式描述軟件行爲,以達到可讀性更高(讓非技術人員也能夠看懂)。

以上測試代碼中,屬於BDD部分由Mocha提供的,如:describe, it, before, after...這些均爲BDD風格的接口。若是是TDD風格(如:XUnit)的接口則是:suite, test, setup, teardown...

2. 鏈式調用

(1)什麼是鏈式調用
driver
  .native()
  .elementByName('PERSONAL')
  .click()
  .sleep(1000)
  .takeScreenshot()
  .elementByName('Logout')
  .click()
  .sleep(1000)
  .takeScreenshot();

以上代碼組織方式爲:鏈式調用。

若是你以前把BDD鏈式調用搞混,估計看過如下代碼:

When(...).Then(...).And(...).Should(...)

這段代碼就是BDD接口以鏈式方式調用,可讀性很是高!但關於BDD的部分其實仍是:When、Then、And、Should...

(2)爲什麼Macaca測試案例使用鏈式調用風格?

某些狀況下,使用鏈式調用方式書寫代碼是很舒服的,如C#的linq:

var rs = user.Where(x => x.Length == 3).Select(x => x).ToList();

但若是把全部測試操做(不管操做間有無關聯)都用鏈式調用方式組合,就比較奇怪了。如:

return driver
       .webview()
       .elementById('pushView')
       .tap()
       .sleep(5000)
       .webview()
       .elementById('popView')
       .tap()
       .sleep(5000)
       .takeScreenshot();

上面2個webview element的操做是沒有任何關係的。而使用鏈式調用的場景通常是先後依賴、連續操做、層級遞進,如上面的linq例子:where的結果集,接着要進行數據提取,而後是再把集合封裝爲list結構。

因此,基於鏈式調用的原意,上面的案例的寫法就有些奇怪了,而且Node.js的新手也不習慣。然而,爲啥做者會寫出這種的測試代碼?緣由在於:Node.js這個語言!

Node.js是異步編程語言,例子以下:

var el = driver.webview().elementById('hyddd')
  el.tap()

上面2句,同步編程語言是怎麼理解呢?

(1)獲取hyddd的element;

(2)對element進行tap()操做;

但換做異步編程語言呢?

(1)獲取hyddd的element;

(2)el.tap()同時於(1)執行,也就說,el還沒賦值,(2)就已經開始執行了,徹底沒等(1)返回(2)就執行了;

無法好好玩耍了,若是原生Node.js程序時要處理同步場景,就會出現所謂的callback hell,爲了不callback hell,就出現了Promise模式。嗯,在上面的測試代碼中是否是看到這個單詞?它做用就是把異步模式變爲同步模式,同時避免callback hell。而它的表現就是如今這種鏈式調用!!!因此測試案例長得比較奇怪是開發語言致使的。

就我的的測試哲學而言,腳本性的語言是最適合寫測試腳本的,但Node.js異步編程風格比較特別,增長了測試案例編寫者入門門檻,因此我其實更傾向Python。前幾天和Macaca做者聊過,對Python的支持估計也要等一段時間,但願這天儘快到來。

相關文章
相關標籤/搜索