Macaca 基于 macaca 的遍历 NoSmoke

小马 · 2018年01月03日 · 最后由 墨语 回复于 2018年09月13日 · 3586 次阅读
本帖已被设为精华帖!

一 部署环境

项目git地址:

https://github.com/macacajs/NoSmoke

环境介绍:

操作系统

cmd@TR:~$ lsb_release -a

No LSB modules are available.

Distributor ID: Ubuntu

Description: Ubuntu 16.04.3 LTS

Release: 16.04

Codename: xenial

Macaca底层依赖

请先部署安装好Macaca

cmd@TR:~$ macaca doctor

macaca-doctor version: 2.0.4


Node.js checklist:

node env: /opt/nodejs/bin/node

node version: v6.10.3


Android checklist:

JAVA version is `1.8.0_151`

JAVA_HOME is set to `/usr/lib/jvm/java-8-oracle`

ANDROID_HOME is set to `/opt/android-sdk-linux`

Platforms is set to `/opt/android-sdk-linux/platforms/android-26`

ADB tool is set to `/opt/android-sdk-linux/platform-tools/adb`

gradle is installed, version: 3.5


Installed driver list:

android: 2.0.44

chrome: 1.0.7

electron: 1.1.19

部署NoSmoke:

直接参考官方的2种方式均可以:

1 是npm i 方式

2 是git clone 方式

Step 2. Setup NoSmoke - You can choose several ways to run it :]

Method 1: install the nosmoke command line from npmjs

$ npm i nosmoke -g

Open the terminal and initialize macaca server macaca server --verbose

then in your workspace directory, execute the following command

$ nosmoke -h path-of-your-hook.js -c path-of-your-config.yml

For full set of command please check:

nosmoke --help

Usage: nosmoke [options]

Options:

-p, --port port to use (5678 default)
-u, --udid udid of device
-h, --hooks location of the hook.js file
-c, --config location of the configuration file
-s, --silent start without opening browser
--verbose show more debugging information
-v, --versions output version infomation
-h, --help output usage information

Method 2: install via clone from git

$ git clone git@github.com:macacajs/NoSmoke.git

Open the terminal and initialize macaca server macaca server --verbose

then run the following under the nosmoke root dir:

$ bin/nosmoke -h path-of-your-hook.js -c path-of-your-config.yml

Note: -h is optional and -c (the path of the configuration file is a must) in order to run the crawler

检查部署后输出

cmd@TR:~$ nosmoke -v
1.0.1

cmd@TR:~$ nosmoke --help
Usage: nosmoke [options]
Options:
-p, --port <d> port to use (5678 default)
-u, --udid <s> udid of device
-a, --app <s> path of app, will override the one specified in crawler.config.yml
-h, --hooks <s> location of the hook.js file
-c, --config <s> location of the configuration.yml file
-s, --silent start without opening browser
--verbose show more debugging information
--server <s> adddress for server: "http://172.31.9.162:1212/"
-v, --versions output version infomation
-h, --help output usage information

二 跑Demo测试

测试Demo 在路径

github路径:

https://github.com/macacajs/NoSmoke/tree/master/public

下的文件crawler.config.yml 既是遍历Demo的配置文件

本地git项目路径:

cmd@TR:~/workspace/git/NoSmoke/public$ ls -al

总用量 36

drwxrwxr-x 3 cmd cmd 4096 1 3 09:53 .

drwxrwxr-x 8 cmd cmd 4096 1 2 15:31 ..

-rw-rw-r-- 1 cmd cmd 928 1 3 10:18 androidTest.yml

-rw-rw-r-- 1 cmd cmd 1272 1 3 10:44 androidDemo.yml

-rw-rw-r-- 1 cmd cmd 3714 1 2 15:31 crawler.config.yml

-rw-rw-r-- 1 cmd cmd 2486 1 2 15:31 hooks.js

-rw-rw-r-- 1 cmd cmd 86 1 2 15:31 index.css

drwxrwxr-x 4 cmd cmd 4096 1 3 10:19 reports

-rw-rw-r-- 1 cmd cmd 326 1 3 09:55 webDemo.yml

-rw-rw-r-- 1 cmd cmd 420 1 3 09:55 webTest.yml

初期为了方便,可以将自己的遍历配置 .yml文件都先放这。调试通了后,你复制粘贴到其它路径都可以。关于yml文件格式的书写格式语法,请自行去学习。

hooks.js 也是遍历配置文件:再精密设计的深度遍历算法对于不同的UI 界面设计, 也不能完全保证能够cover 大部分的遍历场景,因此通过钩子的形式给使用者提供不干预流程的前提下,定制遍历可能性
用户可以通过定制 /public/hooks.js 中的各个函数 对默认行为进行定制。

reports 是结果报告目录,命令行有参数可以指定相关设置。不配置也可以,会在当前执行目录自动生成。

跑android

根据crawler.config.yml

简单改一下android的配置:

另存为androidDemo.yml

---
# 1. Initialization option
desiredCapabilities:
platformName: 'android'
isWaitActivity: true
activity: 'LoginActivity'
permissionPatterns: '[\"继续安装\",\"下一步\",\"好\",\"允许\",\"确定\",\"我知道\"]'
app: 'https://npmcdn.com/android-app-bootstrap@latest/android_app_bootstrap/build/outputs/apk/android_app_bootstrap-debug.apk'

# 2. Crawling option
crawlingConfig:
platform: 'android'
packages: 'com.github.android_app_bootstrap|com.xxx.your.optional.app'
targetElements:
loginAccount:
searchValue : 'please input username'
actionValue : '中文+Test+12345678'
loginPassword:
searchValue : 'please input password'
actionValue : '111111'
loginButton:
searchValue : 'Login'
alertConfirm:
searchValue : 'yes'
asserts:
- type: 'regex'
given: 'android\s+bootstrap'
then: 'please\s+input\s+username'
- type: 'regex'
given: 'HOME'
then: 'list'
exclusivePattern: 'pushView|popView|cookie|userAgent:|Mozilla|cookie:|setTitle|Macaca Test Swipe API'
clickTypes:
- 'android.widget.ImageView'
- 'android.widget.TextView'
- 'android.widget.Button'
editTypes:
- 'android.widget.EditText'
tabBarTypes:
- 'android.widget.TabWidget'
...

如何跑?

1 依赖macaca server 发请求 所以需要先启动

macaca server --verbose

2 启动android虚拟器或USB连接真机

cmd@TR:$ adb devices -l

List of devices attached

192.168.58.101:5555 device product:vbox86p model:Samsung_Galaxy_S7_6_0_0API_23__1440x2560 device:vbox86p

3 执行遍历配置

cmd@TR:~/workspace/git/NoSmoke/public$ nosmoke -c androidDemo.yml

跑Pc Web

简单改一下Pc Web的配置:

另存为webDemo.yml


---
# 1. Initialization option
desiredCapabilities:
# Web Configuration
platformName: 'Desktop'
browserName: 'Electron'
url: 'https://macacajs.github.io'
# 2. Crawling option
# Web Configuration
crawlingConfig:
platform: 'pc-web'
blacklist:
- 'github.com'
clickTypes:
- 'a'
editTypes:
- 'input'
...

如何跑?

1 依赖macaca server 发请求 所以需要先启动

macaca server --verbose

2 配置的是Electron浏览器

只要安装了 npm i macaca-electron -g 驱动即可

3 执行遍历配置

cmd@TR:~/workspace/git/NoSmoke/public$ nosmoke -c webDemo.yml

三 效果与配置参数说明

根据执行的效果和配置文件写的内容,大家应该可以很快理解。

安卓的既是根据app配置的路径 安装待测app 然后searchValue : 'please input username' 是找到该用户名输入框,actionValue : '中文+Test+12345678'是在该用户名输入框输入内容。

loginAccount:

searchValue : 'please input username'

actionValue : '中文+Test+12345678'

是一组小case 其中 loginAccount:是你自定义的case名称,你换其他名称亦可。其他看下文参数配置说明即可明白,不再赘述。

web的既是访问macacajs的github官网,然后

clickTypes:

- 'a'

editTypes:

- 'input'

该段既是遍历配置块,什么意思呢,大家用火狐的web开发者工具 查看元素,即可明白。

a 和 input 就是html中的标签属性。意思就是遇到a 属性的UI元素就点击,遇到input属性的UI元素就输入(输入的内容好像给了个默认值为)

我们拿百度说明:

如百度的搜索内容输入框 和 搜索按钮百度一下 看到他们的标签属性都是类似这样写法

<input class="s_ipt" name="wd" id="kw" maxlength="100" autocomplete="off" type="text">

<input value="
百度一下" id="su" class="btn self-btn bg s_btn" type="submit">

以及含<a </a>

而这一句,是在真机测试时来捕获系统权限安装弹窗,让android-unlock 自动许可安装通过的一步。
permissionPatterns: '[\"继续安装\",\"下一步\",\"好\",\"允许\",\"确定\",\"我知道\"]'

具体配置说明可参考NoSmoke的配置参数

b. Configurable

Refer to the crawler.config.yml file in the NoSmoke/public folder as a example. You can choose which platform to conduct the crawling task:

desiredCapabilities:
platformName: 'iOS'
deviceName: 'iPhone 6 Plus'
app: 'https://npmcdn.com/ios-app-bootstrap@latest/build/ios-app-bootstrap.zip'

And the corresponding configuration for crawling the app:

crawlingConfig:
platform: 'ios' // platforms to run: android, ios, pc-web
testingPeriod: // maximun testing period for a crawling task, after which the task will terminate
testingDepth : // maximum testing depth of the UI window tree, exeeding which 'Back' navigation will be triggered
newCommandTimeout:// time interval takes to examine current window source after a crawling UI action has been performed
launchTimeout: // time interval to wait after app has been launched.
maxActionPerPage: // max UI actions filtered and performed perpage, this will provide greate memory optimization and prevent an Page for staying too long

targetElements: // array of hight priority UI element to perform
asserts: // provide for regex assert test cases for windows
exclusivePattern: // specify the pattern hence you can let those element which contain the regex pattern be excluded from exection
clickTypes: // specify the types of UI element which can handle click events
editTypes: // specify the types of UI element which can handle edit events
horizontalScrollTypes: // specify the types of UI element which can handle horizontal scroll
tabBarTypes: // specify the types of UI element may act as a control widget in master-detail pattern
exclusiveTypes: // specify the types of UI element in which all the sub-views will be exclueded from scanning and crawl

或该文片段:
YML 配置文件选项详解:

# 1. Initialization option
desiredCapabilities:
platformName: 'platform iOS/Android'
deviceName: 'name of the device'
app: 'url for downloading app here'

# 2. Crawling option
crawlingConfig:
platform: 'iOS'
targetElements:
loginAccount:
actionType : 'action type: 1-click; 2-input'
searchValue : 'the value to search'
actionValue : 'the value to input'
exclusivePattern: 'pushView/popView'
clickTypes:
- 'array of clickable UI types: StaticText/Button'
editTypes:
- 'array of editable UI types: SecureTextField/TextFiled'
horizontalScrollTypes:
- 'array of horizontal scrollable UI types: PageIndicator'
verticalScrollTypes:
- 'array of vertical scrollable UI types: ScrollView'
tabBarTypes:
- 'array of control widget which behaves like a master in the
master-detail view structures: TabBar'
exclusiveTypes:
- 'array of disabled and esclusive UI types: NavigationBar'
navigationBackKeyword:
- 'array of words on which items should be regarded
as a back button: back'

以及macaca的配置参数:

https://macacajs.github.io/zh/helpful-settings

四 改造app测试

既然跑通了android app和Pc Web的Demo,我们接下来就可以再简单的用下其他app 或网站来继续测试。

另存一个yml文件androidTest.yml 根据以上对Demo的效果和配置参数的理解,我们尝试写出以下遍历配置先。

其中根据macaca提供的desiredCapabilities参数配置 加了一些 比如NoSmoke没有的reuse udid等 大家自行查阅对比。

---

# 1. Initialization option

desiredCapabilities:

platformName: 'android'

udid: 45806625

app: '/home/cmd/app/acp4.7p.apk'

packages: 'com.sinacp.ggaicai'

activity: 'com.aicai.pluginhost.activity.MainActivity'

isWaitActivity: true

reuse: 3

testingPeriod: 36000

permissionPatterns: '[\"继续安装\",\"下一步\",\"好\",\"允许\",\"确定\",\"我知道\"]'



# 2. Crawling option

crawlingConfig:

platform: 'android'

targetElements:

INmy:

actionType: 1

searchValue : '我的'

loginUI:

actionType: 1

searchValue : '立即登录/注册'

loginAccount:

actionType: 2

searchValue : "
手机号/用户名"

actionValue : 'mdc123'

loginPassword:

actionType: 2

searchValue : "
登录密码"

actionValue : '123123'

loginButton:

actionType: 1

searchValue : "
登录"

clickTypes:

- 'android.widget.ImageView'

- 'android.widget.TextView'

- 'android.widget.Button'

# - 'android.widget.LinearLayout'

editTypes:

- 'android.widget.EditText'

tabBarTypes:

- 'android.widget.TabWidget'

...

接下来跑一下,效果还可以。继续研究。

四 有意思的permissionPatterns参数

运行真机小米MIX2时候,发现居然不用特别处理 手动点击“继续安装”android-unlock 了,然后仔细研究了下permissionPatterns 以为是NoSmoke提供的 结果看了源码没有。
然后又去wd.java API里找 去macaca-cli里找都没找到,然后看了下macaca server日志,发现应该是UIAutomatorWD干的事。

permissionPatterns: '[\"继续安装\",\"下一步\",\"好\",\"允许\",\"确定\",\"我知道\"]'

而这一句,是在真机测试时来捕获系统权限安装弹窗,让android-unlock 自动许可安装通过的一步。

是macaca的Desired Capabilities 是最近一个版本新加的 在官方说明中 还未有。

这是个很重要的 参数。 在真机测试时。 真棒。底层解决了。

看了下macaca server的日志

发现

>> helper.js:176:12 [master] pid:25727 Using local app form /home/cmd/app/acp4.7p.apk
>> checking permissionPatterns: [\"继续安装\",\"下一步\",\"好\",\"允许\",\"确定\",\"我知道\"]
>> uiautomator-client.js:62:14 [master] pid:25727 INSTRUMENTATION_STATUS: numtests=1
INSTRUMENTATION_STATUS: stream=
com.macaca.android.testing.UIAutomatorWD:
>> uiautomator-client.js:62:14 [master] pid:25727
INSTRUMENTATION_STATUS: id=AndroidJUnitRunner
INSTRUMENTATION_STATUS: test=MacacaTestRunner
INSTRUMENTATION_STATUS: class="
com".macaca.android.testing.UIAutomatorWD
INSTRUMENTATION_STATUS: current=1
INSTRUMENTATION_STATUS_CODE: 1

>> uiautomator-client.js:62:14 [master] pid:25727 INSTRUMENTATION_STATUS: stream=
UIAutomatorWD->http://localhost:9002<-UIAutomatorWD
INSTRUMENTATION_STATUS_CODE: 0

>> UIAutomatorWD http server ready
>> macaca-android.js:303:10 [master] pid:25727 start app with: {"
package":"com.sinacp.ggaicai","activity":""}
>> responseHandler.js:49:14 [master] pid:25727 Send HTTP Respone to Client[2018-01-03 14:28:04]: {"
sessionId":"41c53e4f-4ae4-4762-8a08-867edd515f94","status":0,"value":"{\"platformName\":\"android\",\"app\":\"/home/cmd/app/acp4.7p.apk\",\"packages\":\"com.sinacp.ggaicai\",\"activity\":\"com.aicai.pluginhost.activity.MainActivity\",\"isWaitActivity\":true,\"reuse\":3,\"udid\":45806625,\"permissionPatterns\":\"[\\\\\\\"继续安装\\\\\\\",\\\\\\\"下一步\\\\\\\",\\\\\\\"好\\\\\\\",\\\\\\\"允许\\\\\\\",\\\\\\\"确定\\\\\\\",\\\\\\\"我知道\\\\\\\"]\"}"}

是UIAutomatorWD负责发的这个 responseHandler ,就去找到UIAutomatorWD 项目 发现最近NoSmoke的作者提交了permissionPatterns 相关

https://github.com/macacajs/UIAutomatorWD/commit/dee4dad116995f956cdfa9fc7fbca68da8912ac3

论坛和群里 经常有问包括appium的 在真机测试时都是需要先权限安装Unlock 和Appium Settings
怎么自动化的解决系统安装弹窗的问题,也有不少方案源码。

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 12 条回复 时间 点赞

permissionPatterns: '[\"继续安装\",\"下一步\",\"好\",\"允许\",\"确定\",\"我知道\"]'

而这一句,是在真机测试时来捕获系统权限安装弹窗,让android-unlock 自动许可安装通过的一步。

是macaca的Desired Capabilities 是最近一个版本新加的 在官方说明中 还未有。

这是个很重要的 参数。 在真机测试时。 真棒。底层解决了。

看了下macaca server的日志

发现

helper.js:176:12 [master] pid:25727 Using local app form /home/cmd/app/acp4.7p.apk
checking permissionPatterns: [\"继续安装\",\"下一步\",\"好\",\"允许\",\"确定\",\"我知道\"]
uiautomator-client.js:62:14 [master] pid:25727 INSTRUMENTATION_STATUS: numtests=1
INSTRUMENTATION_STATUS: stream=
com.macaca.android.testing.UIAutomatorWD:
uiautomator-client.js:62:14 [master] pid:25727
INSTRUMENTATION_STATUS: id=AndroidJUnitRunner
INSTRUMENTATION_STATUS: test=MacacaTestRunner
INSTRUMENTATION_STATUS: class="com".macaca.android.testing.UIAutomatorWD
INSTRUMENTATION_STATUS: current=1
INSTRUMENTATION_STATUS_CODE: 1

uiautomator-client.js:62:14 [master] pid:25727 INSTRUMENTATION_STATUS: stream=
UIAutomatorWD->http://localhost:9002<-UIAutomatorWD
INSTRUMENTATION_STATUS_CODE: 0

UIAutomatorWD http server ready
macaca-android.js:303:10 [master] pid:25727 start app with: {"package":"com.sinacp.ggaicai","activity":""}
responseHandler.js:49:14 [master] pid:25727 Send HTTP Respone to Client[2018-01-03 14:28:04]: {"sessionId":"41c53e4f-4ae4-4762-8a08-867edd515f94","status":0,"value":"{\"platformName\":\"android\",\"app\":\"/home/cmd/app/acp4.7p.apk\",\"packages\":\"com.sinacp.ggaicai\",\"activity\":\"com.aicai.pluginhost.activity.MainActivity\",\"isWaitActivity\":true,\"reuse\":3,\"udid\":45806625,\"permissionPatterns\":\"[\\\\"继续安装\\\\",\\\\"下一步\\\\",\\\\"好\\\\",\\\\"允许\\\\",\\\\"确定\\\\",\\\\"我知道\\\\"]\"}"}

是UIAutomatorWD负责发的这个 responseHandler ,就去找到UIAutomatorWD 项目 发现最近NoSmoke的作者提交了permissionPatterns 相关

https://github.com/macacajs/UIAutomatorWD/commit/dee4dad116995f956cdfa9fc7fbca68da8912ac3

论坛和群里 经常有问包括appium的 在真机测试时都是需要先权限安装Unlock 和appium-setting
怎么自动化的解决系统安装弹窗的问题,也有不少方案源码。

===================================================

`shell am instrument -w -r -e permissionPattern ${this.permissionPatterns} -e port ${this.proxyPort} -e class ${UIAUTOMATORWD.PACKAGE_NAME} ${UIAUTOMATORWD.TEST_PACKAGE}.test/${UIAUTOMATORWD.RUNNER_CLASS}`.split(' ');

和该句代码有关系。

https://developer.android.com/studio/command-line/adb.html?hl=zh-cn

https://developer.android.com/reference/android/app/Instrumentation.html
instrument [options] component 使用 Instrumentation 实例启动监控。通常,目标 component 是表单 test_package/runner_class。
选项包括:

-r:输出原始结果(否则对 report_key_streamresult 进行解码)。与 [-e perf true] 结合使用以生成性能测量的原始输出。
-e name value:将参数 name 设为 value。对于测试运行器,通用表单为 -e testrunner_flag value[,value...]。
-p file:将分析数据写入 file。
-w:先等待仪器完成,然后再返回。测试运行器需要使用此选项。
--no-window-animation:运行时关闭窗口动画。
--user user_id | current:指定仪器在哪个用户中运行;如果未指定,则在当前用户中运行。

思寒_seveniruby 将本帖设为了精华贴 01月03日 21:46

LZ,能讲下nosmoke在pc_web,遍历百度【输入keyword和点击“百度一下”过程,详细的yaml文件,怎么写】谢谢

bill 回复

https://github.com/macacajs/NoSmoke/issues/38 应该这么写 见webTest.yml 但跑起来有些问题

小马 回复

大神,你看我的yaml文件如下--这是macaca server的情况-------nosmoke运行情况-------请大神指导【问题就是Electron打开了百度页面,输入和点击的操作不会执行】

bill 回复

@Samuel.ZhaoY 这个要作者看了。
呵呵 和你说了 这里是个issue有问题啊。现象就是打开百度首页 剩下的就不跑了 但是nosmoke log看的到 找到了一些 a 或 input的元素。

你那个 框起来的 是找不到reports目录 这个应该不用自己创建 在执行nosmoke -c webTest.yml 的时候 会自动在同脚本目录创建,
不过我看你是win环境 不排除可能这个自动创建在win下出bug了,你可以自己手动创建reports目录先。

小马 回复

好的,试试

要是用wd.java 搞自动允许弹窗许可或点击通过的话 代码里是这样写的

porps.put("permissionPatterns","[\\\"继续安装\\\",\\\"下一步\\\",\\\"好\\\",\\\"允许\\\",\\\"确定\\\",\\\"我知道\\\"]");

macaca wd.java 2.0.20 目前向手机安装的有
1 UiAutoMator sample
2 com.macaca.android.testing.test
3 android-unlock

macaca server 的这个desiredCapabilities 参数 permissionPatterns 是个很不错的通用各类安装提示 系统权限获取弹窗的通用解决方案.
既可以各类自动化工具初始化时向手机安装组件过程的弹窗,也可以是比如请求读取联系人许可的权限弹窗的自动点允许。

wd.py 的话 是这样写

desired_caps = {
'platformName': 'android',
'app': 'D:\\Install\\apk\\acp_android_v4_2_0-233611.apk',
'reuse': 3,
'package': 'com.sinacp.ggaicai',
'activity': 'com.aicai.pluginhost.activity.MainActivity',
'permissionPatterns': '[\\\"继续安装\\\",\\\"下一步\\\",\\\"好\\\",\\\"允许\\\",\\\"确定\\\",\\\"我知道\\\"]',
}

小马 python appium UI 自动化测试框架讨论 中提及了此贴 03月13日 18:38

您好 有一个问题,我的权限弹窗的activity和首页的activity不是同一个,使用了permissionPatterns后无效。这个有解决方法吗?

执行PCweb,报这个是为什么?
Error: >> session.js:47:16 [master] pid:16844 Platform must in (android, chrom
e, electron, ios, puppeteer)
at Logger.error (D:\macaca\node_modules\xlogger\lib\xlogger.js:169:9)
at detectDevice (D:\macaca\node_modules\webdriver-server\lib\server\contro
llers\session.js:47:16)
at Object.createDevice (D:\macaca\node_modules\webdriver-server\lib\server
\controllers\session.js:13:18)
at createDevice.next ()
at onFulfilled (D:\macaca\node_modules\co\index.js:65:19)
at D:\macaca\node_modules\co\index.js:54:5
at new Promise ()
at Object.co (D:\macaca\node_modules\co\index.js:50:10)
at Object.toPromise (D:\macaca\node_modules\co\index.js:118:63)
at next (D:\macaca\node_modules\co\index.js:99:29)

可以举例说明一下钩子怎么使用吗

进击的程序茗 Macaca-NoSmoke 遍历调研过程记录 中提及了此贴 07月03日 09:29
16楼 已删除

求教大神报告器的 每个digest的time怎么设置啊?

simple 专栏文章:[精华帖] 社区历年精华帖分类归总 中提及了此贴 12月13日 14:44
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册