A lightweight Python testing framework with decorator-based test collection and automatic discovery—designed for personal projects and learning.
Note: PyForge is designed for personal projects, learning, and small-scale testing. It is not a substitute for production frameworks like pytest.
- 🎯 Simple Decorators — Mark tests with
@test, automatic collection - 🚀 Zero Configuration — Works out of the box
- 📦 Zero Dependencies — Pure Python, nothing to install but PyForge itself
- 🔍 Auto-Discovery — Finds and loads all
test*.pyfiles automatically - ⚡ Fast Execution — Minimal overhead, quick feedback
- 🏷️ Test Markers — Organize tests by priority (
integration,slow) - 📊 Parameterized Tests — Run one test with multiple inputs
- ⊘ Skip Tests — Conditionally skip tests with clear reasons
- ✅ Full Type Hints — PEP 484 type annotations throughout
- 🎨 Clean Output — Color-coded results with minimal internal noise
pip install pyforge-testOr from GitHub:
pip install git+https://github.com/ertanturk/pyforge-test.gitmkdir -p tests && touch tests/__init__.pyCreate tests/test_example.py:
from pyforge_test import test
@test
def test_addition() -> None:
"""Test basic arithmetic."""
assert 2 + 2 == 4
@test
def test_strings() -> None:
"""Test string manipulation."""
assert "hello".upper() == "HELLO"pyforgeExpected output:
Discovering test modules in '/path/to/tests'...
Loaded: test_example.py
Loaded 1 test module(s).
Executing 2 test(s).
PyForge Test Results
------------------------------------------------------------------------
test_example.py
PASSED test_addition (Line 4)
PASSED test_strings (Line 9)
------------------------------------------------------------------------
Summary: PASSED: 2/2 FAILED: 0/2 SKIPPED: 0/2 ERRORS: 0/2
Took 5 ms to execute all tests
------------------------------------------------------------------------
pyforge # Run all tests
pyforge -q # Quiet: only failures
pyforge -v # Verbose: full tracebacks
pyforge --fail-fast # Stop on first failure
pyforge -k api # Filter by test name
pyforge test_api.py # Run specific filefrom pyforge_test import test
@test
def test_example() -> None:
"""Test function requirements:
- Starts with 'test_'
- No parameters
- Return type -> None
- Uses @test decorator
"""
assert TrueRun the same test with multiple inputs:
from pyforge_test import test_parameterized
@test_parameterized([
(2, 3, 5),
(10, 5, 15),
(100, 200, 300),
])
def test_addition(a: int, b: int, expected: int) -> None:
"""Generates: test_addition_0, test_addition_1, test_addition_2"""
assert a + b == expectedExecution priority: Unmarked (0) → Integration (1) → Slow (2)
from pyforge_test import test, test_marker
# Fast unit test (runs first)
@test
def test_fast() -> None:
assert 2 + 2 == 4
# Integration test (requires external resources)
@test_marker("integration")
@test
def test_database() -> None:
db.connect()
assert db.is_connected()
# Slow test (performance-intensive)
@test_marker("slow")
@test
def test_large_dataset() -> None:
result = process_records(1_000_000)
assert len(result) == 1_000_000Important:
@test_markermust come before@test
import sys
from pyforge_test import test, test_skip, test_skipif
@test_skip(reason="Not implemented yet")
def test_future() -> None:
"""Always skipped."""
pass
@test_skipif(sys.platform == "win32", reason="Unix only")
def test_unix() -> None:
"""Skipped on Windows."""
passmy-project/
├── src/
│ ├── main.py
│ └── utils.py
├── tests/
│ ├── __init__.py # Required (can be empty)
│ ├── test_main.py # Auto-discovered
│ └── test_utils.py # Auto-discovered
├── README.md
└── pyproject.toml
PyForge is fully type-checked and linted:
- Ruff: All checks passing ✅
- Pylint: 9.89/10 score ✅
- Pyright: Strict type checking ✅
- Type Hints: Full PEP 484 compliance ✅
- Complete Guide: docs/Documentation.md
- Development Guide: .github/instructions/pyforge.instructions.md
- Examples: tests/test_test.py
- Roadmap: docs/FUTURE_UPDATES.md
Code standards:
- PEP 484 type hints on all functions
- Google-style docstrings
- Exception chaining:
raise ... from e - No bare
exceptstatements
MIT — See LICENSE
Contributions welcome! Open an issue or PR on GitHub.
Status: Alpha (v0.2.0) | Python: 3.12+ | Type Safe: Yes | Dependencies: 0