新手区 [已解决] Appium-Python 测试聊天时同时发送 9 张图片的问题

meShaw · 2016年01月11日 · 最后由 meShaw 回复于 2016年01月13日 · 2748 次阅读

感谢 @chenhengjie123 @huanzhijin 耐心回答

测试的功能

模拟微信聊天,测试一次发送 9 张图片,图片是否全部发送成功的功能,未成功的图片左侧出现小感叹号的图标。

我的思路

同时选择 9 张图片发送后,获取聊天列表 textview,通过 textview[-1],textview[-2]...textview[-9] 这样遍历每一条消息的 LinearLayout,看是否包含小感叹号的图标,不包含则表示发送成功。

代码如下

listViews = wd.find_element_by_id("listview")                                        
textview = listViews.find_elements_by_class_name("android.widget.LinearLayout")      # 获取聊天信息的列表
for count in range(9):
    try:
        wd.textview[-(count+1)].find_element_by_id("station_chat_fail_img")      # 小感叹号图标 id = station_chat_fail_img
        ex = True
    except:
        ex = False
    if  ex == False:
        print("------- success to send the pic")
    else:
        print("------- fail to send the pic")

问题 1:

实际上是每次都会有发送不成功的图片,但是测试不出来,结果显示:

print(ex) 了一下,显示 9 个全是 False。

解决方法:

1.wd.textview[-(count+1)].find_element_by_id("station_chat_fail_img") 语法错误,取不到值,应该为textview[-(count+1)].find_element_by_id("station_chat_fail_img")
2.因为感叹号图标一直存在,只是图片发送成功和不成功时透明度不同,所以只是 find 这个 element 是判断不出来的,应该改为textview[-(count+1)].find_element_by_id("station_chat_fail_img").is_displayed()

问题 2

问题 1 解决后,出现了另一个问题,发现上面的方法不能准确判断到第几张图片发送不成功

解决方法:

因为在 Android 的 Appium 的默认模式下,只有屏幕上显示出来的 element 才能被 find 到,而我的屏幕上一次只能显示 4 张图片,没办法全部取到 textview 的 9 个元素。于是修改为每次取最后 3 张图片进行判断,然后滑动一次屏幕,循环 3 次:

for x in range(3): 
    listViews = wd.find_element_by_id("listview")
    textview = listViews.find_elements_by_class_name("android.widget.LinearLayout")  
    for count in range(3):
        try:
            textview[-(count+1)].find_element_by_id("station_chat_fail_img").is_displayed()
            ex = True 
        except:
            ex = False
        if  ex == False:
            print("------- success to send the pic")
        else:
            print("------- fail to send the pic")
    wd.swipe(300,100,300,1020,800)

然后,获取完整 textview 的方法目前 Android 需要用 Selendroid 模式,这个我会继续学习。

共收到 14 条回复 时间 点赞
1楼 已删除

日志不够全,最关键的 find_element_by_id("station_chat_fail_img") 的相关日志没打出来。

另外,你确认下感叹号图标控件没显示的时候是控件不存在还是控件内容变了?如果只是内容变了(从感叹号改为没内容),那么无论有没有感叹号都是能 find 到的。

wd.textview[-(count+1)].find_element_by_id("station_chat_fail_img")
这段有问题吧??改为 textview[-(count+1)].find_element_by_id("station_chat_fail_img") 这样试试

#2 楼 @chenhengjie123
对的我确认了一下,感叹号图标是一直存在的,只是透明度变了

于是我改成了textview[-(count+1)].find_element_by_id("station_chat_fail_img").is_displayed()

但是还发现两个问题:
1.发送了 9 张,第 5 张未发送成功,于是从第 5 张开始全部显示发送未成功
2.调用 is_displayed() 这个接口是不是超级费时啊?总共判断 9 次,差不多用了 5 分钟。。

#3 楼 @huanzhijin 对的我改了一下,但是不太明白。

通过@chenhengjie123解答,我确认到感叹号控件是一直存在的,所以按照我上面的判断:

正确的textview[-(count+1)].find_element_by_id("station_chat_fail_img")全都会返回 True

但是wd.textview[-(count+1)].find_element_by_id("station_chat_fail_img")这样取值取到的都是 False

是为什么?wd.textview[-(count+1)].find_element_by_id("station_chat_fail_img")取得是什么值?

#5 楼 @xzhan wd.textview[-(count+1)].find_element_by_id("station_chat_fail_img") 这个什么值也取不到吧,应该语法错了,wd 没 textview 的方法吧,所以你第一次时全部是 False

#6 楼 @huanzhijin 明白了,多谢!

#7 楼 @xzhan Good!问题解决了~

如果把问题解析和解决方案附到正文并把标题加上【已解决】就更好啦~这样后面的童鞋也更容易找到解决方案。

#8 楼 @chenhengjie123 没有没有,还没有完全解决,我还有问题想请教。

这种方法不能准确判断出是第几张发送不成功是为什么?

实际发送了 9 张,但是从下往上数第 1,2,5 这 3 张没有发送成功

可是测试的结果却是这样:

我开始考虑了一下,是不是因为,刚刚点击完发送按钮,这段【判断是否发送成功的代码】就立马开始执行,所以判断的并不是9 张图片全部发送出去的时候,所以我就在在wd.find_element_by_id("done_btn").click()后面加了一个time.sleep(5),等 9 张图片全发送了再开始判断,但是测试结果依然和实际不符,想不明白是为什么了。。。

建议你试试在判断开始前截个图看看?因为你说的从界面上看的效果看起来和你的测试结果刚好相反,你看下是不是你的 display 刚好用反了?

meShaw #11 · 2016年01月12日 Author

#10 楼 @chenhengjie123 不是的,上面那个情况只是凑巧了。。我验证了好几次,测试出来的失败和成功的个数没有什么规律,和实际也不符的。

我的 display 部分是这样的,没有反啊:

for count in range(9):
    try:
        textview[-(count+1)].find_element_by_id("station_chat_fail_img").is_displayed() 
        ex = True
    except:
        ex = False
    if  ex == False:
        print("------- success to send the pic")
    else:
        print("------- fail to send the pic")
    wd.swipe(300,200,300,400,800)

#11 楼 @xzhan 你用的是 android 上 appium 的默认模式吧?如果是的话那没有显示出来的元素是不会被 find 到的。从你截图看一次最多显示 4 个,但你的 textview 数组就直接有 9 个元素了,这点我没搞明白。

meShaw #12 · 2016年01月12日 Author

#12 楼 @chenhengjie123 我之前也考虑到这个问题,然后我的解决办法是:

上面代码里最后一行,每次循环里我写了一个wd.swipe(300,200,300,400,800),就是每次验证一张图就把屏幕往下滑一点,然后取到再上面的图。。。

但是你这么一说。。好像这样做不对。。

然后我这样做了一下,用一个嵌套循环,每次 textlist 取最后 3 个,然后滑动一次屏幕:

for x in range(3): 
    for count in range(3):
        try:
            textview[-(count+1)].find_element_by_id("station_chat_fail_img").is_displayed()
            ex = True 
        except:
            ex = False
        if  ex == False:
            print("------- success to send the pic")
        else:
            print("------- fail to send the pic")
    wd.swipe(300,100,300,1020,800)

或者有没有在当前屏幕上能获取到完整的 textview 的方法?

#13 楼 @xzhan 获取完整 textview 的方法目前 Android 需要用 Selendroid 模式。用默认模式是拿不到没有显示的元素的。

如果要变通的话,那就用类似你上面的方法,有一点要修改:每次 swipe 完后整个 textview 必须重新用 find 生成。否则 appium 会使用缓存的元素(大部分情况下已失效),而不是你滑动后出现的元素。

meShaw #14 · 2016年01月13日 Author

#14 楼 @chenhengjie123 好的!学习了!多谢!

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