Green is a clean, colorful, fast python test runner.
—
Green provides seamless integration with setuptools, allowing it to be used as a setup.py command for test execution in Python packages with full configuration support and package-aware test discovery.
Setuptools command class that enables using Green as a python setup.py command for running tests.
class green(setuptools.Command):
"""
Setuptools command for running Green tests.
Enables Green to be used as a setuptools command, providing
integration with Python package build and test workflows.
"""
description = "Run tests using Green test runner"
user_options = [
# Command-line options available for setup.py green
# Generated dynamically from Green's configuration options
]
def initialize_options(self):
"""Initialize command options with Green defaults."""
def finalize_options(self):
"""Finalize and validate command options."""
def run(self):
"""Execute Green test runner with configured options."""Helper function for retrieving available Green options for setuptools integration.
def get_user_options():
"""
Get available Green options for setuptools command.
Returns:
list: List of (option_name, short_option, description) tuples
compatible with setuptools command option format
Example:
options = get_user_options()
for option_name, short_option, description in options:
print(f"{option_name}: {description}")
"""# setup.py
from setuptools import setup, find_packages
setup(
name="mypackage",
version="1.0.0",
packages=find_packages(),
# Include Green in setup requirements
setup_requires=['green'],
# Optional: specify test suite for Green discovery
test_suite='tests',
# Standard package metadata
author="Your Name",
author_email="you@example.com",
description="My Python package",
install_requires=[
'requests',
'click',
],
extras_require={
'dev': ['green', 'coverage', 'flake8'],
'test': ['green'],
}
)# setup.cfg
[metadata]
name = mypackage
version = 1.0.0
description = My Python package
author = Your Name
author_email = you@example.com
[options]
packages = find:
install_requires =
requests
click
[options.extras_require]
dev =
green
coverage
flake8
test = green
# Green-specific configuration
[green]
verbose = 2
processes = 4
run-coverage = true
omit-patterns = */tests/*,*/venv/*
# Setup command aliases for convenience
[aliases]
test = green# pyproject.toml
[build-system]
requires = ["setuptools>=45", "wheel", "green"]
build-backend = "setuptools.build_meta"
[project]
name = "mypackage"
version = "1.0.0"
description = "My Python package"
authors = [{name = "Your Name", email = "you@example.com"}]
dependencies = [
"requests",
"click"
]
[project.optional-dependencies]
dev = ["green", "coverage", "flake8"]
test = ["green"]
[tool.green]
verbose = 2
processes = 4
run-coverage = true
omit-patterns = ["*/tests/*", "*/venv/*"]# Run tests using Green via setuptools
python setup.py green
# With Green-specific options
python setup.py green --verbose 2 --run-coverage
# Using aliases defined in setup.cfg
python setup.py test
# Run specific test targets
python setup.py green --targets tests.test_module# Install package in development mode with test dependencies
pip install -e .[dev]
# Run tests during development
python setup.py green --verbose 2
# Run tests with coverage
python setup.py green --run-coverage --verbose 2
# Run specific test modules during debugging
python setup.py green --targets tests.test_auth --verbose 3 --processes 1# setup.py with custom Green configuration
from setuptools import setup, Command
import sys
class GreenTestCommand(Command):
"""Custom test command using Green."""
description = 'Run tests using Green with custom configuration'
user_options = [
('test-suite=', 't', 'Test suite to run'),
('coverage', 'c', 'Run with coverage'),
('verbose=', 'v', 'Verbosity level'),
]
def initialize_options(self):
self.test_suite = 'tests'
self.coverage = False
self.verbose = 2
def finalize_options(self):
if self.verbose:
self.verbose = int(self.verbose)
def run(self):
"""Run tests with Green."""
import green.cmdline
# Build Green command line arguments
green_args = [self.test_suite]
if self.coverage:
green_args.extend(['--run-coverage'])
if self.verbose:
green_args.extend(['--verbose', str(self.verbose)])
# Run Green
exit_code = green.cmdline.main(green_args)
sys.exit(exit_code)
setup(
name="mypackage",
# ... other setup parameters ...
cmdclass={
'test': GreenTestCommand,
'green': GreenTestCommand,
},
setup_requires=['green'],
)# setup.py for package that uses Green internally
from setuptools import setup, find_packages
setup(
name="mypackage",
version="1.0.0",
packages=find_packages(),
# Include Green as a dependency for development/testing
extras_require={
'dev': [
'green>=3.0.0',
'coverage>=5.0',
'flake8',
'mypy',
],
'test': ['green>=3.0.0'],
},
# Specify test command
test_suite='tests',
# Command aliases
cmdclass={
'test': 'green.command:green',
},
# Package metadata
author="Package Author",
description="A package that uses Green for testing",
long_description=open('README.md').read(),
long_description_content_type='text/markdown',
python_requires='>=3.8',
classifiers=[
'Development Status :: 5 - Production/Stable',
'Intended Audience :: Developers',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
'Programming Language :: Python :: 3.12',
],
)# tox.ini
[tox]
envlist = py38,py39,py310,py311,py312
[testenv]
deps =
green
coverage
commands =
python setup.py green --run-coverage --verbose 1
[testenv:dev]
deps =
green
coverage
flake8
mypy
commands =
python setup.py green --run-coverage --verbose 2
flake8 src tests
mypy src# Makefile
.PHONY: test test-verbose test-coverage clean install
# Basic test running
test:
python setup.py green
# Verbose test output
test-verbose:
python setup.py green --verbose 2
# Test with coverage
test-coverage:
python setup.py green --run-coverage --verbose 2
# Development installation
install-dev:
pip install -e .[dev]
# Clean build artifacts
clean:
python setup.py clean --all
rm -rf build/ dist/ *.egg-info/
find . -name '*.pyc' -delete
find . -name '__pycache__' -delete
# Full development workflow
dev: clean install-dev test-coverage# Dockerfile for development
FROM python:3.9
WORKDIR /app
# Copy package files
COPY setup.py setup.cfg pyproject.toml ./
COPY src/ src/
COPY tests/ tests/
# Install package with test dependencies
RUN pip install -e .[test]
# Run tests using Green via setuptools
CMD ["python", "setup.py", "green", "--verbose", "2"]# docker-compose.yml for testing
version: '3.8'
services:
test:
build: .
volumes:
- .:/app
command: python setup.py green --run-coverage --verbose 2
test-py38:
build:
context: .
dockerfile: Dockerfile.py38
volumes:
- .:/app
command: python setup.py green --verbose 1
test-py311:
build:
context: .
dockerfile: Dockerfile.py311
volumes:
- .:/app
command: python setup.py green --verbose 1# .github/workflows/test.yml
name: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.8, 3.9, "3.10", 3.11, 3.12]
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install package with test dependencies
run: |
pip install -e .[test]
- name: Run tests with Green via setuptools
run: |
python setup.py green --junit-report test-results.xml --run-coverage
- name: Upload test results
uses: actions/upload-artifact@v3
if: always()
with:
name: test-results-${{ matrix.python-version }}
path: test-results.xml# setup.py with explicit test configuration
setup(
name="mypackage",
# Explicit test suite specification
test_suite='tests',
# Alternative: use Green's discovery
# Green will automatically discover tests in 'tests/' directory
# Package structure:
# mypackage/
# ├── setup.py
# ├── src/
# │ └── mypackage/
# │ ├── __init__.py
# │ └── core.py
# └── tests/
# ├── __init__.py
# ├── test_core.py
# └── integration/
# └── test_integration.py
)# setup.py with environment-specific test configuration
import os
from setuptools import setup
# Determine test configuration based on environment
if os.environ.get('CI'):
# CI environment: fast, minimal output
test_config = {
'verbose': 1,
'processes': 0, # Auto-detect
'run_coverage': True,
'junit_report': 'test-results.xml'
}
elif os.environ.get('DEVELOPMENT'):
# Development: detailed output, limited processes
test_config = {
'verbose': 3,
'processes': 2,
'run_coverage': True,
'debug': True
}
else:
# Default configuration
test_config = {
'verbose': 2,
'processes': 4,
'run_coverage': False
}
class CustomGreenCommand(Command):
def run(self):
import green.cmdline
args = ['tests/']
for key, value in test_config.items():
if value is True:
args.append(f'--{key.replace("_", "-")}')
elif value not in (False, None):
args.extend([f'--{key.replace("_", "-")}', str(value)])
exit_code = green.cmdline.main(args)
sys.exit(exit_code)
setup(
# ... package configuration ...
cmdclass={'test': CustomGreenCommand},
)When using python setup.py green, all Green command-line options are available:
# Verbosity control
python setup.py green --verbose 2
python setup.py green -v 3
# Process control
python setup.py green --processes 4
python setup.py green --processes 0 # Auto-detect
# Coverage
python setup.py green --run-coverage
python setup.py green --coverage-config-file .coveragerc
# Output formats
python setup.py green --junit-report test-results.xml
python setup.py green --no-color
# Test selection
python setup.py green --targets tests.test_auth
python setup.py green --file-pattern "*_test.py"
# Debug options
python setup.py green --debug
python setup.py green --keep-reportsBefore (unittest):
# setup.py
setup(
name="mypackage",
test_suite='tests',
)python setup.py testAfter (Green):
# setup.py
setup(
name="mypackage",
test_suite='tests',
setup_requires=['green'],
)# setup.cfg
[aliases]
test = green
[green]
verbose = 2
run-coverage = truepython setup.py test # Now uses Green!Install with Tessl CLI
npx tessl i tessl/pypi-green