Skip to main content

测试你的代码

风格指南部分所述,所有代码都需要检查以下内容:

  • 所有单元测试通过
  • 所有代码通过代码检查工具的检查

本地测试使用pytest进行,并使用pre-commit来运行我们的代码检查工具,它是在运行script/setup时作为虚拟环境的一部分安装的。

在运行测试之前需要安装Python测试依赖项。这可以通过使用VScode开发容器和相应的任务来实现。请检查开发容器文档以获取运行任务的指导。

要在整个代码库上运行我们的代码检查工具,请运行以下命令:

pre-commit run --all-files

要运行完整的测试套件,比开发容器默认设置的更多依赖项是必需的。要安装所有依赖项,请激活虚拟环境并运行命令:

uv pip install -r requirements_test_all.txt

或者,在Visual Studio Code中,启动安装所有测试要求任务。

要开始测试并运行完整的测试套件,请激活虚拟环境并运行命令:

pytest tests

或者,在Visual Studio Code中,启动Pytest任务。

可能需要根据您的发行版/操作系统安装额外的软件包:

  • Fedora: sudo dnf -y install systemd-devel gcc-c++
  • Ubuntu: sudo apt-get install libudev-dev
重要

在创建拉取请求之前运行pytestpre-commit以避免麻烦的修复。pre-commit将在提交更改时由git自动调用。

note

运行完整的pytest测试套件将花费相当长的时间,因此作为拉取请求的最低要求,请至少运行与您的代码更改相关的测试(有关如何操作的详细信息见下文)。完整的测试套件将在您创建拉取请求后由CI运行,并在可以合并之前运行。

运行pytest将对本地可用的Python版本运行单元测试。我们在CI中对所有支持的Python版本运行测试。

向测试环境添加新依赖项

如果您正在为某个集成编写测试,并且您更改了依赖项,则运行script/gen_requirements_all.py脚本以更新所有需求文件。 接下来,您可以通过运行以下命令在开发环境中更新所有依赖项:

uv pip install -r requirements_test_all.txt

或者,在Visual Studio Code中,启动安装所有测试要求任务。

运行有限的测试套件

您可以向pytest传递参数,以便能够运行单个测试套件或测试文件。 以下是一些有用的命令:

# 在第一个测试失败后停止
$ pytest tests/test_core.py -x

# 运行指定名称的测试
$ pytest tests/test_core.py -k test_split_entity_id

# 测试在运行2秒后失败
$ pytest tests/test_core.py --timeout 2

# 显示10个最慢的测试
$ pytest tests/test_core.py --duration=10

如果您只想测试您的集成,并包括测试覆盖率报告,建议使用以下命令:

pytest ./tests/components/<your_component>/ --cov=homeassistant.components.<your_component> --cov-report term-missing -vv

或者,在Visual Studio Code中,启动代码覆盖率任务。

防止代码检查错误

在您尝试提交时,已有几个代码检查工具设置为自动运行,作为运行script/setup的一部分,位于虚拟环境中。

您也可以手动运行这些代码检查工具:

pre-commit run --show-diff-on-failure

或者,在Visual Studio Code中,启动Pre-commit任务。

这些代码检查工具也可以直接运行,您可以对单个文件运行测试:

ruff check homeassistant/core.py
pylint homeassistant/core.py

关于PyLint和PEP8验证的说明

如果您无法避免某个PyLint警告,请在该行添加注释以禁用PyLint检查,格式为# pylint: disable=YOUR-ERROR-NAME。例如,如果PyLint错误地报告某个对象没有某个成员,就可能避免它。

为集成编写测试

快照测试

Home Assistant支持一种称为快照测试(也称为审批测试)的测试概念,这些测试将值与存储的参考值(快照)进行断言。

快照测试与常规(功能)测试不同,不能替代功能测试,但对于测试较大的输出非常有用。 在Home Assistant中,例如,它们可以用于:

  • 确保实体状态的输出是并且保持预期状态。
  • 确保注册中的区域、配置、设备、实体或问题条目是并且保持预期状态。
  • 确保诊断转储的输出是并且保持预期状态。
  • 确保FlowResult是并且保持预期状态。

还有许多其他大型输出的情况,如JSON、YAML或XML结果。

快照测试和常规测试之间的一个重大区别在于,结果是通过在特殊模式下运行测试来捕获的,该模式创建快照。任何后续测试的顺序运行将比较结果与快照。如果结果不同,测试将失败。

Home Assistant中的快照测试建立在Syrupy之上,因此在编写Home Assistant测试时可以应用其文档。 这是一个快照测试,断言实体状态的输出:

# tests/components/example/test_sensor.py
from homeassistant.core import HomeAssistant
from syrupy.assertion import SnapshotAssertion


async def test_sensor(
hass: HomeAssistant,
snapshot: SnapshotAssertion,
) -> None:
"""测试传感器状态。"""
state = hass.states.get("sensor.whatever")
assert state == snapshot

当第一次运行此测试时,它将失败,因为没有快照存在。 要创建(或更新)快照,请使用--snapshot-update标志运行测试:

pytest tests/components/example/test_sensor.py --snapshot-update

或者,在Visual Studio Code中,启动更新syrupy快照任务。

这将在tests/components/example/snapshots中创建一个快照文件。快照文件的命名与测试文件相同,在本例中为test_sensor.ambr,并且是人类可读的。快照文件必须提交到版本库。

当再次运行测试时(不带更新标志),将比较结果与存储的快照,所有内容应通过。

当测试结果发生变化时,测试将失败,快照需要再次更新。

谨慎使用快照测试!由于很容易创建快照,因此很容易倾向于对快照断言所有内容。但是,请记住,这并不是功能测试的替代。

作为示例,当测试实体在设备返回错误时是否变得不可用时,最好断言您期望的具体变化:断言实体的状态变为unavailable。此功能测试比使用快照断言该实体的所有状态更好,因为它假定在拍摄快照时它按预期工作。