编写测试#
本节包含一系列关于在 conda
仓库中编写测试的指南和准则。
指南#
集成测试 本指南概述了如何使用完整的命令调用编写集成测试。它还介绍了创建供此类测试使用的夹具。
一般准则#
注意
需要注意的是,现有测试可能会偏离这些准则,这没关系。这些准则是为了告知我们希望所有新测试的外观和功能。
首选测试样式 (pytest)#
虽然我们的代码库包含基于类的 unittest
测试,但我们对所有新测试的首选格式是 pytest
样式测试。这些测试是使用函数编写的,并使用夹具处理测试上下文的设置和拆卸。我们建议您先熟悉 pytest
,然后再尝试为 conda
编写测试。前往他们的 入门指南 了解更多信息。
组织测试#
测试应以反映主要 conda
模块的方式进行组织。例如,如果您要为 conda/base/context.py
中的函数编写测试,则应将此测试放在 tests/base/test_context.py
中。
"conda.testing" 模块#
这是一个包含任何可能有助于编写测试的内容的模块,包括夹具、函数和类。您可以根据需要随意对此模块进行添加,但请注意组织。例如,如果您的测试实用程序主要仅适用于 base
模块,请考虑将它们存储在 conda.testing.base
中。
添加新夹具#
对于范围或目的非常有限的夹具,可以在测试本身旁边定义它们。但是,如果这些夹具可以在多个测试中使用,则应将它们保存在单独的 fixtures.py
文件中。 conda.testing
模块已经包含几个此类文件。
如果您想在新的文件中添加新夹具,请确保在 tests/conftest.py::pytest_plugins
中添加对该模块的引用。这是我们向测试提供夹具的首选方法。由于这些是在环境中包含的方式,您应该注意命名方案并选择可能不会相互冲突的命名方案。考虑使用前缀来实现这一点。
上下文对象#
conda
中的上下文对象用作单例。这意味着每次运行 conda
命令时,只实例化一个对象。这是有道理的,因为它包含程序的所有配置,重新实例化它或创建多个副本效率低下。
这在测试中会导致问题,在测试中您可能希望在同一个进程中运行数百次 conda
命令。因此,在编写测试时,始终将此对象重置为全新状态非常重要。
这可以通过使用 reset_context
函数来完成,该函数也位于 conda.base.context
模块中。以下示例显示了如何修改上下文对象,然后使用 reset_conda_context
pytest
夹具重置它
import os
import tempfile
from conda.base.context import reset_context, context
from conda.testing.fixtures import reset_conda_context
TEST_CONDARC = """
channels:
- test-channel
"""
def test_that_uses_context(reset_conda_context):
# We first created a temporary file to hold our test configuration
with tempfile.TemporaryDirectory() as tempdir:
condarc_file = os.path.join(tempdir, "condarc")
with open(condarc_file, "w") as tmp_file:
tmp_file.write(TEST_CONDARC)
# We use the reset_context function to load our new configuration
reset_context(search_path=(condarc_file,))
# Run various test assertions, below is an example
assert "test-channel" in context.channels
使用此测试夹具可确保将上下文对象恢复到测试之前的状态。对于此特定测试,这意味着 channels
设置将恢复为其默认配置。如果您需要在测试期间手动重置上下文,则可以通过手动调用 reset_context
命令来完成,如下面的示例所示
from conda.base.context import reset_context
def test_updating_context_manually():
# Load some custom variables into context here like above...
reset_context()
# Continue testing with a fresh context...