APP测试项目scripts,page,base中driver的传递过程
在PO模式之前,脚本只写一个test_*****.py的文件。这样写的缺点是所有代码在一个文件中,另一个文件对同一个操作再写一遍。并且代码量特别大。所以多文件区分PO模式应运而生。这样修改不同的功能,只要找到对应的文件即可,代码也变的轻便,易于理解。
创建一个测试项目,里面有base文件夹,scripts文件夹,page文件夹,report文件夹, pytest.ini文件。这些是并列关系。以电话本的测试为例:
page目录中的文件命名格式,举例在addPerson_page.py这个文件中创建一个类AddPersonPage,它需要继承BaseAction,所以AddPersonPage具有了BaseAction类定义的方法。比如def click(self, loc) def input(self, loc, text).这些方法。在page页面中,定义的方法名为click_toast,意思是点击toast弹窗。click_creat_people是点击创建联系人,方法名是你操作手机页面的按钮,文本框的动作和其命名。这样便于你理解这个方法是干什么的。方法内容是self. + BaseAction的方法 + (self. + 元素的定位方式, +phone_num(如果有参数,比如输入框需要输入数字,))
addPerson_page.py文件代码
import os, sys
sys.path.append(os.getcwd())
from selenium.webdriver.common.by import By
from base.base_action import BaseAction
class AddPersonPage(BaseAction):
toast_right_button = By.ID, 'com.android.contacts:id/left_button'
create_people_button = By.ID, 'com.android.contacts:id/floating_action_button'
# name_button和tel_button索引不一样
name_button = By.XPATH, "//*[contains(@text,'姓名')]"
phone_button = By.XPATH, "//*[contains(@text,'电话')]"
email_button = By.XPATH, "//*[contains(@text,'电子邮件')]"
save_button = By.ID, 'com.android.contacts:id/menu_save'
def __init__(self, driver):
BaseAction.__init__(self, driver)
def click_toast(self):
self.click(self.toast_right_button)
def click_creat_people(self):
# find_element_by_(括号里是具体的值),然后click.就写成 self.click(self.**)
self.click(self.create_people_button)
def input_name(self, name):
self.input(self.name_button, name)
def input_phone(self, phone_num):
self.input(self.phone_button, phone_num)
def input_email(self, email):
self.input(self.email_button, email)
def click_save_button(self):
self.click(self.save_button)
test_addPerson.py代码如下:
import os, sys
sys.path.append(os.getcwd())
from page.addPerson_page import AddPersonPage
from base.base_driver import BaseDriver
import time
class TestAddPerson:
def setup(self):
baseDriver = BaseDriver()
driver = baseDriver.create_driver()
self.addPerson = AddPersonPage(driver)
#添加联系人的方法
def test_add_person(self):
self.addPerson.click_creat_people()
self.addPerson.click_toast()
self.addPerson.input_name('ami')
self.addPerson.input_phone(12345678999)
self.addPerson.input_email('123@qq.com')
self.addPerson.click_save_button()
base_action.py
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
class BaseAction:
def __init__(self, driver):
self.driver = driver
def click(self,loc):
self.custom_find_element(loc).click()
def input(self, loc, text):
ele = self.custom_find_element(loc)
ele.click()
ele.send_keys(text)
#自定义查找元素的方法
def custom_find_element(self, loc, time=10, poll=1):
return WebDriverWait(self.driver, time, poll).until(lambda x:x.find_element(loc[0], loc[1]))
#通过元素的id和元素的下标,查找并返回该元素
def custom_find_ele_ById_And_index(self, loc, eleIndex):
list = self.driver.find_elements(By.ID,loc[1])
return list[eleIndex]
# 通过元素的id和元素的内容,查找并返回一个元素
def custom_find_ele_ById_And_content(self, loc, content):
list = self.driver.find_elements(By.ID,loc[1])
for i in list:
if i.get_attribute('text') == content:
return i
base_driver.py代码如下:
from appium import webdriver
class BaseDriver:
def create_driver(self):
desired_caps = {}
# 设备信息
desired_caps['platformName'] = 'Android'
desired_caps['platformVersion'] = '6.0'
desired_caps['deviceName'] = 'emulator-5554'
# app的信息 com.android.contacts
desired_caps['appPackage'] = 'com.android.contacts'
desired_caps['appActivity'] = '.activities.PeopleActivity'
# 解决输入中文
desired_caps['unicodeKeyboard'] = True
desired_caps['resetKeyboard'] = True
# 声明我们的driver对象
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps)
return driver
总结:
base_driver.py文件返回了一个driver. 供test_addPerson.py文件使用。
分离之后,scripts把driver给page, page再给base_action.把driver传给谁,谁就需要重写init方法。再通过init方法传init(self, driver)
变量=方法 其中变量分为全局变量和局部变量。全局变量,供本文件中的所有方法调用,特点是变量前加self. 局部变量在本方法执行完后就消失。
一个类,在创建对象时,就会调用自身的init方法。