自动化测试

在Kedro项目中实现高质量代码和可维护性的重要步骤是使用自动化测试。让我们看看如何设置它。

简介

软件测试是检查您编写的代码是否满足需求的过程。软件测试可以是手动自动的。在Kedro的上下文中:

  • 手动测试是指运行项目的部分或全部内容,并检查结果是否符合预期。

  • 自动化测试是指编写新代码(使用称为测试框架的库)来运行项目的部分或全部内容,并自动将结果与预期进行比对。

随着项目规模扩大,新代码将越来越依赖现有代码。当这些相互依赖性增加时,在代码库的某部分进行更改可能会意外破坏另一部分的预期功能。

手动测试的主要缺点是耗时。通常在新功能添加后,手动测试仅运行一次。每次代码变更后对整个代码库重复进行手动测试是不现实的,这意味着该策略经常会遗漏破坏性变更。

这个问题的解决方案是自动化测试。自动化测试允许在每次添加新功能或修改旧功能时,在几秒钟内运行整个代码库的众多测试。通过这种方式,可以在开发过程中发现破坏性变更,而不是在生产环境中。

使用pytest设置自动化测试

Python有许多可用的测试框架,其中最流行的是pytest(快速概览请参阅项目主页)。pytest因其简短易读的测试和强大的功能集而常被用于Python项目中。

让我们看看如何在您的Kedro项目中使用pytest开始工作。

安装测试需求

在开始测试需求之前,确保已在本地安装项目非常重要。这允许您通过将项目的不同部分导入测试文件来进行测试。

安装您的项目,包括所有项目特定的依赖项和测试需求:

  1. 将以下部分添加到项目根目录下的pyproject.toml文件中:

[project.optional-dependencies]
dev = [
    "pytest-cov",
    "pytest-mock",
    "pytest",
]
  1. 导航到项目的根目录并运行:

pip install ."[dev]"

或者,您可以像安装其他包一样单独安装测试需求,使用pip,确保您已在本地安装项目并且项目的虚拟环境已激活

  1. 要安装您的项目,请导航至项目根目录并运行以下命令:

pip install -e .

注意: 选项 -e 会安装项目的可编辑版本,这样您可以在不每次重新安装的情况下修改项目文件。

  1. 逐个安装测试需求:

pip install pytest

创建一个/tests目录

既然已经安装了pytest,你需要一个地方来存放测试文件。在项目的根目录下创建一个/tests文件夹。

mkdir <project_root>/tests

测试目录结构

项目中的/tests子目录结构应与项目/src/目录结构保持一致。/tests文件夹中的所有文件都应命名为test_.py格式。下方是一个/tests文件夹的示例。

src
│   ...
└───<package_name>
│   └───pipelines
│       └───dataprocessing
│           │   ...
│           │   nodes.py
│           │   ...
│
tests
└───pipelines
│   └───dataprocessing
│       │   ...
│       │   test_nodes.py
│       │   ...

创建一个示例测试

现在你已经有了存放测试的地方,可以在新文件/src/tests/test_run.py中创建一个示例测试。 这个示例测试展示了如何使用KedroSession类以编程方式执行kedro run

from pathlib import Path
from kedro.framework.session import KedroSession
from kedro.framework.startup import bootstrap_project

class TestKedroRun:
    def test_kedro_run(self):
        bootstrap_project(Path.cwd())

        with KedroSession.create(project_path=Path.cwd()) as session:
            assert session.run() is not None

这个测试是冗余的,但它介绍了pytest的一些核心功能,并展示了测试文件的布局:

  • 测试通过以test_开头的方法或函数,以及以Test开头的类来实现。

  • assert 语句用于将测试结果与预期值进行比较。

虽然这个具体示例没有使用fixtures,但它们是pytest中定义可重用测试资源的重要组成部分。参见Fixtures

测试名称应尽可能具有描述性,尤其是在团队协作时。例如,名为test_node_passes_with_valid_input的测试比名为test_passes的测试更容易理解其目的。

你可以阅读入门页面了解更多关于pytest的基础用法。如需编写自己的测试和使用pytest的所有功能,请参阅项目文档

运行你的测试

要运行测试,请从项目根目录下执行pytest命令。

cd <project_root>
pytest

如果您按照上一节的步骤创建了示例测试,您应该在终端中看到以下输出。

============================= test session starts ==============================
...
collected 1 item

tests/test_run.py .                                                  [100%]

============================== 1 passed in 0.38s ===============================

该输出表明文件src/tests/test_run.py中的一个测试已成功运行。

使用pytest-cov添加测试覆盖率报告

查看项目测试覆盖率很有帮助。为此,您可以安装并配置pytest-cov插件(用于pytest),该插件基于流行的coverage.py

安装 pytest-cov

像使用pip安装其他包一样安装pytest,确保您的项目虚拟环境已激活

pip install pytest-cov

配置 pytest 以使用 pytest-cov

要配置pytest使用pytest-cov生成覆盖率报告,您可以将以下行添加到/pyproject.toml文件中(如果该文件不存在,请创建它)。

[tool.pytest.ini_options]
addopts = """
--cov-report term-missing \
--cov src/<package_name> -ra"""

使用 pytest-cov 运行 pytest

在安装了pytest-cov的情况下,在spaceflights starter中运行pytest会生成以下额外报告。

Name                                                     Stmts   Miss  Cover   Missing
--------------------------------------------------------------------------------------
src/spaceflights/__init__.py                                 1      1     0%   4
src/spaceflights/__main__.py                                30     30     0%   4-47
src/spaceflights/pipeline_registry.py                        7      7     0%   2-16
src/spaceflights/pipelines/__init__.py                       0      0   100%
src/spaceflights/pipelines/data_processing/__init__.py       1      1     0%   3
src/spaceflights/pipelines/data_processing/nodes.py         25     25     0%   1-67
src/spaceflights/pipelines/data_processing/pipeline.py       5      5     0%   1-8
src/spaceflights/pipelines/data_science/__init__.py          1      1     0%   3
src/spaceflights/pipelines/data_science/nodes.py            20     20     0%   1-55
src/spaceflights/pipelines/data_science/pipeline.py          8      8     0%   1-40
src/spaceflights/settings.py                                 0      0   100%
--------------------------------------------------------------------------------------
TOTAL                                                       98     98     0%

这是coverage.py(通过pytest-cov)生成的最简单报告。它概述了每个项目文件中可执行语句被测试覆盖的比例。有关完整功能集的详细信息,请参阅coverage.py文档