Running Tests#

PyDASA uses pytest as its testing framework to ensure code quality and reliability across all modules.

Test Structure#

The test suite is organized to mirror the package structure:

tests/
└── pydasa/
    ├── analysis/       # Analysis module tests
    ├── context/        # Unit system tests
    ├── core/           # Core functionality tests
    ├── data/           # Test data and fixtures
    ├── dimensional/    # Buckingham Pi theorem tests
    ├── elements/       # Variable and parameter tests
    ├── modules/        # Module-specific tests
    ├── serialization/  # Parser and serialization tests
    ├── structs/        # Data structure tests
    ├── validations/    # Validation system tests
    └── workflows/      # Workflow orchestration tests

Running All Tests#

To run the complete test suite:

# From the project root directory
pytest tests/

With verbose output:

pytest tests/ -v

Running Specific Tests#

Run tests for a specific module:

# Test specific module
pytest tests/pydasa/workflows/

# Test specific file
pytest tests/pydasa/workflows/test_basic.py

# Test specific test class
pytest tests/pydasa/workflows/test_basic.py::TestWorkflowBase

# Test specific test method
pytest tests/pydasa/workflows/test_basic.py::TestWorkflowBase::test_initialization

Test Coverage#

The project maintains high test coverage across core modules. Coverage reports are automatically generated and tracked via Codecov.

To generate a local coverage report:

# Install coverage tools
pip install pytest-cov

# Run tests with coverage
pytest tests/ --cov=pydasa --cov-report=html

# View the report (opens in browser)
# The report will be in htmlcov/index.html

Coverage Status#

Current coverage status by module:

  • core/: Foundation classes, configuration, I/O

  • dimensional/: Buckingham Pi theorem, dimensional matrix solver

  • elements/: Variable and parameter management

  • workflows/: AnalysisEngine, MonteCarloSimulation, SensitivityAnalysis

  • validations/: Decorator-based validation system

  • serialization/: LaTeX and formula parsing

  • ⚠️ context/: Unit conversion system (partial coverage - stub implementation)

  • ⚠️ structs/: Data structures (partial test coverage)

Writing Tests#

Test Conventions#

PyDASA tests follow these conventions:

  1. Test files: Named test_*.py to be discovered by pytest

  2. Test classes: Named TestClassName using unittest.TestCase

  3. Test methods: Named test_method_name describing what is tested

  4. Assertions: Use both unittest assertions and pytest assertions

Example Test Structure#

import unittest
import pytest
from pydasa.workflows.basic import WorkflowBase
from pydasa.elements.parameter import Variable

class TestWorkflowBase(unittest.TestCase):
    """Tests for WorkflowBase class."""

    def setUp(self):
        """Set up test fixtures."""
        self.workflow = WorkflowBase(_idx=0, _fwk="PHYSICAL")

    def test_initialization(self):
        """Test workflow initialization."""
        assert self.workflow._idx == 0
        assert self.workflow._fwk == "PHYSICAL"

    def test_variable_management(self):
        """Test adding and retrieving variables."""
        var = Variable(_sym="x", _dims="L")
        self.workflow.add_variable(var)
        assert "x" in self.workflow.variables

    def tearDown(self):
        """Clean up after tests."""
        pass

Test Data and Fixtures#

Test data is centralized in tests/pydasa/data/test_data.py for consistency:

from tests.pydasa.data.test_data import get_simulation_test_data

def test_with_fixture():
    """Test using shared test data."""
    data = get_simulation_test_data()
    # Use data in your test
    assert data is not None

Continuous Integration#

Tests are automatically run on every commit via GitHub Actions:

  • ✅ All tests must pass before merging

  • ✅ Coverage reports are uploaded to Codecov

  • ✅ Test results are visible in pull requests

Test Requirements#

Testing dependencies are specified in pyproject.toml:

[project.optional-dependencies]
dev = [
    "pytest>=8.1.1",
    "pytest-cov>=4.0.0",  # For coverage reports
]

Install testing dependencies:

pip install -e ".[dev]"

Troubleshooting Tests#

Common Issues#

Import Errors

Install PyDASA in development mode: pip install -e .

Missing Dependencies

Install dev dependencies: pip install -e ".[dev]"

Test Discovery Issues

Ensure test files are named test_*.py and located in tests/ directory

Failed Tests After Changes

Run specific test to see detailed error: pytest path/to/test_file.py -v

Debug Mode#

Run tests with detailed output and stop at first failure:

# Stop on first failure
pytest tests/ -x

# Show local variables on failure
pytest tests/ -l

# Enter debugger on failure
pytest tests/ --pdb

Best Practices#

When writing tests for PyDASA:

  1. Test one thing at a time: Each test method should verify a single behavior

  2. Use descriptive names: Test names should clearly indicate what is being tested

  3. Include docstrings: Explain what the test verifies

  4. Test edge cases: Include tests for boundary conditions and error cases

  5. Keep tests independent: Tests should not depend on execution order

  6. Use fixtures appropriately: Share setup code via setUp/tearDown or pytest fixtures

  7. Mock external dependencies: Isolate unit tests from external systems

  8. Maintain coverage: Aim for high coverage on core functionality

Contributing Tests#

When contributing to PyDASA:

  1. Add tests for new features: All new code should include tests

  2. Update tests for changes: Modify existing tests when changing functionality

  3. Run full test suite: Execute pytest tests/ before committing

  4. Check coverage: Ensure new code maintains or improves coverage

  5. Follow conventions: Match existing test structure and naming

See the Contributing to PyDASA guide for more details on the development workflow.