一、
(1)、创建autotest_app项目
(2)、封装元素的各类操作
pip install selenium
pip install Appium-Python-Client
basepage.py
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from appium.webdriver.common.mobileby import MobileBy
from common.logger import Log
import datetime
class BasePage:
def __init__(self,driver):
self.driver = driver
self.logger =Log()
#等待元素可见
def wait_eleVisible(self,locator,by=MobileBy.ID,wait=30,requence=0.5):
try:
start = datetime.datetime.now()
WebDriverWait(self.driver,wait,requence).until(EC.visibility_of_element_located((by, locator)))
end = datetime.datetime.now()
wait_times = (end - start).seconds
self.logger.info("等待元素可见:{0},起始时间:{1},等待时长:{2}".format(locator,start,wait_times))
except Exception as e:
self.logger.error("等待元素可见异常{0}".format(e))
raise
#等待元素存在
def wait_elePrences(self, locator, by=MobileBy.ID,wait=30, requence=0.5):
try:
start = datetime.datetime.now()
WebDriverWait(self.driver, wait, requence).until(EC.presence_of_element_located((by, locator)))
end = datetime.datetime.now()
wait_times = (end - start).seconds
self.logger.info("等待元素存在:{0},起始时间:{1},等待时长:{2}".format(locator, start, wait_times))
except Exception as e:
self.logger.error("查看元素可见异常{0}".format(e))
raise
#查找元素
def find_element(self, locator, by=MobileBy.ID):
self.logger.info("开始查找元素:{0}={1}".format(by, locator))
try:
return self.driver.find_element(by, locator)
except Exception as e:
self.logger.error("元素查找不到{0}".format(e))
raise
#智能查找元素
def find_element_wait_and_focus(self, locator, wait_ele, by=MobileBy.ID, wait=30,
requence=0.5, index=None):
# 查找元素
self.logger.info("开始查找元素:{0}={1}".format(by, locator))
# 等待元素
if wait_ele == 'visibility':
self.wait_eleVisible(locator, by, wait,requence)
else:
self.wait_elePrences(locator, by, wait,requence)
try:
return self.driver.find_element(by, locator)
except Exception as e:
self.logger.error("元素查找不到{0}".format(e))
raise
#查的多个元素
def find_elements(self, locator, by=MobileBy.ID):
self.logger.info("开始查找符合表达式的所有元素:{0}={1}".format(by, locator))
try:
return self.driver.find_elements(by, locator)
except Exception as e:
self.logger.error("元素查找不到{0}".format(e))
raise
#元素的点击操作。
def click_element(self,locator,wait_ele='visibility',by=MobileBy.ID,wait=30, requence=0.5,index=None):
ele = self.find_element_wait_and_focus(locator, wait_ele, by, wait,
requence, index)
try:
self.logger.info("对元素{0}进行点击操作。".format(locator))
ele.click()
except Exception as e:
self.logger.error("元素点击操作失败{0}".format(e))
raise
#元素的输入操作
def input_text(self,value,locator,by=MobileBy.ID,wait=30,requence=0.5,wait_ele='visibility',index=None):
ele = self.find_element_wait_and_focus(locator, wait_ele, by, wait,requence, index)
try:
self.logger.info("在元素:{0}={1}中输入内容:{2}".format(by, locator, value))
ele.clear()
ele.send_keys(value)
except Exception as e:
self.logger.error("元素输入操作失败{0}".format(e))
raise
#获取元素的属性值。
def get_element_attribube(self,attr_name,locator,by=MobileBy.ID,wait=30,requence=0.5,
wait_ele='visibility',index=None):
ele = self.find_element_wait_and_focus(locator, wait_ele, by, wait,requence, index)
try:
self.logger.info("获取元素{0}={1} 的属性值:{2}。".format(by, locator, attr_name))
return ele.get_attribute(attr_name)
except Exception as e:
self.logger.error("获取元素属性失败{0}".format(e))
raise
#获取元素的文本内容
def get_text(self,locator,by=MobileBy.ID,wait=30,requence=0.5,wait_ele='visibility',index=None):
ele = self.find_element_wait_and_focus(locator, wait_ele, by, wait,requence, index)
try:
self.logger.info("获取元素{0}={1} 的文本内容。".format(by, locator))
return ele.text
except Exception as e:
self.logger.error("获取元素文本内容失败{0}".format(e))
raise
#确定要操作的元素 - 查找多个和查找单个。确定元素操作对象。
def _get_element(self,locator,by,index=None):
if index is not None:
# 在查找到多个元素的基础之上,随机选择其中的一个。
import random
eles = self.find_elements(locator, by)
if index == -1 or index < 0:
pos = random.randint(0, len(eles) - 1)
return eles[pos]
else:
return eles[index]
else:
return self.find_element(locator, by)
import logging, time
import os,sys
# log_path是存放日志的路径
cur_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))))
log_path = os.path.join(os.path.dirname(cur_path), 'logs/autotest_app/api')
# 如果不存在这个logs文件夹,就自动创建一个
if not os.path.exists(log_path):os.makedirs(log_path)
class Log():
def __init__(self):
# 文件的命名
self.logname = os.path.join(log_path, '%s.log' % ('api_'+ time.strftime('%Y_%m_%d')))
self.logger = logging.getLogger()
self.logger.setLevel(logging.DEBUG)
# 日志输出格式
self.formatter = logging.Formatter('[%(asctime)s] - %(filename)s] - %(levelname)s: %(message)s')
def __console(self, level, message):
# 创建一个FileHandler,用于写到本地
fh = logging.FileHandler(self.logname, 'a', encoding='utf-8')
fh.setLevel(logging.DEBUG)
fh.setFormatter(self.formatter)
self.logger.addHandler(fh)
# 创建一个StreamHandler,用于输出到控制台
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
ch.setFormatter(self.formatter)
self.logger.addHandler(ch)
# 创建一个StreamHandler,用于输出到stdout
ch2 = logging.StreamHandler(sys.stdout)
ch2.setLevel(logging.DEBUG)
ch2.setFormatter(self.formatter)
self.logger.addHandler(ch2)
if level == 'info':
self.logger.info(message)
elif level == 'debug':
self.logger.debug(message)
elif level == 'warning':
self.logger.warning(message)
elif level == 'error':
self.logger.error(message)
# 这两行代码是为了避免日志输出重复问题
self.logger.removeHandler(ch)
self.logger.removeHandler(fh)
self.logger.removeHandler(ch2)
# 关闭打开的文件
fh.close()
def debug(self, message):
self.__console('debug', message)
def info(self, message):
self.__console('info', message)
def warning(self, message):
self.__console('warning', message)
def error(self, message):
self.__console('error', message)
if __name__ == "__main__":
log = Log()
log.info("---测试开始----")
log.info("操作步骤1,2,3")
log.warning("----测试结束----")
3、运行第一个测试用例
pip install pytest
(1) 、创建test_suitest存放测试用例
(2)、创建page_obj 独立分离每个页面的操作
(3)、创建page_lct存放页面元素
login_lct.py
#用户名
user_name = 'xyz.nesting.intbee:id/phoneNumEt'
#密码
pwd = 'xyz.nesting.intbee:id/password'
#登录按钮
button = 'xyz.nesting.intbee:id/submitBtn'
login_page.py
from page_lct import login_lct
from common.basepage import BasePage
class LoginPage(BasePage):
def login(self, username, password):
# 输入用户名
self.input_text(username, login_lct.user_name)
# 输入密码
self.input_text(password, login_lct.pwd)
# 点击登录按钮
self.click_element(login_lct.button)
-------
test_login.py
import pytest
import logging
from page_obj.login_page import LoginPage
class TestLogin:
@pytest.mark.smoke
def test_login_success(self, app_page):
'''成功登录'''
# 步骤
LoginPage(app_page).login('xxxxxxx', 'xxxxxx')
logging.info("开始断言")
conftest.py
import pytest, os
from selenium import webdriver
from appium import webdriver
import logging
cur_path = os.path.dirname(os.path.realpath(__file__))
@pytest.fixture()
def app_page():
logging.info('----------------测试开始-----------------')
desired_caps = {}
desired_caps['platformName'] = 'Android'
desired_caps['platformVersion'] = '8.1.0'
desired_caps['deviceName'] = 'xxxxxx'
desired_caps['appPackage'] = 'xxxx'
desired_caps['appActivity'] = 'xxxxxx'
desired_caps['autoGrantPermissions'] = True
desired_caps['automationName'] = 'uiautomator2'
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps)
yield driver
logging.info('----------------测试结束-----------------')
driver.quit()
main.py
import pytest, time, os
cur_path = os.path.dirname(os.path.realpath(__file__))
now = time.strftime("%Y-%m-%d")
report_file = 'report/'+now+'_test_result.html'
pytest.main(['test_suites/test_login.py'])
运行main.py程序,成功执行测试用例