参考: https://appium.io/docs/en/about-appium/intro/

uiselector 元素定位:https://developer.android.google.cn/reference/androidx/test/uiautomator/UiSelector?hl=en

添加conftest.py

  1. import pytest
  2. from appium import webdriver
  3. from appium.webdriver.common.touch_action import TouchAction
  4. @pytest.fixture(scope="session",autouse=True)
  5. def driver():
  6. print("在所有的测试用例执行之前创建driver")
  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': "org.cnodejs.android.md", # 应用的包名
  15. 'appActivity': ".ui.activity.MainActivity" # 应用的活动页名称
  16. }
  17. driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_capabilities=desired_caps)
  18. driver.implicitly_wait(5) # 全局的隐式等待时间
  19. yield driver # 将driver 传递出来
  20. print("执行所有的用例执行之后的操作")

滑动操作

image.png
比如 刚下载的客户端,首页加载页面,需要右滑进入app中。
上下滑动,找到滑动的区域。
image.png

通过一个实例 演示向上滑动之后 获取页面中的数据
testcases/test_actions/test_appium.py

  1. from appium.webdriver.webdriver import WebDriver
  2. import time
  3. def test_swipe(driver:WebDriver):
  4. viewgroup = driver.find_element_by_android_uiautomator('new UiSelector().className("android.view.ViewGroup").index(2)')
  5. # 获取元素控件的坐标位置
  6. print('location', viewgroup.location)
  7. print('rect', viewgroup.rect) # {'height': 1440, 'width': 900, 'x': 0, 'y': 160}
  8. while True:
  9. # 向上滑动
  10. driver.swipe(start_x=1,start_y=viewgroup.rect['height']+viewgroup.rect['y']-1,
  11. end_x=1,end_y=viewgroup.rect['y']-1,duration=1200)
  12. time.sleep(1.5)
  13. eles = driver.find_elements_by_id('org.cnodejs.android.md:id/tv_title')
  14. for ele in eles:
  15. print(ele.text)

大家思考 如何实现 向右,向左,向下滑动。

滑动定位元素

image.png
要从滑动列表中定位 helloworld,但是不知道要滑动多少次才能找到。
使用下面的方法:

  1. # testcases/test_actions/test_appium.py
  2. from appium.webdriver.webdriver import WebDriver
  3. import time
  4. def test_swipe(driver:WebDriver):
  5. viewgroup = driver.find_element_by_android_uiautomator('new UiSelector().className("android.view.ViewGroup").index(2)')
  6. # 获取元素控件的坐标位置
  7. print('location', viewgroup.location)
  8. print('rect', viewgroup.rect) # {'height': 1440, 'width': 900, 'x': 0, 'y': 160}
  9. flag = False
  10. while True:
  11. # 向上滑动
  12. driver.swipe(start_x=1,start_y=viewgroup.rect['height']+viewgroup.rect['y']-1,
  13. end_x=1,end_y=viewgroup.rect['y']-1,duration=1200)
  14. time.sleep(1.5)
  15. eles = driver.find_elements_by_id('org.cnodejs.android.md:id/tv_title')
  16. for ele in eles:
  17. print(ele.text)
  18. if ele.text == "helloworld":
  19. ele.click()
  20. flag = True
  21. break
  22. if flag == True:
  23. break #中断while 循环

使用这种方法必须要精准的控制滑动速度,否则滑动过快,可能会错过目标元素。

https://appium.io/docs/en/writing-running-appium/android/uiautomator-uiselector/

  1. # testcases\test_actions\test_appium.py
  2. from appium.webdriver.webdriver import WebDriver
  3. import time
  4. def test_swipe(driver:WebDriver):
  5. viewgroup = driver.find_element_by_android_uiautomator('new UiSelector().className("android.view.ViewGroup").index(2)')
  6. # 获取元素控件的坐标位置
  7. print('location', viewgroup.location)
  8. print('rect', viewgroup.rect) # {'height': 1440, 'width': 900, 'x': 0, 'y': 160}
  9. flag = False
  10. while True:
  11. # 向上滑动
  12. driver.swipe(start_x=1,start_y=viewgroup.rect['height']+viewgroup.rect['y']-1,
  13. end_x=1,end_y=viewgroup.rect['y']-1,duration=1200)
  14. time.sleep(1.5)
  15. eles = driver.find_elements_by_id('org.cnodejs.android.md:id/tv_title')
  16. for ele in eles:
  17. print(ele.text)
  18. if ele.text == "helloworld":
  19. ele.click()
  20. flag = True
  21. break
  22. if flag == True:
  23. break #中断while 循环
  24. def test_swipe_by_text(driver:WebDriver):
  25. ele = driver.find_element_by_android_uiautomator('new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().text("Jenkins持续集成测试-2").instance(0));')
  26. ele.click()

运行

  1. (venv) C:\Users\zengy\PycharmProjects\apptesting>pytest testcases\test_actions\test_appium.py::test_swipe_by_text -s -v

::test_swipe_by_text 指定运行测试函数

webview 元素定位选取

混合app中会使用到原生组件以及webview 视图。webview 中嵌套网页。

准备环境

  • Edge 浏览器 或 Chrome浏览器(需要翻墙)
  1. 在浏览器的地址栏中输入 edge://inspect/#devices
  2. 在模拟器的 浏览器中打开网址

image.png

点击 【inspect】可以打开界面
image.png

app中如果需要 调试 webview 页面,需要开发在测试版本中的app 进行配置
https://developer.chrome.com/docs/devtools/remote-debugging/webviews/
需要在 app 中添加配置

  1. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
  2. WebView.setWebContentsDebuggingEnabled(true);
  3. }

打包后的apk文件
app-release.zip

webview 调试

打开话题详情页面
在浏览器中可以识别到整个页面 (如果识别不到,重启下 模拟器试试)
image.png

  • 75.0.3770.143 手机渲染webview 视图的Chrome内核版本。

image.png

下载chromedriver

根据在浏览器中看到 手机端使用的Chrome版本下载对应的驱动。
下载 https://npm.taobao.org/mirrors/chromedriver/
image.png

配置代码

因为要使用到webview 进行切换。需要指定 chromedirver
image.png
conftest.py 文件中添加 ChromeDriver的配置

  1. import pytest
  2. from appium import webdriver
  3. from appium.webdriver.common.touch_action import TouchAction
  4. import os
  5. chromedriver= os.path.join(os.path.dirname(os.path.abspath(__file__)),'drivers/chromedriver.exe')
  6. @pytest.fixture(scope="session",autouse=True)
  7. def driver():
  8. print("在所有的测试用例执行之前创建driver")
  9. desired_caps = {
  10. 'platformName': 'Android', # 测试Android系统
  11. 'platformVersion': '7.1.2', # Android版本 可以在手机的设置中关于手机查看
  12. 'deviceName': '127.0.0.1:62001', # adb devices 命令查看 设置为自己的设备
  13. 'automationName': 'UiAutomator2', # 自动化引擎
  14. 'noReset': True, # 不要重置app的状态
  15. 'fullReset': False, # 不要清理app的缓存数据
  16. 'chromedriverExecutable': chromedriver, # chromedriver 对应的绝对路径
  17. 'appPackage': "org.cnodejs.android.md", # 应用的包名
  18. 'appActivity': ".ui.activity.MainActivity" # 应用的活动页名称
  19. }
  20. driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_capabilities=desired_caps)
  21. driver.implicitly_wait(5) # 全局的隐式等待时间
  22. yield driver # 将driver 传递出来
  23. print("执行所有的用例执行之后的操作")

image.png

编写自动化代码

  1. # testcases/test_actions/test_appium.py
  2. from appium.webdriver.webdriver import WebDriver
  3. import time
  4. from selenium.webdriver.support.wait import WebDriverWait
  5. import selenium.webdriver.support.expected_conditions as EC
  6. from selenium.webdriver.common.by import By
  7. def test_swipe(driver:WebDriver):
  8. viewgroup = driver.find_element_by_android_uiautomator('new UiSelector().className("android.view.ViewGroup").index(2)')
  9. # 获取元素控件的坐标位置
  10. print('location', viewgroup.location)
  11. print('rect', viewgroup.rect) # {'height': 1440, 'width': 900, 'x': 0, 'y': 160}
  12. flag = False
  13. while True:
  14. # 向上滑动
  15. driver.swipe(start_x=1,start_y=viewgroup.rect['height']+viewgroup.rect['y']-1,
  16. end_x=1,end_y=viewgroup.rect['y']-1,duration=1200)
  17. time.sleep(1.5)
  18. eles = driver.find_elements_by_id('org.cnodejs.android.md:id/tv_title')
  19. for ele in eles:
  20. print(ele.text)
  21. if ele.text == "helloworld":
  22. ele.click()
  23. flag = True
  24. break
  25. if flag == True:
  26. break #中断while 循环
  27. def test_swipe_by_text(driver:WebDriver):
  28. ele = driver.find_element_by_android_uiautomator('new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().text("Jenkins持续集成测试-2").instance(0));')
  29. ele.click()
  30. def test_webview(driver:WebDriver):
  31. driver.find_element_by_id('org.cnodejs.android.md:id/tv_title').click()
  32. # 等待webview 加载出来
  33. wait = WebDriverWait(driver,5)
  34. wait.until(EC.presence_of_element_located((By.CLASS_NAME,'android.webkit.WebView')))
  35. # 切换视图
  36. # 获取所有的视图
  37. contexts = driver.contexts
  38. print(contexts) # ['NATIVE_APP', 'WEBVIEW_org.cnodejs.android.md']
  39. # 切换到浏览器视图中
  40. driver.switch_to.context(contexts[-1])
  41. # 可以使用浏览器的元素定位
  42. driver.find_element_by_xpath('//td[@class="right"]/img').click()
  43. # 再次从webview中切换回原生控件中
  44. driver.switch_to.context(contexts[0])
  45. driver.find_element_by_android_uiautomator('new UiSelector().className("android.widget.Button").text("登录")').click()

运行

  1. (venv) C:\Users\zengy\PycharmProjects\apptesting>pytest testcases\test_actions\test_appium.py::test_webview -s -v