Skip to main content

自定义组件测试

本指南概述了如何构建和实现应用程序组件的测试,以确保一致性和充分的覆盖率。

文件命名

  • 测试文件应遵循与被测试组件相同的目录结构,但应放在相应的单元测试文件夹中。

例如,如果组件的文件路径是 src/backend/base/blaflow/components/prompts/,那么测试文件应该位于 src/backend/tests/unit/components/prompts

  • 测试文件名应使用蛇形命名法,并遵循 test_<file_name>.py 的模式。

例如,如果要测试的文件是 提示词Component.py,那么测试文件应该命名为 test_prompt_component.py

文件结构

  • 每个测试文件应该按组件将测试分组到类中。文件中不应该有独立的测试函数——只有类中的测试方法。
  • 类名应遵循 Test<ClassName> 的模式。 例如,如果被测试的组件是 提示词Component,那么测试类应该命名为 Test提示词Component

导入、继承和必需方法

为了标准化组件测试,已经创建了基础测试类,所有组件测试类都应该导入并继承这些类。这些基础类位于文件 src/backend/tests/unit/base.py 中。

导入基础测试类:


_10
from tests.base import ComponentTestBaseWithClient
_10
from tests.base import ComponentTestBaseWithoutClient

这些基础类强制执行组件测试类必须实现的必需方法。基础类确保在以前版本中构建的组件在当前版本中继续工作。通过继承这些基础类之一,开发人员必须定义以下用 @pytest.fixture 装饰的方法:

  • component_class: 返回要测试的组件类。例如:

_10
@pytest.fixture
_10
def component_class(self):
_10
return 提示词Component

  • default_kwargs: 返回一个字典,包含实例化组件所需的默认参数。例如:

_10
@pytest.fixture
_10
def default_kwargs(self):
_10
return {"template": "Hello {name}!", "name": "John", "_session_id": "123"}

  • file_names_mapping: 返回一个字典列表,表示被测试组件随时间变化的 versionmodulefile_name 之间的关系。如果是未发布的组件,可以留空。例如:

_10
@pytest.fixture
_10
def file_names_mapping(self):
_10
return [
_10
{"version": "1.0.15", "module": "prompts", "file_name": "提示词"},
_10
{"version": "1.0.16", "module": "prompts", "file_name": "提示词"},
_10
{"version": "1.0.17", "module": "prompts", "file_name": "提示词"},
_10
{"version": "1.0.18", "module": "prompts", "file_name": "提示词"},
_10
{"version": "1.0.19", "module": "prompts", "file_name": "提示词"},
_10
]

测试组件功能

一旦定义了测试文件的基本结构,就可以实现组件功能的测试方法。必须遵循以下准则:

  1. 测试方法名称应该具有描述性,使用蛇形命名法,并遵循 test_<case_name> 的模式。
  2. 每个测试应遵循 Arrange, Act, Assert 模式:
    1. Arrange:准备数据。
    2. Act:执行组件。
    3. Assert:验证结果。

示例

  1. Arrange:准备数据。

建议使用在基本结构中定义的 fixtures,但不是强制性的。


_10
def test_post_code_processing(self, component_class, default_kwargs):
_10
component = component_class(**default_kwargs)

  1. Act:执行组件。

调用在 Arrange 步骤中准备的组件的 .to_frontend_node() 方法。


_10
def test_post_code_processing(self, component_class, default_kwargs):
_10
component = component_class(**default_kwargs)
_10
_10
frontend_node = component.to_frontend_node()

  1. Assert:验证结果。

执行 .to_frontend_node() 方法后,结果数据可以在字典 frontend_node["data"]["node"] 中进行验证。断言应该清晰并覆盖预期的结果。


_10
def test_post_code_processing(self, component_class, default_kwargs):
_10
component = component_class(**default_kwargs)
_10
_10
frontend_node = component.to_frontend_node()
_10
_10
node_data = frontend_node["data"]["node"]
_10
assert node_data["template"]["template"]["value"] == "Hello {name}!"
_10
assert "name" in node_data["custom_fields"]["template"]
_10
assert "name" in node_data["template"]
_10
assert node_data["template"]["name"]["value"] == "John"