Lore testing standards

June 5, 2026 · View on GitHub

This document defines the standard patterns for testing across the Lore codebase.

Overview

TypeLocationFrameworkPurpose
Unit testsInline #[cfg(test)] modulesRust/tokioModule-level testing
Integration testslore-revision/tests/Rust/tokioCross-module testing
Smoke testsscripts/test/Python/pytestCLI and server testing
Load testsInternal infrastructureInternal harnessPerformance testing

1. Rust unit tests

Inline in source modules with #[cfg(test)]:

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_sync_example() {
        // synchronous test
    }
}

2. Rust async tests

Frameworks: tokio, mockall, async-trait

All async tests use the LORE_CONTEXT.scope() pattern:

#[tokio::test]
async fn test_example() {
    LORE_CONTEXT
        .scope(setup_test_execution(), async {
            // test code
        })
        .await;
}

Test independence

Tests MUST be independent and isolated. Avoid:

  • #[serial] — Forces sequential execution, indicating shared mutable state.
  • Test dependencies — Tests that rely on other tests running first.

If you find yourself needing #[serial], refactor the test to:

  1. Create isolated test fixtures and state per test.
  2. Use unique identifiers (for example, random repository names or unique temp directories).
  3. Mock shared resources instead of using real shared state.
// Anti-pattern: shared state requiring serial execution
#[tokio::test]
#[serial]  // DON'T DO THIS
async fn test_with_shared_state() { ... }

// Preferred: isolated test with unique fixtures
#[tokio::test]
async fn test_with_isolated_state() {
    let test_repo = test_store_create();  // Creates unique test repository
    // Test uses only this isolated state
}

Key files:

  • lore-revision/tests/helper.rstest_store_create(), setup_test_execution().
  • lore-revision/tests/ — Cross-module integration tests.

3. Smoke tests (scripts/test/)

Framework: pytest

Requirement: All Lore CLI commands must have smoke test coverage. When adding a new command, add corresponding tests to scripts/test/.

Key files

FilePurpose
conftest.pyFixtures and server management
lore.pyLore wrapper class for the CLI
error_types.pyException mapping from CLI output

Fixtures

  • new_lore_repo — Creates a new test repository.
  • lore_executable_path — Path to the Lore client binary.
  • auto_lore_local_server — Auto starts the server for the session.

Usage

@pytest.mark.smoke
def test_commit(new_lore_repo):
    repo: Lore = new_lore_repo()
    repo.stage(offline=True)
    repo.commit("Test commit", offline=True)
    repo.push()

Running with uv

Tests require Python 3.13+. Use uv to manage dependencies and run tests:

# Install dependencies
uv sync

# Run all smoke tests with local server
uv run pytest scripts/test/ --lore-client-binary=release --lore-server-binary=release

# Run only tests marked as smoke
uv run pytest scripts/test/ -m smoke

# Run tests in parallel (uses pytest-xdist)
uv run pytest scripts/test/ -n auto

# Against external server
uv run pytest scripts/test/ --disable-local-server --lore-remote-url=lore://host:port

Command-line options

OptionDefaultDescription
--lore-client-binaryreleasePath or "release"/"debug"
--lore-server-binaryreleasePath or "release"/"debug"
--lore-remote-urllore://127.0.0.1:41338Server address
--disable-local-serverfalseUse external server
--disable-auto-serverfalseDon't auto start the server

pytest markers

MarkerDescription
@pytest.mark.smokeSmoke tests for basic functionality
@pytest.mark.slowSlow running tests
@pytest.mark.disable_auto_serverTests requiring the --disable-auto-server flag

4. Load tests

Lore has a load-testing suite that exercises concurrent clone, commit, sync, lock, and compaction workloads. It runs on internal infrastructure and isn't part of the open-source repository, so its harness and scenarios aren't documented here.


5. Best practices

  1. All Lore commands must have smoke tests in scripts/test/.
  2. Use LORE_CONTEXT.scope() for all async Rust tests.
  3. Keep tests independent — Avoid #[serial] and test dependencies; use isolated fixtures.
  4. Use the new_lore_repo fixture for smoke tests (handles cleanup).
  5. Mark tests with @pytest.mark.smoke for smoke test runs.
  6. Use offline=True for operations that don't need the server.
  7. Feature-gate integration tests that require external dependencies.