A tool for migrating unittest test suites to pytest format
Project description
splurge-unittest-to-pytest
A practical toolset to migrate Python unittest-based tests into idiomatic pytest style. The project features a multi-pass analyzer that intelligently analyzes test patterns and applies transformations with high confidence. The project exposes both a command-line interface and a programmatic API built around libcst-based transformations to preserve semantics while producing readable pytest code.
Enhanced robustness: Comprehensive error handling, cross-platform path support, and intelligent fallback mechanisms ensure reliable operation across diverse codebases and environments.
Quick start
Install (recommended using a virtual environment):
pip install splurge-unittest-to-pytest
Run the CLI (module mode shown):
python -m splurge_unittest_to_pytest migrate [OPTIONS] [SOURCE_FILES...]
OR
splurge-unittest-to-pytest migrate [OPTIONS] [SOURCE_FILES...]
By default the tool preserves the original source file extensions and will
write converted output next to the inputs. Use -t/--target-root to write to
an alternate location.
At-a-glance features
- Multi-pass analyzer that intelligently analyzes test patterns and applies transformations with high confidence, preserving semantics where code mutates accumulators or depends on loop ordering.
- Enhanced pattern support: Custom test prefixes (
spec_,should_,it_), nested test classes, custom setup methods, and advanced exception handling. - Intelligent Configuration System: Advanced validation with cross-field rules, use case detection, and intelligent suggestions for optimal settings.
- Smart Error Recovery: Context-aware error classification, actionable suggestions, and step-by-step recovery workflows for complex migration scenarios.
- Configuration Templates: Pre-configured templates for common scenarios (basic migration, CI/CD integration, batch processing, advanced analysis).
- Interactive Configuration Builder: Guided configuration process with intelligent defaults based on project analysis.
- Comprehensive Documentation: Auto-generated configuration documentation with examples, constraints, and common mistakes for all 30+ settings.
- Safe CST-based transformations using
libcstto preserve formatting and minimize behavior changes. - Dry-run preview modes: print converted code, show unified diffs
(
--diff), or list files only (--list). - Always applies code formatters:
isort+black. - Conservative transformations: class-based tests inheriting from
unittest.TestCaseare preserved to maintain class-scoped fixtures and organization unless a conversion is explicitly desired. - Backups of originals are created by default; pass
--skip-backupto disable creating backup copies before writing. Note: if a.backupfile already exists it will be preserved and not overwritten. - Configurable discovery patterns: Custom test method prefixes (
--prefix), nested class support, and enhanced setup method detection via the CLI or a programmaticMigrationConfig.
See docs/README-DETAILS.md for a comprehensive feature and CLI reference.
Programmatic API and developer docs
For programmatic usage, templates, and end-to-end examples see the API docs:
docs/api/README.md— programmatic API index with examples and workflowsdocs/api/programmatic_api.md— migrate() usage and EventBus exampledocs/api/configuration_api.md— configuration schema, templates, and validation notesdocs/api/cli_mapping.md— CLI to programmatic mapping and CI exampledocs/api/end_to_end_workflow.md— a complete end-to-end programmatic workflowdocs/configuration/configuration-reference.md— full configuration reference (auto-generated)
Common CLI options (summary)
-d, --dir DIR: Root directory for discovery-f, --file PATTERN: Glob pattern(s) to select files (repeatable)--dry-run: Preview generated output without writing files (presence-only flag)--diff: When used with--dry-run, show unified diffs (presence-only flag)--list: When used with--dry-run, list files only (presence-only flag)--posix: Force POSIX-style path output in dry-run mode (presence-only flag)- (no
--quietflag) The tool is quiet by default; use--verbose/--debugto increase output verbosity. --suffix SUFFIX: Append a suffix to converted filenames--backup-root DIR: Root directory for backup files when recursing. When specified, backups preserve folder structure. By default, backups are created next to the original files.--skip-backup: Skip creating backup copies of originals when writing (presence-only flag). By default the tool will create a backup of the original file when writing; if a backup file already exists the tool will not overwrite it—an existing.backupfile is preserved.--prefix PREFIX: Allowed test method prefixes (repeatable; default:test). Supports custom prefixes likespec,should,itfor modern testing frameworks.-c, --config FILE: YAML configuration file to load settings from (overrides CLI defaults).--suggestions: Show intelligent configuration suggestions (presence-only flag).--use-case-analysis: Show detected use case analysis (presence-only flag).--field-help FIELD: Show help for a specific configuration field.--list-templates: List available configuration templates (presence-only flag).--template TEMPLATE: Use a pre-configured template (e.g., 'basic_migration', 'ci_integration').--generate-docs [markdown|html]: Generate configuration documentation.
For the full set of flags and detailed help, run:
python -m splurge_unittest_to_pytest migrate --help
Examples
Preview conversion for a single file and print generated code:
python -m splurge_unittest_to_pytest migrate --dry-run tests/test_example.py
Show unified diff for a directory:
python -m splurge_unittest_to_pytest migrate -d tests --dry-run --diff
Verbose dry-run with POSIX paths:
The tool is quiet by default. Use --verbose or --debug or --info to increase output verbosity. For example:
python -m splurge_unittest_to_pytest migrate -d tests --dry-run --posix --verbose
Perform migration and write files to converted/ (preserve extensions). Backups are created by default; to disable backups pass --skip-backup:
python -m splurge_unittest_to_pytest migrate -d tests -t converted
# Disable backups when writing:
python -m splurge_unittest_to_pytest migrate -d tests -t converted --skip-backup
Redirect backups to a custom directory while preserving folder structure:
# Create backups in a centralized location when processing multiple directories:
python -m splurge_unittest_to_pytest migrate -d tests --backup-root ./backups
Migrate with custom test prefixes for modern testing frameworks:
# Support spec_ methods for BDD-style tests
python -m splurge_unittest_to_pytest migrate tests/ --prefix spec --dry-run
# Support multiple prefixes for hybrid test suites
python -m splurge_unittest_to_pytest migrate tests/ --prefix test --prefix spec --prefix should
Use intelligent configuration suggestions and analysis:
# Get intelligent suggestions for your project
python -m splurge_unittest_to_pytest migrate tests/ --suggestions
# Analyze your project's use case and get tailored recommendations
python -m splurge_unittest_to_pytest migrate tests/ --use-case-analysis
# Get help for a specific configuration field
python -m splurge_unittest_to_pytest migrate --field-help max_file_size_mb
Use configuration templates for common scenarios:
# List available templates
python -m splurge_unittest_to_pytest migrate --list-templates
# Use a pre-configured template
python -m splurge_unittest_to_pytest migrate tests/ --template ci_integration
# Generate configuration documentation
python -m splurge_unittest_to_pytest migrate --generate-docs markdown
Use YAML configuration files for complex setups:
# Create a configuration file with all settings
python -m splurge_unittest_to_pytest init-config my-migration.yaml
# Use the configuration file
python -m splurge_unittest_to_pytest migrate --config my-migration.yaml tests/
Programmatic usage (quick)
from splurge_unittest_to_pytest import main
from splurge_unittest_to_pytest.context import MigrationConfig
config = MigrationConfig(dry_run=True)
result = main.migrate(["tests/test_example.py"], config=config)
if result.is_success():
gen_map = result.metadata.get("generated_code", {})
print(gen_map)
else:
print("Migration failed:", result.error)
Contributing & development
- Run tests locally:
python -m pytest -q - Use ruff for linting/formatting:
python -m ruff check --fixandpython -m ruff format - Tests exercise the core transformers and pipeline; run the full suite before opening PRs.
See docs/README-DETAILS.md for developer notes, architecture guidance, and
contribution conventions.
License
MIT. See LICENSE for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file splurge_unittest_to_pytest-2025.1.1.tar.gz.
File metadata
- Download URL: splurge_unittest_to_pytest-2025.1.1.tar.gz
- Upload date:
- Size: 185.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9d67cd9f822f6ce644db542fb3a229c03296d48d2e7ae33a48e9cb902a735d3f
|
|
| MD5 |
71d7ca16194bec50af8c66d4fc5ccfb3
|
|
| BLAKE2b-256 |
905ef5ec1d473e7d4e57671a908c86d18dbfb22458072c03b5c0b921ba22e378
|
File details
Details for the file splurge_unittest_to_pytest-2025.1.1-py3-none-any.whl.
File metadata
- Download URL: splurge_unittest_to_pytest-2025.1.1-py3-none-any.whl
- Upload date:
- Size: 206.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d5796c93d2413773e735fd7023d64b27ba43c5a5b327d5ecf8426c8c6bba3f70
|
|
| MD5 |
40b1ab4d09d6603449b483b385492e40
|
|
| BLAKE2b-256 |
a4094680b2553b2890b9c8b13f733ec023a28c61505ad546c7cd6f02f64dbb88
|