如何將標準測試新增至整合
當您為自己建立自訂類別,或為了在 LangChain 整合中發布時,新增標準測試以確保其運作如預期非常重要。本指南將向您展示如何將標準測試新增至每種整合類型。
設定
首先,讓我們安裝 2 個依賴項
langchain-core
將定義我們想要匯入以定義自訂工具的介面。langchain-tests
將提供我們想要使用的標準測試,以及執行這些測試所需的 pytest 外掛程式。建議釘選到最新版本:
由於新版本的 langchain-tests
中新增的測試可能會破壞您的 CI/CD 管道,因此我們建議釘選 langchain-tests
的版本,以避免意外變更。
- Poetry
- Pip
如果您遵循了先前的指南,您應該已經安裝了這些依賴項!
poetry add langchain-core
poetry add --group test langchain-tests==<latest_version>
poetry install --with test
pip install -U langchain-core langchain-tests
# install current package in editable mode
pip install --editable .
新增和設定標準測試
langchain-tests
套件中有 2 個命名空間
- 單元測試 (
langchain_tests.unit_tests
):旨在用於隔離測試元件,且無法存取外部服務 - 整合測試 (
langchain_tests.integration_tests
):旨在用於測試可存取外部服務的元件(尤其是元件旨在互動的外部服務)。
這兩種測試類型都以 pytest
基於類別的測試套件實作。
透過子類化每種標準測試類型的基底類別(請參閱下文),您可以獲得該類型的所有標準測試,並且可以覆寫測試套件用來設定測試的屬性。
為了以與本指南相同的方式執行測試,我們建議在兩個測試子目錄下的測試檔案中子類化這些類別
tests/unit_tests
用於單元測試tests/integration_tests
用於整合測試
實作標準測試
在以下標籤中,我們展示如何實作每種元件類型的標準測試
- 聊天模型
- 向量儲存
- 嵌入
- 工具
- 檢索器
若要設定聊天模型的標準測試,我們將子類化 ChatModelUnitTests
和 ChatModelIntegrationTests
。在每個子類別上,我們覆寫以下 @property
方法,以指定要測試的聊天模型和聊天模型的設定
屬性 | 描述 |
---|---|
chat_model_class | 要測試的聊天模型的類別 |
chat_model_params | 傳遞給聊天的參數 |
模型的建構子 |
此外,聊天模型標準測試還測試一系列行為,從最基本的要求(產生對查詢的回應)到選用功能,例如多模態支援和工具呼叫。為了讓測試執行成功
- 如果模型旨在支援某項功能,則應通過測試;
- 如果模型不打算支援某項功能,則應跳過測試。
「選用」功能的測試透過一組屬性來控制,這些屬性可以在測試模型子類別上覆寫。
您可以在 單元測試 和 整合測試 的 API 參考中查看可設定功能的完整列表。
例如,若要啟用影像輸入的整合測試,我們可以實作
@property
def supports_image_inputs(self) -> bool:
return True
在整合測試類別上。
有關執行哪些測試、如何跳過每個測試以及每個測試的疑難排解提示的詳細資訊,請參閱 API 參考。請參閱詳細資訊
單元測試範例
"""Test chat model integration."""
from typing import Type
from langchain_parrot_link.chat_models import ChatParrotLink
from langchain_tests.unit_tests import ChatModelUnitTests
class TestChatParrotLinkUnit(ChatModelUnitTests):
@property
def chat_model_class(self) -> Type[ChatParrotLink]:
return ChatParrotLink
@property
def chat_model_params(self) -> dict:
# These should be parameters used to initialize your integration for testing
return {
"model": "bird-brain-001",
"temperature": 0,
"parrot_buffer_length": 50,
}
整合測試範例
"""Test ChatParrotLink chat model."""
from typing import Type
from langchain_parrot_link.chat_models import ChatParrotLink
from langchain_tests.integration_tests import ChatModelIntegrationTests
class TestChatParrotLinkIntegration(ChatModelIntegrationTests):
@property
def chat_model_class(self) -> Type[ChatParrotLink]:
return ChatParrotLink
@property
def chat_model_params(self) -> dict:
# These should be parameters used to initialize your integration for testing
return {
"model": "bird-brain-001",
"temperature": 0,
"parrot_buffer_length": 50,
}
以下說明如何為典型的向量儲存設定標準測試(使用 ParrotVectorStore
作為預留位置)
向量儲存測試目前沒有可設定的選用功能。
from typing import Generator
import pytest
from langchain_parrot_link.vectorstores import ParrotVectorStore
from langchain_core.vectorstores import VectorStore
from langchain_tests.integration_tests import VectorStoreIntegrationTests
class TestParrotVectorStore(VectorStoreIntegrationTests):
@pytest.fixture()
def vectorstore(self) -> Generator[VectorStore, None, None]: # type: ignore
"""Get an empty vectorstore for unit tests."""
store = ParrotVectorStore(self.get_embeddings())
# note: store should be EMPTY at this point
# if you need to delete data, you may do so here
try:
yield store
finally:
# cleanup operations, or deleting data
pass
設定測試包括實作 pytest 夾具,以設定空的向量儲存,並在測試執行結束後拆解向量儲存。
夾具 | 描述 |
---|---|
vectorstore | 產生器,為單元測試產生空的向量儲存。向量儲存在測試執行結束後清理。 |
例如,以下是 Chroma 整合的 VectorStoreIntegrationTests
類別
from typing import Generator
import pytest
from langchain_core.vectorstores import VectorStore
from langchain_tests.integration_tests.vectorstores import VectorStoreIntegrationTests
from langchain_chroma import Chroma
class TestChromaStandard(VectorStoreIntegrationTests):
@pytest.fixture()
def vectorstore(self) -> Generator[VectorStore, None, None]: # type: ignore
"""Get an empty vectorstore for unit tests."""
store = Chroma(embedding_function=self.get_embeddings())
try:
yield store
finally:
store.delete_collection()
pass
請注意,在初始 yield
之前,我們使用 嵌入物件來實例化向量儲存。這是預先定義的 「假」嵌入模型,它將為文件產生簡短的任意向量。如果需要,您可以使用不同的嵌入物件。
在 finally
區塊中,我們呼叫將向量儲存帶到乾淨狀態所需的任何整合特定邏輯。此邏輯在每次測試之間執行(例如,即使測試失敗)。
有關執行哪些測試以及每個測試的疑難排解提示的詳細資訊,請參閱 API 參考。
若要設定嵌入模型的標準測試,我們將子類化 EmbeddingsUnitTests
和 EmbeddingsIntegrationTests
。在每個子類別上,我們覆寫以下 @property
方法,以指定要測試的嵌入模型和嵌入模型的設定
屬性 | 描述 |
---|---|
embeddings_class | 要測試的嵌入模型的類別 |
embedding_model_params | 傳遞給嵌入模型的建構子的參數 |
有關執行哪些測試、如何跳過每個測試以及每個測試的疑難排解提示的詳細資訊,請參閱 API 參考。請參閱詳細資訊
單元測試範例
"""Test embedding model integration."""
from typing import Type
from langchain_parrot_link.embeddings import ParrotLinkEmbeddings
from langchain_tests.unit_tests import EmbeddingsUnitTests
class TestParrotLinkEmbeddingsUnit(EmbeddingsUnitTests):
@property
def embeddings_class(self) -> Type[ParrotLinkEmbeddings]:
return ParrotLinkEmbeddings
@property
def embedding_model_params(self) -> dict:
return {"model": "nest-embed-001"}
整合測試範例
from typing import Type
from langchain_parrot_link.embeddings import ParrotLinkEmbeddings
from langchain_tests.integration_tests import EmbeddingsIntegrationTests
class TestParrotLinkEmbeddingsIntegration(EmbeddingsIntegrationTests):
@property
def embeddings_class(self) -> Type[ParrotLinkEmbeddings]:
return ParrotLinkEmbeddings
@property
def embedding_model_params(self) -> dict:
return {"model": "nest-embed-001"}
"""Test ParrotLink embeddings."""
from typing import Type
from langchain_parrot_link.embeddings import ParrotLinkEmbeddings
from langchain_tests.integration_tests import EmbeddingsIntegrationTests
class TestParrotLinkEmbeddingsIntegration(EmbeddingsIntegrationTests):
@property
def embeddings_class(self) -> Type[ParrotLinkEmbeddings]:
return ParrotLinkEmbeddings
@property
def embedding_model_params(self) -> dict:
return {"model": "nest-embed-001"}
若要設定工具的標準測試,我們將子類化 ToolsUnitTests
和 ToolsIntegrationTests
。在每個子類別上,我們覆寫以下 @property
方法,以指定要測試的工具和工具的設定
屬性 | 描述 |
---|---|
tool_constructor | 要測試的工具的建構子,或已實例化的工具。 |
tool_constructor_params | 傳遞給工具的參數(選用)。 |
tool_invoke_params_example | 傳遞給工具的 invoke 方法的參數範例。 |
如果您正在測試工具類別並將類別(例如 MyTool
)傳遞給 tool_constructor
,則可以在 tool_constructor_params
中傳遞給建構子的參數。
如果您正在測試已實例化的工具,則可以將已實例化的工具傳遞給 tool_constructor
,並且不要覆寫 tool_constructor_params
。
有關執行哪些測試、如何跳過每個測試以及每個測試的疑難排解提示的詳細資訊,請參閱 API 參考。請參閱詳細資訊
from typing import Type
from langchain_parrot_link.tools import ParrotTool
from langchain_tests.unit_tests import ToolsUnitTests
class TestParrotMultiplyToolUnit(ToolsUnitTests):
@property
def tool_constructor(self) -> Type[ParrotTool]:
return ParrotTool
@property
def tool_constructor_params(self) -> dict:
# if your tool constructor instead required initialization arguments like
# `def __init__(self, some_arg: int):`, you would return those here
# as a dictionary, e.g.: `return {'some_arg': 42}`
return {}
@property
def tool_invoke_params_example(self) -> dict:
"""
Returns a dictionary representing the "args" of an example tool call.
This should NOT be a ToolCall dict - i.e. it should not
have {"name", "id", "args"} keys.
"""
return {"a": 2, "b": 3}
from typing import Type
from langchain_parrot_link.tools import ParrotTool
from langchain_tests.integration_tests import ToolsIntegrationTests
class TestParrotMultiplyToolIntegration(ToolsIntegrationTests):
@property
def tool_constructor(self) -> Type[ParrotTool]:
return ParrotTool
@property
def tool_constructor_params(self) -> dict:
# if your tool constructor instead required initialization arguments like
# `def __init__(self, some_arg: int):`, you would return those here
# as a dictionary, e.g.: `return {'some_arg': 42}`
return {}
@property
def tool_invoke_params_example(self) -> dict:
"""
Returns a dictionary representing the "args" of an example tool call.
This should NOT be a ToolCall dict - i.e. it should not
have {"name", "id", "args"} keys.
"""
return {"a": 2, "b": 3}
若要設定檢索器的標準測試,我們將子類化 RetrieversUnitTests
和 RetrieversIntegrationTests
。在每個子類別上,我們覆寫以下 @property
方法
屬性 | 描述 |
---|---|
retriever_constructor | 要測試的檢索器的類別 |
retriever_constructor_params | 傳遞給檢索器的建構子的參數 |
retriever_query_example | 傳遞給檢索器的 invoke 方法的查詢範例 |
有關執行哪些測試以及每個測試的疑難排解提示的詳細資訊,請參閱 API 參考。
from typing import Type
from langchain_parrot_link.retrievers import ParrotRetriever
from langchain_tests.integration_tests import (
RetrieversIntegrationTests,
)
class TestParrotRetriever(RetrieversIntegrationTests):
@property
def retriever_constructor(self) -> Type[ParrotRetriever]:
"""Get an empty vectorstore for unit tests."""
return ParrotRetriever
@property
def retriever_constructor_params(self) -> dict:
return {"k": 2}
@property
def retriever_query_example(self) -> str:
"""
Returns a str representing the "query" of an example retriever call.
"""
return "example query"
執行測試
您可以使用以下命令從專案根目錄執行這些測試
- Poetry
- Pip
# run unit tests without network access
poetry run pytest --disable-socket --allow-unix-socket --asyncio-mode=auto tests/unit_tests
# run integration tests
poetry run pytest --asyncio-mode=auto tests/integration_tests
# run unit tests without network access
pytest --disable-socket --allow-unix-socket --asyncio-mode=auto tests/unit_tests
# run integration tests
pytest --asyncio-mode=auto tests/integration_tests
測試套件資訊和疑難排解
如需可用的標準測試套件的完整列表,以及有關包含哪些測試以及如何疑難排解常見問題的資訊,請參閱標準測試 API 參考。
您可以在該 API 參考中列出的個別測試套件下查看疑難排解指南。例如,此處是 ChatModelIntegrationTests.test_usage_metadata
的指南。