PhaseFieldX Unit Testing Framework: How to Add Tests with pytest

PhaseFieldX uses pytest as its unit testing framework; you can add new tests by creating Python files matching test_*.py in the test/ directory, writing functions that start with test_, and executing pytest test/ --disable-warnings locally or through the automated CI pipeline.

The PhaseFieldX repository relies on pytest to maintain code quality and ensure reliability across its phase-field simulation codebase. Whether you are extending existing algorithms or adding new helper utilities, understanding the testing conventions allows you to contribute with confidence. This guide covers the exact file structure, naming conventions, and commands used in the castillonmiguel/phasefieldx repository.

Testing Framework Overview

PhaseFieldX implements pytest as its sole unit testing framework. According to the source code, the project follows standard pytest discovery rules where test modules reside exclusively under the test/ folder at the repository root. The GitHub Actions workflow in .github/workflows/testing.yml executes the full suite with the command pytest test/ --disable-warnings, ensuring every pull request passes the complete test matrix before merging.

Test Structure and Conventions

File Naming Patterns

All test files must follow pytest discovery conventions. The repository accepts two patterns:

These modules live in the test/ directory, as seen in test/test_file_utilities.py, which imports pytest directly and validates file handling utilities.

Test Function Requirements

Every test function must begin with the prefix test_ to be recognized by pytest's test collector. The function should import the target code from the phasefieldx package and use standard assert statements for validation. No special decorators are required for basic functionality testing.

How to Add New Tests to PhaseFieldX

Writing a Basic Unit Test

Create a new file in test/ following the test_*.py pattern. Import pytest and the specific function or class you want to validate from the main package, then write a function prefixed with test_ that asserts expected behavior:


# test/test_my_helper.py

import pytest
from phasefieldx import my_helper  # replace with the actual import

def test_my_helper_basic():
    """Check that my_helper returns the expected result for a simple case."""
    input_value = 10
    expected = 20           # replace with the real expected value

    assert my_helper(input_value) == expected

This structure works because the file location matches pytest's discovery pattern and the function name triggers automatic test execution during collection.

Using Fixtures for Temporary Resources

For tests requiring file system operations or setup/teardown logic, leverage pytest's fixture system. The built-in tmp_path fixture provides isolated temporary directories without manual cleanup:


# test/test_my_algorithm.py

import os
import pytest
from phasefieldx import run_algorithm

@pytest.fixture
def temp_dir(tmp_path):
    """Create a temporary working directory for the test."""
    return str(tmp_path)

def test_algorithm_writes_output(temp_dir):
    """Verify that the algorithm creates the expected output file."""
    run_algorithm(temp_dir)                 # call the function you want to test

    output_file = os.path.join(temp_dir, "result.txt")
    assert os.path.isfile(output_file)      # output file must exist

    # optionally check its contents

    with open(output_file) as f:
        assert "SUCCESS" in f.read()

The temp_dir fixture wraps tmp_path to provide a string path compatible with legacy file operations, ensuring your test runs in an isolated environment.

Running Tests Locally and in CI

Local Execution

Run the complete test suite from the repository root using the same command defined in the CI pipeline:


# Install the package first (required for imports)

pip install .

# Execute all tests

pytest test/ --disable-warnings

This command mirrors the automated testing defined in .github/workflows/testing.yml at lines 40-45, ensuring consistency between local development and continuous integration environments.

Continuous Integration

The repository automatically executes tests on every push and pull request. The workflow file .github/workflows/testing.yml triggers pytest test/ --disable-warnings within a conda environment, validating code against the project's declared dependencies in pyproject.toml. Any new test files added to the test/ directory automatically join this execution queue without requiring workflow modifications.

Summary

  • PhaseFieldX uses pytest: The framework enforces naming conventions (test_*.py files, test_* functions) for automatic discovery.
  • Tests live in test/: All test modules must reside in this root-level directory, as demonstrated by test/test_file_utilities.py.
  • CI runs pytest test/ --disable-warnings: This command, defined in .github/workflows/testing.yml, validates every contribution.
  • Add tests by creating files: New test modules automatically integrate into both local runs and GitHub Actions workflows.

Frequently Asked Questions

What unit testing framework does PhaseFieldX use?

PhaseFieldX uses pytest as its unit testing framework. The source code in test/test_file_utilities.py explicitly imports pytest, and the CI pipeline in .github/workflows/testing.yml executes the pytest command to run the entire suite.

Where should I place new test files in the repository?

Place all new test files in the test/ directory at the repository root. Name the file using the test_*.py pattern (e.g., test_new_feature.py) so pytest's test collector discovers it automatically during execution.

How do I run the PhaseFieldX tests on my local machine?

First install the package using pip install . from the repository root, then execute pytest test/ --disable-warnings. This command matches the CI configuration and runs all discovered tests while suppressing non-error warnings.

Can I use pytest fixtures when adding tests to PhaseFieldX?

Yes, pytest fixtures are fully supported. You can use built-in fixtures like tmp_path for temporary directories or define custom fixtures within your test file for reusable setup logic, as shown in the test_algorithm_writes_output example above.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →