Skip to main content
uv run syncs the project deps + tests group on demand, so the default test suite needs no upfront install โ€” just uv run pytest --numprocesses=auto dimos (xdist parallelizes across cores). Self-hosted tests need the heavy optional extras (LFS data, perception models, simulation, hardware SDKs, โ€ฆ). Sync them explicitly before running:

Types of tests

In general, there are different types of tests based on what their goal is: The distinction between unit, integration, and functional tests is often debated and rarely productive. Rather than waste time on classifying tests, itโ€™s better to separate tests by how they are used: The purpose of running tests in a loop is to get immediate feedback. The faster the loop, the easier it is to identify a problem since the source is the tiny bit of code you changed. Self-hosted tests are marked with @pytest.mark.self_hosted (they need LFS, ROS, CUDA, or other heavy deps); the default suite is everything else.

Usage

Default suite

This is the same as:
The default addopts in pyproject.toml includes a -m filter that excludes self_hosted/mujoco, so plain pytest dimos runs only the default suite; --numprocesses=auto parallelizes across cores via pytest-xdist.

Self-hosted tests

(Shortcut for pytest -m 'not (mujoco or self_hosted_large)' dimos: runs the default suite and self-hosted tests, excluding only mujoco and self_hosted_large.) Before running tests it calls bin/build-test-natives, which builds any missing native test dependencies. This includes slow agent and MCP-style integration tests in addition to slower transport and module tests. If one of those paths is broken, a failure can take close to a minute to surface because the harness waits for the agent flow to finish before timing out. When writing or debugging a specific self-hosted test, override -m yourself to run it:

Testing on a fresh Ubuntu install

CI tests dimos with pre-built images and cached deps, so it canโ€™t catch gaps between what installation/ubuntu.md tells a new user to do and what a clean machine actually needs (e.g. a system package we require but forgot to document). The misc/fresh-ubuntu-tests/ harness closes that gap. It replays the documented install + test flow inside a fresh, official, unmodified Ubuntu Desktop 24.04 VM (VirtualBox). Itโ€™s intended to be executed locally.
skip

Writing tests

Test files live next to the code they test. If you have dimos/core/pubsub.py, its tests go in dimos/core/test_pubsub.py. When writing tests you probably want to limit the run to whatever tests youโ€™re writing:

Fixtures

Pytest fixtures are very useful for making sure test failures donโ€™t affect other tests. Whenever you have something that needs to be cleaned up when the test is over (disconnect, close, delete temp files, etc.), you should use a fixture. Simple example code:
The yield is key: everything before it is setup, everything after is teardown. The teardown runs even if the test fails, so you never leak resources between tests.

Mocking

Itโ€™s easier to use the mocker fixture instead of unittest.mock. It automatically undoes all patches when the test ends, so you donโ€™t need with blocks. Patching a method:
There are other useful things in mocker, like mocker.MagicMock() for creating fake objects.

Useful pytest options

Tool files

Dev-only pseudo-tests โ€” the kind that need human interaction or make no assertions โ€” live in tool_*.py files (e.g. dimos/protocol/pubsub/benchmark/tool_benchmark.py). pytest never collects them, because the filename doesnโ€™t match the test_*.py pattern, so a normal pytest run stays clean. Run one on demand by naming it directly:
(-s keeps stdout/stdin open for prints and interactive input; add --timeout=0 for long-running or interactive ones.)

Markers

We have a few markers in use now.
  • self_hosted: used to mark tests that need the self-hosted runner (LFS, ROS, CUDA, heavy deps).
  • mujoco: tests which use MuJoCo. These are very slow and donโ€™t work in CI currently.
If a test needs to be skipped for some reason, please use on of these markers, or add another one.
  • skipif_in_ci: tests which cannot run in GitHub Actions
  • skipif_no_openai: tests which require an OPENAI_API_KEY key in the env
  • skipif_no_alibaba: tests which require an ALIBABA_API_KEY key in the env