Тестування додатків LangChain4j

March 2, 2026 · View on GitHub

Зміст

Цей посібник проведе вас через тести, які демонструють, як тестувати AI-додатки без необхідності ключів API чи зовнішніх сервісів.

Швидкий старт

Запустіть усі тести однією командою:

Bash:

mvn test

PowerShell:

mvn --% test

Коли всі тести проходять, ви побачите вивід, як на скриншоті нижче — тести виконуються без жодних помилок.

Successful Test Results

Успішне виконання тестів, що показує проходження всіх тестів без помилок

Що охоплюють тести

Цей курс зосереджений на блокових тестах, які запускаються локально. Кожен тест демонструє окрему концепцію LangChain4j. Нижче показано тестову піраміду — саме блокові тести утворюють швидку, надійну основу, на якій будується ваша тестова стратегія.

Testing Pyramid

Тестова піраміда, що показує баланс між блоковими тестами (швидкі, ізольовані), інтеграційними тестами (реальні компоненти) і end-to-end тестами. Це навчання охоплює саме блокове тестування.

МодульТестиФокусКлючові файли
00 - Швидкий старт6Шаблони підказок та заміщення зміннихSimpleQuickStartTest.java
01 - Вступ8Пам'ять розмови та стан чатуSimpleConversationTest.java
02 - Інженерія підказок12Патерни GPT-5.2, рівні готовності, структурований вивідSimpleGpt5PromptTest.java
03 - RAG10Інгестування документів, ембеддинги, пошук за схожістюDocumentServiceTest.java
04 - Інструменти12Виклики функцій і ланцюжки інструментівSimpleToolsTest.java
05 - MCP8Протокол Model Context з транспортом stdioSimpleMcpTest.java

Запуск тестів

Запустіть усі тести з кореня:

Bash:

mvn test

PowerShell:

mvn --% test

Запуск тестів для конкретного модуля:

Bash:

cd 01-introduction && mvn test
# Або з кореня
mvn test -pl 01-introduction

PowerShell:

cd 01-introduction; mvn --% test
# Або з кореня
mvn --% test -pl 01-introduction

Запуск одного класу тестів:

Bash:

mvn test -Dtest=SimpleConversationTest

PowerShell:

mvn --% test -Dtest=SimpleConversationTest

Запуск конкретного тестового методу:

Bash:

mvn test -Dtest=SimpleConversationTest#слідЗберігатиІсторіюРозмови

PowerShell:

mvn --% test -Dtest=SimpleConversationTest#слід зберігати історію розмови

Запуск тестів у VS Code

Якщо ви користуєтеся Visual Studio Code, Test Explorer пропонує графічний інтерфейс для запуску та налагодження тестів.

VS Code Test Explorer

Test Explorer у VS Code, що показує дерево тестів із усіма Java класами та окремими тестовими методами

Щоб запускати тести у VS Code:

  1. Відкрийте Test Explorer, натиснувши іконку колби на панелі активності
  2. Розгорніть дерево тестів, щоб побачити всі модулі та класи тестів
  3. Натисніть кнопку відтворення поруч із будь-яким тестом, щоб запустити його окремо
  4. Натисніть «Run All Tests», щоб виконати весь набір
  5. Клацніть правою кнопкою миші по тесту та виберіть «Debug Test», щоб встановити брекпойнти та проходити крок за кроком

Test Explorer показує зелені позначки для пройдених тестів і надає докладні повідомлення про помилки, якщо тести не проходять.

Шаблони тестування

Шаблон 1: Тестування шаблонів підказок

Найпростіший шаблон тестує шаблони підказок без виклику будь-якої AI-моделі. Ви перевіряєте, що заміщення змінних працює правильно, а підказки форматуються очікувано.

Prompt Template Testing

Тестування шаблонів підказок із потоком заміщення змінних: шаблон із заповнювачами → застосовані значення → перевірений форматований вивід

@Test
@DisplayName("Should format prompt template with variables")
void testPromptTemplateFormatting() {
    PromptTemplate template = PromptTemplate.from(
        "Best time to visit {{destination}} for {{activity}}?"
    );
    
    Prompt prompt = template.apply(Map.of(
        "destination", "Paris",
        "activity", "sightseeing"
    ));
    
    assertThat(prompt.text()).isEqualTo("Best time to visit Paris for sightseeing?");
}

Цей тест знаходиться у 00-quick-start/src/test/java/com/example/langchain4j/quickstart/SimpleQuickStartTest.java.

Запустіть його:

Bash:

cd 00-quick-start && mvn test -Dtest=SimpleQuickStartTest#тестуванняФорматуванняШаблонуПідказки

PowerShell:

cd 00-quick-start; mvn --% test -Dtest=SimpleQuickStartTest#тестуванняФорматуванняШаблонуПідказки

Шаблон 2: Мокінг мовних моделей

При тестуванні логіки розмови використовуйте Mockito для створення підроблених моделей, які повертають заздалегідь визначені відповіді. Це робить тести швидкими, безкоштовними і детермінованими.

Mock vs Real API Comparison

Порівняння, що показує, чому для тестування переважно використовувати моки: вони швидкі, безкоштовні, детерміновані та не потребують ключів API

@ExtendWith(MockitoExtension.class)
class SimpleConversationTest {
    
    private ConversationService conversationService;
    
    @Mock
    private OpenAiOfficialChatModel mockChatModel;
    
    @BeforeEach
    void setUp() {
        ChatResponse mockResponse = ChatResponse.builder()
            .aiMessage(AiMessage.from("This is a test response"))
            .build();
        when(mockChatModel.chat(anyList())).thenReturn(mockResponse);
        
        conversationService = new ConversationService(mockChatModel);
    }
    
    @Test
    void shouldMaintainConversationHistory() {
        String conversationId = conversationService.startConversation();
        
        ChatResponse mockResponse1 = ChatResponse.builder()
            .aiMessage(AiMessage.from("Response 1"))
            .build();
        ChatResponse mockResponse2 = ChatResponse.builder()
            .aiMessage(AiMessage.from("Response 2"))
            .build();
        ChatResponse mockResponse3 = ChatResponse.builder()
            .aiMessage(AiMessage.from("Response 3"))
            .build();
        
        when(mockChatModel.chat(anyList()))
            .thenReturn(mockResponse1)
            .thenReturn(mockResponse2)
            .thenReturn(mockResponse3);

        conversationService.chat(conversationId, "First message");
        conversationService.chat(conversationId, "Second message");
        conversationService.chat(conversationId, "Third message");

        List<ChatMessage> history = conversationService.getHistory(conversationId);
        assertThat(history).hasSize(6); // 3 повідомлення від користувача + 3 повідомлення від ШІ
    }
}

Цей шаблон застосовується в 01-introduction/src/test/java/com/example/langchain4j/service/SimpleConversationTest.java. Мок гарантує послідовну поведінку, щоб ви могли перевірити коректність управління пам’яттю.

Шаблон 3: Тестування ізоляції розмов

Пам’ять розмови має розділяти користувачів. Цей тест перевіряє, що контексти розмов не змішуються.

Conversation Isolation

Тестування ізоляції розмов, що показує окремі сховища пам’яті для різних користувачів щоб запобігти змішуванню контекстів

@Test
void shouldIsolateConversationsByid() {
    String conv1 = conversationService.startConversation();
    String conv2 = conversationService.startConversation();
    
    ChatResponse mockResponse = ChatResponse.builder()
        .aiMessage(AiMessage.from("Response"))
        .build();
    when(mockChatModel.chat(anyList())).thenReturn(mockResponse);

    conversationService.chat(conv1, "Message for conversation 1");
    conversationService.chat(conv2, "Message for conversation 2");

    List<ChatMessage> history1 = conversationService.getHistory(conv1);
    List<ChatMessage> history2 = conversationService.getHistory(conv2);
    
    assertThat(history1).hasSize(2);
    assertThat(history2).hasSize(2);
}

Кожна розмова підтримує свою власну незалежну історію. В продакшн-системах ця ізоляція критична для багатокористувацьких застосунків.

Шаблон 4: Тестування інструментів окремо

Інструменти — це функції, які може викликати AI. Тестуйте їх напряму, щоб переконатися, що вони працюють правильно незалежно від рішень AI.

Tools Testing

Тестування інструментів окремо, показуючи мок-інструмент, що виконується без викликів AI для перевірки бізнес-логіки

@Test
void shouldConvertCelsiusToFahrenheit() {
    TemperatureTool tempTool = new TemperatureTool();
    String result = tempTool.celsiusToFahrenheit(25.0);
    assertThat(result).containsPattern("77[.,]0°F");
}

@Test
void shouldDemonstrateToolChaining() {
    WeatherTool weatherTool = new WeatherTool();
    TemperatureTool tempTool = new TemperatureTool();

    String weatherResult = weatherTool.getCurrentWeather("Seattle");
    assertThat(weatherResult).containsPattern("\\d+°C");

    String conversionResult = tempTool.celsiusToFahrenheit(22.0);
    assertThat(conversionResult).containsPattern("71[.,]6°F");
}

Ці тести з 04-tools/src/test/java/com/example/langchain4j/agents/tools/SimpleToolsTest.java перевіряють логіку інструментів без участі AI. Приклад ланцюжка показує, як вихід одного інструменту передається як вхід іншому.

Шаблон 5: Тестування RAG в пам’яті

Системи RAG зазвичай потребують векторних баз даних та сервісів ембеддингів. Візерунок “в пам’яті” дає змогу тестувати весь конвеєр без зовнішніх залежностей.

In-Memory RAG Testing

Робочий процес тестування RAG в пам’яті, що показує парсинг документів, зберігання ембеддингів і пошук за схожістю без потреби у базі даних

@Test
void testProcessTextDocument() {
    String content = "This is a test document.\nIt has multiple lines.";
    InputStream inputStream = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8));
    
    DocumentService.ProcessedDocument result = 
        documentService.processDocument(inputStream, "test.txt");

    assertNotNull(result);
    assertTrue(result.segments().size() > 0);
    assertEquals("test.txt", result.segments().get(0).metadata().getString("filename"));
}

Цей тест з 03-rag/src/test/java/com/example/langchain4j/rag/service/DocumentServiceTest.java створює документ в пам’яті та перевіряє нарізку на частини і обробку метаданих.

Шаблон 6: Інтеграційне тестування MCP

Модуль MCP тестує інтеграцію Model Context Protocol з транспортом stdio. Ці тести перевіряють, чи ваш додаток може запускати і взаємодіяти з MCP-серверами як підпроцесами.

Тести в 05-mcp/src/test/java/com/example/langchain4j/mcp/SimpleMcpTest.java перевіряють поведінку клієнта MCP.

Запустіть їх:

Bash:

cd 05-mcp && mvn test

PowerShell:

cd 05-mcp; mvn --% test

Філософія тестування

Тестуйте ваш код, а не AI. Ваші тести повинні перевіряти код, що ви пишете, контролюючи, як будуються підказки, як керується пам’ять і як виконуються інструменти. Відповіді AI варіюються і не повинні бути частиною тверджень тестів. Запитуйте себе, чи правильно ваш шаблон підказки заміщує змінні, а не чи дає AI правильну відповідь.

Використовуйте моки для мовних моделей. Це зовнішні залежності, які працюють повільно, дорого і недетерміновано. Мокінг робить тести швидкими (мілісекунди замість секунд), безкоштовними (без витрат на API) та детермінованими (однаковий результат кожного разу).

Підтримуйте тести незалежними. Кожен тест повинен налаштовувати власні дані, не покладатися на інші тести і прибирати за собою. Тести мають проходити незалежно від порядку виконання.

Тестуйте крайні випадки, а не лише успішні шляхи. Спробуйте пусті вхідні дані, дуже великі вхідні дані, спеціальні символи, недійсні параметри та граничні умови. Вони часто виявляють баги, які при нормальному використанні не проявляються.

Використовуйте описові назви. Порівняйте shouldMaintainConversationHistoryAcrossMultipleMessages() і test1(). Перша точно повідомляє, що тестується, що значно полегшує налагодження помилок.

Наступні кроки

Тепер, коли ви розумієте шаблони тестування, зануртесь глибше в кожен модуль:

README кожного модуля надає докладне пояснення концепцій, що тестуються тут.


Навігація: ← Назад до головної


Відмова від відповідальності:
Цей документ було перекладено за допомогою сервісу автоматичного перекладу Co-op Translator. Хоча ми прагнемо до точності, зверніть увагу, що автоматичний переклад може містити помилки чи неточності. Оригінальний документ рідною мовою слід вважати авторитетним джерелом. Для критичної інформації рекомендується звертатися до професійного людського перекладу. Ми не несемо відповідальності за будь-які непорозуміння чи неправильні тлумачення, що виникли внаслідок використання цього перекладу.