REPOSITORY / ScuroNeko/Laniakea

Wiki

KNOWLEDGE REPOSITORY
3
Testing Bots with Laniakea
ScuroNeko edited this page 2026-05-20 13:19:27 +03:00

Testing Bots with Laniakea

Russian version: Testing-Bots-with-Laniakea-RU

Laniakea is very testable with ordinary Go tests. The repository itself already uses unit-style tests for handlers, context helpers, argument validation, long replies, runners, and request-shape assertions. This page collects the most useful testing patterns.

What to test

Good test targets include:

  • handler return behavior;
  • command argument validation;
  • middleware decisions;
  • long-message splitting;
  • callback payload behavior;
  • update routing;
  • runner shutdown behavior;
  • request bodies sent to Telegram methods.

General testing strategy

The most practical approach is:

  1. isolate one behavior;
  2. create a small bot, plugin, or MessageContext;
  3. use a fake HTTP client when you need to inspect Telegram requests;
  4. assert the outgoing request shape or returned behavior directly.

This keeps tests fast and independent from real Telegram infrastructure.

Testing MessageContext helpers

Many helper methods can be tested by constructing a MessageContext directly.

Common ingredients:

  • a fake tgapi.API with a custom http.Client;
  • a synthetic tgapi.Message with Chat.ID;
  • a logger created with slog.CreateLogger().

Example pattern:

ctx := &laniakea.MessageContext{
	Api:    api,
	Msg:    &tgapi.Message{Chat: &tgapi.Chat{ID: 42, Type: string(tgapi.ChatTypePrivate)}},
	Logger: slog.CreateLogger(),
}

This is enough to test helpers such as:

  • Answer(...)
  • AnswerLong(...)
  • AnswerPhoto(...)
  • KeyboardLong(...)
  • NewDraft()

Testing outgoing request bodies

When you care about exact Telegram request shape, use a fake http.Client transport and inspect req.Body.

This is especially useful for:

  • optional fields;
  • parse modes;
  • direct message topic IDs;
  • split long-message requests;
  • keyboard attachment behavior.

The repository already uses this pattern extensively for MessageContext helper tests.

Testing long replies

Long plain-text helpers are a good candidate for regression tests.

Things worth checking:

  • the text is split into Telegram-safe parts;
  • joining the parts reconstructs the original text;
  • keyboards only appear on the final chunk in KeyboardLong(...);
  • no request is sent when validation fails before sending.

Testing command argument validation

Command argument validation can often be tested without a full bot instance.

Create a command and call its validation path indirectly or through higher-level behavior.

Useful cases:

  • required argument positions;
  • integer and boolean regex validation;
  • extra arguments beyond the declared set.

Testing update routing

For routing tests, create a small bot with:

  • a logger;
  • one or more registered plugins;
  • synthetic tgapi.Update values.

Then call the bot's handling path in a focused test and assert:

  • which handler was called;
  • what MessageContext fields were populated;
  • whether context mutations leaked across plugins.

This is particularly useful for:

  • non-command update handlers;
  • callback flows;
  • channel post handling;
  • update-type isolation.

Testing runners

Runners are easy to test without starting a full bot process.

Useful assertions:

  • one-time synchronous runners run exactly once;
  • background runners stop after context cancellation;
  • misconfigured runners are skipped.

A typical pattern is:

  • create a context with cancel;
  • register a runner that increments an atomic counter;
  • call ExecRunners(ctx);
  • cancel the context and wait for runner wait groups.

Testing error handling

When testing error behavior, decide which layer you are verifying:

  • handler returns an error;
  • middleware replies manually and stops;
  • helper validation prevents sending.

For centralized error flow, assert both:

  • the user-facing response shape if relevant;
  • the logical error path taken by the handler or helper.

Testing with fake Telegram APIs

You do not need a real Telegram bot token for most unit tests.

A fake http.Client with a custom transport is enough to:

  • return canned Telegram responses;
  • inspect raw JSON request bodies;
  • verify request counts;
  • simulate failures.

This approach is used throughout the repository for API, context, and command-generation tests.

Small unit tests

Best for:

  • helper validation;
  • argument parsing;
  • payload encoding;
  • simple middleware behavior.

Focused integration-style tests

Best for:

  • command routing;
  • callback flows;
  • request serialization;
  • long-reply behavior;
  • runner lifecycle behavior.

Regression-test ideas

When you fix a bug, consider adding a test for:

  • nil or missing context fields;
  • oversized message text or caption;
  • update types with unusual payload shape;
  • strict versus tolerant payload decoding;
  • shutdown and cancellation timing;
  • plugin snapshot behavior after registration.

Recommendations

  • Prefer fast, deterministic tests over large end-to-end setups.
  • Use fake HTTP transports to test Telegram-facing behavior.
  • Keep update fixtures small and purpose-built.
  • Add regression tests for every bug you fix in routing, validation, or payload handling.