Macaca UI 自动化 Macaca-Java 版实践心得

Yinxl · 2016年11月24日 · 最后由 tangoliver 回复于 2023年02月14日 · 3732 次阅读

以下文章转载自我的云栖社区:UI 自动化 Macaca-Java 版实践心得

导语

在上篇分享中,跟大家分享了Macaca-Java 版入门指南,相信很多同学已经可以依据教程开始实践 UI 自动化工作,但入门问题解决了,要真正在业务中实践还需要面临不少挑战,这篇文章则紧接上一篇,就 Macaca 在业务中的实际应用给出一些经验总结,希望能给在迷茫中不知如何入手的同学们一些方向,同时欢迎大家就本篇文章中涉及的一些方案给出更优的答案,大家一起进步。

当 Macaca 遭遇具体业务

1. UI 控件不同平台的统一处理问题

首先,我们看一下对于单个平台,是如何做控件的查找与操作的:

//SampleTest.java

public void test() throws Exception {
    driver.elementById("targetElementId"); // elment的唯一标识
    driver.click();
}

当平台扩展为多个时,一般来讲,如何进行同一个控件的操作呢?比如对应同一个按钮,在 iOS 平台,我们可以知道他的 name 属性,但是在安卓平台,对应的同一个控件,没有 name 属性,需要通过 id 属性来获取,那代码就会演变成如下样式:

//SampleTest.java
public void test() throws Exception {
    if (driver.curPlatform==PlatformType.IOS)
    {
        // 如果是iOS平台,根据name属性查找控件
        driver.elementByName("targetElementName");
        driver.click();
    } else {
        // 如果是安卓平台,根据id属性查找控件
        driver.elementById("targetElementId");
        driver.click();
    }
}

众所周知,对于 UI 自动化,控件的查找是使用相当频繁的一种操作,那么问题来了,有没有一种方式,可以统一控件的查找而不必通过一个接一个的 if else 分支来完成呢?

2. 测试稳定性问题

测试的稳定性,是影响自动化测试的另一大因素,因为移动端操作场景的复杂性,测试用例执行的过程中可能出现多种意料之外的响应,比如点击某一个按钮,预期结果是进入下一个页面,但是却弹出了某个弹框,或者真正跳转的页面并不是我们所预期的页面,或者跳转了我们所预期的页面,但因为网络数据的加载主视图并没有刷新,这样一来,针对我们的目标页面所做的操作都会失败,因为我们无法找到预期页面的目标控件,在这种情况下,我们需要在保证预期页面已经加载的情况下再执行预期流程的用例,如何做到这一点呢?

再者,长距离到达组件入口的问题也是影响自动化稳定性的另一因素,比如我们想要测试某个基金详情页,但是要进入某个详情页,必须经过登录 - 首页-A 页面-B 页面 - 目标页面几个必须步骤,在到达目标页面之前的任何一个链条中出现中断,这次测试就等于无效了,这种问题怎么破?

当然,影响自动化测试稳定性的场景还有很多,这些在真正的业务实践中会逐步暴露出来,如何保证自动化测试的稳定性,是自动化测试的又一个难题。

3. 测试报告输出问题

对应每一项测试流程,执行完毕之后我们都希望能看到详尽的测试报告,如何快速高效的输出可读性强的测试报告,同样是一个必须解决的问题。

4. 学习维护成本问题

自动化平台或者工具如果对环境配置、使用规范,脚本等有较复杂要求的话,那么对于入门刚刚的测试工程师来说有一定的学习成本。另外,跟随目标产品的版本迭代,自动化脚本要做对应的调整,如果对应的调整成本比较高,也很难保证将自动化的工作方式坚持下去。

我们是如何解决这些问题的

1. 如何解决不同平台的控件统一问题

研究上面的第一个问题,我们会发现控件的获取虽然根据平台不同而需要单独处理,但是控件的获取方式其实都是统一的,获取控件有两大要素,一是获取控件的方式,比如 name,id,xpath,css,class name 等等,二是要获取控件的值,这个值是与获取控件的方式想对应的,针对移动端测试来说,目前一般覆盖 iOS,Android 两个平台,我们以这个为例,其实对于 UI 操作上的一个控件,提供两个平台分别的获取方式以及值就可以解决控件一致性的问题,代码如下:

// CommonUIBean.java

/**
 * 当安卓 ios两个平台对应同一控件的获取方式不一致时使用本构造函数
 * @param androidBy 获取安卓对应控件的方式
 * @param androidValue 获取安卓对应控件的值
 * @param iosBy 获取ios对应控件的方式
 * @param iosValue 获取ios对应控件的值
 */
public CommonUIBean(GetElementWay androidBy,String androidValue,GetElementWay iosBy,String iosValue){
    this.androidBy = androidBy;
    this.androidValue = androidValue;
    this.iosBy = iosBy;
    this.iosValue = iosValue;
}

/**
 * 构造函数,用于ios&android两个平台获取UI一致的情况
 * @param commonBy 统一获取控件方式
 * @param commonValue 统一获取控件值
 */
public CommonUIBean(GetElementWay commonBy,String commonValue){
    this.androidBy = commonBy;
    this.androidValue = commonValue;
    this.iosBy = commonBy;
    this.iosValue = commonValue;
}

如上图这样,我们就统一了控件的一次性获取问题,通过这一层封装,如果要表示跨两个平台的一个控件,就可以简化为如下这样:

CommonUIBean targetElement = new CommonUIBean(GetElementWay.ID,"targetElementId",GetElementWay.NAME,"targetElementName");

2. 如何保证测试稳定性

1、对于要测试的页面抽象成类,增加页面是否加载成功的逻辑,所有页面内部的测试逻辑,均在确认该页面加载成功后再执行从而保证自动化稳定性。

2.对于长距离到达组件入口的问题,通过 scheme 跳转解决。具体来讲,对于目标页面,只要支持 scheme 跳转,我们可以直接通过 scheme 的方式从首页直接进行加载,这样可以一步到达目标页面,省略掉了前面的诸多链路,从而保证了测试的稳定性。当然,这种方式需要依赖开发同学的支持,只有在开发层面上尽可能多的支持独立页面的 scheme 跳转方式,才能真正使这个解决方案大放光彩。

当然,除了这些之外,对于其他分支的阻塞场景,一方面需要我们对业务复杂度的深入了解,一方面需要在今后的实践中不断积累。

3. 如何详尽的输出测试报告

对于这个问题,我们是分这么几步走的:

1.按照业务需求将错误类型进行分类整理

2.规范化结果输出的规则

3.在对应节点按照既定规则输出日志并写入文件

这样,用例执行结束后,我们就可以看到具体的执行过程以及结果了,规范化日志输出的规则还有一个好处是便于今后结果的集成展示,比如我们要通过 web 直观的看到执行进度以及结果的时候,就可以通过解析日志得到相应数据。

4. 学习维护成本问题

关于学习成本,就要回到我们的标题,我们这里讲的是 Macaca-Java 版最佳实践,其实在最早的调研阶段,我们都是通过 Javascript 写用例的,但是考虑到大部分同学的学习成本,所以在 Macaca 支持 Java 后,我们立即转型到 Java 版本上来,这样大大减小了学习成本,另外,我们在设计自己的框架的时候,设置了 config 配置文件来配置通用信息,比如应用信息、用户信息等都可以通过配置文件配置,对于用例编写中常用的类进行了封装,形成了一套用例编写规范,这些对于新上手的同学都降低了接入成本,甚至对于不熟悉 Java 的同学,都可以比较 easy 的比葫芦画瓢的编写自己的用例。

关于维护成本,我们对于控件的封装使控件更新的成本变低,对于 Page 的封装,使得同一个页面的测试入口都集中在一起,每个页面各自维护自己的操作入口,这样当我们需要测试一个流程时,只需要把经过的页面对应的操作组装到一起就可以了,当我们需要更新某一个页面的某个操作时,只需要去页面对应的类中去修改指定的操作,而不影响原有的流程化逻辑,具体请参考源码。

Demo 实例

广告时间结束,正片从这里开始。

上面讲了这么多内容做铺垫,相信很多同学已经不耐烦的想要直接看源码了,好的,这就满足泥萌。不过要成功的跑起我们的测试用例来,必须保证本机已经配置好了 Macaca 的相关环境,还没配置的同学请参考我上一篇文章Macaca-Java 版入门指南

目前我们已经将如上介绍的应用层部分源码封装成为独立的 biz 层以 Jar 包的形式提供,同时提供了一个接入 biz 层的 sample,对应的源码均已开源,地址如下:

下面我们以 sample 为例,讲解接入以及使用方法:

下载源码 github 地址

$ git clone https://github.com/macaca-sample/macaca-java-biz-sample.git

更新依赖

$ cd macaca-java-biz-sample 
$ make install

如果下载依赖过程中报错,可能是由于 mvn -s 命令没有生效导致的,建议将根目录下 settings.xml 中的依赖配置到本地 Maven 目录下的 settings.xml 中。

如何修改目标平台 ios/android?

// Config.java
 // 目标平台- ios android 
   public static final String PLATFORM = "ios"; 

注意:执行 iOS 用例时需要将 XCode 升级到最新的 8.1,执行用例前请先启动目标模拟器。

启动 server

$ macaca server --verbose

注意启动 server 时不能加代理,因为 server 在本机启动需要连接 localhost,加代理会导致无法建立连接。

执行测试用例

$ mvn -s settings.xml test 

Demo 详解

如果你成功跑起来了用例,那么下一步我们就来详细研究一下 Demo 的源码部分了,如果你非常不幸的因为各种原因没能 run 起来,请先保证 Macaca 的环境已经正常安装 (macaca-doctor),如果环境正常但还是启动失败,请毫不吝啬的联系我。

下面给出一张各 package 的作用讲解,在看过这部分之后相信大部分人已经基本清楚这个框架的基础结构了,然后更深入的理解,还需要大家认真去研究一下源码。
bootstrap

To Do

1. 数据驱动实现

目前的框架已经解决了一些自动化测试用例编写中的基本问题,但是在写过一定量的 case 后,我们会发现 case 的组装实际上是一种类似的逻辑:获取控件 (通过多种方式) -> 对控件进行某种操作 (click)->与预期结果进行对比得到 case 执行结果,这有限的几种,既然这些操作如此相似,那我们是不是可以通过一种数据驱动的方式更有效的进行 case 的管理,就像如下这张图这样:
_2016_09_23_11_24_45
最后我们期望达到的效果是建立一个管理系统,将所有的流程通过用例管理系统进行如上信息的管理,最终实现零编码的自动化用例设计,当然这其中还需要解决诸多问题,需要我们在积累编写经验的同时不断完善。也欢迎志同道合的同学们加入到这个过程中一起努力!

2. 与网络数据的结合

想象一下我们的自动化测试工作已经正常投产,然后在运行过程中我们发现了一些 bug,这时候开发就需要去解决这些 bug,对于开发同学,我们现在能提供的是 bug 出现时的屏幕截图,但是很多时候仅仅依赖一个截图是不能帮助开发同学去定位真正的问题的,如果能获取用户当时的请求和后端的返回数据,结合屏幕截图,则能大大的方便开发同学定位并解决问题,这一步要如何实现,还需要我们进一步的思考。如果这一步完成了,那么我们相当于将线上巡检与 UI 自动化结合在了一起,无疑是一件很有意义的大跨越。

除了网络数据,还有很多可以和 UI 自动化结合的点子,比如埋点,比如监控,因为 UI 操作是一切 app 行为的基础,所以从 UI 自动化出发,我们有很多事情可以做,有没有热血沸腾了呢?

附录

“Macaca 开源社区” 群的钉钉群号: 11775486(欢迎入群讨论,钉钉顶部搜索框搜索群号加入即可)

更多相关文章

UI 自动化框架调研总结
从无到有搭建 Macaca 环境 (forMac)
Macaca-Java 版入门指南
UI 自动化 Macaca-Java 版实践心得
UI 自动化利器 - 为你的应用自动添加控件 ID 探索
Macaca 基础原理浅析

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

请问如何定位 img 的 src?

求助,pc 桌面版基于 electronjs 的桌面版应用的 UI 页面中,需要使用到鼠标右键的操作,试问鼠标右键的模拟操作 macaca 如何实现呢,api 中未发现,借问求分享哦

Yinxl UI 自动化 Macaca-Java 版实践心得 中提及了此贴 10月23日 10:14

自定义报告器能分享下嘛,还有那个数据驱动肿么样了,看起来非常有搞头,我们也想搞~

Yinxl 基于 Macaca 的混合 H5 应用 UI 自动化入门 中提及了此贴 08月08日 19:53
Yinxl 从无到有搭建 Macaca 环境 (forMac) 中提及了此贴 06月28日 20:10
Yinxl UI 自动化框架调研总结 中提及了此贴 06月28日 20:09
Yinxl Macaca-Java 版入门指南 中提及了此贴 06月28日 20:08
Yinxl #41 · 2017年06月05日 Author
oneHappiness 回复

群号没有失效哦 ,我们都在里面讨论呢,这个是钉钉群号哈,不要找成微信了~哈哈

11775486 这个群号失效了啊,还有讨论的地方吗

Yinxl Macaca-Java 版入门指南 中提及了此贴 04月06日 15:30
Yinxl #38 · 2017年02月28日 Author
阿森 回复

哇 谢谢 哈哈 ~ 握爪~ 文章底部更新了开源钉钉群号,欢迎入群讨论

macaca 真的很好用,关键是稳定,快,比 appium 快,楼主的 common 的公共类中写的真的很好,就用你的了,O(∩_∩) O 哈哈~

超级赞,写的真的很好。

Yinxl #33 · 2017年02月17日 Author

#31 楼 @mengde0077 首先你可以 macaca doctor 打印一下当前的环境配置情况,其次需要确认你用的 shell 是不是系统自带的,不同的 shell 对应的环境变量要修改不同的 profile 的,比如你用的如果是 zsh,那么要改的文件就不是 bash_profile,而是 .zshrc

补充:
在 node 命令行中:是可以获取到 java_home 变量的
node

process.env.JAVA_HOME
'/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home'

你好! 我这边 MAC 环境 , 已经配置了 JAVA_HOME;
.bash_profile
export JAVA_HOME=$(/usr/libexec/java_home)

但安装 macaca-android 报 :Error: $JAVA_HOME is not set

具体如下:
sudo cnpm i macaca-android -g
Error: $JAVA_HOME is not set
at checkJavaHome.then.catch.then.then.catch.then.std (/usr/local/lib/node_modules/.macaca-android_npminstall/node_modules/.1.0.4@java-home/lib/java-home.js:89:25)
at process._tickCallback (internal/process/next_tick.js:103:7)
/usr/local/lib/node_modules/.macaca-android_npminstall/node_modules/.0.1.16@unlock-apk/script/build.js:28
throw e;
^

Error: $JAVA_HOME is not set
at checkJavaHome.then.catch.then.then.catch.then.std (/usr/local/lib/node_modules/.macaca-android_npminstall/node_modules/.1.0.4@java-home/lib/java-home.js:89:25)
at process._tickCallback (internal/process/next_tick.js:103:7)
Error: post install error, please remove node_modules before retry!
Run "sh -c node ./script/build.js" error, exit code 1
at ChildProcess.proc.on.code (/usr/local/lib/node_modules/cnpm/node_modules/npminstall/node_modules/runscript/index.js:67:21)
at emitTwo (events.js:106:13)
at ChildProcess.emit (events.js:191:7)
at maybeClose (internal/child_process.js:877:16)
at Process.ChildProcess._handle.onexit (internal/child_process.js:226:5)
npminstall version: 2.12.0
npminstall args: /usr/local/bin/node /usr/local/lib/node_modules/cnpm/node_modules/.bin/npminstall --china --userconfig=/Users/caolinming/.cnpmrc --disturl=https://npm.taobao.org/mirrors/node --registry=https://registry.npm.taobao.org macaca-android -g

感谢! 学习中!

cp settings.xml ~/.m2/settings.xml
后 mvn -s settings.xml clean install -DskipTests

运行 mvn test 没有报错 了!

#27 楼 @mengde0077 执行过 mvn -s settings.xml clean install -Dmaven.test.skip=true 了吗 新的工程 需要重新更新依赖的,我刚本地重新 clone 跑了一下是可以的

@junhe 你好! 用新的工程 操作 还是报错!
$ mvn test
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building autoui 0.0.2
[INFO] ------------------------------------------------------------------------
[WARNING] The POM for macaca.java:biz:jar:0.0.1 is missing, no dependency information available
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.345 s
[INFO] Finished at: 2017-02-16T11:28:37+08:00
[INFO] Final Memory: 7M/155M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal on project autoui: Could not resolve dependencies for project com.javademo:autoui:jar:0.0.2: Failure to find macaca.java:biz:jar:0.0.1 in https://repo.maven.apache.org/maven2 was cached in the local repository, resolution will not be reattempted until the update interval of central has elapsed or updates are forced -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/DependencyResolutionException

OK 谢谢

Yinxl #25 · 2017年02月15日 Author

#23 楼 @mengde0077 文档已经更新哈

Yinxl #24 · 2017年02月15日 Author

#23 楼 @mengde0077 不好意思,原来这个工程已经不维护了,新的工程地址请参考 https://github.com/macaca-sample/macaca-java-biz-sample 用法和之前这个一样哈

你好!
mac 环境
mvn -s settings.xml clean install -DskipTests 编译成功了!

mvn -e test 时报错! 该怎么解决?

[ERROR] Failed to execute goal on project autoui: Could not resolve dependencies for project com.javademo:autoui:jar:0.0.2: Failure to find macaca.java:biz:jar:0.0.1 in https://repo.maven.apache.org/maven2 was cached in the local repository, resolution will not be reattempted until the update interval of central has elapsed or updates are forced -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal on project autoui: Could not resolve dependencies for project com.javademo:autoui:jar:0.0.2: Failure to find macaca.java:biz:jar:0.0.1 in https://repo.maven.apache.org/maven2 was cached in the local repository, resolution will not be reattempted until the update interval of central has elapsed or updates are forced
at org.apache.maven.lifecycle.internal.LifecycleDependencyResolver.getDependencies(LifecycleDependencyResolver.java:221)

#21 楼 @f_si 解决了,是代码没有写服务关闭,然后再次启动就会造成 Address already in use: bind

跑 mvn test 出下面错误是为什么呀?
Caused by: java.net.BindException: Address already in use: bind
at sun.nio.ch.Net.bind0(Native Method)
at sun.nio.ch.Net.bind(Unknown Source)
at sun.nio.ch.Net.bind(Unknown Source)
at sun.nio.ch.ServerSocketChannelImpl.bind(Unknown Source)
at sun.nio.ch.ServerSocketAdaptor.bind(Unknown Source)
at org.eclipse.jetty.server.ServerConnector.open(ServerConnector.java:321)
at org.eclipse.jetty.server.AbstractNetworkConnector.doStart(AbstractNetworkConnector.java:80)
at org.eclipse.jetty.server.ServerConnector.doStart(ServerConnector.java:236)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.server.Server.doStart(Server.java:366)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at com.github.tomakehurst.wiremock.jetty9.JettyHttpServer.start(JettyHttpServer.java:118)
... 24 more

Yinxl #20 · 2016年12月19日 Author

#19 楼 @yee_hao Macaca 的最新版本已经支持了键盘的一些操作,对应 keys() API 传入链接中的键盘指令就可以操作键盘,https://w3c.github.io/webdriver/webdriver-spec.html#keyboard-actions, 不过目前看只支持安卓和 web, iOS 的怕是要自己封装下键盘操作了

键盘很有可能挡住了元素,怎么收起键盘呢?

Yinxl Macaca 基础原理浅析 中提及了此贴 12月07日 19:05
Yinxl #17 · 2016年12月07日 Author

#16 楼 @t137983656 你好,重装一下 macaca-ios 驱动试下吧

MinstonedeMacBook-Pro:MedicalConsult-Test Minstone$ macaca doctor

macaca-doctor version: 1.0.28

Node.js checklist:

node env: /Applications/Appium.app/Contents/Resources/node/bin//node
node version: v5.10.1

iOS checklist:

Xcode is installed at: /Applications/Xcode.app/Contents/Developer
Xcode Command Line Tools is ready, version: 2345.1.
iproxy[usbmuxd] is installed at: /usr/local/bin/iproxy
ios_webkit_debug_proxy is installed at: /usr/local/bin/ios_webkit_debug_proxy

Android checklist:

JAVA version is 1.8.0_101
JAVA_HOME is set to /Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home
ANDROID_HOME is not set

Installed driver list:

chrome: 1.0.5
ios: 1.0.48

MinstonedeMacBook-Pro:MedicalConsult-Test Minstone$

这是我 macaca doctor ,显示全部成功了(不算安卓),前两天可以运行,今天突然不能运行了,请问知道是怎么回事吗?

下面是错误的提示:

MinstonedeMacBook-Pro:MedicalConsult-Test Minstone$ mvn test
[INFO] Scanning for projects...
[WARNING]
[WARNING] Some problems were encountered while building the effective model for macaca.webdriver.client:macacatestsample:jar:1.0.1
[WARNING] 'build.plugins.plugin.version' for org.apache.maven.plugins:maven-compiler-plugin is missing. @ line 12, column 12
[WARNING]
[WARNING] It is highly recommended to fix these problems because they threaten the stability of your build.
[WARNING]
[WARNING] For this reason, future Maven versions might no longer support building such malformed projects.
[WARNING]
[INFO]

[INFO] ------------------------------------------------------------------------
[INFO] Building macacatestsample 1.0.1
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ macacatestsample ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory /Users/Minstone/Desktop/MedicalConsult-Test/src/main/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ macacatestsample ---
[INFO] No sources to compile
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ macacatestsample ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory /Users/Minstone/Desktop/MedicalConsult-Test/src/test/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ macacatestsample ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ macacatestsample ---
[INFO] Surefire report directory: /Users/Minstone/Desktop/MedicalConsult-Test/target/surefire-reports


T E S T S

Running macaca.client.IosSampleTest
500
Response content:Internal Server Error
Tests run: 2, Failures: 0, Errors: 2, Skipped: 0, Time elapsed: 0.57 sec <<< FAILURE!
test_case_1(macaca.client.IosSampleTest) Time elapsed: 0.135 sec <<< ERROR!
com.alibaba.fastjson.JSONException: syntax error, pos 1, json : Internal Server Error
at com.alibaba.fastjson.parser.DefaultJSONParser.parse(DefaultJSONParser.java:1361)
at com.alibaba.fastjson.parser.DefaultJSONParser.parse(DefaultJSONParser.java:1268)
at com.alibaba.fastjson.JSON.parse(JSON.java:137)
at com.alibaba.fastjson.JSON.parse(JSON.java:128)
at com.alibaba.fastjson.JSON.parseObject(JSON.java:201)
at macaca.client.common.Utils.postRequest(Utils.java:95)
at macaca.client.common.Utils.request(Utils.java:135)
at macaca.client.commands.Session.createSession(Session.java:25)
at macaca.client.MacacaClient.initDriver(MacacaClient.java:781)
at macaca.client.IosSampleTest.setUp(IosSampleTest.java:40)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)

test_case_1(macaca.client.IosSampleTest) Time elapsed: 0.136 sec <<< ERROR!
java.lang.NullPointerException
at macaca.client.common.Utils.deleteRequest(Utils.java:111)
at macaca.client.common.Utils.request(Utils.java:137)
at macaca.client.commands.Session.delSession(Session.java:35)
at macaca.client.MacacaClient.quit(MacacaClient.java:801)
at macaca.client.IosSampleTest.tearDown(IosSampleTest.java:102)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:33)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)

Results :

Tests in error:
test_case_1(macaca.client.IosSampleTest): syntax error, pos 1, json : Internal Server Error
test_case_1(macaca.client.IosSampleTest)

Tests run: 2, Failures: 0, Errors: 2, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.971 s
[INFO] Finished at: 2016-12-07T14:19:44+08:00
[INFO] Final Memory: 9M/155M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test (default-test) on project macacatestsample: There are test failures.
[ERROR]
[ERROR] Please refer to /Users/Minstone/Desktop/MedicalConsult-Test/target/surefire-reports for the individual test results.
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException
MinstonedeMacBook-Pro:MedicalConsult-Test Minstone$

要是楼主把 自定义报告器 的加上就完美了,赞

写得真不错

Yinxl #11 · 2016年11月25日 Author

#10 楼 @xdf 自定义报告这个我看一下能不能整个 demo 出来吧,主要思路就是通过 result.log 确定用例的最终结果 (如果所有的用例都是成功的,则表示用例成功,只要有一个失败的,就表示用例失败),结合截屏图片和 custom.log 进行分步骤输出,剩下的就是组装到报告里了。

@junhe 自定义报告器能分享下吗?

#4 楼 @guoqx 对的 可以根据自身需要做任意的切分和聚合,生成自己想要的各种报告

#6 楼 @zyyuyu123 我没说明白,是代码迁移了哈 文章中已经更新了代码库地址 新的地址是这个https://github.com/Yinxl/bootstrap.git

写的非常好,赞一个

iOS Android 一起搞定了

如果我想生成自己定制的测试报告,是不是可以从 custom.log 中取字段,在测试结束后自动执行填到测试报告模板中生成报告

连 demo 都写得这么规范,给君禾点赞!

#1 楼 @zyyuyu123 不好意思哈,刚发上来的时候地址没更新,现在已经更新了哈

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册