Macaca 如何重头开始编辑一个自己的基于 web 浏览器的 macaca 用例脚本项目

小马 · August 08, 2016 · Last by 测试抗巴子 replied at June 26, 2017 · 2389 hits

该文为macaca的nodejs版本 样例https://github.com/macacajs/macaca-test-sample
macaca java版本 https://github.com/macacajs/wd.java
macaca python版本 https://github.com/macacajs/wd.py

一 建立一个新用例脚本项目

D:\macaca\me-app

拷贝D:\macaca\macaca-test-sample-master 官方示例脚本下的依赖文件 app 、package.json、 README.md

到新项目 me-app 下。为图方便。macaca-test 文件夹也整个copy过来。

2016年8月10日补充:
我们来看下package.json

{
"name": "macaca-test-sample",
"version": "1.0.8",
"description": "aicai-sample",
"keywords": [
"macaca",
"sample"
],

/*"repository": {
"type": "git",
"url": "git://github.com/macacajs/macaca-test-sample.git"
},*/


"dependencies": {
"macaca-utils": "^0.1.8"
},
"devDependencies": {
"jshint": "*",
"macaca-cli": "^1.1.0",
"pre-commit": "1.1.1",
"webdriver-client": "~1.0.0"
},

"scripts": {
"test": "make test-pc",
"jshint": "make jshint"
},

"pre-commit": [
"jshint"
],
"license": "MIT"
}

package.json 主要是用来配置依赖的nodejs模块的,dependencies是配置所依赖的模块 ,devDependencies是用来配置开发环境下依赖的模块。
你可以根据需要在这里来编辑项目组件依赖和其他一些配置。大家要自己从头写的话,还是要熟悉这里。

二 创建用例脚本文件 *.test.js

D:\macaca\me-app\macaca-test

将示例脚本macaca-desktop-sample.test.js 重命名为H5-aicai-sample.test.js

开始编辑修改 H5-aicai-sample.test.js脚本的内容。

三 编辑业务流脚本内容

涉及到用一些工具来定位元素

3.1 chrome浏览器的DevTools

新开一chrome窗口,直接按F12快捷键调出该工具。

然后你可以调整下用哪类devices分辨率来展示页面。

然后URL栏输入需要查看的地址。

最后你便可以用查看元素工具来定位元素ID等资源信息了。

3.2 firefox浏览器的firebug

如果是xpath定位的话,有一个有用的插件FirePath.

https://addons.mozilla.org/zh-CN/firefox/addon/firepath/

最后H5-aicai-sample.test.js 脚本内容如下

只是简单的测试下,看是否可以如此构建自己的用例项目。所以业务流程只是简单的 输入用户名 输入密码 点击登录,由于还不会破验证码没输入所以会提示‘请输入验证码’。同时 注释掉删除掉了一些验证步骤和自己不了解的原脚本内容。
2016年8月10日 修改后

'use strict';

var wd = require('webdriver-client')({
platformName: 'desktop',
browserName: 'chrome'
});

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

const driver = wd.initPromiseChain();
const initialURL = 'http://m.aicai.com/m/login.do?agentId=1&vt=5';

before(() => {
return driver
.initDriver()
.setWindowSize(1280, 800)
.sleep(3000);
});

it('#0 should go into H5login', function() {
return driver
.get(initialURL)
.sleep(5000);
});

it('#1 should edit webform H55login and prompt 请输入验证码 ', function() {
return driver
.elementById('jq_account')
.sendKeys('h5test0808a')
.sleep(3000)

.elementById('jq_password')
.sendKeys('0808a123')
.sleep(3000)

.elementById('submit')
.click()
.sleep(3000)

.source()
.then(function(html) {
html.should.containEql('请输入验证码');
})
});


after((done) => {
return driver
.quit(done);
});
});

这次加入了断言代码也就是

 .source()
.then(function(html) {
html.should.containEql('请输入验证码');
})

该段。这段是这样的, 先调用.source() 获取当前的一个html页面数据,然后结合should.js断言库,判断这个html是否包含对应的字符串.
关于should.js 请查看http://shouldjs.github.io/

那么实际也可以用https://macacajs.github.io/macaca-wd/api/#hasElement has系列的是macaca封装好的断言API

再补充下,像脚本里的这些框架代码
describe
before
it
after 来自于mocha.js 关于mocha.js请查看http://mochajs.org/

四 运行环境准备工作

老样子,你需要到 D:\macaca\me-app> 目录下执行下npm i 来为me-app 准备macaca的组件包依赖。

成功看到安装成功日志后,接下来便可以执行用例脚本了。

五 执行用例脚本

D:\macaca\me-app\macaca-test>dir



驱动器 D 中的卷没有标签。

卷的序列号是 0A87-8753

D:\macaca\me-app\macaca-test 的目录

2016/08/08 14:40 <DIR> .

2016/08/08 14:40 <DIR> ..

2016/08/08 14:12 2,876 androidapp-acp-sample.test.js

2016/08/04 16:27 638 debug.log

2016/08/08 14:58 1,746 H5-aicai-sample.test.js

2016/07/23 02:59 1,437 macaca-mobile-browser-sample.test.js

2016/07/23 02:59 33 mocha.opts

2016/08/04 17:53 22 test.js

6 个文件 6,752 字节

2 个目录 101,416,828,928 可用字节


D:\macaca\me-app\macaca-test>macaca run -d H5-aicai-sample.test.js --verbose
>> index.js:17:12 [master] pid:11912 webdriver server start with config:
{ port: 3456,
window: true,
ip: '*.*.*.*',
host: 'cmd-PC',
loaded_time: '2016-08-10 11:15:32' }
>> middlewares.js:17:10 [master] pid:11912 base middlewares attached
>> router.js:108:10 [master] pid:11912 router set
>> webdriver sdk launched
>>

>>
aicai-sample

>> responseHandler.js:11:12 [master] pid:11912 Recieve HTTP Request from Client: method: POST url: /wd/hub/session, jsonBody: {"desiredCapabilities":{"autoAcceptAlerts":true,"browserName":"chrome","platformName":"desktop","version":"","javascriptEnabled":true,"platform":"ANY"}}
>> session.js:47:10 [master] pid:11912 Creating session, sessionId: d7c46de0-03e3-48bc-bfdb-9c8a39e71ad7.
>> chromedriver bin path: D:\nodejs\node-global\node_modules\macaca-chrome\node_modules\macaca-chromedriver\exec\chromedriver.exe
>> macaca-chromedriver.js:89:16 [master] pid:11912 Noting to kill.
>> kill all chromedriver process success!
>> Starting ChromeDriver 2.20.353145 (343b531d31eeb933ec778dbcf7081628a1396067) on port 9515
Only local connections are allowed.

>> chromedriver starting success.
>> proxy.js:52:14 [master] pid:11912 Proxy: /status:GET to http://localhost:9515/wd/hub/status:GET with body:
>> proxy.js:58:16 [master] pid:11912 Got response with status 200: "{\"sessionId\":\"\",\"status\":0,\"value\":{\"build\":{\"version\":\"alpha\"},\"os\":{\"arch\":\"x86_64\",\"name\":\"Windows NT\",\"version\":\"10.0\"}}}"
>> proxy.js:52:14 [master] pid:11912 Proxy: /session:POST to http://localhost:9515/wd/hub/session:POST with body: {"desiredCapabilities":{"autoAcceptAlerts":true,"browserName":"chrome","platformName":"desktop","version":"","javascriptEnabled":true,"platform":"ANY","window":true}}
>> proxy.js:58:16 [master] pid:11912 Got response with status 200: {"sessionId":"ef744a2babc69552261dffd7dacfccfd","status":0,"value":{"acceptSslCerts":true,"applicationCacheEnabled":false,"browserConnectionEnabled":false,"browserName":"chrome","chrome":{"userData...
>> chromedriver ready with: {"
sessionId":null,"status":0,"value":{"acceptSslCerts":true,"applicationCacheEnabled":false,"browserConnectionEnabled":false,"browserName":"chrome","chrome":{"userDataDir":"C:\\Users\\cmd\\AppData\\Local\\Temp\\scoped_dir1300_27322"},"cssSelectorsEnabled":true,"databaseEnabled":false,"handlesAlerts":true,"hasTouchScreen":false,"javascriptEnabled":true,"locationContextEnabled":true,"mobileEmulationEnabled":false,"nativeEvents":true,"platform":"Windows NT","rotatable":false,"takesHeapSnapshot":true,"takesScreenshot":true,"version":"52.0.2743.82","webStorageEnabled":true}}
>> responseHandler.js:43:14 [master] pid:11912 Send HTTP Respone to Client: {"
sessionId":"d7c46de0-03e3-48bc-bfdb-9c8a39e71ad7","status":0,"value":"{\"autoAcceptAlerts\":true,\"browserName\":\"chrome\",\"platformName\":\"desktop\",\"version\":\"\",\"javascriptEnabled\":true,\"platform\":\"ANY\",\"window\":true}"}
>> responseHandler.js:11:12 [master] pid:11912 Recieve HTTP Request from Client: method: POST url: /wd/hub/session/d7c46de0-03e3-48bc-bfdb-9c8a39e71ad7/window/current/size, jsonBody: {"width":1280,"height":800}
>> proxy.js:52:14 [master] pid:11912 Proxy: /wd/hub/session/d7c46de0-03e3-48bc-bfdb-9c8a39e71ad7/window/current/size:POST to http://localhost:9515/wd/hub/session/ef744a2babc69552261dffd7dacfccfd/window/current/size:POST with body: {"width":1280,"height":800}
>> proxy.js:58:16 [master] pid:11912 Got response with status 200: {"sessionId":"ef744a2babc69552261dffd7dacfccfd","status":0,"value":null}
>> session.js:107:14 [master] pid:11912 Send HTTP Respone to Client: {"sessionId":"d7c46de0-03e3-48bc-bfdb-9c8a39e71ad7","status":0,"value":null}
>> responseHandler.js:11:12 [master] pid:11912 Recieve HTTP Request from Client: method: POST url: /wd/hub/session/d7c46de0-03e3-48bc-bfdb-9c8a39e71ad7/url, jsonBody: {"url":"http://m.aicai.com/m/login.do?agentId=1&vt=5"}
>> proxy.js:52:14 [master] pid:11912 Proxy: /wd/hub/session/d7c46de0-03e3-48bc-bfdb-9c8a39e71ad7/url:POST to http://localhost:9515/wd/hub/session/ef744a2babc69552261dffd7dacfccfd/url:POST with body: {"url":"http://m.aicai.com/m/login.do?agentId=1&vt=5"}
>> proxy.js:58:16 [master] pid:11912 Got response with status 200: {"sessionId":"ef744a2babc69552261dffd7dacfccfd","status":0,"value":null}
>> session.js:107:14 [master] pid:11912 Send HTTP Respone to Client: {"sessionId":"d7c46de0-03e3-48bc-bfdb-9c8a39e71ad7","status":0,"value":null}
>>
>> #0 should go into H5login (6071ms)

>> responseHandler.js:11:12 [master] pid:11912 Recieve HTTP Request from Client: method: POST url: /wd/hub/session/d7c46de0-03e3-48bc-bfdb-9c8a39e71ad7/element, jsonBody: {"using":"id","value":"jq_account"}
>> proxy.js:52:14 [master] pid:11912 Proxy: /wd/hub/session/d7c46de0-03e3-48bc-bfdb-9c8a39e71ad7/element:POST to http://localhost:9515/wd/hub/session/ef744a2babc69552261dffd7dacfccfd/element:POST with body: {"using":"id","value":"jq_account"}
>> proxy.js:58:16 [master] pid:11912 Got response with status 200: {"sessionId":"ef744a2babc69552261dffd7dacfccfd","status":0,"value":{"ELEMENT":"0.8424815980731128-1"}}
>> session.js:107:14 [master] pid:11912 Send HTTP Respone to Client: {"sessionId":"d7c46de0-03e3-48bc-bfdb-9c8a39e71ad7","status":0,"value":"{\"ELEMENT\":\"0.8424815980731128-1\"}"}
>> responseHandler.js:11:12 [master] pid:11912 Recieve HTTP Request from Client: method: POST url: /wd/hub/session/d7c46de0-03e3-48bc-bfdb-9c8a39e71ad7/element/0.8424815980731128-1/value, jsonBody: {"value":["h5test0808a"]}
>> proxy.js:52:14 [master] pid:11912 Proxy: /wd/hub/session/d7c46de0-03e3-48bc-bfdb-9c8a39e71ad7/element/0.8424815980731128-1/value:POST to http://localhost:9515/wd/hub/session/ef744a2babc69552261dffd7dacfccfd/element/0.8424815980731128-1/value:POST with body: {"value":["h5test0808a"]}
>> proxy.js:58:16 [master] pid:11912 Got response with status 200: {"sessionId":"ef744a2babc69552261dffd7dacfccfd","status":0,"value":null}
>> session.js:107:14 [master] pid:11912 Send HTTP Respone to Client: {"sessionId":"d7c46de0-03e3-48bc-bfdb-9c8a39e71ad7","status":0,"value":null}
>> responseHandler.js:11:12 [master] pid:11912 Recieve HTTP Request from Client: method: POST url: /wd/hub/session/d7c46de0-03e3-48bc-bfdb-9c8a39e71ad7/element, jsonBody: {"using":"id","value":"jq_password"}
>> proxy.js:52:14 [master] pid:11912 Proxy: /wd/hub/session/d7c46de0-03e3-48bc-bfdb-9c8a39e71ad7/element:POST to http://localhost:9515/wd/hub/session/ef744a2babc69552261dffd7dacfccfd/element:POST with body: {"using":"id","value":"jq_password"}
>> proxy.js:58:16 [master] pid:11912 Got response with status 200: {"sessionId":"ef744a2babc69552261dffd7dacfccfd","status":0,"value":{"ELEMENT":"0.8424815980731128-2"}}
>> session.js:107:14 [master] pid:11912 Send HTTP Respone to Client: {"sessionId":"d7c46de0-03e3-48bc-bfdb-9c8a39e71ad7","status":0,"value":"{\"ELEMENT\":\"0.8424815980731128-2\"}"}
>> responseHandler.js:11:12 [master] pid:11912 Recieve HTTP Request from Client: method: POST url: /wd/hub/session/d7c46de0-03e3-48bc-bfdb-9c8a39e71ad7/element/0.8424815980731128-2/value, jsonBody: {"value":["0808a123"]}
>> proxy.js:52:14 [master] pid:11912 Proxy: /wd/hub/session/d7c46de0-03e3-48bc-bfdb-9c8a39e71ad7/element/0.8424815980731128-2/value:POST to http://localhost:9515/wd/hub/session/ef744a2babc69552261dffd7dacfccfd/element/0.8424815980731128-2/value:POST with body: {"value":["0808a123"]}
>> proxy.js:58:16 [master] pid:11912 Got response with status 200: {"sessionId":"ef744a2babc69552261dffd7dacfccfd","status":0,"value":null}
>> session.js:107:14 [master] pid:11912 Send HTTP Respone to Client: {"sessionId":"d7c46de0-03e3-48bc-bfdb-9c8a39e71ad7","status":0,"value":null}
>> responseHandler.js:11:12 [master] pid:11912 Recieve HTTP Request from Client: method: POST url: /wd/hub/session/d7c46de0-03e3-48bc-bfdb-9c8a39e71ad7/element, jsonBody: {"using":"id","value":"submit"}
>> proxy.js:52:14 [master] pid:11912 Proxy: /wd/hub/session/d7c46de0-03e3-48bc-bfdb-9c8a39e71ad7/element:POST to http://localhost:9515/wd/hub/session/ef744a2babc69552261dffd7dacfccfd/element:POST with body: {"using":"id","value":"submit"}
>> proxy.js:58:16 [master] pid:11912 Got response with status 200: {"sessionId":"ef744a2babc69552261dffd7dacfccfd","status":0,"value":{"ELEMENT":"0.8424815980731128-3"}}
>> session.js:107:14 [master] pid:11912 Send HTTP Respone to Client: {"sessionId":"d7c46de0-03e3-48bc-bfdb-9c8a39e71ad7","status":0,"value":"{\"ELEMENT\":\"0.8424815980731128-3\"}"}
>> responseHandler.js:11:12 [master] pid:11912 Recieve HTTP Request from Client: method: POST url: /wd/hub/session/d7c46de0-03e3-48bc-bfdb-9c8a39e71ad7/element/0.8424815980731128-3/click, jsonBody: {}
>> proxy.js:52:14 [master] pid:11912 Proxy: /wd/hub/session/d7c46de0-03e3-48bc-bfdb-9c8a39e71ad7/element/0.8424815980731128-3/click:POST to http://localhost:9515/wd/hub/session/ef744a2babc69552261dffd7dacfccfd/element/0.8424815980731128-3/click:POST with body: {}
>> proxy.js:58:16 [master] pid:11912 Got response with status 200: {"sessionId":"ef744a2babc69552261dffd7dacfccfd","status":0,"value":null}
>> session.js:107:14 [master] pid:11912 Send HTTP Respone to Client: {"sessionId":"d7c46de0-03e3-48bc-bfdb-9c8a39e71ad7","status":0,"value":null}
>> responseHandler.js:11:12 [master] pid:11912 Recieve HTTP Request from Client: method: GET url: /wd/hub/session/d7c46de0-03e3-48bc-bfdb-9c8a39e71ad7/source, jsonBody: {}
>> proxy.js:52:14 [master] pid:11912 Proxy: /wd/hub/session/d7c46de0-03e3-48bc-bfdb-9c8a39e71ad7/source:GET to http://localhost:9515/wd/hub/session/ef744a2babc69552261dffd7dacfccfd/source:GET with body: {}
>> proxy.js:58:16 [master] pid:11912 Got response with status 200: {"sessionId":"ef744a2babc69552261dffd7dacfccfd","status":0,"value":"<!DOCTYPE html><html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en\"><head><link href=\"http://m.aicaicdn.com/wap5/js/??plugin...
>> session.js:107:14 [master] pid:11912 Send HTTP Respone to Client: {"
sessionId":"d7c46de0-03e3-48bc-bfdb-9c8a39e71ad7","status":0,"value":"\"<!DOCTYPE html><html xmlns=\\\"http://www.w3.org/1999/xhtml\\\" lang=\\\"en\\\"><head><link href=\\\"http://m.aicaicdn.com/wap5/js/??plugins/lhgdialog/skins/chrome.css\\\" rel=\\\"stylesheet\\\" id=\\\"lhgdialoglink\\\" />\\n\\t<meta charset=\\\"utf-8\\\" />\\n\\t<meta name=\\\"viewport\\\" content=\\\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui\\\" /> \\n\\t<meta name=\\\"format-detection\\..."}
>>
>> #1 should edit webform H55login and login (9543ms)

>> responseHandler.js:11:12 [master] pid:11912 Recieve HTTP Request from Client: method: DELETE url: /wd/hub/session/d7c46de0-03e3-48bc-bfdb-9c8a39e71ad7, jsonBody: {}
>> macaca-chromedriver.js:141:18 [master] pid:11912 chromedriver exit with code: 1, signal: null
>> session.js:80:12 [master] pid:11912 Delete session, sessionId: d7c46de0-03e3-48bc-bfdb-9c8a39e71ad7
>> responseHandler.js:43:14 [master] pid:11912 Send HTTP Respone to Client: {"sessionId":"d7c46de0-03e3-48bc-bfdb-9c8a39e71ad7","status":0}
>>

>>
2 passing (21s)


>> Test completed!


相关知识栈:

macaca https://github.com/macacajs
macaca API http://macacajs.github.io/macaca-wd/api/

nodejs http://nqdeng.github.io/7-days-nodejs/

mocha.js 脚本组织框架 http://mochajs.org/ https://github.com/mochajs/mocha

should.js macaca引用的一个断言库 http://shouldjs.github.io/

wd.js http://admc.io/wd/ https://github.com/admc/wd

webdriverio https://github.com/webdriverio

建议从上往下看,围绕自家业务流程脚本为目标,以当前业务脚本实现遇到的实际问题为出发点;
前期不要搞的太复杂,想的太完美;
能用macaca API最原生支持的解决业务脚本问题,就不要过度扩展使用自己不熟悉的组件包。

以下为参考的文章,向作者表示感谢,提供了思路。
如何从头编写你的 Macaca 测试用例
编写移动端 Macaca 测试用例 [单步调试]
Macaca-iOS 入门那些事 2
[基于 Node.js 的自动化测试-Macaca] - 自动化测试实践总结

更多信息请参考wiki汇总

小马的macaca入门指引合集

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 7 条回复 时间 点赞
小马 [Topic was deleted] 中提及了此贴 09 Aug 10:55
小马 [Topic was deleted] 中提及了此贴 10 Oct 10:21

我能问一下,macaca发现了bug,可以用什么办法可以读取浏览器或者移动设备的log并记录吗,小白的我只晓得截图。

@Cononico 你说的bug 是需测项目的bug吗? 如果是,要看你是安卓还是ios app 或者是web网页。不同的平台使用的技术都有差异。另,要看你发现的是什么类型的bug,如果是基于macaca的功能回归的,基本都是界面元素断言来判断某一业务功能是否在UI层成功,如果是这类失败就try cache截图,如果是java构建的macaca自动化 可以用其他日志工具 比如maven surefire-report和testng 结合来获取运行日志。 其他手段 安卓的话可以adb log命令 adb相关的去获取或查看手机端执行日志。

index.js:17:12 [master] pid:14172 webdriver server start with config:
{ port: 3456,
verbose: false,
always: true,
window: true,
ip: '192.168.2.168',
host: 'sunyakuan-PC',
loaded_time: '2016-12-09 17:15:17' }
middlewares.js:17:10 [master] pid:14172 base middlewares attached
router.js:129:10 [master] pid:14172 router set
webdriver sdk launched
E:\node\node_modules\macaca-cli\lib\run\index.js:44
throw err;
^

Error: Cannot find test framework "mocha" in E:\macaca\demo\macaca-test-sample-n
odejs-master\macaca-test\node_modules
at Runner.initFramework (E:\node\node_modules\macaca-cli\lib\run\index.js:71
:13)
at co.then (E:\node\node_modules\macaca-cli\lib\run\index.js:41:10)
at process._tickCallback (internal/process/next_tick.js:103:7)

npm下载的依赖里面是有mocha的,请问下遇到过这样的问题了的吗?

#7楼 @sunkuan2007 我也遇到这个问题 请问你解决里面?如果解决了 麻烦告诉下你是怎么解决呢

#8楼 @xiaocong168 😂 周末把所有安装都删除了重新安装了一次还是报错,你解决了给我说下。。。

#9楼 @sunkuan2007 我也还没解决 搞了两天了

erinet 回复

搞定了吗? 我擦 烦人啊

需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up