使用 Python 语言 从 0 到 1 搭建完整 Web UI自动化测试学习系列 40--完善优化 Allure 测试报告显示内容

测试学习记录,仅供参考!

优化完善 Allure 测试报告显示内容

一、 Allure 相关用例描述:

|-----------------------|-----------|------------------------------------------------------|----------------------------------------------------|
| 使用方法 | 参数值 | 参数说明 | 备注 |
| @allure.epic() | epic描述 | 敏捷里面的概念,对用例或用例集进行描述分类;定义项目、当有多个项目时使用;下面是feature; | 很少使用,一般是在类方法上使用;在函数方法亦可使用,但是会单独展示一个新的 epic 范围模块出来; |
| @allure.feature() | 模块名称 | 功能点的描述,与 epic 类似,只是比 epic 级别低;用例按照模块区分,有多个模块时给每个起名字; | 经常使用,在类方法上使用;在函数方法亦可使用,但是作用范围是函数方法级别的;也是单独显示新的; |
| @allure.story() | 用例名称 | 用户故事,与 epic 类似,只是比 feature 级别低;一个用例的描述,下面是story; | 在测试函数方法上面使用;亦可在类方法上使用,会在feature 级别下生成一个story模块; |
| @allure.title() | 用例标题 | 一个用例标题;重命名 html 报告的用例名称; | 一般在测试函数方法上使用,在类方法上不生效; |
| @allure.testcase() | 测试用例的链接地址 | 与 link 类似,对应功能测试用例系统里面的 case;自动化用例对应的功能用例存放系统的地址; | 类方法、测试函数上都可以使用,作用域随使用范围; |
| @allure.issue() | 缺陷地址 | 与 link 类似,对应缺陷管理系统里边的缺陷地址; | 类方法、测试函数上都可以使用,作用域随使用范围; |
| @allure.description() | 用例描述 | 进行测试用例的描述,对测试用例的详细描述; | 偶尔用到,作用域随使用范围; |
| @allure.step() | 操作步骤 | 进行测试用例的步骤,测试用例的操作步骤; | 根据实际情况使用; |
| @allure.severity() | 用例等级 | BLOCKER、CRITICAL、NORMAL、MINOR、TRIVIAL; | 不常使用,作用域随使用范围; |
| @allure.link() | 定义链接 | 用于定义一个链接,在测试报告展现;(推荐使用) | 类方法、测试函数上都可以使用,作用域随使用范围; |
| @allure.attachment() | 附件 | 添加测试报告附件; | 经常使用; |

二、常用到的方法

1、以项目根目录 testcase 软件包 login 目录下 test.login.py 文件为例;

@allure.feature()

用于定义测试用例所属的feature

先导包 import allure,同样使用装饰器 @allure.feature(),模块级别的,在类级别方法上面经常使用;

python 复制代码
# 导包
import pytest
from time import sleep
from pageObject.login_page.login_page import LoginPage
from util_tools.handle_data.operateJson import read_json
import allure

@allure.feature('这是一个@allure.feature,登录模块')
class TestLogin:

    # 登录成功
    # @pytest.mark.run(order=1)   # 指定先运行
    # 使用参数化实现一条测试用例跑多种场景--可迭代对象里面有多少组数据就跑多少次测试用例
    @pytest.mark.parametrize('data', read_json('./data/login_success.json'))
    # 用一个 data(需与上面保持一致) 参数去接收参数化数据
    def test_login_success(self, not_login_driver, data):
        # 进行列表解包--通过两个参数去接收列表中的数据
        username, password = data
        # 传浏览器对象--再把结果返回
        login_page = LoginPage(not_login_driver)
        # 直接调用页面类中的 login 操作--里面需要输入两个参数(参数化传两个参数)
        login_page.login(username, password)
        # 断言结果
        login_page.assert_is_element_present(login_page.assert_result)
        sleep(2)

    # 登录失败
    @pytest.mark.parametrize('data', read_json('./data/login_failed.json'))
    def test_login_failed(self, not_login_driver, data):
        username, password = data
        login_page = LoginPage(not_login_driver)
        login_page.login(username, password)
        login_page.assert_title('系统提示')
        sleep(2)

2、只运行登录测试用例查看;显示略微直观,可以看到哪一个测试函数属于哪个模块;

@allure.story()

用于定义测试用例所属的 feature 下的 story ,级别比 feature 低;

3、使用装饰器 @allure.story(),函数方法级别,在测试函数方法上面使用,亦可在类方法上使用;

python 复制代码
import pytest
from time import sleep
from pageObject.login_page.login_page import LoginPage
from util_tools.handle_data.operateJson import read_json
import allure

# @allure.epic('测试环境测试用例,this is a @allure.epic')
# @allure.story('类方法使用,this is a @allure.story')
@allure.feature('这是一个@allure.feature,登录模块')
class TestLogin:

    @allure.story('用户登录成功的测试用例,this is a @allure.story')
    # @pytest.mark.run(order=1)   # 指定先运行
    # 使用参数化实现一条测试用例跑多种场景--可迭代对象里面有多少组数据就跑多少次测试用例
    @pytest.mark.parametrize('data', read_json('./data/login_success.json'))
    # 用一个 data(需与上面保持一致) 参数去接收参数化数据
    def test_login_success(self, not_login_driver, data):
        # 进行列表解包--通过两个参数去接收列表中的数据
        username, password = data
        # 传浏览器对象--再把结果返回
        login_page = LoginPage(not_login_driver)
        # 直接调用页面类中的 login 操作--里面需要输入两个参数(参数化传两个参数)
        login_page.login(username, password)
        # 断言结果
        login_page.assert_is_element_present(login_page.assert_result)
        sleep(2)

    @allure.story('登录失败,this is a @allure.story')
    @pytest.mark.parametrize('data', read_json('./data/login_failed.json'))
    def test_login_failed(self, not_login_driver, data):
        username, password = data
        login_page = LoginPage(not_login_driver)
        login_page.login(username, password)
        login_page.assert_title('系统提示')
        sleep(2)

4、只运行登录测试用例查看;显示进一步直观显示需要关注的功能点;

@allure.title()

5、使用装饰器 @allure.title(),添加成功后自定义测试用例名称,未使用是直接显示测试函数名称;

一般在测试函数方法上使用,在类方法上不生效;

python 复制代码
import pytest
from time import sleep
from pageObject.login_page.login_page import LoginPage
from util_tools.handle_data.operateJson import read_json
import allure

@allure.feature('这是一个@allure.feature,登录模块')
class TestLogin:

    @allure.title('这是一个@allure.title,登录成功的测试用例')
    @allure.story('用户登录成功的测试用例,this is a @allure.story')
    # @pytest.mark.run(order=1)   # 指定先运行
    # 使用参数化实现一条测试用例跑多种场景--可迭代对象里面有多少组数据就跑多少次测试用例
    @pytest.mark.parametrize('data', read_json('./data/login_success.json'))
    # 用一个 data(需与上面保持一致) 参数去接收参数化数据
    def test_login_success(self, not_login_driver, data):
        # 进行列表解包--通过两个参数去接收列表中的数据
        username, password = data
        # 传浏览器对象--再把结果返回
        login_page = LoginPage(not_login_driver)
        # 直接调用页面类中的 login 操作--里面需要输入两个参数(参数化传两个参数)
        login_page.login(username, password)
        # 断言结果
        login_page.assert_is_element_present(login_page.assert_result)
        sleep(2)

    @allure.title('这是一个@allure.title,登录失败的场景')
    @allure.story('登录失败,this is a @allure.story')
    @pytest.mark.parametrize('data', read_json('./data/login_failed.json'))
    def test_login_failed(self, not_login_driver, data):
        username, password = data
        login_page = LoginPage(not_login_driver)
        login_page.login(username, password)
        login_page.assert_title('系统提示')
        sleep(2)

6、只运行登录测试用例查看;可以看到自定义的测试用例名称;

@allure.link()

用于在测试报告中添加链接,例如跳转到 BUG 跟踪工具中的问题页面

7、使用装饰器 @allure.link(),第一个参数是 URL 链接地址,第二个参数是自定义的链接名称;

python 复制代码
@allure.link(url='http://www.baidu.com',name='百度一下,这是一个@allure.link')
@allure.description()

8、 使用装饰器 @allure.description(),用例描述有时候可能会用到;一般根据实际场景在测试报告中给测试用例添加描述信息;

python 复制代码
@allure.description('这是一个@allure.description,测试用例的描述信息,这是测试登录成功。')
@allure.step()

标记测试步骤,在编写测试用例时,通常会将测试步骤分为多个部分,以便更好地理解每个步骤的执行情况;pytest-Allure提供了allure.step函数,可以方便地标记测试步骤;

9、使用装饰器 @allure.step(),可以让测试用例在 allure 报告种显示更加详细的测试过程;

python 复制代码
@allure.step('这是一个@allure.step,标记测试用例的测试步骤')
@allure.severity()

用于设置测试用例严重等级,allure 对用例的等级划分成五个等级:

blocker:阻塞缺陷(功能未实现,无法下一步)

critical:严重缺陷 (功能点缺失)

normal:一般缺陷 (边界情况,格式错误)

minor:次要缺陷(界面错误与ui需求不符)

trivial:轻微缺陷(必须项无提示,或者提示不规范)

10、使用装饰器 @allure.severity(),这个方法不经常使用,了解即可;

vb 复制代码
`@allure.severity(allure.severity_level.BLOCKER)
@allure.severity(allure.severity_level.CRITICAL)
@allure.severity(allure.severity_level.NORMAL)
@allure.severity(allure.severity_level.MINOR)
@allure.severity(allure.severity_level.TRIVIAL)`
@allure.attachment()

用于在测试报告中添加附件,例如日志文件、截图等,通过 allure.attachment() 在函数内部使用,不是采用装饰器的方式;

11、 第一个参数是 显示信息内容,第二个参数跟上附件显示名称,第三个参数跟上附件类型;

python 复制代码
import pytest
from time import sleep
from pageObject.login_page.login_page import LoginPage
from util_tools.handle_data.operateJson import read_json
import allure

@allure.epic('这是一个@allure.epic,测试登录功能模块')
@allure.feature('这是一个@allure.feature,登录模块')
class TestLogin:

    @allure.severity(allure.severity_level.CRITICAL)
    @allure.description('这是一个@allure.description,测试用例的描述信息,这是测试登录成功。')
    @allure.link(url='http://www.baidu.com', name='百度一下,这是一个@allure.link')
    @allure.title('这是一个@allure.title,登录成功的测试用例')
    @allure.story('用户登录成功的测试用例,this is a @allure.story')
    # @pytest.mark.run(order=1)   # 指定先运行
    # 使用参数化实现一条测试用例跑多种场景--可迭代对象里面有多少组数据就跑多少次测试用例
    @pytest.mark.parametrize('data', read_json('./data/login_success.json'))
    # 用一个 data(需与上面保持一致) 参数去接收参数化数据
    def test_login_success(self, not_login_driver, data):
        # 进行列表解包--通过两个参数去接收列表中的数据
        username, password = data
        # 传浏览器对象--再把结果返回
        login_page = LoginPage(not_login_driver)
        # 直接调用页面类中的 login 操作--里面需要输入两个参数(参数化传两个参数)
        login_page.login(username, password)

        allure.attach('这是一个@allure.attach', name='截图', attachment_type=allure.attachment_type.TEXT)
        # 断言结果
        login_page.assert_is_element_present(login_page.assert_result)
        sleep(2)

    @allure.title('这是一个@allure.title,登录失败的场景')
    @allure.story('登录失败,this is a @allure.story')
    @pytest.mark.parametrize('data', read_json('./data/login_failed.json'))
    def test_login_failed(self, not_login_driver, data):
        username, password = data
        login_page = LoginPage(not_login_driver)
        login_page.login(username, password)
        login_page.assert_title('系统提示')
        sleep(2)

12、只运行登录测试用例查看;

13、使用比较多的是前面两种 @allure.feature()、@allure.story() 和 allure.attachment() 这三种方法;根据实际场景选择性的使用哪一个方法来更好的管理测试用例的结构。

@allure.feature() 和 @allure.story() :经常使用,用于管理测试报告结构数;

allure.attachment() :用的很多,主要是丰富测试报告内容;

补充其他模块的测试用例

14、提交订单测试用例提交 allure 方法;

python 复制代码
# 导包
from pageObject.flow_page.flow_page import FlowPage
from pageObject.flow_page.search_page import SearchPage
from time import sleep
import allure

@allure.feature('结算中心')
class TestFlow:

    @allure.story('购物车中没有商品下单场景。')
    # 失败场景,购物车没有商品时
    def test_purchase_failure(self, login_driver):
        flow_page = FlowPage(login_driver)
        flow_page.flow_failed()
        # 断言没有商品时跳转的url页面地址
        assert flow_page.current_url == 'http://localhost:8088/ecshop/flow.php?step=checkout'
        sleep(3)

    @allure.story('成功提交商品订单。')
    # 成功操作,购物车有商品
    def test_purchase_success(self, login_driver):
        # 先将商品加入购物车
        search_page = SearchPage(login_driver)
        search_page.add_cart()
        # 去结算中心提交订单
        flow_page = FlowPage(login_driver)
        flow_page.flow_success()
        # 订单提交成功,断言url
        assert flow_page.current_url == 'http://localhost:8088/ecshop/flow.php?step=done'
        sleep(3)

15、注册页面测试用例提交 allure 方法;

python 复制代码
# 导包
from pageObject.register_page.register_page import RegisterPage
import pytest
from time import sleep
from util_tools.handle_data.readYaml import read_yaml
import allure

@allure.feature('注册模块')
class TestRegister:

    @allure.story('注册成功的场景。')
    # 注册成功场景
    @pytest.mark.parametrize('data', read_yaml('./data/register_success.yaml'))
    def test_register_success(self, not_login_driver, data):
        # 调用页面类相关的操作--直接调用RegisterPage()把浏览器对象get_driver传给它
        register_page = RegisterPage(not_login_driver)
        # 如果使用 *data 解包数据,data的元素数量必须跟click_register方法的入参个数保持一致
        register_page.click_register(*data)
        # 添加等待时间查看效果
        sleep(3)
        # 断言结果
        register_page.assert_is_element_present(register_page.assert_result)

    @allure.story('注册失败的场景。')
    # 注册失败场景
    @pytest.mark.parametrize('data', read_yaml('./data/register_failed.yaml'))
    def test_register_failed(self, not_login_driver, data):
        register_page = RegisterPage(not_login_driver)
        register_page.click_register(*data)
        sleep(3)
        register_page.assert_element_not_visible(register_page.assert_result)

    @allure.story('注册页面成功跳转到登录页面。')
    # 跳转链接--只是一个按钮,不需要参数化
    def test_check_skip_login(self, not_login_driver):
        register_page = RegisterPage(not_login_driver)
        register_page.skip_login_page()
        # 断言结果--直接断言页面url
        assert register_page.current_url == 'http://localhost:8088/ecshop/user.php?act=login'

16、其他根据实际业务测试场景自行补充完善,跑目前所有测试用例,运作 run.py 文件查看测试报告结果;

如若嫌测试用例执行较慢,可以设置多线程去跑,会快很多;

这样就可以比较清晰的了解测试报告中测试用例的运行情况;目前左边的部分基本已经优化完了;右边是每个测试用例执行的过程,目前比较单一,后续优化显示的更加丰富一些;

未完待续。。。

相关推荐
SunnyRivers1 小时前
打包 Python 项目
python·打包
万行1 小时前
机器人系统SLAM讲解
开发语言·python·决策树·机器学习·机器人
WinstonJQ1 小时前
AirSim无人机仿真入门(一):实现无人机的起飞与降落
python·机器人·游戏引擎·ue4·无人机
Quintus五等升1 小时前
深度学习②|实现人数回归预测
人工智能·深度学习·学习·机器学习·回归
tjjucheng1 小时前
专业做小程序定制开发的厂家
python
Hello.Reader1 小时前
Flink DynamoDB Connector 用 Streams 做 CDC,用 BatchWriteItem 高吞吐写回
大数据·python·flink
gc_22992 小时前
学习python调用dmpython库获取达梦数据库模式信息的基本方式
python·dmpython
reasonsummer2 小时前
【教学类-130-01】20260118对称汉字剪纸28个
python
victory04312 小时前
minimind SFT失败原因排查和解决办法
人工智能·python·深度学习