Appium Appium_Android 怎么检查页面元素是否存在

55hhy · 2014年10月30日 · 最后由 55hhy 回复于 2014年10月30日 · 4451 次阅读

一般页面上有 Start 按钮,没有 Start 之前其他的元素都不可点:
但是如果 Start 之后就没有 Start,页面元素都可点:

现在的问题是我判断 Start 按钮是否存在时,总是会直接判断页面元素存在,不存在就直接报错,源码如下:

public void checkSPStatus(){
    if(driver.findElementById("com.ef.efekta.englishtown:id/planButton")==null){
        WebElement lessonOne = driver.findElementByXPath("//android.view.View[1]/android.widget.FrameLayout[1]/android.view.View[1]/android.widget.RelativeLayout[1]/android.support.v4.view.ViewPager[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.widget.LinearLayout[1]/android.widget.RelativeLayout[1]/android.widget.ImageView[1]");
        lessonOne.click();
    }
}

报错信息:

info: [debug] [BOOTSTRAP] [debug] Got command of type ACTION
info: [debug] [BOOTSTRAP] [debug] Got command action: click
info: [debug] Responding to client with success: {"status":0,"value":true,"sessionId":"88e61052-a8ec-48cd-bf98-bdc1567d4362"}
info: <-- POST /wd/hub/session/88e61052-a8ec-48cd-bf98-bdc1567d4362/element/3/click 200 285.858 ms - 76 {"status":0,"value":true,"sessionId":"88e61052-a8ec-48cd-bf98-bdc1567d4362"}
info: [debug] [BOOTSTRAP] [debug] Returning result: {"value":true,"status":0}
info: --> POST /wd/hub/session/88e61052-a8ec-48cd-bf98-bdc1567d4362/element {"using":"id","value":"com.ef.efekta.englishtown:id/planButton"}
info: [debug] Pushing command to appium work queue: ["find",{"strategy":"id","selector":"com.ef.efekta.englishtown:id/planButton","context":"","multiple":false}]
info: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"action","action":"find","params":{"strategy":"id","selector":"com.ef.efekta.englishtown:id/planButton","context":"","multiple":false}}
共收到 31 条回复 时间 点赞

web 页面?

#1 楼 @lihuazhang Android 页面 不是 web 只是是平板 App 不是手机 App

#2 楼 @55hhy 有点看不懂

现在的问题是我判断 Start 按钮是否存在时,总是会直接判断页面元素存在,不存在就直接报错
这个是啥意思?

#3 楼 @lihuazhang

if(driver.findElementById("com.ef.efekta.englishtown:id/planButton")==null)

这句 页面元素不存在应该是直接执行

lessonOne.click();

但是现在就说找不到 if 判断里面的元素

#4 楼 @55hhy 依然不懂。。

WebElement lessonOne = driver.findElement(By.clasaname(""));
boolean lessonOneEnable = lessonOne.isEnabled();
if(lessonOneEnable){
lessonOne.click();
} else {
WebElement startBtn = drvier.findElement(By.id(""));
startBtn.click();
lessonOne.click();
}
不知道这个可不可以

#5 楼 @lihuazhang
看图 第一张图上 Start 点击之后就会到第二张图,同时第二张图上所有元素就可以点击
所以我要先判断这个 Start button 有没有被点击过,点了就不存在了,不存在了我就进行其他操作了
结果判断 Start 的我就写在 if 判断里面

if(driver.findElementById("com.ef.efekta.englishtown:id/planButton")==null)

最终就是每次必须存在,Start 不存在就直接在这里挂了

#6 楼 @chenleslie It works,thank you very much!

#7 楼 @55hhy 哦 你的意思是假如 startButton 不出现, driver.findElementById("com.ef.efekta.englishtown:id/planButton") 就会出错吧?

#10 楼 @55hhy 那是因为你的元素没有 render 出来,去 find 肯定会出错。

getAttribute 看一下 enabled,clickable,大概只是不可见

#6 楼 @chenleslie @55hhy 这个代码会有逻辑风险。如果有个 bug,不点 start,也能开始 lesson。

55hhy #16 · 2014年10月30日 Author

#13 楼 @lihuazhang 能详细说说吗?水平很差的,我。

#14 楼 @55hhy 你的逻辑是只有 start 了才能点击 lesson 吧?

55hhy #18 · 2014年10月30日 Author

#15 楼 @lihuazhang 嗯。但是有时候进来就已经 Start 了,那就直接点击 lesson

#16 楼 @55hhy 那看你们能否接受了。。

55hhy #18 · 2014年10月30日 Author

#17 楼 @lihuazhang 接受什么?

#18 楼 @55hhy 你这边的用例是不是:

进入,看到 start, 点击 start, 才能开始?

那你现在出现了一进来已经 start 了,这是否能接受啊

55hhy #21 · 2014年10月30日 Author

#19 楼 @lihuazhang 哦 这个是因为有些账号用户可能之前就 Start 了 那再次进来就已经是 Started 状态了

#19 楼 @lihuazhang 我想点 start 的目的就是为了能够点 lesson,所以,start 点不点不是关键

#21 楼 @chenleslie
#20 楼 @55hhy

嗯,我知道,所以我说的是,如果有一个 bug, 比如一个新人,啥都没开始,他一进来无需点击 start button,就可以开始 lesson1,如果 start button 那边有业务逻辑,那就糟糕了。

不存在就報錯 <--- 所以你應該用 try catch


try {
        WebElement check = driver.findElementById("com.ef.efekta.englishtown:id/planButton");
                    //如果存在執行這裡
                } catch (Error e) {
                    //如果不存在執行這裡
                }

两个用例,一个用没点过 start 的账号,另一个用点过 start 的账号。
基本上在业务视角每个用例只有一种结果。

55hhy #24 · 2014年10月30日 Author

#22 楼 @lihuazhang 现在的逻辑是这样子处理的

public void checkSPStatus(){

    WebElement lessonOne = driver.findElementByXPath("//android.view.View[1]/android.widget.FrameLayout[1]/android.view.View[1]/android.widget.RelativeLayout[1]/android.support.v4.view.ViewPager[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.widget.LinearLayout[1]/android.widget.RelativeLayout[1]");
    if (!lessonOne.isEnabled()) {
        driver.findElementById("com.ef.efekta.englishtown:id/planButton").click();
    }
    else{
        lessonOne.click();
    }
}

如果有 Start 的话 Lesson 是点不了的

程序出错是因为 driver.findElementById("com.ef.efekta.englishtown:id/planButton") 语句执行直接抛异常了,然后就终止了代码的执行。你可以用捕获异常的方式进行处理,23 楼已给出样例

使用 try catch 即可

比如 start 这个功能,设计了这两个用例:
用例 A:
1、新注册账号进入页面。期望结果:lesson1 不可点
2、点击 start。期望结果:start 消失
3、点击 lesson1,期望结果:进入相应页面

用例 B:
1、新注册账号进入页面。
2、点击 start。期望结果:start 消失
3、退出应用,再次进入页面。期望结果:没有 start 按钮。
4、点击 lesson1,期望结果:进入相应页面

假如 app 包含这样的 bug:新注册的用户进入页面没有 start 按钮,lesson1 可点击。按 25 楼的写法会漏掉这个 bug。
假如有另一个 bug:新注册的用户进入页面有 start 按钮,lesson1 可点击。还是会漏掉。

55hhy #28 · 2014年10月30日 Author

#28 楼 @sanlengjingvv 脑洞大开 不过现在还没有这么细 我主流程还没有走通 磕磕绊绊啊

楼主,请问你这个问题解决了没有呢,我这边使用 if(driver.findElementByName("登 录").isEnabled()),当登录按钮不存在的时候会报错的

55hhy #30 · 2015年06月16日 Author

#30 楼 @miumiu 对 元素不存在的时候是会报错的 只能找其他按钮来判断
在评论里面我们找到了解决方案 就是迂回的

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