本文的翻译是专门为Python QA工程师课程的学生准备的。
我们生活在一个软件正迅速推向市场的时代。 因此,开发过程变得非常紧张。 较高的软件实施速度和快速交付看起来是业务模型的重要组成部分,但是这里出现了有关如何交付质量合适的软件的问题。
为什么我们需要自动化测试
自动化测试有很多优点,这是三个主要优点:
重用:即使有新版本的操作系统,也不必每次都编写新的脚本,除非迫切需要。
可靠性:人们容易犯错误,而汽车则使错误发生的可能性降低。 当执行需要连续执行的重复步骤/测试时,它们的工作速度更快。
工作24/7:您可以在一天中的任何时间(甚至是远程)开始测试。 如果您从晚上开始测试,即使您在睡觉时也可以运行。
用Python开发的全功能pytest测试工具
当前,有许多测试框架和工具。 有不同类型的框架,例如,数据驱动,关键字驱动,混合,BDD等。 您可以选择最适合您的要求的一种。
我必须说,Python和
pytest
在这件事上占据着巨大的位置。 Python及其相关工具得到了广泛的使用,可能是因为与其他语言相比,几乎没有编程经验的人更容易使用它们。
pytest
框架
pytest
编写小型测试
pytest
容易,但它也可以扩展以支持应用程序和库的复杂功能测试。
pytest
一些关键功能:
- 自动检测测试模块和功能;
- 有效的CLI可改善对您要运行或跳过的内容的控制;
- 大型第三方插件生态系统;
- 夹具-不同类型,不同应用;
- 使用传统的单元测试框架。
自动和可配置的测试检测
默认情况下,
pytest
期望在名称以
test_
或
test_
结束的Python模块中查找测试。 另外,默认情况下,它期望测试函数的名称以前缀
test_
。 但是,可以通过将您自己的配置添加到
pytest
配置
pytest
之一来更改此测试检测协议。
让我们看一个非常简单的测试函数:
class CheckClass(object): def one_check(self): x = "this" assert 'h' in x def two_check(self): x = "hello" assert hasattr(x, 'check')
你有没有注意到? 没有
assertEqual
或
assertDictEqual
,只有可访问且可理解的
assert
。 无需导入这些函数即可简单地比较两个对象。 断言是Python已经拥有的东西,不需要重新发明轮子。
模板代码? 不用担心,夹具会抢救!
查看测试电子钱包程序中基本操作的测试函数:
// test_wallet.py from wallet import Wallet def test_default_initial_amount(): wallet = Wallet() assert wallet.balance == 0 wallet.close() def test_setting_initial_amount(): wallet = Wallet(initial_amount=100) assert wallet.balance == 100 wallet.close() def test_wallet_add_cash(): wallet = Wallet(initial_amount=10) wallet.add_cash(amount=90) assert wallet.balance == 100 wallet.close() def test_wallet_spend_cash(): wallet = Wallet(initial_amount=20) wallet.spend_cash(amount=10) assert wallet.balance == 10 wallet.close()
嘿,有趣! 你注意到了吗? 有很多样板代码。 另一点值得注意的是,此测试除了测试功能部件之外还执行其他操作,例如,创建Wallet并使用
wallet.close()
将其关闭。
现在让我们看一下如何使用pytest
pytest
摆脱样板代码。
import pytest from _pytest.fixtures import SubRequest from wallet import Wallet
很好,不是吗? 现在,测试功能非常紧凑,并且可以完全执行它们应该执行的操作。 使用
wallet
配置,安装和关闭电子
wallet
。 固定装置不仅有助于编写可重用的代码,而且还增加了数据共享的概念。 如果仔细观察,
wallet
的金额就是测试逻辑外部提供的测试数据的一部分,而不是固定在函数内部。
@pytest.mark.parametrize('wallet', [(10,)], indirect=True)
在更受控制的环境中,您可能具有一个包含测试数据的文件,例如可以读取该文件的存储库或外壳中的
test-data.ini
,而您的测试功能可以调用各种外壳以读取测试数据。
但是,建议将所有灯具放在一个特殊的
conftest.py
文件中。 这是pytest中的一个特殊文件,允许测试检测全局夹具。
但是我有一些要在不同数据集上运行的测试用例!
别担心,
pytest
具有一个很酷的功能来参数化您的灯具。 让我们来看一个例子。
假设您的产品具有本地管理的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
),并且将来,如果您向产品中添加新参数,那么您要做的就是添加另一个元组。
pytest如何与Selenium和API测试的用户界面测试集成?
好吧,您的产品可能有多个接口。 CLI-如上所述。 类似于GUI和API。 在部署软件产品之前,对所有产品进行测试非常重要。 在企业软件中,几个组件相互连接并且相互依赖,一个部分的更改会影响所有其他部分。
请记住,
pytest
只是用于简单测试的框架,而不是特定类型的测试。 也就是说,您可以使用Selenium为GUI创建测试,或者使用Python的
requests
库为API创建测试,然后使用
pytest
运行它们。
例如,在较高级别上,这可能是对存储库结构的检查。

如您在上图中所看到的,这为分离组件提供了一个很好的机会:
apiobjects :创建用于调用API端点的包装器的好地方。 您可能拥有一个
BaseAPIObject
和一个满足您要求的派生类。
helpers :您可以在这里添加您的helper方法。
lib :可以由各种组件使用的库文件,例如,
conftest
的
conftest
,
pageobjects
等。
pageobjects :
PageObjects体系结构
PageObjects
可用于为各种GUI页面创建类。 我们使用
Webium ,它是Python页面对象模板的实现库。
套件 :您可以编写自己的一组pylint检查代码,它们将帮助您对代码质量更有信心。
测试 :您可以根据自己的喜好对测试进行分类。 这将使管理和检查测试变得容易。
我带来它只是为了参考,可以根据您的个人需求来组织存储库的结构和依赖项。
我有很多测试用例,我希望它们可以并行运行
您的集合中可以有许多测试用例,碰巧您需要并行运行它们并减少总体测试执行时间。
Pytest提供了一个很棒的并行测试运行插件
pytest-xdist
,它为基本pytest添加了几种独特的执行模式。 使用
pip
安装此插件。
pip install pytest-xdist
让我们来看一个例子。
我有一个用于Selenium GUI测试的CloudApp自动化测试存储库。 此外,它还在不断发展和更新新的测试,现在有数百个测试。 我想做的是并行运行它们,并减少总体测试执行时间。
在终端中,只需在项目根文件夹/ test文件夹中键入
pytest
。 这将允许您执行所有测试。
pytest -s -v -n=2

pytest-xdist
将并行运行所有测试!
这样,您还可以并行运行多个浏览器。
报告书
Pytest内置支持创建测试结果文件的功能,可以使用Jenkins,Bamboo或其他持续集成服务器打开这些测试结果文件。 使用以下内容:
pytest test/file/path — junitxml=path
这将有助于生成可通过许多解析器打开的出色XML文件。
结论
Pytest的知名度每年都在增长。 此外,它还具有强大的社区支持,使您可以访问许多扩展,例如
pytest-django ,这将帮助您在Django中编写针对Web应用程序的测试。 请记住,pytest支持unittest测试用例,因此,如果使用
unittest
,则应该更详细地考虑pytest。
资料来源
仅此而已。 在
课程中见!