如何使用Pytest进行测试

开始使用 Python 进行测试可能十分困难。Python 的标准库确实提供了一些用于编写测试的实用程序和帮助程序,但也有一些缺点可能会导致编写比较困难。

Pytest 是最常用的 Python 测试工具和框架之一。尽管 Pytest 可以帮助实现高度复杂的测试方案,但在创建测试时,它不会强制使用其功能。你可以编写简单的测试,但仍受益于快速且功能齐全的测试运行程序以及有用的报告。

Pytest 的一个关键点在于利用它可以更轻松地编写测试。可以编写一个没有依赖项或配置的测试函数并立即运行测试。

我们在此介绍 Pytest 入门所需的一些基础知识,以便你可以将自己的测试套件提升到新的水平。

要学习的知识

完成本模块后,能够使用 Pytest 编写测试,解释其丰富的故障报告,并利用其功能齐全的测试运行程序。应该可以轻松使用测试函数和类,并且能够确定何时使用哪一个。

有了这些知识后,你可以:

  • 使用 Pytest 的现有测试或扩展现有的测试套件。

  • 使用 Pytest 的错误报告准确确定故障。

  • 使用 Pytest 作为库和命令行工具。

主要目标是什么?

你应该可以轻松使用 Pytest 和编写 Pytest 测试,在我们的帮助下编写更多更好的测试,成为更高效的工程师。

0Pytest基础知识

让我们开始使用 Pytest 进行测试。如上面所述,Pytest 高度可配置,可处理复杂的测试套件。但是,开始编写测试时不需要用到太多。事实上,编写测试的框架越简单越好。

在本部分结束时,应拥有开始编写第一个测试并使用 Pytest 运行它们所需的一切内容。

约定

在深入了解编写测试之前,我们必须了解 Pytest 所依赖的一些测试约定。

在 Python 中没有关于测试文件、测试目录或常规测试布局的硬性规则。你可以通过了解这些规则使用自动测试发现和执行,而无需进行任何其他配置。

测试目录和测试文件

测试的主目录是 tests 目录。可以将此目录置于项目的根级别,但有人也经常把它与代码模块放在一起。

备注

在本模块中,我们默认使用项目根目录中的 tests。

让我们看看名为 jformat 的小型 Python 项目的根目录是怎样的:

 
  1. .

  2. ├── README.md

  3. ├── jformat

  4. │ ├── __init__.py

  5. │ └── main.py

  6. ├── setup.py

  7. └── tests

  8. └── test_main.py

tests 目录位于具有一个测试文件的项目的根目录中。在这种情况下,此测试文件称为 test_main.py。此示例演示了两个关键约定:

  • 使用 tests 目录来放置测试文件和嵌套的测试目录。

  • 测试文件的前缀为 test。此前缀指示文件包含测试代码。

注意

避免将 test(单一形式)用作目录名称。test 名称是一个 Python 模块,因此创建一个与之同名的目录将会替代它。请始终改用复数形式的 tests。

测试函数

使用 Pytest 的一个有力论据是,它允许编写测试函数。与测试文件类似,测试函数必须带有 test_ 前缀。test_ 前缀可确保 Pytest 收集并执行测试。

一个简单的测试函数如下所示:

 
  1. def test_main():

  2. assert "a string value" == "a string value"

备注

如果你熟悉使用 unittest,则在测试函数中使用 assert 可能会令人惊喜。稍后我们会更详细地介绍普通断言,但使用 Pytest,你将通过普通断言获得丰富的失败报告。

测试类和测试方法

与文件和函数的约定类似,测试类和测试方法使用以下约定:

  • 测试类的前缀为 Test

  • 测试方法的前缀为 test_

与 Python 的 unittest 库的核心区别在于无需继承。

以下示例对类和方法使用这些前缀和其他 Python 命名约定。它演示了一个小型测试类,该类在检查应用程序中的用户名。

 
  1. class TestUser:

  2. def test_username(self):

  3. assert default() == "default username"

运行测试

Pytest 既是测试框架,也是测试运行程序。测试运行程序是命令行中的可执行文件,在高级别可以:

  • 通过查找测试运行的所有测试文件、测试类和测试函数来执行测试集合。

  • 通过执行所有测试来启动测试运行。

  • 跟踪测试失败、测试错误和测试通过的信息。

  • 在测试运行结束时提供丰富的报告。

备注

由于 Pytest 是外部库,因此必须安装后才能使用。

鉴于 test_main.py 文件中的这些内容,我们可以看到 Pytest 运行测试时的行为:​​​​​​​

 
  1. # contents of test_main.py file

  2. def test_main():

  3. assert True

在命令行中,在 test_main.py 文件所在的同一路径中,可以运行 pytest 可执行文件:​​​​​​​

 
  1. $ pytest

  2. =========================== test session starts ============================

  3. platform -- Python 3.10.1, pytest-6.2.5, py-1.11.0, pluggy-1.0.0

  4. rootdir: /private/tmp/project

  5. collected 1 item

  6. test_main.py . [100%]

  7. ============================ 1 passed in 0.00s =============================

在后台,Pytest 可收集测试文件中的示例测试,而无需进行任何配置。

强大的断言语句

到目前为止,测试示例全部使用普通的 assert 调用。在 Python 中,assert 语句不用于测试,因为它在断言失败时缺少正确的报告。但是,Pytest 没有此限制。在后台,Pytest 使语句能够执行丰富的比较,而无需强制用户编写更多代码或配置任何内容。

通过使用普通的 assert 语句,可以使用 Python 的运算符。例如:>、<、!=、>= 或 <=。所有 Python 运算符都是有效的。此功能可能是 Pytest 最关键的功能:你不需要了解用于编写断言的新语法。

让我们看看在处理与 Python 对象的常见比较时它是如何转换的。在本例中,我们在比较长字符串时完成失败报告:

 
  1. ================================= FAILURES =================================

  2. ____________________________ test_long_strings _____________________________

  3. def test_long_strings():

  4. left = "this is a very long strings to be compared with another long string"

  5. right = "This is a very long string to be compared with another long string"

  6. > assert left == right

  7. E AssertionError: assert 'this is a ve...r long string' == 'This is a ve...r long string'

  8. E - This is a very long string to be compared with another long string

  9. E ? ^

  10. E + this is a very long strings to be compared with another long string

  11. E ? ^ +

  12. test_main.py:4: AssertionError

Pytest 显示有关失败的有用上下文。字符串开头的大小写不正确,单词中包含一个额外字符。但除字符串外,Pytest 还可以帮助其他对象和数据结构。例如,以下是它处理列表的方式:

 
  1. ________________________________ test_lists ________________________________

  2. def test_lists():

  3. left = ["sugar", "wheat", "coffee", "salt", "water", "milk"]

  4. right = ["sugar", "coffee", "wheat", "salt", "water", "milk"]

  5. > assert left == right

  6. E AssertionError: assert ['sugar', 'wh...ater', 'milk'] == ['sugar', 'co...ater', 'milk']

  7. E At index 1 diff: 'wheat' != 'coffee'

  8. E Full diff:

  9. E - ['sugar', 'coffee', 'wheat', 'salt', 'water', 'milk']

  10. E ? ---------

  11. E + ['sugar', 'wheat', 'coffee', 'salt', 'water', 'milk']

  12. E ? +++++++++

  13. test_main.py:9: AssertionError

此报告标识索引 1(列表中的第二项)有所不同。它不仅标识索引号,还提供失败的表示形式。除了提供项比较之外,它还可以报告项是否缺失,并提供信息,使你准确得知可能是哪一项。在以下情况中,此项为 "milk":

 
  1. ________________________________ test_lists ________________________________

  2. def test_lists():

  3. left = ["sugar", "wheat", "coffee", "salt", "water", "milk"]

  4. right = ["sugar", "wheat", "salt", "water", "milk"]

  5. > assert left == right

  6. E AssertionError: assert ['sugar', 'wh...ater', 'milk'] == ['sugar', 'wh...ater', 'milk']

  7. E At index 2 diff: 'coffee' != 'salt'

  8. E Left contains one more item: 'milk'

  9. E Full diff:

  10. E - ['sugar', 'wheat', 'salt', 'water', 'milk']

  11. E + ['sugar', 'wheat', 'coffee', 'salt', 'water', 'milk']

  12. E ? ++++++++++

  13. test_main.py:9: AssertionError

最后,让我们看看它如何处理字典。如果存在失败,则比较两个大字典可能会让人难以应对,但 Pytest 在提供上下文并查明失败时会执行未完成的工作:

 
  1. ____________________________ test_dictionaries _____________________________

  2. def test_dictionaries():

  3. left = {"street": "Ferry Ln.", "number": 39, "state": "Nevada", "zipcode": 30877, "county": "Frett"}

  4. right = {"street": "Ferry Lane", "number": 38, "state": "Nevada", "zipcode": 30877, "county": "Frett"}

  5. > assert left == right

  6. E AssertionError: assert {'county': 'F...rry Ln.', ...} == {'county': 'F...ry Lane', ...}

  7. E Omitting 3 identical items, use -vv to show

  8. E Differing items:

  9. E {'street': 'Ferry Ln.'} != {'street': 'Ferry Lane'}

  10. E {'number': 39} != {'number': 38}

  11. E Full diff:

  12. E {

  13. E 'county': 'Frett',...

  14. E

  15. E ...Full output truncated (12 lines hidden), use '-vv' to show

在此测试中,字典中有两个失败。一个是 "street" 值不同,另一个是 "number" 不匹配。

Pytest 可以准确地检测到这些差异(即使它是单个测试中的一个失败)。由于字典包含许多项,Pytest 省略相同的部分,且只显示相关内容。如果我们使用建议的 -vv 标记来使输出内容更加详细,让我们看看会发生什么情况:

 
  1. ____________________________ test_dictionaries _____________________________

  2. def test_dictionaries():

  3. left = {"street": "Ferry Ln.", "number": 39, "state": "Nevada", "zipcode": 30877, "county": "Frett"}

  4. right = {"street": "Ferry Lane", "number": 38, "state": "Nevada", "zipcode": 30877, "county": "Frett"}

  5. > assert left == right

  6. E AssertionError: assert {'county': 'Frett',\n 'number': 39,\n 'state': 'Nevada',\n 'street': 'Ferry Ln.',\n 'zipcode': 30877} == {'county': 'Frett',\n 'number': 38,\n 'state': 'Nevada',\n 'street': 'Ferry Lane',\n 'zipcode': 30877}

  7. E Common items:

  8. E {'county': 'Frett', 'state': 'Nevada', 'zipcode': 30877}

  9. E Differing items:

  10. E {'number': 39} != {'number': 38}

  11. E {'street': 'Ferry Ln.'} != {'street': 'Ferry Lane'}

  12. E Full diff:

  13. E {

  14. E 'county': 'Frett',

  15. E - 'number': 38,

  16. E ? ^

  17. E + 'number': 39,

  18. E ? ^

  19. E 'state': 'Nevada',

  20. E - 'street': 'Ferry Lane',

  21. E ? - ^

  22. E + 'street': 'Ferry Ln.',

  23. E ? ^

  24. E 'zipcode': 30877,

  25. E }

通过运行 pytest -vv,报告会增加详细信息量,并提供精细比较。此报告不仅会检测并显示失败,还支持快速进行更改以修正问题。

02 测试类和方法

使用 Pytest 除了能编写测试函数外,还能使用类。正如我们已经提到的,不需要继承,测试类只遵循一些简单的规则。使用类可以提高灵活性和可重用性。正如你接下来会看到的,Pytest 不会妨碍你,并会避免强制你以某种方式编写测试。

与函数一样,仍然可以使用 assert 语句编写断言。

生成测试类

让我们使用一个实际场景来了解测试类如何提供帮助。以下函数检查给定文件在其内容中是否包含“yes”。如果包含,则返回 True。如果文件不存在,或在其内容中包含“no”,则返回 False。这种情况在使用文件系统指示完成情况的异步任务中很常见。

该函数如下所示:

 
  1. import os

  2. def is_done(path):

  3. if not os.path.exists(path):

  4. return False

  5. with open(path) as _f:

  6. contents = _f.read()

  7. if "yes" in contents.lower():

  8. return True

  9. elif "no" in contents.lower():

  10. return False

下面是名为 test_files.py 的文件中的具有两个测试(每个条件一个测试)的类:

 
  1. class TestIsDone:

  2. def test_yes(self):

  3. with open("/tmp/test_file", "w") as _f:

  4. _f.write("yes")

  5. assert is_done("/tmp/test_file") is True

  6. def test_no(self):

  7. with open("/tmp/test_file", "w") as _f:

  8. _f.write("no")

  9. assert is_done("/tmp/test_file") is False

注意

测试方法对临时测试文件使用 /tmp 路径,因为它更容易用于示例。但是,如果需要使用临时文件,请考虑使用 tempfile 之类的库,它可安全地创建(和删除)这些文件。并非所有系统都有 /tmp 目录,并且该位置可能不是临时的,具体取决于操作系统。

若使用 -v 标志运行测试以增加详细程度,可显示测试通过:

 
  1. pytest -v test_files.py

  2. ============================= test session starts ==============================

  3. Python 3.9.6, pytest-6.2.5, py-1.11.0, pluggy-1.0.0

  4. cachedir: .pytest_cache

  5. rootdir: /private/

  6. collected 2 items

  7. test_files.py::TestIsDone::test_yes PASSED [ 50%]

  8. test_files.py::TestIsDone::test_no PASSED [100%]

  9. ============================== 2 passed in 0.00s ===============================

虽然通过了测试,但它们看起来存在重复,并且在测试完成后还会留下文件。让我们先在下一部分中了解帮助程序方法,然后再了解如何改进测试。

帮助器方法

在测试类中,可以使用几种方法来设置和拆解测试执行。如果定义了测试,Pytest 会自动执行。若要使用这些方法,应知道它们具有特定的顺序和行为。

  • setup:在类中的每个测试之前执行一次

  • teardown:在类中的每个测试之后执行一次

  • setup_class:在类中的所有测试之前执行一次

  • teardown_class:在类中的所有测试之后执行一次

如果测试需要类似的(或相同的)资源才能正常工作时,编写设置方法会很有用。理想情况下,测试完成后不应留下资源,因此在这些情况下,拆解方法可以帮助进行测试清理。

清理

现在来看一个更新的测试类,它会在每次测试后清理文件:

 
  1. class TestIsDone:

  2. def teardown(self):

  3. if os.path.exists("/tmp/test_file"):

  4. os.remove("/tmp/test_file")

  5. def test_yes(self):

  6. with open("/tmp/test_file", "w") as _f:

  7. _f.write("yes")

  8. assert is_done("/tmp/test_file") is True

  9. def test_no(self):

  10. with open("/tmp/test_file", "w") as _f:

  11. _f.write("no")

  12. assert is_done("/tmp/test_file") is False

由于使用了 teardown() 方法,所以此测试类不再遗留 /tmp/test_file。

设置

我们可以对此类执行的另一个改进是添加指向文件的变量。由于该文件现已在六个位置声明,因此对路径的任何更改都意味着在所有这些位置更改它。此示例展示添加了声明路径变量的 setup() 方法后该类是什么样子:

 
  1. class TestIsDone:

  2. def setup(self):

  3. self.tmp_file = "/tmp/test_file"

  4. def teardown(self):

  5. if os.path.exists(self.tmp_file):

  6. os.remove(self.tmp_file)

  7. def test_yes(self):

  8. with open(self.tmp_file, "w") as _f:

  9. _f.write("yes")

  10. assert is_done(self.tmp_file) is True

  11. def test_no(self):

  12. with open(self.tmp_file, "w") as _f:

  13. _f.write("no")

  14. assert is_done(self.tmp_file) is False

自定义帮助程序方法

可以在类中创建自定义帮助程序方法。这些方法不得以名称 test 为前缀,并且不能命名为安装程序或清理方法。在 TestIsDone 类中,我们可以在自定义帮助程序中自动创建临时文件。该自定义帮助程序方法可能如以下示例所示:​​​​​​​

 
  1. def write_tmp_file(self, content):

  2. with open(self.tmp_file, "w") as _f:

  3. _f.write(content)

Pytest 不会自动执行 write_tmp_file() 方法,其他方法可以直接调用该方法以保存重复的任务,例如写入文件。

将测试方法更新为使用自定义帮助程序后,整个类如下例所示:

 
  1. class TestIsDone:

  2. def setup(self):

  3. self.tmp_file = "/tmp/test_file"

  4. def teardown(self):

  5. if os.path.exists(self.tmp_file):

  6. os.remove(self.tmp_file)

  7. def write_tmp_file(self, content):

  8. with open(self.tmp_file, "w") as _f:

  9. _f.write(content)

  10. def test_yes(self):

  11. self.write_tmp_file("yes")

  12. assert is_done(self.tmp_file) is True

  13. def test_no(self):

  14. self.write_tmp_file("no")

  15. assert is_done(self.tmp_file) is False

何时使用类而不是函数

关于何时使用类而不是函数没有任何严格的规则。一个好的做法是持续遵循项目和团队中一直使用的惯例做法。可通过下面这些常用问题来帮助确定何时使用类:

  • 测试是否需要类似的设置或清理帮助程序代码?

  • 将测试组合在一起是否有逻辑上的意义?

  • 测试套件中是否至少有一些测试?

  • 测试能否受益于常用的帮助程序函数?

03 练习

在本练习中,使用 Pytest 测试函数。然后发现并修复函数当中导致测试失败的一些潜在问题。查看失败结果和使用 Pytest 丰富的错误报告功能对于发现和修复生产代码中存在问题的测试或 bug 至关重要。

在本练习中,我们使用称为 admin_command() 的函数,该函数接受系统命令作为输入,并可以使用 sudo 工具为其添加前缀(可选操作)。该函数有一个 bug,你将通过编写测试来发现该 bug。

步骤 1 - 为本练习添加测试文件

1.使用测试文件的 Python 文件名约定创建一个新的测试文件。将测试文件命名为 test_exercise.py 并添加以下代码:​​​​​​​

 
  1. def admin_command(command, sudo=True):

  2. """

  3. Prefix a command with `sudo` unless it is explicitly not needed. Expects

  4. `command` to be a list.

  5. """

  6. if sudo:

  7. ["sudo"] + command

  8. return command

函数 admin_command() 使用 command 参数接受列表作为输入,并且可以使用 sudo 为列表添加前缀(可选操作)。如果 sudo 关键字参数设置为 False,则该参数会返回输入的命令。

2.在同一个文件中,追加对 admin_command() 函数的测试。测试使用返回示例命令的帮助程序方法:

 
  1. class TestAdminCommand:

  2. def command(self):

  3. return ["ps", "aux"]

  4. def test_no_sudo(self):

  5. result = admin_command(self.command(), sudo=False)

  6. assert result == self.command()

  7. def test_sudo(self):

  8. result = admin_command(self.command(), sudo=True)

  9. expected = ["sudo"] + self.command()

  10. assert result == expected

备注

在与实际代码相同的文件中进行测试并不常见。为简单起见,本练习中的示例将具有同一文件中的实际代码。在实际 Python 项目中,文件和目录通常会将测试与正在测试的代码分开。

步骤 2 - 运行测试并确定失败

由于测试文件有一个要测试的函数和几个要验证其行为的测试,现在是时候运行测试和处理失败了。

  • 使用 Python 执行文件:

$ pytest test_exercise.py

运行应以一项测试通过和一项失败完成,失败输出应类似于以下输出:

 
  1. =================================== FAILURES ===================================

  2. __________________________ TestAdminCommand.test_sudo __________________________

  3. self = <test_exercise.TestAdminCommand object at 0x10634c2e0>

  4. def test_sudo(self):

  5. result = admin_command(self.command(), sudo=True)

  6. expected = ["sudo"] + self.command()

  7. > assert result == expected

  8. E AssertionError: assert ['ps', 'aux'] == ['sudo', 'ps', 'aux']

  9. E At index 0 diff: 'ps' != 'sudo'

  10. E Right contains one more item: 'aux'

  11. E Use -v to get the full diff

  12. test_exercise.py:24: AssertionError

  13. =========================== short test summary info ============================

  14. FAILED test_exercise.py::TestAdminCommand::test_sudo - AssertionError: assert...

  15. ========================= 1 failed, 1 passed in 0.04s ==========================

输出在 test_sudo() 测试中失败。Pytest 正在提供有关正在比较的两个列表的详细信息。在这种情况下,变量 result 中没有 sudo 命令,这是测试预期的结果。

步骤 3 - 修复 bug 并使测试通过

在进行任何更改之前,首先必须了解为什么会发生故障。虽然可以看到没有达到预期(结果中没有 sudo),但必须找出原因。

满足 sudo=True 条件时,请查看 admin_command() 函数中的以下代码行:​​​​​​​

 
  1. if sudo:

  2. ["sudo"] + command

列表的操作不用于返回该值。由于未返回该值,因此该函数最终返回不含 sudo 的命令。

1.更新 admin_command() 函数以返回列表操作,以便在请求 sudo 命令时使用修改的结果。更新后的函数应如下所示:​​​​​​​

 
  1. def admin_command(command, sudo=True):

  2. """

  3. Prefix a command with `sudo` unless it is explicitly not needed. Expects

  4. `command` to be a list.

  5. """

  6. if sudo:

  7. return ["sudo"] + command

  8. return command

2.使用 Pytest 重新运行测试。尝试在 Pytest 中使用 -v 标志来提高输出的详细程度:

$ pytest -v test_exercise.py

3.现在,请验证输出。它现在应显示两个通过的测试:

 
  1. ============================= test session starts ==============================

  2. Python 3.9.6, pytest-6.2.5, py-1.11.0, pluggy-1.0.0

  3. cachedir: .pytest_cache

  4. rootdir: /private

  5. collected 2 items

  6. test_exercise.py::TestAdminCommand::test_no_sudo PASSED [ 50%]

  7. test_exercise.py::TestAdminCommand::test_sudo PASSED [100%]

  8. ============================== 2 passed in 0.00s ===============================

备注

由于该函数能够处理更多不同大小写的值,因此应添加更多测试以涵盖这些变化。这可防止将来对函数的更改导致不同的(意外)行为。

步骤 4 - 通过测试添加新代码

在前面的步骤中添加测试后,你应该能够轻松地对函数进行更多更改,并用测试来验证它们。即使现有测试未涵盖这些更改,你仍可以确信你不会打破任何以前的假设。

在这种情况下,函数 admin_command() 会盲目信任 command 参数始终是列表。让我们通过确保引发包含有用错误消息的异常来改进这一点。

1.首先,创建捕获行为的测试。虽然函数尚未更新,但可以尝试测试优先法(也称为测试驱动开发或 TDD)。

  • 更新 test_exercise.py 文件,使其在顶入 pytest。此测试使用 pytest 框架中的内部帮助程序:

import pytest
  • 现在,将新的测试追加到类以检查异常。当传递给函数的值不是列表时,此测试应预计函数返回 TypeError:

 
  1. def test_non_list_commands(self):

  2. with pytest.raises(TypeError):

  3. admin_command("some command", sudo=True)

2.使用 Pytest 再次运行测试,它们应全部通过:

 
  1. ============================= test session starts ==============================

  2. Python 3.9.6, pytest-6.2.5, py-1.11.0, pluggy-1.0.0

  3. rootdir: /private/

  4. collected 3 items

  5. test_exercise.py ... [100%]

  6. ============================== 3 passed in 0.00s ===============================

测试足以检查 TypeError,但最好添加包含有用错误消息的代码。

3.更新函数以显式引发包含有用错误消息的 TypeError:​​​​​​​

 
  1. def admin_command(command, sudo=True):

  2. """

  3. Prefix a command with `sudo` unless it is explicitly not needed. Expects

  4. `command` to be a list.

  5. """

  6. if not isinstance(command, list):

  7. raise TypeError(f"was expecting command to be a list, but got a {type(command)}")

  8. if sudo:

  9. return ["sudo"] + command

  10. return command

4.最后,更新 test_non_list_commands() 方法以检查错误消息:​​​​​​​

 
  1. def test_non_list_commands(self):

  2. with pytest.raises(TypeError) as error:

  3. admin_command("some command", sudo=True)

  4. assert error.value.args[0] == "was expecting command to be a list, but got a <class 'str'>"

更新的测试使用 error 作为保存所有异常信息的变量。使用 error.value.args 可以查看异常的参数。在这种情况下,第一个参数包含测试可以检查的错误字符串。

检查工作

此时,应有一个名为 test_exercise.py 的 Python 测试文件,其中包含:

  • 接受参数和关键字参数的 admin_command() 函数。

  • admin_command() 函数中包含有用错误消息的 TypeError 异常。

  • 具有 command() 帮助程序方法和三个检查 admin_command() 函数的测试方法的 TestAdminCommand() 测试类。

在终端中运行测试时,所有测试均应通过,无任何错误。

04 知识检查,来复习一下

1. 为什么对 Pytest 测试使用纯 assert 语句很有用?

A.它可加快测试执行速度。

B.通过它可使用 Python 运算符进行任何比较。

C.通过它可并行执行测试。

2. 对测试类中的测试进行分组的原因之一是什么?

A.这样该测试可以从常用设置或清理中受益。

B.这样测试便可以利用纯断言语句。

C.这样该测试可以随机化,以获得更好的覆盖范围。

3. Pytest 可否用作用于测试的 Python 库?

A.否,Pytest 没有其他用作库的模块和帮助程序。

B.否,Pytest 仅允许通过插件实现扩展性。

C.是的,Pytest 具有可在测试中导入的模块和帮助程序。

总结

在本文中,我们介绍了使用 Pytest 的基础知识,Pytest 是 Python 最受欢迎的测试框架之一。首先,我们介绍了一些有关为 Pytest 编写测试的基础知识,然后介绍了运行 Pytest 命令行工具的示例。然后,你阅读了测试类和方法,这些类和方法提供了与测试函数不同的灵活性。

最后,你尝试了为有问题的函数生成测试。通过测试可以找出问题,并进行一些修复。

现在,你应该能够轻松查看为 Pytest 编写的测试。使用测试函数或类,你应该能够为 Pytest 编写新测试或扩展现有测试套件。

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

 

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!有需要的小伙伴可以点击下方小卡片领取   

使用 pytest 进行测试的基本步骤如下: 1. 安装 pytest:在终端或命令行中使用 pip 命令安装 pytest,例如:`pip install pytest` 2. 创建测试文件:在项目目录下创建一个以 `test_` 开头或以 `_test` 结尾的测试文件,例如 `test_example.py`。 3. 编写测试用例:在测试文件中编写测试用例,一个测试用例就是一个普通的函数,以 `test_` 开头的函数名。例如: ```python def test_addition(): assert 1 + 1 == 2 def test_subtraction(): assert 5 - 3 == 2 ``` 4. 运行测试:在终端或命令行中运行 `pytest` 命令,它会自动发现并运行测试文件中的测试用例。例如:`pytest` 5. 查看测试结果:pytest 会输出测试运行的结果,显示每个测试用例的运行状态(通过/失败),以及详细的错误信息(如果有)。例如: ``` ================================ test session starts ================================ ... collected 2 items test_example.py .F [100%] ===================================== FAILURES ====================================== _________________________________ test_subtraction __________________________________ def test_subtraction(): > assert 5 - 3 == 4 E assert (5 - 3) == 4 test_example.py:6: AssertionError ========================== short test summary info =========================== FAILED test_example.py::test_subtraction - assert (5 - 3) == 4 ``` 通过上述步骤,你就可以使用 pytest 来编写和运行测试用例,以验证代码的正确性。除了基本的断言外,pytest 还提供了许多其他功能,如参数化测试测试夹具等,可以根据需要进行使用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值