selendroid 入门

wuming · 2015年03月22日 · 最后由 黑水 回复于 2016年09月21日 · 2750 次阅读
本帖已被设为精华帖!

长久以来没有一个人写个具体的 selendroid 教程,害得我们这些初入门的都不懂得大神们说的 selendroid 有自己的 inspector 是啥意思。或者一说 webview,大神们就说用 selendroid 模式,然后无语中。。。
吐槽完毕。没办法只好自己去官网看了一遍又一遍。最终还是把官网的 demo 跑起来了。。
官网地址:http://selendroid.io/
首先,先去官网下 jar 包,目前我用到过的就是 selendroid-standalone-0.15.0-with-dependencies.jar 和 selendroid-client-0.15.0.jar。search 里面都有,其实里面的都可以下载下来,免得到时候些脚本的时候连缺什么都不知道。

再然后把最右边的 demo 的 apk 下下来。
打开模拟器,我用的是 genymotion,版本是 4.1.1。
所有的都准备好了,接下来打开你的 cmd 命令,然后到你下载的 jar 包和 demo 的 apk 下的文件夹输入

java -jar selendroid-standalone-0.15.0-with-dependencies.jar -app selendroid-test-app-0.15.0.apk

这样就打开了 selendroid-standalone 的一个端口为 4444 的服务器。
打开浏览器,输入http://localhost:4444/wd/hub/status,得到以下信息,说明你运行成功了。

再然后打开 Eclipse,编写 demo 脚本,添加 jar 依赖。

@Test
public void test() throws Exception {
    SelendroidCapabilities capa = new SelendroidCapabilities("io.selendroid.testapp:0.15.0");

    WebDriver driver = new SelendroidDriver(capa);
    //driver.getPageSource();
    WebElement inputField = driver.findElement(By.id("my_text_field"));
    Assert.assertEquals("true", inputField.getAttribute("enabled"));
    inputField.sendKeys("Selendroid");
    Assert.assertEquals("Selendroid", inputField.getText());
    driver.quit();
}

现在重点来了,怎么打开 inspector 呢。打开浏览器输入:http://localhost:4444/inspector。结果得到的是:

它是让你跑 debug 模式,然后才能打开 inspector。在代码中随便定个点,然后才能定位。
再次刷新http://localhost:4444/inspector,可以正确定位到了,借用官网的图。

而且惊喜的发现点击 inspector 上的元素,在下面的框会生成 xpath。

试过可以直接用。至于后面的 HTML Source 一直都是空白,不知道为啥。
下一步可以结合 appium 的 Selendroid 用在项目中。期望 webview 可以顺利解决。
总结:Selendroid Inspector 总体感觉还是不错,就是画面做的不够好。不过比 appium Android 自带的 inspector 渣渣和 UIAutomatorviewer 好多了,这两个要是改进到能支持 webview 的定位多好,不用瞎折腾了。
更新:今天又用了会 selendroid,果然槽点特别多。。
1.每次脚本改了任何代码,server 都要重新再次打开。改进办法:写个 bat 文档,每次点开就行。
2.webview 居然定不到具体的元素,定到的还是一整块。自动生成的 xpath 也不能用。最后只好用 driver.getPageSource(),官网也推荐用这个。
3.自带 inspector 不能用代理,否则会显示不出来。

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

Selendroid 的 webview 的原理

private String executeJavascriptInWebView(final String script) {
result = null;
ServerInstrumentation.getInstance().getCurrentActivity().runOnUiThread(new Runnable() {
public void run() {
if (webview.getUrl() == null) {
}
return;
// seems to be needed

webview.setWebChromeClient(chromeClient);
webview.loadUrl("javascript:" + script);
} });
long timeout = System.currentTimeMillis() + scriptTimeout;
synchronized (syncObject) {
while (result == null && (System.currentTimeMillis() < timeout)) {
try {
}
syncObject.wait(2000);
} catch (InterruptedException e) {
throw new SelendroidException(e);
} 
}
return result;


好文,后面学习 seledroid 就参照这个文章来撘环境了。
在 google 的规划中,webview 的自动化貌似是用 chromedriver 来做的,和 uiautomator 定位有所不同。

话说怎么那么多人写 xpath 都那么喜欢用工具生成的……自己写不是更灵活吗……

#2 楼 @chenhengjie123 Selendroid 用的是 javascript 来做的。

#3 楼 @lihuazhang 那不就类似于 selenium 1 的做法吗?

#4 楼 @chenhengjie123 AndroidAtoms.java 谷歌下

@lihuazhang 原理暂时还看不懂,希望过段时间能看懂。。

@chenhengjie123 有些人比较懒。。

selendroid 模式比 uiautomator 模式更有用, 推荐大家好好看看. 替代 robotium 的方案有两个.
一个是 calabash, 一个是 selendroid. calabash 是 BDD 方式, 并不是所有人都喜欢.
selendroid 相对更好些. 但是一直被 appium 遮盖了光芒.

#1 楼 @lihuazhang robotium 的源代码
robotium 和 selendroid 原理都是一样的. 只是封装方式不同. robotium 是 api 方式. selendroid 是 webdriver api 方式. 而 calabash 是 BDD 模式. 风格不同.


/**
 * Executes the given JavaScript function
 * 
 * @param function the function as a String
 * @return true if JavaScript function was executed
 */

private boolean executeJavaScriptFunction(final String function){
    final WebView webView = viewFetcher.getFreshestView(viewFetcher.getCurrentViews(WebView.class, true));

    if(webView == null){
        return false;
    }

    final String javaScript = prepareForStartOfJavascriptExecution();
    Activity activity = activityUtils.getCurrentActivity(false);
    if(activity != null){
    activity.runOnUiThread(new Runnable() {
        public void run() {
            if(webView != null){
                webView.loadUrl("javascript:" + javaScript + function);
            }
        }
    });
    }
    else{
        inst.runOnMainSync(new Runnable() {
        public void run() {
            if(webView != null){
                webView.loadUrl("javascript:" + javaScript + function);
            }
        }
    });
    }
    return true;
}

#6 楼 @woshizh 这两天在研究 selendroid,imspector 上 screenshot 总是无法显示,forceuninstall 后好了一会又坏了,求助。。

#10 楼 @neyo 我这里用 17 版本测没有遇到过呢

#11 楼 @niuniudd 在 mac 上一直出问题。。换了 windows 就好了

#11 楼 @niuniudd 按照官方范例的参数配置方法,现在只成功跑过范例。。。想跑别的包都会签名错误,求指导

#13 楼 @neyo 我用钉钉试验过,我的做法是先把 apk 中 META-INF 目录下的文件都删掉,然后再启动服务器和脚本,不能提前手动安装 apk

1.每次脚本改了任何代码,server 都要重新再次打开。改进办法:写个 bat 文档,每次点开就行。
对这个问题我的猜测是否没有在代码结束执行前 driver.quit(),session 没有停止,他就不能启动下一个 session

#15 楼 @niuniudd 我这边 server 貌似只在报错之后才需要重开。appium 客户端 override exsiting sessions 不知道能不能解决你的问题,需要删 meta-inf 以及不能提前安装 apk 啊,那没跑一次就要做次删除操作了好麻烦啊

#16 楼 @neyo单独使用 selendroid 在 我自己的框架里,appium 的这个 override exsiting sessions 我看看原理先,经过你的 PC 重新签名安装后的应用就不用卸载了,因为再执行签名都用的是你 PC 生成的是一致的

18楼 已删除

#17 楼 @niuniudd 最近没碰 selendroid,今天正好在做些相关资料翻看了帖子,能看到你的回答真是太好了~之前因为无法签名问题没有在别的应用上实用成功就放着了。看到你的回答,等下我也去试试看~另外还想问下,之前看到过 selendroid 处理 toast 的帖子,不知道你这边实践成功了吗

#19 楼 @neyo 这块我还真没机会试过,我只在 web 应用中用 selendroid,app 没 toast 弹出。不过看介绍 selendroid 应该是支持 toast 的

#20 楼 @niuniudd 好的,谢啦~我去研究下!

#20 楼 @niuniudd 上次你说要删除 meta-inf 没理解,今天在论坛的 robotium 区看到了说明,现在这块算是搞清楚了。。toast 处理上,目前不知道如何抓 toast 的文本了。。

黑水 [该话题已被删除] 中提及了此贴 09月21日 20:22
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册