Unit Testing & Screenshots
Relevant source files
The following files were used as context for generating this wiki page:
Unit tests verify that specific parts of the BandaStation game logic function correctly through automation. These tests run during every Pull Request to identify bugs before they reach the production environment. The system includes standard DM-based logic tests, structural linters, and specialized screenshot tests to ensure visual consistency for game icons and species.
Sources: code/modules/unit_tests/README.md:3-8, tools/ci/show_screenshot_test_results.js:33-37
DM Unit Testing Architecture
The core unit testing framework executes subtypes of /datum/unit_test. When the UNIT_TESTS define is active, the game setup process triggers the Run() procedure for all defined tests. A test fails if it invokes the Fail() procedure or if an assertion macro detects an invalid state.
Sources: code/modules/unit_tests/README.md:10-12, code/modules/unit_tests/README.md:39-41
Test Lifecycle and API
The following diagram illustrates the execution flow of a standard unit test:
The system provides several assertion macros to simplify verification:
| Macro | Description |
|---|---|
TEST_ASSERT(assertion, reason) | Fails and stops the test if the assertion is false. |
TEST_ASSERT_EQUAL(a, b, msg) | Verifies that a == b. |
TEST_ASSERT_NOTNULL(a, msg) | Verifies that a is not null. |
TEST_FAIL(reason) | Marks a failure but allows the test to continue. |
allocate(type, ...) | Creates an instance that is automatically destroyed after the test. |
Sources: code/modules/unit_tests/README.md:73-98
Best Practices for DM Tests
- Consistency: Tests should use
mob/living/carbon/human/consistentinstead of the standard human mob to ensure predictable results. - Emulation: Tests should emulate real game scenarios by using actual items rather than test-only dummies where possible.
- Isolation: Test units of code separately (e.g., individual tests for reagent exposure vs. metabolization).
- RNG: Avoid using
probor other RNG functions, as these can cause "flaky" failures despite seeding.
Sources: code/modules/unit_tests/README.md:58-69, code/modules/unit_tests/README.md:111-113, tools/ci/check_grep.sh:110-117
Screenshot Comparison Testing
Screenshot tests capture in-game icons and compare them against "expected" master images. This prevents accidental changes to complex visual elements, such as alien species sprites. If a test produces a diff, the CI suite generates a report for the developer.
Sources: tools/ci/show_screenshot_test_results.js:33-37
Screenshot Failure Workflow
When a screenshot test fails, the system provides a visual diff and a path to update the reference image:
Developers can resolve failures by downloading a generated zip file of the new screenshots and extracting it into the code/modules/unit_tests/screenshots/ directory.
Sources: tools/ci/show_screenshot_test_results.js:15-60, tools/ci/show_screenshot_test_results.js:168-185
Automated Linting (Check Grep)
The check_grep.sh script performs static analysis on the codebase and maps to enforce standards and prevent common errors. It uses ripgrep (if available) or standard grep to scan for patterns that violate project conventions.
Sources: tools/ci/check_grep.sh:1-40
Key Linting Rules
| Category | Checks |
|---|---|
| Map Sanity | Non-TGM formatting, unexpected comments, invalid procs in variables. |
| Whitespace | Space indentation (must use tabs), mixed indentation, CRLF line endings. |
| Common Errors | Unmanaged global variables, improper balloon_alert usage, src used as a trait source. |
| BYOND 515/516 | Deprecated .proc/ syntax, missing byond:// prefix for internal hrefs. |
| Spelling | Misspellings of "Nanotrasen", "CentCom", and "maintenance". |
Sources: tools/ci/check_grep.sh:51-105, tools/ci/check_grep.sh:124-180, tools/ci/check_grep.sh:310-330
TGUI and Integration Testing
TGUI utilizes a separate testing stack. Developers can run TGUI-specific checks via Juke Build or Bun:
bun tgui:test: Executes unit and integration tests for the React-based interface components.bun tgui:lint: Runs code style and structural checks.bun tgui:tsc: Validates code against the TypeScript compiler.
Sources: tgui/README.md:65-98
Flaky Test Management
The system includes automated logic to handle "flaky" tests—tests that fail inconsistently due to environment or timing issues.
- Rerun Logic: The
rerunFlakyTests.jshook identifies failing "Integration Tests" or "Alternate Tests" and automatically triggers a workflow restart. - Reporting: If a test fails after a retry,
reportFlakyTests.jsextracts the failure details from the logs and creates or updates a GitHub issue labeled "🤖 Flaky Test Report".
Sources: tools/pull_request_hooks/rerunFlakyTests.js:7-40, tools/pull_request_hooks/rerunFlakyTests.js:235-260