pytest+selenium+allure Marco simple de automatización de Webui
- introducir
-
- Arquitectura de software
- Instalación de dependencia
- Estructura de directorios
- demostración en el expediente
- formato de archivo yml
- paquete de controladores web
- decorador de funciones
- método init_data para leer diferentes archivos de parámetros
- Encapsulación y configuración de registros de registradores
- read_data reescribe configparser para resolver la transcodificación
- operación inicial de la página web y métodos públicos
- run_test define elementos y comandos de inicio
- Connftest define el controlador global
- ejecutar archivo de entrada
introducir
Marco de automatización fácil.
Arquitectura de software
pytest5.4.2
selenio3.141.0
encanto_python_commons2.8.29
PyYAML5.4.1
pitón == 3.6.0
Instalación de dependencia
使用 pip install -r requisitos.txt
Estructura de directorios
casodirectorio de archivos de caso
data_case
controladores de parámetros de casowebdriver almacena
libDefinir registro, leer yml,
registros de decorador de tiempoalmacenar
la página del archivo de registro
Informe de encapsulación de métodos funcionalesInforme de almacenamiento
test_run
Defina la clase de inicio e inicie el comando config.ini utilizadoArchivo de configuración
connftest.pyEl uso compartido global utiliza
el archivo run.py==entry
demostración en el expediente
import allure
import pytest
from page.webpage import BasePage
from lib.init_data import get_data
base_data=get_data("demo.yml")
@pytest.mark.usefixtures()
class Test_case():
@pytest.mark.parametrize("uer",base_data['test_id'])
@allure.feature('打开百度登录')
def test_1(self,uer):
d =BasePage()
d.by_id(uer)
assert 1==2```
formato de archivo yml
test_id:
- "s-top-loginbtn我的","id",'我的'
paquete de controladores web
from selenium import webdriver
#封装Chrome启动的driver
def webdrivers():
d = webdriver.Chrome()
return d
webdrivers()
decorador de funciones
import time
#等待时间装饰器
def think_time(func):
def thinktime(*args,**kwargs):
time.sleep(1)
return func(*args,**kwargs)
return thinktime
método init_data para leer diferentes archivos de parámetros
from lib.read_data import data
import os
#对读取测试数据及ini文件的配置
BASE_PATH = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
def get_data(file_name):
data_file_path = os.path.join(BASE_PATH, "data_case", file_name)
if '.yml' in file_name:
test_data = data.load_yaml(data_file_path)
if '.json' in file_name:
test_data = data.load_json(data_file_path)
if '.ini' in file_name:
test_data = data.load_ini(data_file_path)
return test_data
Encapsulación y configuración de registros de registradores
import os, time
import os.path
import socket
import logging
import logging.handlers
#log日志的配置封装
def singleton(cls, *args, **kw):
instances = {
}
def _singleton():
if cls not in instances:
instances[cls] = cls(*args, **kw)
return instances[cls]
return _singleton
# @singleton
class JFMlogging(object):
def __init__(self):
# host_name = socket.gethostname()
# ip = socket.gethostbyname(host_name)
log_path = 'logs' # 日志存放目录
if not os.path.exists(log_path):
os.mkdir(log_path)
log_file = os.path.join(log_path, "{}.log".format(time.strftime("%Y%m%d")))
self.logger = logging.getLogger()
self.logger.setLevel(logging.INFO)
self.logging_msg_format = '[%(asctime)s] [%(levelname)s] [%(module)s.py-line:%(lineno)d] %(message)s'
self.formater = logging.Formatter(self.logging_msg_format)
self.fileHandler = logging.FileHandler(log_file, mode='a', encoding="UTF-8")
self.fileHandler.setFormatter(self.formater)
self.fileHandler.setLevel(logging.INFO)
self.console = logging.StreamHandler()
self.console.setLevel(logging.INFO)
self.console.setFormatter(self.formater)
self.logger.addHandler(self.fileHandler)
self.logger.addHandler(self.console)
# def getloger(self):
# return self.logger
log = JFMlogging().logger
read_data reescribe configparser para resolver la transcodificación
import yaml
import json
from configparser import ConfigParser
from lib.loggers import log
class MyConfigParser(ConfigParser):
# 重写 configparser 中的 optionxform 函数,解决 .ini 文件中的 键option 自动转为小写的问题
def __init__(self, defaults=None):
ConfigParser.__init__(self, defaults=defaults)
def optionxform(self, optionstr):
return optionstr
class ReadFileData():
def load_yaml(self, file_path):
log.info("加载 {} 文件......".format(file_path))
with open(file_path, encoding='utf-8') as f:
data = yaml.safe_load(f)
log.info("读到数据 ==>> {} ".format(data))
return data
def load_json(self, file_path):
log.info("加载 {} 文件......".format(file_path))
with open(file_path, encoding='utf-8') as f:
data = json.load(f)
log.info("读到数据 ==>> {} ".format(data))
return data
def load_ini(self, file_path):
log.info("加载 {} 文件......".format(file_path))
config = MyConfigParser()
config.read(file_path, encoding="UTF-8")
data = dict(config._sections)
return data
data = ReadFileData()
operación inicial de la página web y métodos públicos
from lib.init_data import get_data
from lib.func import think_time
import os
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
BASE_CONF = get_data(os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), "config.ini"))['App']
class WebPage():
#读取config.ini中的配置
def __init__(self,d):
self.d = d
self.web = BASE_CONF['URL_NAME']
self.time_out = BASE_CONF['WAIT_TIMEOUT']
class BasePage(WebPage):
#初始化
def __init__(self):
self.driver = webdriver.Chrome()
self.wait = WebDriverWait(self.driver,10)
self.driver.maximize_window()
WebPage.__init__(self,self.driver)
self.openBaidu()
def openBaidu(self):
#默认打开百度
self.d.get(self.web)
#————————————————————————————————————封装公共方法——————————————————————————————————————————
def by_id(self,id):
self.d.find_element_by_id(id).click()
def by_class(self,classname):
self.d.find_element_by_class_name(classname).click()
run_test define elementos y comandos de inicio
import pytest
import os
#定义启动项
class RunTest():
def _runpytest(self):
pass
#pytest启动
@staticmethod
def run_alltest():
# # 执行pytest单元测试,生成 Allure 报告需要的数据存在 /temp 目录,使用--clean-alluredir 覆盖之前的json文件
# pytest.main(['-s', '-q','--alluredir', './report','--clean-alluredir'])
# # 执行命令 allure generate ./temp -o ./report --clean ,生成测试报告
# # os.system(" allure generate ./report/result_allure -o ./report/result_html -c")
pytest.main(['-s', '-q', '--alluredir', './report', '--clean-alluredir'])
os.system('allure generate ./report -o ./report/temp --clean')
Connftest define el controlador global
import pytest
import drivers.webdriver
from lib.loggers import log
#初始化全局 driver
@pytest.fixture(scope='class',autouse=True)
def driver():
try:
global driver
driver =drivers.webdriver.webdrivers()
return driver
except Exception as e:
log.info('初始化webdriver{}'.format(e))
ejecutar archivo de entrada
from test_run import run_test
#入口文件
class startest(run_test.RunTest):
import time
test_data = time
if __name__ == '__main__':
startest.run_alltest()
También es una etapa de aprendizaje para usarlo en el trabajo. El maestro le dará consejos después de leerlo. Si no le gusta, no lo rocíe. ¡Es solo un pequeño registro personal! ! !
Código fuente: https://gitee.com/zc119/web-ui.git