• 先谢谢大家哈

    下面是个例子,这个例子比较蠢。。。。只是为了说明一下问题哈

    我的想法是,使用类对象,按照 case3、case1、case2 的顺序去执行,这几条其实中间没有什么关系;现在如果 case3 执行失败了,那么后面两条就不会执行了;在 HTMLTestRunner 生成的测试报告中体现的就是,case3 Fail ,case1 & case2 Error
    (用 HTMLTestRunner 就是为了可以生成报告)

    我想着能不能 case3 Fail 了,但是可以继续执行 case1 和 case2,或者 HTMLTestRunner 有什么方法可以不用 raise 的方式判断失败,不用终止程序??

    试了试把@classmethod去掉后,每条方法都执行一次 setUp 倒是可以在 Fail 之后继续执行,但是 setUp 比较慢,耗时也就长了,不晓得有没有什么其他的方式或者思路??

    from appium import webdriver
    import unittest
    import time, os
    from selenium.webdriver.support.ui import WebDriverWait
    import HTMLTestRunner
    
    class FooAssertTest(unittest.TestCase):
    
        @classmethod
        def setUp(self):
            os.system("adb shell input keyevent 26")
            os.system("adb shell input keyevent 3")
    
            desired_caps = {}
            desired_caps['platformName'] = 'Android'
            desired_caps['platformVersion'] = '9'   #Pixel 2
            desired_caps['deviceName'] = 'FA7971A04040'    #Pixel 2
            desired_caps['appPackage'] = 'com.android.settings'
            desired_caps['appActivity'] = 'com.android.settings.Settings'
            desired_caps['newCommandTimeout'] = '3600'
            self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
    
        def test_case_2(self):
            self.driver.find_element_by_name("已连接的设备").click()
            self.driver.find_element_by_android_uiautomator('new UiSelector().text("连接偏好设置")').click()
            self.driver.find_element_by_name("蓝牙").click()
            bt = self.driver.find_element_by_id("com.android.settings:id/switch_widget").get_attribute('checked')
            print("蓝牙当前状态:" + bt + '\n')
            try:
                self.assertEqual(bt, 'true', "BT当前处于未开启状态")
            except:
                raise
            finally:
                print("test_case_2 ....................")
                time.sleep(3)
                os.system('adb shell input keyevent 4')
                os.system('adb shell input keyevent 4')
                os.system('adb shell input keyevent 4')
    
        def test_case_3(self):
            self.driver.find_element_by_name("网络和互联网").click()
            self.driver.find_element_by_android_uiautomator('new UiSelector().text("WLAN")').click()
            wifi = self.driver.find_element_by_id("com.android.settings:id/switch_widget").get_attribute('checked')
            print("wifi当前状态: " + wifi + '\n')
            try:
                self.assertEqual(wifi,'true', "WiFi当前处于未开启状态")
            except:
                raise
            finally:
                print("test_case_3 ********************")
                time.sleep(3)
                os.system('adb shell input keyevent 4 && adb shell input keyevent 4')
    
        def test_case_1(self):
            self.driver.find_element_by_name("网络和互联网").click()
            textFly = self.driver.find_element_by_id("android:id/switch_widget").get_attribute("text")
            print("是否处于飞行模式:" + textFly + '\n')
            try:
                self.assertEqual(textFly, '关闭', "飞行模式当前处于开启状态")
            except:
                raise
            finally:
                print("test_case_1 --------------------")
                time.sleep(3)
                os.system('adb shell input keyevent 4')
    
        @classmethod
        def tearDown(self):
            self.driver.keyevent(26)
            self.driver.quit()
    
    
    if __name__ == '__main__':
        suite = unittest.TestSuite()
        suite.addTest(FooAssertTest("test_case_3"))
        suite.addTest(FooAssertTest("test_case_1"))
        suite.addTest(FooAssertTest("test_case_2"))
    
        timestr = time.strftime('%Y-%m-%d-%H%M%S', time.localtime(time.time())) 
        filename = timestr+'.html'
        fp = open(filename,'wb') 
        runner = HTMLTestRunner.HTMLTestRunner(
            stream = fp,
            title = 'Cody Test Demo',
            description = '测试报告'
            )
        runner.run(suite)
        fp.close()
    
  • 这两天搞了一下,之前用的是类对象(@classmethod),一个类里面三条方法都是同一个对象,如果第一个断言抛出异常,则程序结束;
    去掉了装饰器,就可以实现预期效果,但是三条方法,每条执行之前都要初始化,初始化太慢了。。。。。。

    还有没有好的方法??

  • 请问 接电话 有什么方式吗?这个红米手机获取不到接电话这个按钮的元素,坐标也没有效果

  • 这个是红米手机,不知道为啥坐标没反应,元素也获取不到😂

  • 这个是之前几个 demo 复制黏贴出来的。。。。犯了个错误。。。。已经改好了。。。。

  • 问题解决了。

    原因就是 Pixel2(android 9)上没有完整安装 uiautomator2 的相关 apk。按照上一条帖子中查询出的 apk 结果,删除 io.appium.uiautomator2.server(因为手机上只有这一个 apk)。然后重新打开 appium,执行脚本,发现可以正常执行。查询 apk 是完整的。

    步骤:

    1. adb uninstall io.appium.uiautomator2.server # 删除手机中的 uiautomator2 的 apk
    2. 打开 Appium, 重新执行脚本;此时可以正常执行
    3. 再次查询手机中的 apk 是否完整,和上面帖子中的查询结果相比,此次是完整安装:

    此外,也可以在步骤 1 之后加入一步自动安装环境的指令:python -m uiautomator2 init
    然后再执行后面的步骤即可。

  • 考虑到同一台电脑和代码,Pixel 2XL (android 10) 上就可以正常运行;在 Pixel 2 (android 9) 上就报错。问题可能出现在手机上,查询一下安装的 uiautomator2 的相关 package,结果如下图所示,上面的是报错的 Pixel 2 (android 9) ,下面的是正常的 Pixel 2XL (android 10) ,基于此,问题可能出现在没有在手机上正确安装 uiautomator 相关文件。。。

  • 将 platform-tools 从 29.0.6 替换为 28.0.3 之后,执行脚本结果是一样的;Pixel 2XL (android 10) 上就可以正常运行;在 Pixel 2 (android 9) 上报与之前相同的错误;仍然无法执行,再看看还有什么方案。。。

  • 我遇到了同样的问题,使用 uiautomator2,name 就定位不到,后来改成了 driver.find_element_by_android_uiautomator('new UiSelector().text("xxxx")') 就可以正常定位了,建议还是用 android_uiautomator 的方式定位比较好