如果页面还没有完全显示出来,进行页面自动化操作的时候,会报找不到元素的错误。
之前的解决方式是通过time.sleep() 暂停来实现等待,这种方式简单粗暴。设置等待多长时间,程序在运行的过程中就会等待这么长时间。
因为自动化本来就是要比手工测试快。通过使用这种方式进行等待,无形中会浪费很多时间。

隐式等待

创建好driver 之后可以设置全局的全局的元素等待时间。比如说设置全局等待10秒,在代码执行的时候,查找元素,最长等待10秒,如果在第3秒的时候能够找到元素,那么剩下的7秒就不再等待。从而提高自动化的执行效率。

使用的语法是在成功创建driver之后,设置最长元素等待时间。

  1. driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub',desired_capabilities=desired_caps)
  2. # 设置全局最长的元素等待时间
  3. driver.implicitly_wait(10)

分别对这个脚本进行运行时间对比。

在使用 time.sleep 运行程序

  1. from appium import webdriver
  2. from appium.webdriver.common.touch_action import TouchAction
  3. import time
  4. desired_caps = {
  5. 'platformName': 'Android', # 测试Android系统
  6. 'platformVersion': '7.1.2', # Android版本 可以在手机的设置中关于手机查看
  7. 'deviceName': '127.0.0.1:62001', # adb devices 命令查看 设置为自己的设备
  8. 'automationName': 'UiAutomator2', # 自动化引擎
  9. 'noReset': True, # 不要重置app的状态
  10. 'fullReset': False, # 不要清理app的缓存数据
  11. 'appPackage':"com.sina.weibo", # 应用的包名
  12. 'appActivity': ".SplashActivity" # 应用的活动页名称
  13. }
  14. start_time = time.perf_counter()
  15. driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub',desired_capabilities=desired_caps)
  16. # 等待页面加载成功
  17. time.sleep(10)
  18. # This sample code uses the Appium python client
  19. # pip install Appium-Python-Client
  20. # Then you can paste this into a file and simply run with Python
  21. el1 = driver.find_element_by_id("com.sina.weibo:id/rightBtn_wrapper")
  22. el1.click()
  23. time.sleep(1)
  24. el2 = driver.find_element_by_accessibility_id("写微博")
  25. el2.click()
  26. # 等待发微博页面加载成功
  27. time.sleep(1)
  28. el3 = driver.find_element_by_id("com.sina.weibo:id/edit_view")
  29. el3.send_keys("Hi 我在使用自动化方式发布微博")
  30. driver.find_element_by_accessibility_id("插入图片").click()
  31. time.sleep(3)
  32. # 选择图片
  33. xpath_img1 = '//*[@resource-id="com.sina.weibo:id/photo_album_gridview"]/android.widget.RelativeLayout[2]'
  34. xpath_img2 = '//*[@resource-id="com.sina.weibo:id/photo_album_gridview"]/android.widget.RelativeLayout[3]'
  35. driver.find_element_by_xpath(xpath_img1).click()
  36. time.sleep(2)
  37. # 选中
  38. driver.find_element_by_id('com.sina.weibo:id/btn_num_check').click()
  39. # 返回上一层
  40. driver.back()
  41. time.sleep(2)
  42. driver.find_element_by_xpath(xpath_img2).click()
  43. time.sleep(1)
  44. driver.find_element_by_id('com.sina.weibo:id/btn_num_check').click()
  45. # 点击下一步
  46. driver.find_element_by_id('com.sina.weibo:id/btn_confirm_edit').click()
  47. time.sleep(1)
  48. driver.find_element_by_id('com.sina.weibo:id/btn_confirm_edit').click()
  49. time.sleep(1)
  50. el4 = driver.find_element_by_accessibility_id("发送")
  51. el4.click()
  52. # TouchAction(driver).press(x=390, y=200).move_to(x=390, y=1323).release().perform()
  53. end_time = time.perf_counter()
  54. print(f'程序执行花费了{end_time-start_time}s')
  55. # driver.quit()

运行完成之后,总共使用了 36s的时间
image.png

使用隐式等待

  1. from appium import webdriver
  2. from appium.webdriver.common.touch_action import TouchAction
  3. import time
  4. desired_caps = {
  5. 'platformName': 'Android', # 测试Android系统
  6. 'platformVersion': '7.1.2', # Android版本 可以在手机的设置中关于手机查看
  7. 'deviceName': '127.0.0.1:62001', # adb devices 命令查看 设置为自己的设备
  8. 'automationName': 'UiAutomator2', # 自动化引擎
  9. 'noReset': True, # 不要重置app的状态
  10. 'fullReset': False, # 不要清理app的缓存数据
  11. 'appPackage':"com.sina.weibo", # 应用的包名
  12. 'appActivity': ".SplashActivity" # 应用的活动页名称
  13. }
  14. start_time = time.perf_counter()
  15. driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub',desired_capabilities=desired_caps)
  16. # 设置全局最长的元素等待时间
  17. driver.implicitly_wait(10)
  18. # This sample code uses the Appium python client
  19. # pip install Appium-Python-Client
  20. # Then you can paste this into a file and simply run with Python
  21. el1 = driver.find_element_by_id("com.sina.weibo:id/rightBtn_wrapper")
  22. el1.click()
  23. el2 = driver.find_element_by_accessibility_id("写微博")
  24. el2.click()
  25. # 等待发微博页面加载成功
  26. el3 = driver.find_element_by_id("com.sina.weibo:id/edit_view")
  27. el3.send_keys("Hi 我在使用自动化方式发布微博")
  28. driver.find_element_by_accessibility_id("插入图片").click()
  29. # 选择图片
  30. xpath_img1 = '//*[@resource-id="com.sina.weibo:id/photo_album_gridview"]/android.widget.RelativeLayout[2]'
  31. xpath_img2 = '//*[@resource-id="com.sina.weibo:id/photo_album_gridview"]/android.widget.RelativeLayout[3]'
  32. driver.find_element_by_xpath(xpath_img1).click()
  33. # 选中
  34. driver.find_element_by_id('com.sina.weibo:id/btn_num_check').click()
  35. # 返回上一层
  36. driver.back()
  37. driver.find_element_by_xpath(xpath_img2).click()
  38. driver.find_element_by_id('com.sina.weibo:id/btn_num_check').click()
  39. # 点击下一步
  40. driver.find_element_by_id('com.sina.weibo:id/btn_confirm_edit').click()
  41. time.sleep(1)
  42. driver.find_element_by_id('com.sina.weibo:id/btn_confirm_edit').click()
  43. el4 = driver.find_element_by_accessibility_id("发送")
  44. el4.click()
  45. # TouchAction(driver).press(x=390, y=200).move_to(x=390, y=1323).release().perform()
  46. end_time = time.perf_counter()
  47. print(f'程序执行花费了{end_time-start_time}s')
  48. # driver.quit()

image.png

显式等待

使用隐式等待,可以针对全局的元素进行设置最长等待时间。优点就是所有的元素等待都会使用最长的等待时间。但是缺点也很明显,假设设置的全局等待时间为10秒。那么如果开发工程师写的脚本中元素定位写错了,那么执行的时候肯定找不到这个元素,那么等待10秒。

显示等待可以设置针对单个元素设置最长等待时间,比如你在做自动化测试的过程中,根据经验某个元素需要等待比较长的时间才能出来,可以针对单个元素设置最长等待时间。其他元素不会受到影响。

  1. from appium import webdriver
  2. from appium.webdriver.common.touch_action import TouchAction
  3. from selenium.webdriver.support.wait import WebDriverWait
  4. import selenium.webdriver.support.expected_conditions as EC
  5. from selenium.webdriver.common.by import By
  6. import time
  7. desired_caps = {
  8. 'platformName': 'Android', # 测试Android系统
  9. 'platformVersion': '7.1.2', # Android版本 可以在手机的设置中关于手机查看
  10. 'deviceName': '127.0.0.1:62001', # adb devices 命令查看 设置为自己的设备
  11. 'automationName': 'UiAutomator2', # 自动化引擎
  12. 'noReset': True, # 不要重置app的状态
  13. 'fullReset': False, # 不要清理app的缓存数据
  14. 'appPackage':"com.sina.weibo", # 应用的包名
  15. 'appActivity': ".SplashActivity" # 应用的活动页名称
  16. }
  17. # 打开微博
  18. driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub',desired_capabilities=desired_caps)
  19. # 每次打开都有广告加载界面
  20. # 针对单个元素设置最长的等待时间
  21. wait = WebDriverWait(driver,10)
  22. start_time = time.perf_counter()
  23. el1 = wait.until(EC.presence_of_element_located((By.ID,"com.sina.weibo:id/rightBtn_wrapper")))
  24. end_time = time.perf_counter()
  25. print(f'查找元素使用时间: {end_time-start_time}s')
  26. # el1 = driver.find_element_by_id("")
  27. el1.click()