如何使用Pytest进行自动化测试

为什么需要自动化测试

自动化测试有很多优点,但这里有3个主要的点

  1.     可重用性:不需要总是编写新的脚本,除非必要,即使是新的操作系统版本也不需要编写脚本。
  2.     可靠性:人容易出错,机器不太可能。当运行不能跳过的重复步骤/测试时,速度会更快。
  3.     全天运行:您可以在任何时间或远程启动测试。夜间运行正在测试你的软件,即使是在你睡着的时候。

成熟的、功能齐全的Python测试工具——pytest

目前有多种可用的测试框架和工具。这些框架的风格也各不相同,比如数据驱动、关键字驱动、混合、BDD等等。您可以选择最适合您的要求。

Python和pytest在这场竞争中占据了巨大的份额。Python及其相关工具之所以被大量使用,可能是因为与其他语言相比,没有或很少编程经验的人更能负担得起它们。

pytest框架使得编写小型测试变得很容易,但是可以扩展到支持应用程序和库的复杂功能测试。

Pytest的一些主要特性:

  •     自动发现测试模块和功能
  •     有效的CLI来更好地控制您想要运行或跳过的内容
  •     大型第三方插件生态系统
  •     固定装置-不同的类型,不同的范围
  •     与传统的单元测试框架一起工作
  •     如何使用Pytest进行自动化测试
     

在这里插入图片描述

自动和可配置的测试发现

在默认情况下,pytest期望在名称以test_开头或以_test.py结尾的python模块中找到测试。在默认情况下,它期望测试函数名以test_ 开头。但是,可以通过在pytest的一个配置文件中添加您自己的配置来修改这个测试发现协议。


# content of pytest.ini# Example 1: have pytest look for "check" instead of "test"# can also be defined in tox.ini or setup.cfg file, although the section# name in setup.cfg files should be "tool:pytest"[pytest]python_files = check_*.pypython_classes = Checkpython_functions = *_check

 让我们看一下非常基本的测试函数。

 

class CheckClass(object):def one_check(self):x = "this"assert 'h' in xdef two_check(self):x = "hello"assert hasattr(x, 'check')

你注意到什么了吗?没有花哨的assertEqual或assertDictEqual等,只是简单明了的断言。对于比较两个对象的简单操作,不需要导入这些断言函数。assert是python已经提供的功能,因此无需重新发明。

固定装置会起作用的查看测试功能,测试钱包软件的基本操作,比如,


// test_wallet.pyfrom wallet import Walletdef test_default_initial_amount():wallet = Wallet()assert wallet.balance == 0wallet.close()def test_setting_initial_amount():wallet = Wallet(initial_amount=100)assert wallet.balance == 100wallet.close()def test_wallet_add_cash():wallet = Wallet(initial_amount=10)wallet.add_cash(amount=90)assert wallet.balance == 100wallet.close()def test_wallet_spend_cash():wallet = Wallet(initial_amount=20)wallet.spend_cash(amount=10)assert wallet.balance == 10wallet.close()

嗯,有意思!你注意到了吗,很多样板文件。另一件值得注意的事情是,测试除了测试功能之外还做了一些其他的事情,例如实例化钱包并关闭它——Wallet .close()

现在让我们看看如何使用pytest fixture去除样板

 

import pytestfrom _pytest.fixtures import SubRequestfrom wallet import Wallet#==================== fixtures@pytest.fixturedef wallet(request: SubRequest):param = getattr(request, ‘param’, None)if param:prepared_wallet = Wallet(initial_amount=param[0])else:prepared_wallet = Wallet()yield prepared_walletprepared_wallet.close()#==================== testsdef test_default_initial_amount(wallet):assert wallet.balance == 0@pytest.mark.parametrize(‘wallet’, [(100,)], indirect=True)def test_setting_initial_amount(wallet):assert wallet.balance == 100@pytest.mark.parametrize(‘wallet’, [(10,)], indirect=True)def test_wallet_add_cash(wallet):wallet.add_cash(amount=90)assert wallet.balance == 100@pytest.mark.parametrize(‘wallet’, [(20,)], indirect=True)def test_wallet_spend_cash(wallet):wallet.spend_cash(amount=10)assert wallet.balance == 10

整洁!不是吗。测试函数非常微妙,只做它们想做的事情。夹具钱包负责设置和拆卸、实例化和关闭钱包。它不仅有助于编写可重用的代码,还增加了数据分离的本质。如果仔细看,钱包数量是一块测试逻辑之外提供的测试数据,而不是硬编码在测试函数内部。

@pytest.mark.parametrize(‘wallet’, [(10,)], indirect=True)

在更可控的环境中,您可以在存储库中有一个测试数据文件,例如test-data.ini,以及读取该文件的包装器,并且您的测试函数可以调用包装器的另一个接口来读取测试数据。

但是,建议将您的fixture作为conftest.py文件的一部分。这是pytest中的一个特殊文件,它允许测试发现全局fixture。

但是,有一个针对许多不同数据集执行的测试用例!

不用担心,pytest有一个很酷的特性来参数化您的fixture。让我们用一个例子来看看它。

假设您的产品公开CLI接口以在本地管理它。此外,您的产品在启动时设置了许多默认参数,您需要验证所有这些参数的默认值。我们可以考虑为每个设置编写一个测试用例,但是使用pytest就容易得多了


@pytest.mark.parametrize(“setting_name, setting_value”, [(‘qdb_mem_usage’, ‘low’),(‘report_crashes’, ‘yes’),(‘stop_download_on_hang’, ‘no’),(‘stop_download_on_disconnect’, ‘no’),(‘reduce_connections_on_congestion’, ‘no’),(‘global.max_web_users’, ‘1024’),(‘global.max_downloads’, ‘5’),(‘use_kernel_congestion_detection’, ‘no’),(‘log_type’, ‘normal’),(‘no_signature_check’, ‘no’),(‘disable_xmlrpc’, ‘no’),(‘disable_ntp’, ‘yes’),(‘ssl_mode’, ‘tls_1_2’),])def test_settings_defaults(self, setting_name, setting_value):assert product_shell.run_command(setting_name) == \self.”The current value for \’{0}\’ is \’{1}\’.”.format(setting_name, setting_value), \‘The {} default should be {}’.format(preference_name, preference_value)

很酷,不是吗!,你只写了13个测试用例(每个不同setting_value),在未来如果你添加一个新的设置到你的产品,你需要做的就是,再添加一个tuple上面。

它是如何与selenium和API测试的UI测试集成的

嗯,你的产品可以有多种界面。CLI -就像我们上面讨论的。类似地,GUI和API。在部署软件之前,对所有软件进行测试是很重要的。在多个组件相互依赖和耦合的企业软件中,某个部分的更改可能会影响其他部分。

记住,pytest只是一个促进“测试”的框架,而不是特定类型的测试。因此,您可以使用selenium构建GUI测试,或者使用Python的请求库构建API测试,然后使用pytest运行它。

例如,在高层次上,这可能是您的测试存储库结构。
在这里插入图片描述

正如您在上面看到的,这可以很好地分离组件。

  •     apiobjects:为调用API端点创建包装器的好地方。您可以使用BaseAPIObject和派生类来满足您的需求。
  •     helper:编写您的helper方法
  •     库文件,它可以被不同的组件使用,例如你的fixture在conftest, pageobjects等。
  •     pageobjects:pageobjects设计模式可用于创建不同GUI页面的类。我们在站得住使
  •     用Webium,它是Python的一个页面对象模式实现库。
  •     套件:您可以在这里编写pylint代码验证套件,这将有助于您对代码质量有信心。
  •     测试:可以根据测试的风格对测试目录进行分类。它使管理和研究您的测试变得容易。

这只是供参考,存储库的结构和依赖关系可以按照您的需要进行布局。

我有足够的测试用例,想并行运行它们

您的测试套件中可能有大量的测试用例,并且有时您可能想并行地运行测试用例,以减少总体测试执行时间。

Pytest提供了一个很棒的并行运行测试的插件,名为Pytest -xdist,它用一些独特的执行模式扩展了Pytest。使用pip安装此插件
 

pip install pytest-xdist

让我们通过一个示例来快速研究它。

我有一个自动化测试存储库CloudApp,用于使用selenium进行GUI测试。此外,它还随着新的测试用例不断增长,现在已经有了数百个测试。我想做的是并行运行它们,并减少测试执行时间。

在终端中,只需在项目根文件夹/ tests文件夹中键入pytest。这将执行所有测试。
 

pytest -s -v -n=2

在这里插入图片描述

并行运行测试的pytest-xdist

这还可以帮助您在多个浏览器上并行运行测试。

报告

Pytest内置支持创建结果文件,可由Jenkins、Bamboo或其他持续集成服务器读取,使用如下调用:

pytest test/file/path — junitxml=path

 这可以生成很好的XML风格的输出,可以由许多CI系统解析器解释。

结论

Pytest的受欢迎程度逐年上升。此外,它还拥有广泛的社区支持,这让您可以访问很多扩展,比如pytest-django,它可以帮助您为Django web应用程序集成编写测试。记住,pytest支持运行unittest测试用例,所以如果您正在使用unittest, pytest是值得考虑的。

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!

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

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

相关文章

不懂就问,换毛季猫咪疯狂掉毛怎么办?宠物浮毛该如何清理?

最近天气变热了,每天都30度以上,我家猫狂掉毛,床上、地板上堆积了不少。第一次养猫的我没见过这种阵仗,以为它生病了,连忙带它去看医生。医生告诉我,这是正常的猫咪换毛现象,我才放下心来。原来…

Unity动画模块 之 3D模型导入基础设置 Rig页签

​本文仅作笔记学习和分享,不用做任何商业用途本文包括但不限于unity官方手册,unity唐老狮等教程知识,如有不足还请斧正​​ 1.Rig页签 Rig 选项卡 - Unity 手册,rig是设置骨骼与替身系统的,工作流程如下 Avatar是什么…

C语言每日好题(3)

有任何不懂的问题可以评论区留言&#xff0c;能力范围内都会一一回答 #define _CRT_SECURE_NO_WARNING #include <stdio.h> #include <string.h> int main(void) {if ((strlen("abc") - strlen("abcdef")) > 0)printf(">\n")…

【数据结构】TreeMap和TreeSet

目录 前言TreeMap实现的接口内部类常用方法 TreeSet实现的接口常用方法 前言 Map和set是一种专门用来进行搜索的容器或者数据结构&#xff0c;其搜索的效率与其具体的实例化子类有关。 一般把搜索的数据称为关键字&#xff08;Key&#xff09;&#xff0c; 和关键字对应的称为…

Docker介绍、docker安装以及实现docker的远程管理

1.Docker介绍 1.Docker介绍 Docker 是⼀个开源的应用容器引擎&#xff0c;可以实现虚拟化&#xff0c;完全采用“沙盒”机制&#xff0c;容器之间不会存在任何接口。 Docker 通过 Linux Container&#xff08;容器&#xff09;技术将任意类型的应用进行包装&#xff0c;变成一…

Vue 自定义文字提示框

目录 前言代码演示相关代码文字提示框组件定义组件调用前言 今天开发遇上了一个新的问题,要求写一个带着滑动动画的文字提示框。但是我经常使用的Element-UI组件库只有淡入淡出效果,并且想要修改样式只能全局修改,非常不利于后期的开发。因此,我最终选择直接自定义一个符合…

EXCEL 分段排序--Excel难题#86

Excel某表格有3列。 ABC1A1B1512A2B27213A3B33824A4B495A5B5736A6B65777A7B7918A13B131509A14B144910A17B1770211A18B1870512A34B343313A35B3540914A36B3657915A37B3710 现在要求对表格按照第3列进行分段排序&#xff0c;由小到大排列。第1段&#xff1a;第3列小于等于50&…

vue3 antdv3 去掉Modal的阴影背景,将圆角边框改为直角的显示,看上去不要那么的立体的样式处理。

1、来个没有处理的效果图&#xff1a; 这个有立体的效果&#xff0c;有阴影的效果。 2、要处理一下样式&#xff0c;让这个阴影的效果去掉&#xff1a; 图片的效果不太明显&#xff0c;但是阴影效果确实没有了。 3、代码&#xff1a; /* 去掉遮罩层阴影 */.ant-modal-mask {…

【R语言】基于多模型的变量重要性图 (Variable Importance Plots)

变量重要性图 Variable Importance Plots 1. 写在前面2.1数据导入2.2 模型训练2.3 变量重要性2.4 变量重要性图2.5 模型模拟验证3.基于caret包计算变量重要性 1. 写在前面 好久没有更新博客了&#xff0c;正好最近在帮老师做一个项目&#xff0c;里面涉及到了不同环境变量的重要…

动态规划篇-代码随想录算法训练营第三十七天| 打家劫舍Ⅰ,打家劫舍Ⅱ,打家劫舍Ⅲ

打家劫舍Ⅰ 题目链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 讲解视频&#xff1a; 动态规划&#xff0c;偷不偷这个房间呢&#xff1f;| LeetCode&#xff1a;198.打家劫舍 题目描述&#xff1a; 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间…

2024年8月22日嵌入式学习

今日主要学习网络知识 udp recvfrom ssize_t recvfrom(int sockfd, //socket的fd void *buf, //保存数据的一块空间的地址 size_t len, //这块空间的大小 int flags, // 0 默认的接收方式 --- 阻塞方式…

10 Java数据结构:包装类、数组(Array工具类)、ArrayList

文章目录 前言一、包装类1、Integer&#xff08;1&#xff09;基本用法&#xff08;2&#xff09;JDK5前的包装类用法&#xff08;了解即可&#xff0c;能更好帮助我们理解下面的自动装箱和自动拆箱机制&#xff09;&#xff08;3&#xff09;自动装箱与自动拆箱机制 --- 导致&…

基于HarmonyOS的宠物收养系统的设计与实现(一)

基于HarmonyOS的宠物收养系统的设计与实现&#xff08;一&#xff09; 本系统是简易的宠物收养系统&#xff0c;为了更加熟练地掌握HarmonyOS相关技术的使用。 项目创建 创建一个空项目取名为PetApp 首页实现&#xff08;组件导航使用&#xff09; 官方文档&#xff1a;组…

redis实战——go-redis的使用与redis基础数据类型的使用场景(一)

一.go-redis的安装与快速开始 这里操作redis数据库&#xff0c;我们选用go-redis这一第三方库来操作&#xff0c;首先是三方库的下载&#xff0c;我们可以执行下面这个命令&#xff1a; go get github.com/redis/go-redis/v9最后我们尝试一下连接本机的redis数据库&#xff0…

黑神话孙悟空:自媒体小白的流量密码!

当下&#xff0c;黑神话孙悟空的热度如熊熊烈火&#xff0c;席卷了整个游戏世界。 只要与这个话题沾边&#xff0c;似乎就能轻松吸引大量关注。 那么&#xff0c;对于不怎么懂自媒体运营的小伙伴来说&#xff0c;该如何抓住这个机遇呢&#xff1f; 别担心&#xff0c;我们用以…

授权cleanmymac访问全部磁盘 Mac授权访问权限 cleanmymac缺少权限

CleanMyMac是Mac系统下的一款专业的苹果电脑清理软件&#xff0c;同时也是一款优秀的电脑系统管理软件。它能有效清理系统垃圾&#xff0c;快速释放磁盘内存&#xff0c;缓解卡顿现象&#xff0c;保障系统顺畅地运行。 全磁盘访问权限&#xff0c;就好比机场内进行的安全检查。…

微软AI人工智能认证有哪些?

微软提供的人工智能认证主要包括以下几个方面&#xff1a; Azure AI Fundamentals&#xff08;AI900认证&#xff09;&#xff1a;这是一个基础认证&#xff0c;旨在展示与Microsoft Azure软件和服务开发相关的基本AI概念&#xff0c;以创建AI解决方案。它面向具有技术和非技术…

Vue 导航条+滑块效果

目录 前言代码效果展示导航实现代码导航实现代码导航应用代码前言 总结一个最近开发的需求。设计稿里面有一个置顶的导航条,要求在激活的项目下面展示个下划线。我最先开始尝试的是使用 after 的伪类选择器,直接效果一样,但是展示的时候就会闪现变化,感觉不够自然,参考了一…

ES6解构赋值详解;全面掌握:JavaScript解构赋值的终极指南

目录 全面掌握&#xff1a;JavaScript解构赋值的终极指南 一、数组解构赋值 1、基本用法 2、跳过元素 3、剩余元素 4、默认值 二、对象解构赋值 1、基本用法 2、变量重命名 3、默认值 4、嵌套解构 三、复杂的嵌套结构解构 四、函数参数解构赋值 1、对象解构作为函…

ARM——驱动——Linux启动流程和Linux启动

一、flash存储器 lash存储器&#xff0c;全称为Flash EEPROM Memory&#xff0c;又名闪存&#xff0c;是一种长寿命的非易失性存储器。它能够在断电情况下保持所存储的数据信息&#xff0c;因此非常适合用于存储需要持久保存的数据。Flash存储器的数据删除不是以单个的字节为单…