UI自动化测试-pytest框架

 🔥 交流讨论:欢迎加入我们一起学习!

🔥 资源分享耗时200+小时精选的「软件测试」资料包

🔥 教程推荐:火遍全网的《软件测试》教程  

📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!

在进行UI自动化测试的时候,我们需要工具来对测试用例进行收集,执行,标记,参数化。pytest就是这样一个工具。

pytest实际是python的一个单元测试框架,其他还有如unittest等,它可以实现按照规则搜索测试用例,对测试用例进行标记,如只执行L1

级别的测试用例,测试执行用例失败后重新执行,测试用例的参数化等。

pytest不仅适用于UI自动化测试,也适用于接口自动化,对python语言进行单元测试等。

安装pytest

可以使用pip或者pycharm方式进行安装

打开pycharm,左上角File-settings-project:项目名-python interpreter,点击+,搜索pytest,然后install package

第一个pytest脚本

import pytestclass TestDemo:def test_01(self):assert 1==1  # 断言成功def test_02(self):assert 1==2  # 断言失败
if __name__ == '__main__':pytest.main(['-s','test.py'])

在文件输入如上代码。

在这个脚本中,我们首先导入了pytest模块,然后定义了一个class,并定义了两个方法,在方法里用assert进行断言。

assert是python自带的关键字。assert后面接一个表达式,只要表达式的最终结果为True,那么断言通过,用例执行成功,否则用例执行失败。可以看出,第一个方法里结果为true,第二个方法里结果为false。

在main主入口里,调用pytest的main方法,并传入模块名(即文件名)。

点击运行按钮,结果如下:

由结果可以看出,一共收集了两个用例,其中一个运行成功(用.表示),一个运行失败(F表示),失败的原因是1!=2

用例收集规则

pytest按照一定的规则进行用例的收集。

1. 模块名必须以test_开头或_test结尾

这里适用于未指定模块时的收集,如果运行单个文件,在main里指定要执行的文件,则无论这个文件名是什么,都会被执行。

如果在main里不指定模块,如只写pytest.main(),则pytest会默认从当前路径及其所有子目录中搜索py源文件,所有名字以test_开头或者以_test结尾的python源文件(.py文件)被认为是测试模块源文件,不符合这个命名规则的文件会被忽略。

2. 测试类必须以Test开头且不能有init方法

一个文件也可以只写测试方法,不写测试类。

3. 测试方法必须以test开头

在上面的示例脚本中,我们定义了两个test_开头的方法,所以收集了两个用例。非test开头的方法,会被pytest忽略。

运行方式

main函数运行

我们可以在main入口中调用pytest的main方法来运行文件,如上例。

不指定模块名
pytest.main(['-s'])

-s参数表示在控制台输出信息,当不指定模块名时,可以看到,收集了7条用例

指定模块名
 pytest.main(['-s','test.py'])

当指定了模块后,运行文件,只收集当前文件的两条用例。

指定class
 pytest.main(["-s", "test.py::TestDemo"])

我们也可以在模块名上加上指定的class名

命令行窗口运行

不指定模块名

打开terminal,进入目标目录,直接执行“pytest”即可自动寻找当前目录下的测试用例

指定模块名

打开terminal,输入pytest+模块名,指定模块执行。

pytest test.py

指定函数名

打开terminal,输入pytest+模块名+函数名,指定模块执行。

pytest test.py::TestDemo

test runner运行

在File-Settings如图路径,设置default test runner为pytest,点击OK。

再回到测试文件,可以看到类,方法前面都显示运行按钮,点击对应按钮,可以运行类,单独运行某个test。

也可以在不写main函数的情况下,右键以pytest运行文件。注意在配置了runner后,执行不会进入main主入口。

标记机制

pytest提供了标记机制,借助“mark”关键字,我们可以对测试函数(类、方法)进行标记。

我们可以利用标记,对测试用例进行分级,例如某些主流程的用例可以标记为L1,次要流程的用例标记为L2等。这样有一个好处,我们可以在不同的情况执行不同的测试用例,例如,在做冒烟测试的时候,只需要执行L1级别的用例就行了。

●一个测试函数(类、方法)可以有多个标记。

●一个标记也可以应用于多个函数(类、方法)。

●执行参数使用:pytest -m mark名。

●执行多个标记:pytest -m “L1 or L2”。

import pytestclass TestDemo:@pytest.mark.L1@pytest.mark.L2def test_01(self):assert 1==1  # 断言成功@pytest.mark.L2def test_02(self):assert 1==2  # 断言失败
if __name__ == '__main__':pytest.main(['-m L2','test.py'])

如上,给测试用例添加标记,并在main中以-m参数指定选择的标记,也可以使用or和and。

  pytest.main(['-m L2 or L1','test.py']) # 执行标记为L1或者L2的
  pytest.main(['-m L2 and L1','test.py']) #执行标记同时为L1和L2的

测试固件

在进行UI测试时,可能每个用例的操作前提都是需要登录系统,那么我们也不能在每次写用例的时候,都把登录写一遍,或者调用一遍,这样会造成代码冗余。有没有可能,在整个测试类或者所有测试用例执行之前,调用一次登录呢?

这样的工具,就是测试固件,测试固件有不同级别。

函数中的测试固件

●setup_module、teardown_module,在整个文件的开始和最后执行一次。

●setup_function和teardown_function,在每个函数开始前后执行。


import pytest'''
在函数中使用
1.setup_module、teardown_module,在整个文件的开始和最后执行一次
2.setup_function和teardown_function,在每个函数开始前后执行
'''
def setup_module():print('setup_module')def teardown_module():print('teardown_module')def setup_function():print('setup_function')def teardown_function():print('teardown_function')def test_a():print('aaaa')assert 1 == 1def test_b():print('bbbb')assert 1 == 2if __name__ == '__main__':pytest.main(["-s", "test.py"])

class中的测试固件

●setup_class、teardown_class,在整个class的开始和最后执行一次。

●setup_method和teardown_method,在每个方法开始前后执行。

class TestDemo():def setup_class(self):print('setup_class')def teardown_class(self):print('teardown_class')def setup_method(self):print('setup_method')def teardown_method(self):print('teardown_method')def test_a(self):print('aaaa')assert 1 == 1def test_b(self):print('bbbb')assert 1 == 2if __name__ == '__main__':pytest.main(["-s", "test.py"])

setup和teardown

setup和teardown既可以应用在函数中,也可以应用在class中,作用对象是函数或方法,在每个测试用例执行前后执行一次。

我们通常使用setup来进行一些数据准备工作,使用teardown来进行数据清理工作。

import pytestclass TestDemo:def setup(self):print('setup')def teardown(self):print('teardown')@pytest.mark.L1@pytest.mark.L2def test_01(self):assert 1==1  # 断言成功@pytest.mark.L2def test_02(self):assert 1==2  # 断言失败
if __name__ == '__main__':pytest.main(['-s','test.py'])

断言

我们在进行手工测试时,测试用例有预期结果,那么在进行UI测试时,我们也需要来判定结果是否符合我们的预期。

在python中用断言来实现。断言assert用于检查指定的表达式的结果是否为True。

一个测试用例可以写多个断言,当有一个断言失败时,pytest就认为测试的结果为失败,该测试用例的执行会被终止。

如果一条测试用例不写断言,那么它的结果为通过。所以一定要写断言,否则测试执行就没有了意义。

import pytestclass TestDemo:@pytest.mark.L1@pytest.mark.L2def test_01(self):assert 1==1  # 断言成功assert 1==3@pytest.mark.L2def test_02(self):assert 1==2  # 断言失败
if __name__ == '__main__':pytest.main(['-s','test.py'])

参数化

在进行UI测试时,我们需要给测试用例传测试数据,那么如何做呢?

pytest使用@pytest.mark.parametrize装饰器来实现数据驱动测试,也就是常说的参数化。

单个参数

import pytestclass TestDemo:data = ["小红", "小明"]@pytest.mark.parametrize("username",data)def test_01(self,username):print("我是{}".format(username))if __name__ == '__main__':pytest.main(['-s','test.py'])

运行结果如下,这里给一条测试用例传入两条数据,显示收集到了两条用例。

多个参数

列表嵌套字典
import pytestclass TestDemo:data_1 = [{"username": "admin1", "password": "123456"},{"username": "admin2", "password": "12345678"},]@pytest.mark.parametrize("data", data_1)def test_login(self,data):print("账号:{},密码:{}".format(data["username"], data["password"]))if __name__ == '__main__':pytest.main(['-s','test.py'])

可以看到这里传入两条数据,显示收集了两条用例。

列表嵌套列表
import pytestclass TestDemo:data_1 = [["admin1", "123456"],["admin2", "12345678"],]@pytest.mark.parametrize("username,password", data_1)def test_login(self,username, password):print("账号:{},密码:{}".format(username, password))if __name__ == '__main__':pytest.main(['-s','test.py'])

列表嵌套元组
import pytestclass TestDemo:data_1 = [("admin1", "123456"),("admin2", "12345678"),]@pytest.mark.parametrize("username,password", data_1)def test_login(self,username, password):print("账号:{},密码:{}".format(username, password))if __name__ == '__main__':pytest.main(['-s','test.py'])

本文介绍了pytest测试框架的安装、运行、用例收集、标记、测试固件、断言、参数化等内容,实际这些内容只是pytest的冰山一角,还有

失败重跑,测试报告,全局设置等内容没有进行介绍,但学习了本文的内容,相信你已经可以上手进行自动化测试用例的编写了。

欢迎交流,拜拜!

最后我邀请你进入我们的【软件测试学习交流群:785128166】, 大家可以一起探讨交流软件测试,共同学习软件测试技术、面试等软件测试方方面面,还会有免费直播课,收获更多测试技巧,我们一起进阶Python自动化测试/测试开发,走向高薪之路

作为一个软件测试的过来人,我想尽自己最大的努力,帮助每一个伙伴都能顺利找到工作。所以我整理了下面这份资源,现在免费分享给大家,有需要的小伙伴可以关注【公众号:程序员二黑】自提!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/803180.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Lua热更新(AssetBundle)

AssetBundle 新版本导入ab包报错,则删除其中的Tests文件夹。 给资源分组 打包设置:平台、路径、重复打包清空文件夹、复制到streaming文件夹 建议勾选 建议使用LZ4压缩方式 用来观察文件中的包大小,不常用 参数总结: 这六个只做了解,重要的是上面的

Struts2的入门:新建项目——》导入jar包——》jsp,action,struts.xml,web.xml——》在项目运行

文章目录 配置环境tomcat 新建项目导入jar包新建jsp界面新建action类新建struts.xml,用来配置action文件配置Struts2的核心过滤器:web.xml 启动测试给一个返回界面在struts.xml中配置以实现页面的跳转:result再写个success.jsp最后在项目运行 配置环境 …

【数据分享】我国第七次人口普查的100m分辨率人口栅格数据(免费获取\tif格式\2020年)

人口空间分布数据是我们在各项研究中经常使用的数据。之前我们分享过来源于LandScan数据集的2000-2022年的1km精度的人口空间分布栅格数据(可查看之前的文章获悉详情)! 相较于LandScan全球人口数据集,我国历次人口普查的数据对于…

SpringBoot通用模块--文件上传开发(阿里云OSS)

文件上传,是指将本地图片、视频、音频等文件上传到服务器上,可以供其他用户浏览或下载的过程。文件上传在项目中应用非常广泛,我们经常发抖音、发朋友圈都用到了文件上传功能。 实现文件上传服务,需要有存储的支持,那…

基于支持 GPT 的服务的初创公司

Kafkai:多语言长篇内容生成,AI写作的新趋势 介绍 随着生成式预训练 Transformer (GPT) 的出现,技术世界正在见证范式转变。 这种人工智能驱动的创新不仅仅是一种转瞬即逝的趋势,而是一种趋势。 它已成为科技行业的基石&#xff0c…

【C语言】简单介绍进制和操作符

🌈个人主页:是店小二呀 🌈C语言笔记专栏:C语言笔记 🌈C笔记专栏: C笔记 🌈喜欢的诗句:无人扶我青云志 我自踏雪至山巅 本文简要介绍进制和操作符,愿能为您提供帮助!文章…

异常的种类

Oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645 Oracle 运行时错误可以分为 Oracle 错误和用户自定义错误,与此对应,根据异常产生的机制和原理,可将 Oracle 的系统异常分为 3 种 预定义…

使用VPN时,Java程序无法访问远程网络的解决办法

应用场景: 电脑连接VPN之后,Java程序无法连接远程服务,比如第三方接口、远程数据库连接、远程微服务等。我个人遇到的情况有连接海康威视SDK,influxdb以及一些微服务。 解决办法: 启动Java时加入参数:-D…

比较好玩的车子 高尔夫6

https://www.sohu.com/a/484063087_221273 四万多如愿收获手动挡高尔夫6,可靠性、经济性、操控性兼顾_搜狐汽车_搜狐网 2.基本上其他人也不知道到底是什么相关的车子信息

基于单片机和ICL7135多档位数字电压表设计

**单片机设计介绍,基于单片机和ICL7135多档位数字电压表设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机和ICL7135的多档位数字电压表设计是一个结合了硬件与软件技术的综合性项目。这种设计旨在实现一…

Pnpm + Turbo 搭建 Web Component Monorepo 组件库

技术选型 使用 Pnpm Turbo 搭建 Web Component Monorepo项目 stencil-component-ui 组件库 pnpm 作为包管理器Turborepo 作为构建系统Vitepress 管理文档 pnpm 技术 什么是 pnpm? 它有哪些优势? pnpm 跟 npm、yarn一样,都是用于管理Node包依赖的管…

iOS App Store审核要求与Flutter应用的兼容性分析

本文探讨了使用Flutter开发的iOS应用能否上架,以及上架的具体流程。苹果提供了App Store作为正式上架渠道,同时也有TestFlight供开发者进行内测。合规并通过审核后,Flutter应用可以顺利上架。但上架过程可能存在一些挑战,因此可能…

云岚到家项目

一.项目介绍 云岚到家项目是一个家政服务o2o平台,互联网家政是继打车、外卖后的又一个风口,创业者众多,比如:58到家,天鹅到家等,o2o(Online To Offline)是将线下商务的机会与互联网…

openharmony launcher 调研笔记(03)UI 数据装配

最近在看launcher,把自己调研的点做个笔记,持续修改更新中,个人笔记酌情参考。 桌面上半部分包含父子逻辑: Column() { PageDesktopLayout(); } PageDesktopLayout->GridSwiper->Swiper->SwiperPage 1.PageDe…

25.11 MySQL 视图

1. 常见的数据库对象 对象描述表(TABLE)存储数据的逻辑单元, 以行和列的形式存在, 列就是字段, 行就是记录.数据字典系统表, 存放数据库相关信息的表. 数据通常由数据库系统维护, 程序员通常不可修改, 只可查看.约束(CONSTRAINT)执行数据校验的规则, 用于保证数据完整性的规则…

2024马来西亚电商选品博览会

2024马来西亚电商选品博览会 展会概况 展会名称:2024马来西亚电商选品博览会 主办单位:广东进出口商会 时间:2024.11.29-12.1 地点:马来西亚国际贸易展览中心(MITEC) 展览面积:10000平方米 展会简介 2024马来西亚跨境电商选…

包和final.Java

1,包 包就是文件夹。用来管理不同功能的Java类,方便后期代码的维护。 (1)包名的规则是什么? 公司域名反写报的作用,需要全部英文小写,见名知意。com.itheima.domain (2&#xff…

抓住风口,快速上手RAG应用开发!

免责声明~ 任何文章不要过度深思! 万事万物都经不起审视,因为世上没有同样的成长环境,也没有同样的认知水平,更「没有适用于所有人的解决方案」; 不要急着评判文章列出的观点,只需代入其中,适度…

蓝桥杯第十一届c++大学B组详解

目录 1.字符串排序 2.门牌制作 3.即约分数 4.蛇型填数 5.跑步锻炼 6.七段码 7.成绩统计 8.回文日期 9.字串分值和 10.平面切分 1.字符串排序 题目解析:这个题目真没搞懂。有会的大佬教我一下谢谢。 2.门牌制作 题目解析:出过超级多这类题目&am…

NumPy进阶(二)

2. NumPy进阶(二) 2.1 Numpy数组操作 2.1.1 添加元素 numpy.append 函数在数组的末尾添加值。 追加操作会分配整个数组,并把原来的数组复制到新数组中 注意: 插入的维度要保证所有数组的长度是相同的如果没有指定轴,数组会被扁平处理 ndarr…