Skip to content
GitHubRSS

Testing

BigBrotr maintains approximately 2,400 unit tests and 90 integration tests (using testcontainers with PostgreSQL) with a minimum 80% branch coverage requirement.

Terminal window
# All tests (unit + integration)
pytest tests/ -v
# Unit tests only (fast)
pytest tests/ --ignore=tests/integration/ -v
# Single file
pytest tests/unit/core/test_pool.py -v
# Pattern match
pytest -k "health_check" -v
# Coverage report
pytest tests/ --cov=src/bigbrotr --cov-report=html

From pyproject.toml:

  • asyncio_mode = "auto" — no need for @pytest.mark.asyncio decorators
  • --timeout=120 — global test timeout
  • fail_under = 80 — branch coverage threshold
tests/
├── conftest.py # Root fixtures
├── fixtures/
│ └── relays.py # Shared relay fixtures
├── unit/
│ ├── core/
│ │ ├── test_pool.py
│ │ ├── test_brotr.py
│ │ └── test_base_service.py
│ ├── models/
│ │ ├── test_relay.py
│ │ └── test_metadata.py
│ ├── nips/
│ │ ├── test_nip11.py
│ │ └── test_nip66.py
│ ├── utils/
│ │ └── test_protocol.py
│ └── services/
│ ├── test_seeder.py
│ ├── test_finder.py
│ ├── test_validator.py
│ ├── test_monitor.py
│ ├── test_refresher.py
│ └── test_synchronizer.py
└── integration/
└── ... # Testcontainers PostgreSQL
class TestPoolConnect:
"""Tests for Pool.connect() method."""
class TestPoolRetry:
"""Tests for Pool retry behavior."""

test_<method>_<scenario>:

def test_run_empty_batch(self): ...
def test_connect_retry_exhausted(self): ...
def test_fetch_nip11_timeout(self): ...

Every test file should cover:

  • Happy path
  • Empty input
  • Error/exception path
  • Edge cases

Always mock where the function is used, not where it is defined:

# Correct: mock where is_nostr_relay is imported
@patch("bigbrotr.services.validator.is_nostr_relay")
# Wrong: mock at the source module
@patch("bigbrotr.utils.protocol.is_nostr_relay")

The root conftest.py provides shared fixtures:

FixtureProvides
mock_poolMocked asyncpg connection pool
mock_brotrMocked Brotr database facade
mock_connectionMocked database connection
sample_eventPre-built Event instance
sample_relayPre-built Relay instance
sample_metadataPre-built Metadata instance

Service tests mock query functions at the service module namespace:

@patch("bigbrotr.services.finder.service.fetch_candidates")
async def test_run_discovers_relays(self, mock_fetch):
mock_fetch.return_value = [...]
await service.run()
mock_fetch.assert_called_once()

Integration tests use testcontainers to spin up a real PostgreSQL instance:

@pytest.fixture(scope="session")
async def pg_container():
# Starts a PostgreSQL container, applies schema, yields connection
...

These tests verify stored functions, cascade functions, and materialized views against a real database.

  • Contributing — development workflow and coding standards.