前言
¶
Simple, Rapid, Effective, and Scalable
作者:Brian Okken
我发现《Python Testing with pytest》是一本非常有用的 pytest 测试框架入门指南。它已经为我的公司带来了回报。
➤ Chris Shaver
Uprising Technology 产品副总裁
系统的软件测试,特别是在 Python 社区中,通常要么完全被忽视,要么以特别的方式完成。许多 Python 程序员完全不知道 pytest 的存在。Brian Okken 不厌其烦地证明用 pytest 进行软件测试是简单的,自然的,甚至是令人兴奋的。
➤ Dmitry Zinoviev
Author of Data Science Essentials in Python
这本书是每一本综合性的 Python 书籍中缺失的章节。
➤ Frank Ruiz
Principal Site Reliability Engineer, Box, Inc.
目录¶
- 启航
- 安装 pytest
- 执行 pytest
- 用例发现
- 结果详解
- 使用选项
- 测试函数(functions)
- Task 项目
- assert 语句
- 捕获异常
- 匹配标记
- 内置标记
- 测试子集
- 夹具(fixtures)
- 夹具概念
- 夹具定义
- 夹具共享
- 作用域
- 自动使用
- 命名
- 参数化
- 标记夹具
- 内置夹具(built-in fixtures)
- 临时目录
tmpdir
和tmpdir_factory
- 配置选项
pytestconfig
- 缓存
cache
- 捕获输出
capsys
- 猴子补丁
monkeypatch
- 文档信息
doctest_namespace
- 警告信息
recwarn
- 插件(plugins)
- 获取插件
- 安装插件
- 定制插件
- 打包插件
- 测试插件
- 发布插件
- 配置(configurations)
- 配置文件
- 定制配置项
- 定制发现规则
- 禁用 XPASS
- 避免文件名冲突
- 相关工具
- 调试:pdb
- 覆盖率:pytest-cov
- 替身:mock
- 多种配置:tox
- 持续集成:Jenkins CI
- 遗留测试:unittest
前言¶
Python 的使用不仅在软件开发中越来越多,而且在数据分析、研究科学、测试和测量等领域以及其他行业中也越来越多。Python 在许多关键领域的增长还伴随着对正确、有效和高效地安装软件测试的渴望,以确保程序正确运行并产生正确的结果。此外,越来越多的软件项目正在接受持续集成,并包括一个自动化测试阶段,因为发布周期正在缩短,对越来越复杂的项目进行彻底的人工测试是不可行的。团队需要能够信任由持续集成服务器运行的测试来告诉他们是否能够足够信任他们的软件来发布它。
什么是 pytest?¶
pytest
是一个强大的 Python
测试工具,可以用于所有类型和级别的软件测试。pytest
可以被开发团队、 QA 团队、独立的测试团队、实践 TDD
的个人以及开源项目使用。事实上,整个互联网上的项目已经从 unittest 或 nose 转向 pytest,包括 Mozilla
和 Dropbox
。为什么?因为 pytest 提供了强大的特性,比如“断言”重写、第三方插件模型,以及在其他任何测试框架中都无法匹配的强大而简单的 fixture 装置模型。
pytest 是一个软件测试框架,这意味着 pytest 是一个命令行工具,可以自动查找您编写的测试用例,运行测试,并报告结果。它有众多的库供你在测试中使用,以帮助你更有效地测试。它还支持通过编写插件或安装第三方插件来进行扩展。它还可以用来测试 Python 发行版。而且它很容易与其他工具集成,比如持续集成和 web 自动化。
下面是 pytest 在其他测试框架中脱颖而出的一些原因:
- 用 pytest 编写简单的测试非常简单
- 复杂的测试仍然很容易编写
- 测试用例已于阅读
- 上手很快
- 断言只需 assert
- 可以用 pytest 来运行 unittest 或 nose 编写的测试用例
Pytest 是由一个充满激情和不断成长的社区积极开发和维护的。它具备如此优秀的可扩展性和灵活性,以至于它很容易适应你的工作流程。因为它是与 Python 版本分开安装的,所以您可以在旧版本的 python2(2.6 及以上版本)和 python3(3.3 及以上版本)上使用相同的最新版本的 pytest。
Tasks 项目介绍¶
我们将要看到的应用程序叫做 Tasks。Tasks 是一个带有命令行用户界面的最小任务跟踪应用程序。它与许多其他类型的应用程序有足够多的共同之处,我希望您能够很容易地看到您在编写基于 Tasks 的测试时所学到的测试概念是如何适用于现在和将来的项目的。
虽然 Tasks 有一个命令行界面(CLI) ,但 CLI 通过一个应用程序编程接口(API)与代码的其余部分进行交互。API 是我们用来指导大部分测试的接口。API 与数据库控制层交互,数据库控制层与文档数据库(MongoDB 或 TinyDB)交互。数据库类型是在数据库初始化时配置的。
在我们关注 API 之前,让我们看看 tasks
,代表 Tasks 用户界面的命令行工具。
下面是一个例子:
$ tasks add 'do something' --owner Brian
$tasks add 'do something else'
$tasks list
$ tasks update 2 --owner
$ tasks list
$ tasks update 1 --done True
$tasks list
$ tasks delete 1
$ tasks list
这不是最复杂的任务管理应用程序,但是它足够复杂,可以用来探索测试。
测试策略¶
尽管pytest 可用于单元测试、集成测试、系统或端到端测试以及功能测试。
以下是一些有用的定义:
「单元测试」 Unit test
检查一小段代码的测试,比如一个函数或者一个类,独立于系统的其他部分。
我认为第一章,“Getting Started with pytest”,第一页中的测试是对 Tasks 数据结构运行的单元测试。
「集成测试」 Integration test
检查较大一部分代码(可能是几个类或一个子系统)的测试。大多数情况下,它是用于某些测试的标签,这些测试比单元测试大,但比系统测试小。
系统测试(端到端) System test(end-to-end)
是在尽可能接近最终用户环境的环境中,检查所有被测系统的测试。
功能测试 Functional test
检查系统某一个特定功能的测试。例如检查我们在 Tasks 中添加、删除或更新任务条目的效果的测试是一个功能测试。
本书概要¶
- Chapter 1, Getting Started with pytest
你将安装 pytest 并准备使用它。然后,将获得 Tasks 项目的一部分——表示单个任务的数据结构(名为 Task 的元组)——并使用它来测试示例。将学习如何使用一些测试文件来运行 pytest。将看到许多用于 pytest 的流行且非常有用的命令行选项,例如能够测试失败后重跑、在第一次失败后停止执行、控制堆栈跟踪信息和测试详细运行用例等等。
- Chapter 2, Writing Test Functions
在第 2 章,编写测试函数,第 23 页,您将使用 pip 在本地安装 Tasks,并了解如何在 Python 项目中构造测试。这样你就可以开始针对真实的应用程序编写测试了。本章中的所有例子都是针对已安装的应用程序运行测试,包括写入数据库。实际的测试函数是本章的重点,你将学习如何在测试中有效地使用断言。您还将了解标记,这个特性允许您同时标记要运行的许多测试,标记要跳过的测试,或者告诉 pytest 我们已经知道有些测试将会失败。我将介绍如何运行一些测试,不仅仅是使用标记,而是通过将测试代码结构化为目录、模块和类,以及如何运行这些测试子集。
- Chapter 3, pytest Fixtures
并不是所有的测试代码都用于测试函数。在第 3 章,您将学习如何将测试数据传入测试装置 fixture,以及前置 setup 和后置处理 teardown。
设置系统状态(或子系统或单元状态)是软件测试的一个重要部分。您将探索 pytest fixture 的这一方面,以帮助初始化 Tasks 项目的数据库,并预先填充一些测试的测试数据。Fixture 是 pytest 非常强大的一部分,您将学习如何有效地使用它们来进一步减少测试代码的重复,并使您的测试代码具有非常好的可读性和可维护性。Pytest fixture 也是可参数化的,类似于测试函数,您可以使用这个特性在 TinyDB 和 MongoDB (Tasks 支持的数据库后端)上运行所有测试。
- Chapter 4, Builtin Fixtures
在第 4 章,你将看到 pytest 提供的一些现成的内置固定装置。您将了解 pytest 内置装置如何为您跟踪临时目录和文件,帮助您测试被测代码的输出,使用猴子补丁,检查警告,等等。
- Chapter 5, Plugins
在第 5 章,您将学习如何向 pytest 添加命令行选项,修改 pytest 输出,以及通过编写、打包和分发自己的插件与其他人共享 pytest 定制,包括 fixture。我们在本章中开发的插件是用来让我们在测试 Tasks 时看到的测试失败变得更好一点。您还将看到如何正确地测试您的测试插件。这对 meta 来说怎么样?为了防止你没有从本章中得到足够的灵感来写一些你自己的插件,我亲自挑选了一些很棒的插件来展示,详见附录 3 Plugin Sampler Pack。
- Chapter 6, Configuration
说到自定义,您将了解如何使用配置文件自定义 pytest 如何在默认情况下运行您的项目。使用 pytest.ini 文件,您可以做一些事情,比如存储命令行选项,这样就不必每次都输入它们,告诉 pytest 不要查找测试文件的特定目录,指定测试所针对的最小 pytest 版本等等。这些配置元素也可以放在 tox.ini 或 setup.cfg 中。
- Chapter 7, Using pytest with Other Tools
在最后一章,您将看到如何使用已经强大的 pytest,并用补充工具增强您的测试。你将使用 tox 在多个 Python 版本上运行 Tasks 项目。你将测试 Tasks CLI,同时不必使用 mock 运行系统的其余部分。你可以使用 coverage.py 来查看是否有任何 Tasks 项目的源代码没有被测试。你可以使用 Jenkins 来运行测试套件,并随着时间的推移显示结果。最后,您将看到 pytest 如何用于运行 unittest 测试用例,以及如何与基于 unittest 的测试共享 pytest 样式的 fixture 装置。
你需要准备的¶
- Python
您不需要精通 Python,这些示例不会做任何超级奇怪或花哨的事情。
- pip
您应该使用 pip 命令来安装 pytest 和 pytest 插件。
- 命令行
我写这本书,并在 Mac 笔记本电脑上使用 bash 捕获了示例输出。然而,我在 bash 中唯一使用的命令是 cd
到一个特定的目录,当然还有 `pytest
命令。由于 cd 存在于 Windows cmd.exe 和我所知道的所有 unix shell 中,因此所有示例都应该可以在您选择使用的任何类似终端的应用程序上运行。
就是这样,真的,你不需要成为一个编程专家就可以开始用 pytest 编写自动化软件测试。
示例代码¶
本书中的示例是使用 Python 3.6 和 pytest 3.2 版本编写的。Pytest 3.2 版本支持 python2.6、2.7 和 python3.3 + 。