Skip to main content

Pytest-inspired testing and code coverage framework for Stata

Project description

statatest

PyPI version Python versions License: MIT Tests codecov Documentation

A pytest-inspired testing and code coverage framework for Stata.

Documentation | GitHub | PyPI

Features

  • Test Discovery: Automatically find and run test_*.do files
  • Rich Assertions: Built on Stata's native assert with detailed failure messages
  • Fixture System: Reusable setup/teardown with pytest-like scoping
  • Code Coverage: Line-level coverage via SMCL comment instrumentation
  • CI Integration: JUnit XML output for GitHub Actions, LCOV for Codecov
  • Backward Compatible: Works with existing test patterns

Installation

Using uv (recommended)

# Install globally
uv tool install statatest

# Or run directly without installing
uvx statatest tests/

Using pip

pip install statatest

Quick Start

# Run all tests in tests/ directory
statatest tests/

# Run with coverage
statatest tests/ --coverage

# Generate JUnit XML for CI
statatest tests/ --junit-xml=junit.xml

Writing Tests

// tests/test_myfunction.do

// @marker: unit
program define test_basic_functionality
    // Setup
    clear
    set obs 10
    gen x = _n

    // Test
    myfunction x, gen(y)

    // Assert
    assert_var_exists y
    assert_equal _N, expected(10)
end

Assertions

Function Purpose Example
assert_equal Value equality assert_equal "\r(mean)'"", expected("5")`
assert_true Boolean true assert_true _N > 0
assert_false Boolean false assert_false missing(x)
assert_error Command should fail assert_error "invalid_command"
assert_var_exists Variable exists assert_var_exists myvar
assert_approx_equal Float comparison assert_approx_equal r(mean), expected(0.5) tol(0.01)

Fixtures

Create reusable setup/teardown functions with conftest.do:

// tests/conftest.do - Shared fixtures

program define fixture_sample_panel
    clear
    set obs 100
    gen int firm_id = ceil(_n / 10)
    gen int year = 2010 + mod(_n, 10)
    gen double revenue = exp(rnormal(15, 2))
end

program define fixture_sample_panel_teardown
    clear
end

Use fixtures in your tests:

// tests/test_analysis.do
// @uses_fixture: sample_panel

program define test_panel_analysis
    use_fixture sample_panel

    assert_obs_count 100
    assert_var_exists revenue
end

Built-in fixtures:

Fixture Purpose
fixture_tempfile Temporary file path ($fixture_tempfile_path)
fixture_empty_dataset Empty dataset with optional obs count
fixture_seed Reproducible random seed

Configuration

Create statatest.toml in your project root:

[tool.statatest]
testpaths = ["tests"]
test_files = ["test_*.do"]
stata_executable = "stata-mp"

[tool.statatest.coverage]
source = ["code/functions"]
omit = ["tests/*"]

[tool.statatest.reporting]
junit_xml = "junit.xml"
lcov = "coverage.lcov"

GitHub Actions Integration

name: Stata Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: astral-sh/setup-uv@v5
      - run:
          uvx statatest tests/ --junit-xml=junit.xml --coverage
          --cov-report=lcov
      - uses: codecov/codecov-action@v5
        with:
          files: coverage.lcov

Requirements

  • Python: 3.11+
  • Stata: 16+

License

MIT License - see LICENSE for details.

Acknowledgments

  • Inspired by pytest
  • SMCL parsing patterns adapted from mcp-stata (AGPL-3.0)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

statatest-0.1.1.tar.gz (42.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

statatest-0.1.1-py3-none-any.whl (71.5 kB view details)

Uploaded Python 3

File details

Details for the file statatest-0.1.1.tar.gz.

File metadata

  • Download URL: statatest-0.1.1.tar.gz
  • Upload date:
  • Size: 42.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for statatest-0.1.1.tar.gz
Algorithm Hash digest
SHA256 af26ac405880acdf6d1a3ad9d97c345a4c9854bf67582f54ebb99f9619f36256
MD5 608c9b3f489134e67d2f5513df49e546
BLAKE2b-256 d3197748204db9150ce26a304122f5e8d3019d886046f4e211d1b8bb6814ede9

See more details on using hashes here.

Provenance

The following attestation bundles were made for statatest-0.1.1.tar.gz:

Publisher: publish.yml on jigonr/statatest

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file statatest-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: statatest-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 71.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for statatest-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 4da3d0258e707aeb0ad006bfe77ec1668058d867580749e1c3917fc73ad5068f
MD5 91fbc13bde4e9cb152d6d3c5a4ee14f0
BLAKE2b-256 3ecad12c3bf2efb936646ce434886f0551a149bce4b4277685df43dcfa7d2770

See more details on using hashes here.

Provenance

The following attestation bundles were made for statatest-0.1.1-py3-none-any.whl:

Publisher: publish.yml on jigonr/statatest

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page