Macaca [基于 Node.js 的自动化测试-Macaca] - iOS 初次使用 [多图]

达峰的夏天 · 2016年03月10日 · 最后由 陈美娜 回复于 2017年04月11日 · 24790 次阅读
本帖已被设为精华帖!

上一篇 - Tests in Node.js

同步 Node 社区的文章: 链接

如何安装

使用 cnpm 安装即可,上篇文章有提到,请注意 node 版本要 >= 4.2.1。

这是 macaca-cli 的 repo 地址 github/macaca-cli,欢迎各位 start,有问题也请及随时提 issue。

$ cnpm i macaca-cli -g

macaca

看到这个界面,表示安装已经完成了。正常网速下不过十几秒即可安装成功,过程顺畅,安装速度慢或者安装过程中有失败是大家都不能接受的。

# 查看版本
$ macaca -v
# 查看环境
$ macaca doctor

doctor

确认环境已经没有问题,我们接下来跑一个例子。

若想要测试 iOS 下的 webview,需要安装 ios-webkit-debug-proxy:

# 建议使用中科大源

$ HOMEBREW_BOTTLE_DOMAIN=https://mirrors.ustc.edu.cn/homebrew-bottles brew install ios-webkit-debug-proxy

小试牛刀

未避免 App 版权问题,我快速赶了个 App 出来方便演示 Macaca 的使用,有兴趣的可以看源码

gif

用例组织十分简单,在理解要测什么的情况下,直接通过拷贝粘贴即可完成,我简单写了几个如下:

var wd = require('webdriver-client')({
  platformName: platform,
  app: path.join(__dirname, '..', 'app', `${platform.toLowerCase()}-app-bootstrap.zip`)
});

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

  var driver = wd.initPromiseChain();

  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);
  });

  it('#2 should display home', function() {
    return driver
      .takeScreenshot();
  });

  it('#3 should display webview', function() {
    return driver
      .elementByName('Webview')
      .click()
      .sleep(3000)
      .takeScreenshot();
  });

  it('#4 should go into webview', function() {
    return driver
      .webview()
      .elementById('pushView')
      .tap()
      .sleep(5000)
      .webview()
      .elementById('popView')
      .tap()
      .sleep(5000)
      .takeScreenshot();
  });

  it('#5 should go into test', function() {
    return driver
      .native()
      .elementByName('Baidu')
      .click()
      .sleep(5000)
      .takeScreenshot();
  });

  it('#6 should works with web', function() {
    return driver
      .webview()
      .elementById('index-kw')
      .sendKeys('TesterHome')
      .elementById('index-bn')
      .tap()
      .sleep(5000)
      .source()
      .then(function(html) {
        html.should.containEql('TesterHome');
      })
      .takeScreenshot();
  });

  it('#7 should logout success', function() {
    return driver
      .native()
      .elementByName('PERSONAL')
      .click()
      .sleep(1000)
      .takeScreenshot()
      .elementByName('Logout')
      .click()
      .sleep(1000)
      .takeScreenshot();
  });
});

测试用例源码,欢迎下载到本地试验。

跑过简单的上手例子,相信大家已经可以使用了。接下来我会分享实现细节、用例相关、如何支持 pc、如何做持续集成等。

关于开源

在团队成员的共同努力和公司开源协会的帮助下,Macaca 后面会将持续集成相关的平台和模块开源,敬请期待。

欢迎讨论,互相学习。

微博: http://weibo.com/xudafeng
Github: https://github.com/xudafeng

下一篇 - 配置 Docker 环境

共收到 75 条回复 时间 点赞

这算一个 appium 的 client 吗

#1 楼 @seveniruby

appium 是个优秀的工具。但无法满足更轻、更快、更稳、更易集成、更贴合业务的高要求。

欢迎到这里贡献源码: macacajs。相信除了 appium 还有其他选择。

#2 楼 @xdf 恩. appium 太大而全了. 是个中庸的方案. 我看 appium 的官方也出了 nodejs 的 driver. 感觉和他的方案有点像.

#3 楼 @seveniruby

端对端测试原理大相径庭。

相比烂代码,你会喜欢更好的。欢迎尝鲜,更欢迎贡献代码哦-

#2 楼 @xdf 虽然对你的全栈测试不认同,但这个真的不错
你的 js 封装的厉害的,这正是我需要学习和加强的,谢谢开源

#5 楼 @quqing 求同存异很正常啊。希望和前辈们一起努力,把产品做好,解决实际问题和痛苦。

#6 楼 @xdf 有没有考虑过用原生的 Ajax 做成一套接口测试的工具

#7 楼 @quqing RESTful 接口测试吗?推荐看 supertest

mark.好好研究下,实现原理可以再讲一下,毕竟更多人之前没接触这种脚本编写方式哈

—— 来自 TesterHome 官方 安卓客户端

天啊 我被小猴子萌到了 ~ 使用 js 写测试用例的? 这算是类似 appium 的工具吧?

coool, 提一个小问题,你 case 是 thread sleep 5s, 真实环境超过 5s 就会判 fail 么?

#12 楼 @shenkai600 你试试就知道了呀

运行成功是没问题的,再研研究你的用例是怎么写的。还需要多学习

在哪里拷贝黏贴用例呢?请教一下

如何划过引导页呢?

#16 楼 @davidyang 是指软件启动需要滑动操作吗?常规方法即可,我稍后贴个示例

要是支持多语言就好了。比如 python 什么的

#4 楼 @xdf @seveniruby 说实话觉得 Appium 烂代码不敢苟同,无论 client 还是 server 设计上还是有很多考虑的。中庸,步骤繁琐,不够轻这个倒可以说。另外我看你动画里的 log 和测试用例的 demo,不也是很多地方直接沿用别人的接口?除了加个 builder 设计模式,让你一个操作之后还能做另一个操作(google 的 espresso 也用了这种方式),没看到有什么明显的差别。你说的端对端测试原理大相径庭是什么回事?

#19 楼 @uncleleung 没提 appium 代码烂吧. 1.5 代码做了重构. 代码还是挺清晰的. 只是太重了. 其实是把移动测试相关的很多工具都集成进来了. 对新人是有好处的. @xdf 的框架估计是类似 appium 的 node client + appium server. 两者合二为一了.

#20 楼 @seveniruby ” 相比烂代码,你会喜欢更好的。“是这句话让我产生了这个感觉,可能也是我理解错了。其实我更关心的是说端对端测试原理大相径庭是什么意思,哈哈。如果是 node client + node server 合二为一加上把一些额外的功能去掉,我可以理解,但是我没觉得原理上有什么不同啊。因为我看 log 感觉 RESTful 交互那一块都一样一样的。所以我比较感兴趣的是他这个说原理不同是怎么回事

#20 楼 @seveniruby 顺便问问你,我看到 testerhome fork 了一个 appium 出来,还有不少的 pull request, 这个目的是什么?做了一些什么变化?

#14 楼 @davidyang 怎么运行的,我 cd 到那个带测试用例代码的文件后 make test,提升 The environment you requested was unavailable

#22 楼 @uncleleung 以前 TesterHome 给 Appium 提交过代码. 所以有 fork. 提交 PR 用的. 代码已经提交进去了. 所以 fork 的那个基本不用跟了. 1.5 之后代码架构做了很大的变更. 还得重新 fork 子项目.

#21 楼 @uncleleung 达峰是个技术新秀. 搞出来的东西肯定有自己的目标. 我估计是他没预料到 Appium 1.5 之后的变更. 我还没看过 mocaca 的框架. 还没仔细研究过. 从目前来看. 让别人用写脚本可能会是个门槛. 说实话 QA 里面懂 node 和开发里面懂 node 的人都挺少的. 这恰好就是 Appium 的优势所在

#25 楼 @seveniruby 恩,我之前的回复可能略有偏激了,不过纯粹是技术探讨,没有恶意。我有空也先了解一下 mocaca 框架开源的部分,整个框架在 github 上的子项目也不少,无论怎样能做出来还是很牛 b 的。至于 node 我倒觉得有代码能力的 QA 写应该问题不大,如果只是写测试用例的话估计也不需要了解太多的语言特性。话说 Appium 1.5 我也没看,如果有很大的变更那倒蛮有兴趣的。

#26 楼 @uncleleung 变化已经大到你都不认识 Appium 了. 所有的代码都被重构了. 一个项目被拆成了十几个子项目. 感受下吧....

#27 楼 @seveniruby 汗,难怪我刚看了一眼 github 发现怎么 appium 这个项目里代码这么少

@xdf 麻烦给一个 android 的示例嘛,没明白脚本中是如何调用模拟器的。

@xdf 麻烦给一个 android 的示例啊,完全小白

安装完成之后直接报错误


 /usr/local/lib/node_modules/macaca-client/node_modules/mocha/lib/utils.js:577
      if (!files.length) throw new Error("cannot resolve path (or pattern) '" + path + "'");
Error: cannot resolve path (or pattern) 'macaca-test'
    at Object.lookupFiles (/usr/local/lib/node_modules/macaca-client/node_modules/mocha/lib/utils.js:577:32)
    at /usr/local/lib/node_modules/macaca-client/node_modules/mocha/bin/_mocha:320:30
    at Array.forEach (native)
    at Object.<anonymous> (/usr/local/lib/node_modules/macaca-client/node_modules/mocha/bin/_mocha:319:6)
    at Module._compile (module.js:413:34)
    at Object.Module._extensions..js (module.js:422:10)
    at Module.load (module.js:357:32)
    at Function.Module._load (module.js:314:12)
    at Function.Module.runMain (module.js:447:10)
    at startup (node.js:141:18)
    at node.js:933:3
 Test completed!

请问 @xdf 。。。
运行 macaca run --server --verbose
/usr/local/lib/node_modules/macaca-client/node_modules/mocha/lib/utils.js:577
if (! files.length) throw new Error("cannot resolve path (or pattern) '" + path + "'");
Error: cannot resolve path (or pattern) 'macaca-test'
at Object.lookupFiles (/usr/local/lib/node_modules/macaca-client/node_modules/mocha/lib/utils.js:577:32)
at /usr/local/lib/node_modules/macaca-client/node_modules/mocha/bin/_mocha:320:30
at Array.forEach (native)
at Object. (/usr/local/lib/node_modules/macaca-client/node_modules/mocha/bin/_mocha:319:6)
at Module._compile (module.js:413:34)
at Object.Module._extensions..js (module.js:422:10)
at Module.load (module.js:357:32)
at Function.Module._load (module.js:314:12)
at Function.Module.runMain (module.js:447:10)
at startup (node.js:141:18)
at node.js:933:3
Test completed!

之后运行 make install

The following build commands failed:
CompileSwift normal x86_64 /Users/test/macaca/ios-app-bootstrap-master/Carthage/Checkouts/Alamofire/Source/Timeline.swift
CompileSwift normal x86_64 /Users/test/macaca/ios-app-bootstrap-master/Carthage/Checkouts/Alamofire/Source/Upload.swift
CompileSwift normal x86_64 /Users/test/macaca/ios-app-bootstrap-master/Carthage/Checkouts/Alamofire/Source/ParameterEncoding.swift
CompileSwift normal x86_64 /Users/test/macaca/ios-app-bootstrap-master/Carthage/Checkouts/Alamofire/Source/Request.swift
CompileSwift normal x86_64 /Users/test/macaca/ios-app-bootstrap-master/Carthage/Checkouts/Alamofire/Source/ResponseSerialization.swift
CompileSwift normal x86_64 /Users/test/macaca/ios-app-bootstrap-master/Carthage/Checkouts/Alamofire/Source/Error.swift
CompileSwift normal x86_64 /Users/test/macaca/ios-app-bootstrap-master/Carthage/Checkouts/Alamofire/Source/Manager.swift
CompileSwift normal x86_64 /Users/test/macaca/ios-app-bootstrap-master/Carthage/Checkouts/Alamofire/Source/Response.swift
CompileSwiftSources normal x86_64 com.apple.xcode.tools.swift.compiler
(9 failures)

make: *** [install] Error 1

如何配置 ios 的真机测试呢

#33 楼 @chungeguo 传入 udid 即可

#34 楼 @xdf 十分感谢

@ryan730 @imesong 问题欢迎提 issue,处理及时些

马克一下,学习中。

#23 楼 @SkylineJia
跟楼主的步骤是一样的就行

请问@xdf 下载 test-sample ,编译完运行的时候报错,下面是 log:

index.js:62:12 [master] pid:29210 webdriver server start with config:
{ port: 3456,
ip: '10.0.0.22',
host: 'Erics-MacBook-Pro.local',
loaded_time: '2016-03-22 15:51:06' }
middlewares.js:31:10 [master] pid:29210 base middlewares attached
router.js:101:10 [master] pid:29210 router set
webdriver sdk launched

macaca test sample

1) "before all" hook

2) "after all" hook

0 passing (1s)
2 failing

1) macaca test sample "before all" hook:
[init({"autoAcceptAlerts":true,"platformName":"iOS","platformVersion":"9.2","deviceName":"iPhone 5s","app":"/Users/eric/Project/macaca-test-sample/app/ios-app-bootstrap.zip"})] getaddrinfo ENOTFOUND localhost localhost:3456
Error: getaddrinfo ENOTFOUND localhost localhost:3456
at errnoException (dns.js:26:10)
at GetAddrInfoReqWrap.onlookup as oncomplete

2) macaca test sample "after all" hook:
[quit()] getaddrinfo ENOTFOUND localhost localhost:3456
Error: getaddrinfo ENOTFOUND localhost localhost:3456
at errnoException (dns.js:26:10)
at GetAddrInfoReqWrap.onlookup as oncomplete

Test completed!

我只需要测试 Android,参数是 Android

用例的写法和 mocha 很像,刚好最近在用 mocha 测试框架写 Web UI 自动化,看上去有点熟悉感_^

#43 楼 @yhui 默认集成了 mocha

运行测试 sample ios 模拟器一定要 ios 9.2 的吗?

#45 楼 @tediwang 你是什么版本?

@xdf 你好,在环境搭建好后,执行 make test-android,出现以下错误,请帮忙指导下:

middlewares.js:31:10 [master] pid:9507 base middlewares attached
router.js:101:10 [master] pid:9507 router set
webdriver sdk launched
events.js:141
throw er; // Unhandled 'error' event
^

Error: spawn /usr/local/lib/node_modules/.macaca-client_npminstall/mocha/2.2.4/.bin/mocha ENOENT
at exports._errnoException (util.js:870:11)
at Process.ChildProcess._handle.onexit (internal/child_process.js:178:32)
at onErrorNT (internal/child_process.js:344:16)
at nextTickCallbackWith2Args (node.js:438:9)
at process._tickCallback (node.js:352:17)

#48 楼 @xdf 我下载了 macaca-test-sample ,执行 sudo macaca run --server --verbose 得出这样结果,为啥

#49 楼 @holysor 请去掉 sudo 权限运行,参见这篇

#50 楼 @xdf 问题依旧。。。?

#51 楼 @holysor 你是要运行 pc 端的示例么?make test-pc,看这里

#52 楼 @xdf 我运行 PC 的用例,显示失败结果具体是什么原因?我试了试好像不是 make test-pc 问题

#53 楼 @holysor 执行 macaca run --verbose -d ./macaca-test/macaca-desktop-sample.test.js后,log 可以贴么?提个 issue,像这样链接,方便分析和归档

#54 楼 @xdf 已经创建了 issue 链接

#31 楼 @imesong 出现相同的问题,完全是小白,楼主是否可以把步骤写详细点呢?感觉这个适合能编程基础的人使用,而且必须要有 node.js ,linux, 基础。在 window 环境下面不能运行吗?如何运行呢?
开始我是在 Win7 上安装了 ,安排好了 git 和 node.js, 稀里糊涂的安装 macaca 了,在 Node.js command prompt, 运行语句 macaca -v, 和 macaca -doctor 都可以查到信息。 是否认为安排好了呢?
问题出现在,Node.js command prompt 中运行 macaca run --verbose 没反应的。

#44 楼 @xdf 楼主,初始化的时候报错了,貌似是打开模拟器失败?

Error: Command failed: /bin/sh -c open -a Simulator --args -CurrentDeviceUDID "2DA37BDF-CF01-49B5-AA21-E0111E5AFBC2"
The application /Applications/Cocos/cocos-simulator-bin/ios/Simulator.app cannot be opened because it has an incorrect executable format.

    at ChildProcess.exithandler (child_process.js:213:12)
    at emitTwo (events.js:87:13)
    at ChildProcess.emit (events.js:172:7)
    at maybeClose (internal/child_process.js:818:16)
    at Socket.<anonymous> (internal/child_process.js:319:11)
    at emitOne (events.js:77:13)
    at Socket.emit (events.js:169:7)
    at Pipe._onclose (net.js:469:12)

执行 doctor 命令提示 platforms directory is not exist ,这是新建文件夹?

@cxf 提 issue

#59 楼 @cxf 你这个提示是 Android CheckList 下面出现的么?是的话起 Android SDK Manager 看下,可能就是没有安装 SDK Platform。同样小白新手体验 macaca😀 😀

#61 楼 @wolf5 嗯啊,我只是执行 brew install Android。其他的都没装,提示是 Android CheckList 下面。。。准备下载一个

达峰的夏天 [该话题已被删除] 中提及了此贴 06月27日 11:17
达峰的夏天 [该话题已被删除] 中提及了此贴 06月27日 11:17
达峰的夏天 [该话题已被删除] 中提及了此贴 06月27日 11:17
达峰的夏天 [该话题已被删除] 中提及了此贴 06月27日 11:17

请问 win7 怎么搭建环境!我没看到 win7 的环境搭建呀!支持 java 吗、

windows 可以安装和使用吗?

#69 楼 @xdf 😹 不胜感激

小帅 [该话题已被删除] 中提及了此贴 07月26日 18:09
小帅 [该话题已被删除] 中提及了此贴 08月05日 16:54

#31 楼 @imesong 我也出现了和你一模一样的问题,你是怎么解决的?

Error: Command failed: C:\WINDOWS\system32\cmd.exe /s /c "F:\AndroidstudioSdk/platform-tools/adb -s emulator-5554 push C:\Program Files\Nodejs\node_global\npm\node_modules\macaca-android\node_modules\uiautomator-client\bin\uiautomator-bootstrap.jar /data/local/tmp"

at ChildProcess.exithandler (child_process.js:213:12)
at emitTwo (events.js:87:13)
at ChildProcess.emit (events.js:172:7)
at maybeClose (internal/child_process.js:829:16)
at Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)

请问这个问题怎么解决 Win10 系统

为啥我吧 app 的源码下下来一片的报错,有人用 demo 跑通过吗

demo 没有跑通过,求问 demo 怎样才能跑通呢?

源码里面是不是缺少了几个 framework 啊??
编译不通过。。。

这个问题如何解决?

penglindeMacBook-Pro:macaca-test-sample penglin$ make test-ios
macaca doctor

macaca-doctor version: 1.0.23

Node.js checklist:

node env: /usr/local/bin/node
node version: v6.3.1

iOS checklist:

Xcode is installed at: /Applications/Xcode.app/Contents/Developer
Xcode Command Line Tools is ready, version: 2343.
ios_webkit_debug_proxy is installed at: /usr/local/bin/ios_webkit_debug_proxy

Android checklist:

JAVA version is 1.7.0_79
JAVA_HOME is set to /Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home
ANDROID_HOME is set to /usr/local/android-sdk-macosx
Platforms is set to /usr/local/android-sdk-macosx/platforms/android-24
Android tools is set to /usr/local/android-sdk-macosx/tools/android
ADB tool is set to /usr/local/android-sdk-macosx/platform-tools/adb

Installed driver list:

chrome: 1.0.3
electron: 1.1.4
ios: 1.0.40

platform=ios macaca run --verbose -d ./macaca-test/macaca-mobile-sample.test.js

index.js:17:12 [master] pid:641 webdriver server start with config:
{ port: 3456,
verbose: false,
always: true,
window: true,
ip: '192.168.0.106',
host: 'penglindeMacBook-Pro.local',
loaded_time: '2016-10-26 23:57:23' }
middlewares.js:17:10 [master] pid:641 base middlewares attached
router.js:129:10 [master] pid:641 router set
webdriver sdk launched

macaca mobile sample

1) "before all" hook

2) "after all" hook

0 passing (1s)

2 failing

1) macaca mobile sample "before all" hook:
[init({"autoAcceptAlerts":true,"platformName":"iOS","platformVersion":"9.3","deviceName":"iPhone 5s","app":"/Users/penglin/tmp/macaca-test-sample/app/ios-app-bootstrap.zip"})] getaddrinfo ENOTFOUND localhost localhost:3456
Error: getaddrinfo ENOTFOUND localhost localhost:3456
at errnoException (dns.js:28:10)
at GetAddrInfoReqWrap.onlookup as oncomplete

2) macaca mobile sample "after all" hook:
[quit()] getaddrinfo ENOTFOUND localhost localhost:3456
Error: getaddrinfo ENOTFOUND localhost localhost:3456
at errnoException (dns.js:28:10)
at GetAddrInfoReqWrap.onlookup as oncomplete

Test completed!

小帅 如何从头编写你的 Macaca 测试用例 中提及了此贴 12月08日 18:00


博主,模拟器上运行用例成功了,后面的脚本在哪里写?怎么查找以及配置呢?谢谢!

.then(function(html) {
html.should.containEql('TesterHome');
})
then 函数怎么理解啊?

小帅 [视频] 使用 iOS 真机演示 Macaca 测试 中提及了此贴 02月23日 12:28

react native 的控件如何获取啊,有没有可以打印页面元素的方法啊,求大神指导

小帅 Macaca 文档正式开放啦 中提及了此贴 12月11日 16:16
wolfgao 移动客户端 /UI 开源测试框架梳理和大比拼 中提及了此贴 02月27日 21:03
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册