Appium编写脚本中的那些事

官方文档地址:http://appium.io/docs/en/about-appium/intro/

一、常用的元素定位方式

元素定位的官方文档

find_element_by_id  (resource-id)

find_element_by_accessibility_id  (content-desc)

find_element_by_xpath

find_element_by_android_uiautomator

关键的Attribute:resource-id,content-desc,text,bounds,clickable

常用 XPath 相对定位表达式:

二、常用自动化动作支持

click

sendkeys

swipe

touch action

 

 三、capability设置

automationName 默认使⽤用 uiautomator

autoGrantPermissions ⾃自动赋予 App 权限

noReset fullReset 是否在测试前后重置相关环境

unicodeKeyBoard resetKeyBoard 是否需要输入非英文之外的语言并在测试完成后重置输入法

四、appium设备交互api

 发短信,打电话

APP处理:get_performance_data 获取CPU,内存,电量,网络数据

五、等待

1、隐式等待:服务端(Appium)会在特定的超时时间内重试多次寻找控件 

self.driver.implicitly_wait(20)

2、显式等待:在客户端(用例端)根据更灵活的条件循环等待条件满足

from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait

#第一种情况使用lambda函数,如果未发现定位元素返回自定义的错误信息
kk = WebDriverWait(driver,10).until(lambda driver:driver.find_element_by_id("kw"),message="worry!")
kk.send_keys("测试")

#第二种情况使用len判断返回要查找的元素是否大于等于1,如果大于等于1则执行接下来的代码
WebDriverWait(self.driver,15).until(lambda x:len(self.driver.find_element_by_id("image_cancel"))>=1)
self.driver.find_element_by_id("image_cancel").click()

#第三种情况使用expected_conditions判断元素是否可见,如果可见则执行接下来的代码
WebDriverWait(self.driver,15).until(expected_conditions.visibility_of_element_located((By.ID,"image_cancel")))
self.driver.find_element_by_id("image_cancel").click()

#第四种情况使用自定义函数的形式,灵活度自己掌握
def loaded(driver):
  print(datetime.now())
  if len(self.driver.find_element_by_id("image_cancel"))>=1:
    self.driver.find_element_by_id("image_cancel").click()
    return True
  else:
    return False
WebDriverWait(self.driver, 15).until(loaded)

3、强制等待

time.sleep(20)

 六、Toast识别

toast练习的apk下载地址:https://github.com/appium/java-client/blob/master/src/test/resources/apps/ApiDemos-debug.apk

toast捕获必须使用xpath查找,练习代码示例

     def test_toast(self):
          self.driver.find_element_by_accessibility_id('Views').click()
          self.driver.swipe(350,1000,350,300)    #也可以用uiautomator方式
          self.driver.find_element_by_accessibility_id('Popup Menu').click()
          """
          find_element_by_accessibility_id与find_element(MobileBy.ACCESSIBILITY_ID,"Make a Popup!")等效
          """
          self.driver.find_element_by_accessibility_id('Make a Popup!').click()
          # self.driver.find_element(MobileBy.ACCESSIBILITY_ID,"Make a Popup!").click()
          
          self.driver.find_element_by_xpath('//*[@text="Search"]').click()
          # self.driver.find_element(MobileBy.XPATH,'//*[@text="Search"]').click()
          
          #toast第一种识别方法,用class
          # print(self.driver.find_element_by_xpath("//*[@class='android.widget.Toast']").text)
          #toast第二种识别方法,用text文本
          print(self.driver.find_element_by_xpath("//*[contains(@text,'Clicked popup menu item Search')]").text)

七、断言

元素查找:find_elements

元素属性:get_attribute

 1 from appium import webdriver
 2 import time
 3 from unittest import TestCase
 4 from hamcrest import *
 5 
 6 class TestDemo(TestCase):
 7     def setUp(self):
 8         caps = {}
 9         caps["platformName"] = "Android"
10         caps["deviceName"] = "Android Emulator"
11         caps["appPackage"] = "com.xxxx.android"
12         caps["appActivity"] = ".view.WelcomeActivityAlias"
13         caps["autoGrantPermissions"] = "true"
14 
15         self.driver = webdriver.Remote("http://localhost:4723/wd/hub", caps)
16         self.driver.implicitly_wait(20)
17         #打开APP首页时同意内容
18         el2 = self.driver.find_element_by_id("com.xxxx.android:id/tv_agree")
19         el2.click()
20         
21     def test_search(self):
22         el3 = self.driver.find_element_by_id("com.xxxx.android:id/home_search")
23         el3.click()
24         el4 = self.driver.find_element_by_id("com.xxxx.android:id/search_input_text")
25         el4.send_keys("拼多多")
26         self.driver.find_element_by_id('name').click()
27         price = self.driver.find_element_by_id("current_price")
28         #断言拼多多的股价是否大于68.5元
29         assert float(price.text) > 68.5
30         #断言price的元素属性resource-id是否为price
31         assert "price" in price.get_attribute("resource-id")
32         #hamcrest方式断言price元素属性的package包名是否为xueqiu.android
33         assert_that(price.get_attribute("package"),equal_to("com.xxxx.android"))
34 
35     def tearDown(self):
36         time.sleep(3)
37         self.driver.quit()

八、参数化与数据驱动

1、利用pytest进行简单的参数化

pytest和unittest编写上的两点不同:1、类名中是否写TestCase;2、pytest中setup和teardown是小写,而unittest中是大写

 1 import pytest,time
 2 from appium import webdriver
 3 
 4 class TestDemo():
 5     def setup(self):
 6         caps = {}
 7         caps["platformName"] = "Android"
 8         caps["deviceName"] = "Android Emulator"
 9         caps["appPackage"] = "com.xxxx.android"
10         caps["appActivity"] = ".view.WelcomeActivityAlias"
11         caps["autoGrantPermissions"] = "true"
12 
13         self.driver = webdriver.Remote("http://localhost:4723/wd/hub", caps)
14         self.driver.implicitly_wait(20)
15         self.driver.find_element_by_id("com.xxxx.android:id/tv_agree").click()
16         
17     #要进行参数化的数据
18     @pytest.mark.parametrize("keyword,expected_price", [
19         ("拼多多", 68.5),
20         ("京东", 49)
21     ])
22     def test_search(self,keyword,expected_price):
23         self.driver.find_element_by_id("com.xxxx.android:id/home_search").click()
24         self.driver.find_element_by_id("com.xxxx.android:id/search_input_text").send_keys(keyword)
25         self.driver.find_element_by_id('name').click()
26         price = self.driver.find_element_by_id("current_price")
27         assert float(price.text) > expected_price
28     
29     def teardown(self):
30         time.sleep(3)
31         self.driver.quit()

2、数据驱动

 search.yaml数据文件及运行代码实现参数化数据读取来自外部文件

1 - [ pdd, 68.5 ]
2 - [ jd, 48 ]
 1 import pytest,time
 2 import yaml
 3 from appium import webdriver
 4 
 5 class TestDemo():
 6     search_data = yaml.safe_load(open("search.yaml",'r'))
 7     print(search_data)
 8     def setup(self):
 9         caps = {}
10         caps["platformName"] = "Android"
11         caps["deviceName"] = "Android Emulator"
12         caps["appPackage"] = "com.xxxx.android"
13         caps["appActivity"] = ".view.WelcomeActivityAlias"
14         caps["autoGrantPermissions"] = "true"
15 
16         self.driver = webdriver.Remote("http://localhost:4723/wd/hub", caps)
17         self.driver.implicitly_wait(20)
18         self.driver.find_element_by_id("com.xxxx.android:id/tv_agree").click()
19         
20     @pytest.mark.parametrize("keyword,expected_price", search_data)
21     def test_search(self,keyword,expected_price):
22         self.driver.find_element_by_id("com.xxxx.android:id/home_search").click()
23         self.driver.find_element_by_id("com.xxxx.android:id/search_input_text").send_keys(keyword)
24         self.driver.find_elements_by_id('name')[0].click()
25         price = self.driver.find_element_by_id("current_price")
26         assert float(price.text) > expected_price
27         
28     def teardown(self):
29         time.sleep(3)
30         self.driver.quit()

testcase.yaml测试步骤读取外部文件

1 - id: home_search
2 - id: search_input_text
3   input: pdd
4 - id: name
5 - id: current_price
6   get: text
 1 import yaml,time
 2 from appium import webdriver
 3 from selenium.webdriver.remote.webdriver import WebDriver
 4 
 5 class TestDemo():
 6     def setup(self):
 7         caps = {}
 8         caps["platformName"] = "Android"
 9         caps["deviceName"] = "Android Emulator"
10         caps["appPackage"] = "com.xxxx.android"
11         caps["appActivity"] = ".view.WelcomeActivityAlias"
12         caps["autoGrantPermissions"] = "true"
13 
14         self.driver = webdriver.Remote("http://localhost:4723/wd/hub", caps)
15         self.driver.implicitly_wait(20)
16         self.driver.find_element_by_id("com.xxxx.android:id/tv_agree").click()
17         
18     def test_search(self):
19         Test_Case("testcase.yaml").run(self.driver)
20         
21     def teardown(self):
22         time.sleep(3)
23         self.driver.quit()
24         
25 class Test_Case:
26     def __init__(self,path):
27         file = open(path,"r")
28         self.steps = yaml.safe_load(file)
29         print("打印出来的yaml文件内容为:",self.steps)
30 
31     def run(self,driver: WebDriver):
32         for step in self.steps:
33             if isinstance(step, dict):
34                 element = None
35                 if "id" in step.keys():
36                     element = driver.find_element_by_id(step["id"])
37                 elif "xpat" in step.keys():
38                     element = driver.find_element_by_xpath(step["xpath"])
39                 else:
40                     print(step.keys())
41 
42                 if "input" in step.keys():
43                     element.send_keys(step["input"])
44                 elif "get" in step.keys():
45                     text = element.get_attribute(step["get"])
46                     print("获取到的文本内容为:", text)
47                 else:
48                     element.click()

 

 
posted @ 2020-05-23 22:30  韩凯1990  阅读(640)  评论(0编辑  收藏  举报