Testing

PyTropicSquare maintains a comprehensive test suite with automated testing and continuous integration.

Test Reports

The following reports are automatically generated during documentation builds:

  • Test Results - Detailed test execution report (pass/fail status, duration, assertions, tracebacks)

  • Code Coverage - Code coverage analysis (overall percentage, per-module breakdown, line-by-line visualization)

Coverage Target

We maintain a minimum coverage threshold of 70% across the codebase. Pull requests that reduce coverage below this threshold will fail CI checks.

Running Tests Locally

Prerequisites

Install development dependencies:

pip install -r requirements-dev.txt

Running the Full Test Suite

Run all tests with coverage:

pytest tests/ -v --cov=tropicsquare --cov-report=html

This will:

  • Execute all unit tests

  • Generate coverage report in htmlcov/

  • Show coverage summary in terminal

Running Specific Tests

Run a single test file:

pytest tests/unit/test_crc.py -v

Run tests matching a pattern:

pytest tests/ -k "test_crc" -v

Run with HTML report:

pytest tests/ -v --html=report.html --self-contained-html

Continuous Integration

GitHub Actions

Our CI/CD pipeline runs on every push and pull request:

Test Workflow (.github/workflows/tests.yml)
  • Runs on Python 3.11, 3.12, and 3.13

  • Generates JUnit XML for GitHub annotations

  • Posts coverage comments on pull requests

  • Fails if coverage drops below 70%

Documentation Workflow (.github/workflows/sphinx-docs.yml)
  • Runs on master branch only

  • Executes full test suite

  • Generates HTML test reports

  • Builds Sphinx documentation

  • Deploys everything to GitHub Pages

Test Organization

Test Structure

Tests are organized by functionality:

tests/
├── conftest.py              # Shared fixtures and mocks
├── unit/                    # Unit tests (no hardware)
│   ├── test_crc.py         # CRC calculation tests
│   ├── test_exceptions.py  # Exception hierarchy tests
│   ├── test_chip_id.py     # Chip ID parsing tests
│   └── config/             # Configuration tests
└── fixtures/               # Test data from real hardware

Testing Strategy

Unit Tests

Tests that run without hardware, using mocked dependencies:

  • CRC calculations

  • Data parsing (ChipId, SerialNumber, Config)

  • Exception handling

  • Protocol logic with mocked transport

Mock Infrastructure

The test suite includes comprehensive mocks:

  • MockL1Transport - Simulates SPI/UART communication

  • MockCrypto - Deterministic cryptographic operations

  • MockAESGCM - AES-GCM encryption/decryption

Fixtures

Real hardware response data captured for realistic testing:

  • Chip ID structures

  • Configuration register values

  • Protocol responses

  • Error conditions

Writing Tests

Test Naming

Follow pytest conventions:

  • Test files: test_*.py

  • Test classes: Test*

  • Test functions: test_*

Example Test

"""Tests for CRC16 calculation."""

import pytest
from tropicsquare.crc import CRC

class TestCRC16:
    """Test CRC16 functionality."""

    def test_crc16_empty_data(self):
        """Test CRC16 with empty input."""
        result = CRC.crc16(b'')
        assert isinstance(result, bytes)
        assert len(result) == 2

    def test_crc16_consistency(self):
        """Test that same input produces same output."""
        data = b'\\x12\\x34\\x56\\x78'
        result1 = CRC.crc16(data)
        result2 = CRC.crc16(data)
        assert result1 == result2

Using Fixtures

@pytest.fixture
def mock_transport():
    """Provide a mock L1 transport for testing."""
    return MockL1Transport()

def test_with_mock(mock_transport):
    """Test using the mock transport."""
    ts = TropicSquare(mock_transport)
    # Test implementation here

Coverage Guidelines

Target Coverage

Module

Target

Difficulty

crc.py

100%

Easy

exceptions/

100%

Easy

chip_id/

95%+

Easy

config/

90%+

Medium

l2_protocol

85%+

Medium

transports/

80%+

Medium

Overall

70-80%

What to Test

High Priority
  • Core functionality (CRC, parsing, protocol)

  • Error handling and exceptions

  • Public API methods

  • Edge cases and boundary conditions

Medium Priority
  • Internal helper methods

  • Configuration options

  • Platform-specific code paths

Low Priority
  • Debug logging

  • String representations (__repr__, __str__)

  • Trivial getters/setters

Troubleshooting

Common Issues

Import errors

Ensure the package is installed in development mode:

pip install -e .
Coverage not generated

Make sure pytest-cov is installed:

pip install pytest-cov
Tests fail in CI but pass locally

Check Python version compatibility. CI tests on multiple versions.

HTML report not found

Reports are generated in the working directory. Check:

ls test-report.html htmlcov/

Contributing

When contributing code:

  1. Write tests for new functionality

  2. Ensure existing tests pass

  3. Maintain or improve coverage

  4. Follow existing test patterns

  5. Document complex test scenarios

See the GitHub repository for contribution guidelines.