Appium 内置并行执行、获取所有日志、ExtentReports 报告的 Appium 测试框架分享

陈恒捷 for PPmoney · 2017年02月25日 · 最后由 游戏人间 回复于 2019年02月26日 · 4303 次阅读
本帖已被设为精华帖!

首先声明,这个框架不是我写得,我只是在这里分享下。

前言

多机并行执行、出错获取所有可获取的日志、集成良好的报告,一直是一个良好的 UI 自动化框架的终极目标。最近看到 github 上有开源的框架做到了上述的三个点,不敢独享,在此分享下。

框架地址:

https://github.com/saikrishna321/AppiumTestDistribution

示例项目地址(建议新手也看下,学习下良好的测试用例脚本是如何编写的):

https://github.com/saikrishna321/PageObjectPatternAppium

youtube 视频演示:

https://www.youtube.com/watch?v=KfMoJ6dSC3g

框架特性:

  1. 内置 TestNG 和 Cucumber ,你想 BDD 也能用
  2. 出错自动收集 Appium Server Log、脚本报错堆栈、adb log 、截图,基本满足定位问题的所有需要。
  3. 集成 ExtentReports 作为测试报告,美观好用
  4. 据说还支持视频记录测试过程,不过需要额外安装一些组件 。详情请看框架的 readme

Trouble shooting

由于不少同学跟帖说使用示例项目启动报错,自己小小尝试了一下,确实有一些坑。在此记录和分享下。

特别注意,我是在 mac 下进行的尝试,不排除 windows 下有些坑 mac 下不会遇到。

  • 提示 Cannot run program "appium"

原因:一查堆栈,可以看到都和 CommandPrompt.runCommand 方法有关。看下源码:

public class CommandPrompt {

    Process p;
    ProcessBuilder builder;

    public String runCommand(String command) throws InterruptedException, IOException {
        p = Runtime.getRuntime().exec(command);
        // get std output
        BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
        String line = "";
        String allLine = "";
        int i = 1;
        while ((line = r.readLine()) != null) {
            allLine = allLine + "" + line + "\n";
            if (line.contains("Console LogLevel: debug") && line.contains("Complete")) {
                break;
            }
            i++;
        }
        return allLine;

    }

这个方法很简单,就是调用 Runtime.getRuntime().exec(command); 运行命令。经过搜索,这个 runtime 运行时的环境变量 和启动这个命令所在窗口能获得的环境变量是一致的 。提示找不到这个文件,意味着环境变量 PATH 里面没有这个程序入口。具体情况需要大家自行查找。

如果是在 shell 或者 bash 下,有个小技巧可以查下运行时的环境变量的值。往示例项目的 src/test/java/com/appium/tests/Runner.java 里面进行如下修改:

package com.appium.tests;

import com.appium.manager.ParallelThread;
// -----------------新加的一个 import 语句-----------------
import com.appium.utils.CommandPrompt;
// -----------------新加的一个 import 语句 end-----------------
import org.testng.annotations.Test;

import java.util.ArrayList;
import java.util.List;

public class Runner {

    @Test public void testRunner() throws Exception {
        // -----------------新加的输出当前环境变量值的语句-----------------
        CommandPrompt cmd = new CommandPrompt();
        String output = cmd.runCommand("env");
        System.out.println("**********env: " + output);
        // -----------------新加的输出当前环境变量值的语句 end-----------------

        ParallelThread parallelThread = new ParallelThread();
        List<String> test = new ArrayList<String>();
        /*test.add("MultiLoginTest");
        test.add("AddCommentTest");*/
        parallelThread.runner("com.appium.tests");
    }

}

用 maven 运行测试时即可看到环境变量的实际值。

最简单的解决方法:用 npm 重装下 appium 。我就是这么解决的。。。

  • 按照官方要求运行 mvn clean -Dtest=Runner test, 提示 Parameter 'device' is required by @Configuration on method startAppiumServer but has not been marked @Optional or defined

原因:源码中对应 startAppiumServer 的内容如下:

...
    @BeforeClass(alwaysRun = true)
    @Parameters({"device"})
    public synchronized AppiumServiceBuilder startAppiumServer(String device) throws Exception {
        String methodName = getClass().getSimpleName();
        if (prop.containsKey("CI_BASE_URI")) {
...

此处使用了 testng 的 Parameters 注解,但这个 device 并没有通过参数传递到这个方法。因此报错。

解决方案很简单,运行命令里加入设备的 udid 号传给 device 变量即可。例如我用虚拟机,adb devices 输出如下:

List of devices attached
192.168.56.102:5555 device

那么,我的启动命令改为 mvn clean -Dtest=Runner -Ddevice="192.168.56.102:5555" test 就可以正常启动了。

  • 其他

有一些配置项需要根据运行环境进行修改。具体改动可以参照我的修改内容:

diff --git a/config.properties b/config.properties
index 024d934..5e8295f 100644
--- a/config.properties
+++ b/config.properties
@@ -1,8 +1,8 @@
-ANDROID_APP_PATH=/Users/saikrisv/git/PageObjectPatternAppium/build/wordpress.apk
+ANDROID_APP_PATH=/Users/hengjiechen/Develop/tmp/PageObjectPatternAppium/build/wordpress.apk
 APP_PACKAGE=org.wordpress.android
 APP_ACTIVITY=org.wordpress.android.ui.WPLaunchActivity
 RUNNER=distribute
-APPIUM_JS_PATH=/usr/local/lib/node_modules/appium/build/lib/main.js
+APPIUM_JS_PATH=/Users/hengjiechen/.nvm/versions/node/v4.2.6/lib/node_modules/appium/build/lib/main.js
 BROWSER_TYPE=chrome
 APP_TYPE=NA
 FRAMEWORK=testng

写在解决这些问题的最后

最近都比较忙,到今晚才抽空了 1 个小时左右把这个程序跑通。结合最近团队中的一些情况,有一点小感慨。踩坑是一个积累的过程。技术上遇到问题不是自己去踩坑解决,而是直接提问,那么最终得到提升的只会是回答问题的人。他会在一次次踩坑中积累经验,以后遇到这些问题能快速解决,而提问的人,提升速度会慢很多,因为记忆不深刻,下次遇到还得问或者从零查起。

另外,到目前为止,几乎没遇到过完全没有坑的程序。运行环境千差万别,不可避免不同环境下会遇到不同的问题。当遇到这些问题时,能独立找到原因并解决,甚至分享解决方案的同学,才会成为团队的主力,因为他才是提升团队效率的关键。

纯属感慨,大家不需要对号入座。

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

东西看着不错收藏了,辛苦

收藏,回去研究

mark 一下,正好结合修改一下我自己的框架

这个东西真不错印度人真好哈哈

发现了新内容,用 extentreport 快一周,前面很折腾人,后面熟悉了感觉挺好用的,下来再研究一下恒捷分享的框架

挺好的,谢谢分享

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

@chenhengjie123 没跑起来 报错 麻烦看下 谢谢

erinet 回复

你是不是没装 appium 。。。

陈恒捷 回复

安装了
自己写了一个测试 是没问题 但是运行 demo 里面的用例就报错了
@Test
public void login(){
driver.findElement(By.id("org.wordpress.android:id/nux_username")).setValue("test1");
driver.findElement(By.id("org.wordpress.android:id/nux_password")).setValue("test2");
}

erinet 回复

它是要通过命令 appium 来启动 appium 的,是不是环境变量没设置好?

陈恒捷 回复

我手动在 cmd 命令行输入 appium 是能启动的

不得不说报告很漂亮

@chenhengjie123 有没有个生成好的测试报告,可以下载看下

codeskyblue 回复

没有。。。

@xiaocong168 @chenhengjie123 有没有解决,我也遇到你这样问题,启动时候报 appium 找不到,我自己框架什么都能用,说明 appium 本身没问题,我只在config.properties 配好就行了?

paul 回复

没有解决,你要解决了 麻烦你告知下

paul 回复

你的截图 APPIUM_JS_PATH 肯定是错的,windows 下,使用的 js 是 bin 目录下 appium.js。

@keyitest 你好,我昨天也发现了,但是配了后还是报 appium 系统找不到。但环境肯定是好的,用命令都可以执行的

paul 回复

是啊,一直搞不定。只能在虚拟机下的 mac 使用了!

楼主遇到这样问题吗?

请问楼主 写日志那个类是哪个啊我想看下你怎么抓取失败的日志

哇,大赞,大赞,先研究一番

志雄 回复

不是我写的。。。具体看看源码吧?

尝试了一下,没有运行成功,有运行起来的写个简易教程吗?

陈恒捷 回复

写个简易说明把?我没运行起来,官方的示例写的不太清楚

fdeferf 回复

把你报错信息贴上来一下?

找到这篇帖子,简直不能更有用,忍不住打赏,请问这个有运行起来的简易教程可以参考吗

可以简单说一下,运行安装步骤吗

wangpengfei100 回复

后面抽空写下,最近比较忙

陈恒捷 回复

好的好的,感谢感谢

昨天试了一下,没成功。。

wangpengfei100 回复

或者你把报错信息发上来一下,说不定有其它小伙伴遇到过并且解决了?

@mamian @wangpengfei100 我自己尝试了一下,踩到的坑及解决方案已补充到正文中,两位可以参考下。

codeskyblue 回复

最近终于有空自己跑了一遍,有报告生成了。

报告放在了网盘:https://pan.baidu.com/s/1bOakvO

解压后打开 ExtentReports.html 即可。

陈恒捷 回复

还是没成功, 这个示例程序太老, 我不打算运行这个了, 不过我看了下框架了源码, 里面有不少值得学习的地方

陈恒捷 回复

无法运行 Appium 那里,卡住了,npm 重装了 Appium 但是因为网络原因,报错了

wangpengfei 回复

那还是先解决 npm 重装 appium 的问题吧。

看了这个代码,感觉自己写的代码就像一坨狗屎

cloudy 回复

不用急,你已经知道好代码长什么样了,下一步就是怎么逐步优化,写出好代码了。

陈恒捷 回复

是的 逐步优化 加油!

对多设备并发运行的实现感应趣,这一块有独立脚本吗? 可以说明一下一个具体过程??

johnli2046 回复

框架不是我写的,建议直接看源码学习吧。目前根据我的了解,用的应该是 testNG 本身提供的并行执行机制。

@john2046 多设备并发用 testNG 很容易就可以做到的,有兴趣可以看下我写的 框架,和这个框架差不多(重复造轮子)

看了下代码,ExtentManager.java 中在取 appium version 时并没有用到 APPIUM_JS_PATH,而是直接使用 appium -v,导致 windows 上可能会出现找不到 appium

渐次消逝 回复

好的,谢谢~

我在 github 上好像看到过类似的工程不知道是不是楼主的👍

去年 appium 刚入门的时候一直苦于找资料,后来无意中发现了这个工程,醍醐灌顶😂 没想到今天楼主把它引到社区来了,感概一下👍

渐次消逝 回复

内容删除了,方便再分享一下吗?
另外有些问题想咨询下,可以的话加下 569877653 ,或者留个联系方式,谢谢

我想请问下,楼主你知道还有其他基于 python 语言的类似的报告么?

游戏人间 回复

这个不大了解哦

陈恒捷 回复

好的,多谢!~

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