天天看點

Macaca自動化測試Android和IOS應用

版權聲明:本文為部落客原創文章,未經部落客允許不得轉載。 https://blog.csdn.net/u010046908/article/details/54021946

1.Macaca簡介

Macaca是阿裡巴巴集團開發的一套完整的自動化測試解決方案。

2.Macaca特性:

  • 支援移動端和PC端
  • 支援Native, Hybrid, H5 等多種應用類型
  • 提供用戶端工具和持續內建服務

3.macaca-cli用戶端的安裝:

3.1安裝 Node.js

請安裝 Node.js v4.0 或者更高版本,裝好 Node.js 後指令行裡就已經內建了 npm 工具,為了提高安裝子產品的速度,請使用國内的 cnpm。

3.2 iOS 環境安裝

請安裝 Xcode8 或者更高版本

需要安裝 usbmuxd 以便于通過 USB 通道測試 iOS 真機,不需要測試真機則不用安裝

$ brew install usbmuxd

應用中如含有 WebView,請安裝 ios-webkit-debug-proxy

$ brew install ios-webkit-debug-proxy

備注:使用brew指令需要安裝Homebrew(一款常用的 MacOS 的包管理器),請按照官網提示安裝。

準備 App 包:如需要測試 iOS 應用,請使用 Scheme 設定為 debug 的 .app 包。

3.3 Android環境安裝

3.3.1 安裝 JDK

配置 JAVA_HOME,根據你所使用的 shell 工具修改不同的檔案,比如 ~/.bashrc, ~/.bash_profile, ~/.zshrc

shell export JAVA_HOME=path/to/your/Java/Home

3.3.2安裝安卓 SDK

運作 brew install android-sdk,然後安裝18-24版本中的任一 SDK

shell 環境設定 ANDROID_HOME 根據你所使用的Terminal修改不同的

檔案,比如~/.bashrc, ~/.bash_profile, ~/.zshrc
# 如果是通過homebrew安裝的android-sdk,則路徑如下

export ANDROID_HOME = /usr/local/opt/android-sdk

# 如果通過其他方式安裝的sdk,路徑設定為對應的android sdk的路徑

export ANDROID_HOME = path/to/your/Android/sdk
           

注意:準備 App 包:如需要測試 Android 應用,請使用 .apk 格式的包。

3.4 全局安裝macaca

$ npm i -g macaca-cli

如果看到如下可愛的小猴子,那恭喜你安裝成功啦!重新安裝則會覆寫更新。

3.5安裝驅動

3.6 環境檢查

通過 macaca doctor 可以檢查環境是否配置成功

$ macaca doctor

如上圖所示則表示環境均配置正常,如果有錯誤,會出現紅色的提示。

4 運作官方示例

将官方示例(mobile-app-sample-nodejs)克隆到本地,更多的示例請通路macaca-sample。

$ git clone https://github.com/macaca-sample/mobile-app-sample-nodejs.git --depth=1
$ cd mobile-app-sample-nodejs
$ npm i
# 更多運作方式見Makefile
$ macaca run --verbose           

4.1 Android 的自動化測試

先在mobile-app-sample-nodejs/macaca-test/mobile-app-sample.test.js腳本檔案中如果是ios該為Android。

var platform = process.env.platform || 'Android';
platform = platform.toLowerCase();           

在mobile-app-sample-nodejs目錄下執行

macaca run

測試的過程

lidongdeMacBook-Pro:mobile-app-sample-nodejs lidong$ macaca run ./macaca-test/macaca-mobile-sample.test.js
>> webdriver sdk launched
>> 

>> 

>>   macaca mobile sample

>> get /Users/lidong/.macaca-temp/android_app_bootstrap-debug.apk from cache
>> sha:e2ca601f9ee1ec101326d12377a2e8d4
INSTRUMENTATION_STATUS: numtests=1
INSTRUMENTATION_STATUS: stream=
com.android.uiautomator.client.Initialize:
INSTRUMENTATION_STATUS: id=UiAutomatorTestRunner
INSTRUMENTATION_STATUS: test=testStartServer
INSTRUMENTATION_STATUS: class=com.android.uiautomator.client.Initialize
INSTRUMENTATION_STATUS: current=1
INSTRUMENTATION_STATUS_CODE: 1

uiautomator start socket server.

>> socket server ready
>> socket client ready
recive: {"cmd":"wake","args":{}}

return: {"success":true,"data":{"status":0,"value":true}}

recive: {"cmd":"getWindowSize","args":{}}

return: {"success":true,"data":{"status":0,"value":"{\"width\":1080,\"height\":1794}"}}

>> current window size {"width":1080,"height":1794}

recive: {"cmd":"find","args":{"strategy":"class name","selector":"android.widget.EditText","multiple":true}}

return: {"success":true,"data":{"status":0,"value":[{"ELEMENT":"1"},{"ELEMENT":"2"}]}}

recive: {"cmd":"clearText","args":{"elementId":"1"}}

return: {"success":true,"data":{"status":0,"value":true}}

recive: {"cmd":"setText","args":{"elementId":"1","text":"中文+Test+12345678"}}

return: {"success":true,"data":{"status":0,"value":true}}

recive: {"cmd":"find","args":{"strategy":"class name","selector":"android.widget.EditText","multiple":true}}

return: {"success":true,"data":{"status":0,"value":[{"ELEMENT":"3"},{"ELEMENT":"4"}]}}

recive: {"cmd":"clearText","args":{"elementId":"4"}}

return: {"success":true,"data":{"status":0,"value":true}}

recive: {"cmd":"setText","args":{"elementId":"4","text":"111111"}}

return: {"success":true,"data":{"status":0,"value":true}}

recive: {"cmd":"find","args":{"strategy":"name","selector":"Login","multiple":true}}

return: {"success":true,"data":{"status":0,"value":[{"ELEMENT":"5"}]}}

recive: {"cmd":"click","args":{"elementId":"5"}}

return: {"success":true,"data":{"status":0,"value":true}}

>> 
>>      #1 should login success (19613ms)

recive: {"cmd":"getSource","args":{}}

return: {"success":true,"data":{"status":0,"value":true}}


>> { hierarchy: 
   { rotation: '0',
     node: 
      { index: '0',
        class: 'android.widget.FrameLayout',
        package: 'com.github.android_app_bootstrap',
        checkable: 'false',
        checked: 'false',
        clickable: 'false',
        enabled: 'true',
        focusable: 'false',
        focused: 'false',
        scrollable: 'false',
        'long-clickable': 'false',
        password: 'false',
        selected: 'false',
        bounds: '[0,0][1080,1794]',
        node: [Object] } } }

>> 
>>      #2 should display home (911ms)

recive: {"cmd":"find","args":{"strategy":"name","selector":"list","multiple":false}}
等等
           

4.2 IOS 的自動化測試

先在mobile-app-sample-nodejs/macaca-test/mobile-app-sample.test.js腳本檔案中如果是Android改為ios。

var platform = process.env.platform || 'ios';
platform = platform.toLowerCase();           

測試過程

lidongdeMacBook-Pro:mobile-app-sample-nodejs lidong$ macaca run ./macaca-test/macaca-mobile-sample.test.js
>> webdriver sdk launched
>> 

>> 

>>   macaca mobile sample

>> get /Users/lidong/.macaca-temp/android_app_bootstrap-debug.apk from cache
>> sha:e2ca601f9ee1ec101326d12377a2e8d4
INSTRUMENTATION_STATUS: numtests=1
INSTRUMENTATION_STATUS: stream=
com.android.uiautomator.client.Initialize:
INSTRUMENTATION_STATUS: id=UiAutomatorTestRunner
INSTRUMENTATION_STATUS: test=testStartServer
INSTRUMENTATION_STATUS: class=com.android.uiautomator.client.Initialize
INSTRUMENTATION_STATUS: current=1
INSTRUMENTATION_STATUS_CODE: 1

uiautomator start socket server.

>> socket server ready
>> socket client ready
recive: {"cmd":"wake","args":{}}

return: {"success":true,"data":{"status":0,"value":true}}

recive: {"cmd":"getWindowSize","args":{}}

return: {"success":true,"data":{"status":0,"value":"{\"width\":1080,\"height\":1794}"}}

>> current window size {"width":1080,"height":1794}

recive: {"cmd":"find","args":{"strategy":"class name","selector":"android.widget.EditText","multiple":true}}

return: {"success":true,"data":{"status":0,"value":[{"ELEMENT":"1"},{"ELEMENT":"2"}]}}

recive: {"cmd":"clearText","args":{"elementId":"1"}}

return: {"success":true,"data":{"status":0,"value":true}}
           

5.腳本初始化參數

5.1 常見的參數

  1. platformName String 目前用例運作的平台 { iOS / Android / Desktop }
  2. browserName String 目前測試的浏覽器名稱 { iOS: Safari } { Android: Chrome } { Desktop: Chrome / Electron }

5.2 App 相關參數

  1. deviceName String 模拟器的名稱,例如 ‘iPhone 6’ 或者 ‘Nexus 5x’。
  2. app Stirng .ipa,.app 或者 .apk 檔案的絕對位址或者遠端位址,或者是包含上述檔案格式的 Zip 檔案。
  3. udid String 測試裝置的唯一裝置 ID。

5.3 Android 的參數介紹

  1. reuse Number 0: 啟動并安裝 app。{1 (預設): 解除安裝并重裝 app。 2: 僅重裝 app。3: 在測試結束後保持 app 狀态。}
  2. package String Android app 的 package name。
  3. activity String 啟動時的 Activity name。

5.4 iOS 的參數介紹

  1. reuse Number 0: 清楚資料并重裝 app。 1: (預設) 解除安裝并重裝 app。 2: 僅重裝 app。 3: 在測試結束後保持 app 狀态。
  2. bundleId String 應用的 Bundle ID,例如 com.apple.Maps。
  3. autoAcceptAlerts Boolean 自動接受所有的系統彈窗資訊。預設是 false。
  4. autoDismissAlerts Boolean 自動拒絕所有的系統彈窗資訊。預設是 false。

5.5 基本用法

'use strict';

require('should');
var xml2map = require('xml2map');

var platform = process.env.platform || 'ios';
platform = platform.toLowerCase();

var pkg = require('../package');

/**
 * download app form npm
 *
 * or use online resource: https://npmcdn.com/ios-app-bootstrap@latest/build/ios-app-bootstrap.zip
 *
 * npm i ios-app-bootstrap --save-dev
 *
 * var opts = {
 *   app: path.join(__dirname, '..', 'node_modules', 'ios-app-bootstrap', 'build', 'ios-app-bootstrap.zip');
 * };
 */

// see: https://macacajs.github.io/desired-caps

var iOSOpts = {
  deviceName: 'iPhone 5s',
  platformName: 'iOS',
  autoAcceptAlerts: false,
  //reuse: 3,
  //udid: '',
  //bundleId: 'xudafeng.ios-app-bootstrap',
  app: 'http://localhost:8087/ios-app-bootstrap.zip'
};

var androidOpts = {
  platformName: 'Android',
  autoAcceptAlerts: false,
  // reuse: 3,
  // udid: '',
  // package: 'com.github.android_app_bootstrap',
  // activity: 'com.github.android_app_bootstrap.activity.WelcomeActivity',
  app: 'http://localhost:8087/android_app_bootstrap-debug.apk'
};

const isIOS = platform === 'ios';
const infoBoardId = isIOS ? 'info' : 'com.github.android_app_bootstrap:id/info';

const wd = require('macaca-wd');

// override custom wd
require('./wd-extend')(wd, isIOS);

describe('macaca mobile sample', function() {
  this.timeout(5 * 60 * 1000);

  const driver = wd.promiseChainRemote({
    host: 'localhost',
    port: 3456
  });

  driver.configureHttp({
    timeout: 600 * 1000
  });

  before(function() {
    return driver
      .init(isIOS ? iOSOpts : androidOpts);
  });

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

  it('#1 should login success', function() {
    return driver
      .getWindowSize()
      .then(size => {
        console.log(`current window size ${JSON.stringify(size)}`);
      })
      .appLogin('中文+Test+12345678', '111111')
      .sleep(1000);
  });
           

Macaca自動化測試Android和IOS應用,基本上說到這裡就要結束。後面我們還是學習如何自己寫測試腳本。