Skip to content

ertanturk/pyforge-test

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

28 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

PyForge Testing Framework

A lightweight Python testing framework with decorator-based test collection and automatic discoveryβ€”designed for personal projects and learning.

PyPI version Python 3.12+ License: MIT Code Quality Type Checked

Note: PyForge is designed for personal projects, learning, and small-scale testing. It is not a substitute for production frameworks like pytest.

Features

  • 🎯 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*.py files 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

Installation

pip install pyforge-test

Or from GitHub:

pip install git+https://github.com/ertanturk/pyforge-test.git

Quick Start

1. Create Test File

mkdir -p tests && touch tests/__init__.py

Create 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"

2. Run Tests

pyforge

Expected 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
------------------------------------------------------------------------

CLI Options

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 file

Test Features

Basic Tests

from pyforge_test import test


@test
def test_example() -> None:
    """Test function requirements:
    - Starts with 'test_'
    - No parameters
    - Return type -> None
    - Uses @test decorator
    """
    assert True

Parameterized Tests

Run 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 == expected

Test Markers

Execution 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_000

Important: @test_marker must come before @test

Skip Tests

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."""
    pass

Project Structure

my-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

Code Quality

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 βœ…

Documentation

Development

Code standards:

  • PEP 484 type hints on all functions
  • Google-style docstrings
  • Exception chaining: raise ... from e
  • No bare except statements

License

MIT β€” See LICENSE

Contributing

Contributions welcome! Open an issue or PR on GitHub.


Status: Alpha (v0.2.0) | Python: 3.12+ | Type Safe: Yes | Dependencies: 0

About

A lightweight Python unit testing framework for personal projects and learning. Zero configuration, decorator-based tests, automatic discovery.

Resources

License

Stars

Watchers

Forks

Contributors

Languages