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