pytest和Allure搭建自动化测试平台

目录

概述

1 安装环境

1.1 安装Python

 1.1.1 python的下载

 1.1.2 安装Python

1.2  Allure安装

1.2.1 下载软件包

1.2.2 配置Allure  

1.3 pytest架构相关的packet安装

2 Auto test 框架

2.1 代码架构

2.2  conftest.py 文件介绍

2.3 编写case文件

 2.4 运行脚本文件: run.common.sh

3 运行case

3.1 执行case 

3.2 查看report


概述

本文介绍了Python自动化测试环境的搭建及测试框架的使用方法。主要内容包括:1. 环境准备:下载安装Python(建议3.11以下版本)、Allure测试报告框架及Java虚拟机,并配置相关环境变量;2. 测试框架结构:详细说明了代码目录结构(conf、libs、script、test_case等)和关键文件(conftest.py、run_test_01_demo.sh);3. 测试用例编写:展示了一个包含3个测试用例的示例代码,说明了测试初始化和清理操作;4. 测试执行:介绍了通过shell脚本运行测试并生成Allure和pytest两种格式的测试报告。文章通过具体代码示例,完整呈现了从环境搭建到测试执行的自动化测试流程。

1 安装环境

1.1 安装Python

 1.1.1 python的下载

https://www.python.org/

可以选择如下版本,高版本目前处于评测阶段

Windows环境下的下载地址:建议选择下载3.11以下的版本

https://www.python.org/downloads/windows/

 

 1.1.2 安装Python

下载完成后,点击安装包,安装软件。建议选择如下安装方式。

配置安装参数:

安装完成后,检查环境配置参数:

安装完成后,在powershell中验证python是否安装完毕:

1) 使用如下命令,检测python版本

python --version

 

2) 直接敲击python:

python

1.2  Allure安装

1.2.1 下载软件包

1)下载allure,下载地址如下:

https://github.com/allure-framework/allure2/releases

2)安装java虚拟机,下载地址:

https://www.oracle.com/cn/java/technologies/downloads/#jdk24-windows

1.2.2 配置Allure  

下载完成allure包后,解压该文件

配置其环境变量:

在powershell环境下验证allure的功能,在控制台输入如下命令:

allure

控制台显示如下信息说明,allure安装成功。 

1.3 pytest架构相关的packet安装

在控制台输入如下命令,在进行安装python的第三方packet之前,首先执行如下命令:

python -m pip install --upgrade pip

然后使用如下命令安装packet:

pip install xxxx

查询系统用安装的packet

 pip list
Package               Version
--------------------- -------
allure-pytest         2.14.2
allure-python-commons 2.14.2
attrs                 25.3.0
colorama              0.4.6
coloredlogs           15.0.1
exceptiongroup        1.3.0
humanfriendly         10.0
iniconfig             2.1.0
packaging             25.0
pip                   25.1.1
pluggy                1.6.0
pyreadline3           3.5.4
pytest                8.3.5
PyYAML                6.0.2
setuptools            58.1.0
tomli                 2.2.1
typing_extensions     4.13.2

2 Auto test 框架

2.1 代码架构

conf目录:    配置参数,使用.yml或者.ini文件格式

libs目录:      和项目相关的功能库代码

script目录:   操作case相关的脚本文件,文件格式为.sh

test_case目录:  case相关的代码,用于编写case代码 

conftest.py:       系统入口文件,用于初始化设备和加载参数 

run_test_01_demo.sh: case运行文件  

2.2  conftest.py 文件介绍

代码3~8行: 引用公共包

代码11~15: 参数入口函数  

代码21~23行: 创建log目录

代码24~26行: 创建log文件

代码31~40: 初始化log参数  

 代码44~50行: 加载配置文件

代码54~67行:  初始化系统和运行参数

 源文件代码:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-'
import os, sys
import datetime
import logging
import pytest
import coloredlogs
from libs.utilis.config_tool import*


def pytest_addoption(parser):
    parser.addoption(
        "--system_conf", action="store", default="system",
        help="config file option: default is system => config_system.yml"
    )


def setup_logging(level=logging.INFO, log_folder=None, filename=None):

    # create base folder
    if os.path.exists(log_folder) is not True:
        os.makedirs(log_folder)  # create report folder

    log_filename = None
    if filename is not None and log_folder is not None:
        log_filename = log_folder + os.sep + filename

    for handler in logging.root.handlers[:]:
        logging.root.removeHandler(handler)

    log_format = '%(asctime)s - %(levelname)5s - %(lineno)4s - %(filename)18s  -  %(message)10s'
    logging.basicConfig(filename=log_filename, level=level, format=log_format)
    if log_filename is not None:
        console = logging.StreamHandler(stream=sys.stdout)
        console.setLevel(logging.getLogger().level)
        console.setFormatter(logging.Formatter(log_format))
        logging.getLogger().addHandler(console)

    coloredlogs.install(level=level, fmt=log_format, milliseconds=True)
    logging.info('')


@pytest.fixture(scope='session')
def yml_conf(request):
    logging.info('*** start fixture: yml_conf')
    filename = request.config.getoption("--system_conf")
    conf = ConfigTool(filename)
    conf.load_resource_file()
    logging.info(" filename= %s" % filename)
    yield conf


@pytest.fixture(scope='session')
def setup_context(yml_conf):
    log_folder = yml_conf.get_ctc()['logfolder']
    log_folder = '../log/%s' % log_folder
    log_folder =  log_folder +os.sep + ('%s' % datetime.datetime.now().strftime('%Y%m%d-%H%M%S'))
    setup_logging(logging.DEBUG, log_folder, yml_conf.get_ctc()['logfile'])
    logging.info('*** start fixture: context ***')
    logging.info('init context object.')
    logging.info('config file: %s' % yml_conf.filename)
    logging.info('ctc: %s' % yml_conf.get_ctc())
    logging.info('ctc uart: %s' % yml_conf.get_ctc_uart())
    logging.info('gps uart: %s' % yml_conf.get_gps_uart())
    logging.info('relay uart: %s' % yml_conf.get_relay_uart())
    logging.info('\r\n')

2.3 编写case文件

代码第14~18行: case头部分,用于初始化case运行的环境

代码第21~28行: case尾部分,运行完成case,释放资源 

代码31~33: 初始化case运行参数的函数

代码38 ~ 72: 编写一个case类,实现了3个case  

 

源代码文件:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @describe : it is only a sourcecode case
# @Time    : 2019/11/21 20:21
# @Author  : mingfei.tang
import sys
import pytest
import time
import allure
import logging


@pytest.fixture(scope="module", autouse=True)
def mod_header(request):
    logging.info('\r\n')
    logging.info('=========================== start mod_header =================================')
    logging.info('module name: %s' % request.module.__name__)
    logging.info('=========================== End of mod_header ================================')


@pytest.fixture(scope="function", autouse=True)
def func_header(request):
    logging.info('\r\n')
    logging.info('=========================== start func_header =================================')
    logging.info('case name: %s' % request.function.__name__)
    logging.info('run time: %s' % time.asctime())
    logging.info('=========================== End of func_header ===============================')
    logging.info('\r\n')


@pytest.fixture(params=[2])
def init_data(request):
    return request.param


@allure.feature('sourcecode testcase ')
@pytest.mark.usefixtures('setup_context')
class TestClass:
    @classmethod
    def setup_class(cls):
        logging.info('setup class')

    @classmethod
    def teardown_class(cls):
        logging.info("teardown class")

    @allure.severity('blocker')
    @allure.feature('test_demo_case_0')
    @pytest.mark.usefixtures('yml_conf')
    def test_demo_case_0(self):
        init_data = 0
        logging.info('test_demo_case_0')
        logging.debug('test_data: %s' % init_data)
        assert init_data == 0

    @allure.severity('blocker')
    @allure.feature('test_demo_case_1')
    @pytest.mark.usefixtures('yml_conf')
    def test_demo_case_1(self):
        init_data = 14
        logging.info('test_demo_case_1')
        logging.debug('test_data: %s' % init_data)
        assert init_data == 14

    @allure.severity('blocker')
    @allure.feature('test_demo_case_2')
    def test_demo_case_2(self):
        init_data = 15
        time.sleep(10)
        logging.info('test_demo_case_2')
        logging.debug('test_data: %s' % init_data)
        assert init_data == 15

 2.4 运行脚本文件: run.common.sh

代码16~22行: 检查pytest是否已经运行,如果运行则kill pytest

代码24~28行: 运行case

 代码30~34: 使用allure生成report

 代码36~39: 使用pytest生成report

源代码文件:

#!/usr/bin/env bash
# -*- coding: utf-8 -*-
# @Time    : 2019/11/27 09:51
# @File    : run.common.sh
# @Author  : mingfei.tang
###############################
ConfigFile_yml=''
module_name=''
key_words=''
report_dir=''

#DATE="`date +%Y-%m-%d_%H-%M-%S`"
#REPORT_HTML_DIR="report/${report_dir}/${DATE}/html"
#REPORT_PYTEST_DIR="report/${report_dir}/${DATE}/pyhtml"

function kill_pytest()
{
    if [ "${OS}" == "Windows_NT" ]
    then
        taskkill.exe -F -IM pytest.exe -T
    fi
}

function run_test_case()
{
    mkdir -p "${REPORT_PYTEST_DIR}" 2> /dev/null
    pytest --capture=no --color=yes --verbose --alluredir="${REPORT_PYTEST_DIR}" --system_conf="conf/${ConfigFile_yml}.yml" -k "${key_words}" "test_case/${module_name}.py"
}

function run_allure_html_report()
{
    mkdir -p "${REPORT_HTML_DIR}"
    allure generate "${REPORT_PYTEST_DIR}" -o "${REPORT_HTML_DIR}"
}

function run_pytest_html_report()
{
    pytest  --alluredir="${REPORT_PYTEST_DIR}" --system_conf="conf/${ConfigFile_yml}.yml" -k "${key_words}" "test_case/${module_name}.py"  --html="${REPORT_PYTEST_DIR}"/report.html --self-contained-html
}

function run_generate_report()
{
    if [ "${OS}" == "Windows_NT" ]
    then
        run_allure_html_report
    else
        run_pytest_html_report
    fi
}

3 运行case

3.1 执行case 

在代码所在的目录中运行git bash

 

在该目录下执行:

 ./run_test_01_demo.sh

运行log如下:

 运行完成后,生成report:

3.2 查看report

 1) 总的报告结果

 2) 单个case的运行时间

 3)查看case的执行log

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值