0
# Setuptools Integration
1
2
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.
3
4
## Capabilities
5
6
### Green Setuptools Command
7
8
Setuptools command class that enables using Green as a `python setup.py` command for running tests.
9
10
```python { .api }
11
class green(setuptools.Command):
12
"""
13
Setuptools command for running Green tests.
14
15
Enables Green to be used as a setuptools command, providing
16
integration with Python package build and test workflows.
17
"""
18
19
description = "Run tests using Green test runner"
20
user_options = [
21
# Command-line options available for setup.py green
22
# Generated dynamically from Green's configuration options
23
]
24
25
def initialize_options(self):
26
"""Initialize command options with Green defaults."""
27
28
def finalize_options(self):
29
"""Finalize and validate command options."""
30
31
def run(self):
32
"""Execute Green test runner with configured options."""
33
```
34
35
### Options Configuration
36
37
Helper function for retrieving available Green options for setuptools integration.
38
39
```python { .api }
40
def get_user_options():
41
"""
42
Get available Green options for setuptools command.
43
44
Returns:
45
list: List of (option_name, short_option, description) tuples
46
compatible with setuptools command option format
47
48
Example:
49
options = get_user_options()
50
for option_name, short_option, description in options:
51
print(f"{option_name}: {description}")
52
"""
53
```
54
55
## Setup Configuration
56
57
### Basic setup.py Integration
58
59
```python
60
# setup.py
61
from setuptools import setup, find_packages
62
63
setup(
64
name="mypackage",
65
version="1.0.0",
66
packages=find_packages(),
67
68
# Include Green in setup requirements
69
setup_requires=['green'],
70
71
# Optional: specify test suite for Green discovery
72
test_suite='tests',
73
74
# Standard package metadata
75
author="Your Name",
76
author_email="you@example.com",
77
description="My Python package",
78
install_requires=[
79
'requests',
80
'click',
81
],
82
extras_require={
83
'dev': ['green', 'coverage', 'flake8'],
84
'test': ['green'],
85
}
86
)
87
```
88
89
### setup.cfg Configuration
90
91
```ini
92
# setup.cfg
93
[metadata]
94
name = mypackage
95
version = 1.0.0
96
description = My Python package
97
author = Your Name
98
author_email = you@example.com
99
100
[options]
101
packages = find:
102
install_requires =
103
requests
104
click
105
106
[options.extras_require]
107
dev =
108
green
109
coverage
110
flake8
111
test = green
112
113
# Green-specific configuration
114
[green]
115
verbose = 2
116
processes = 4
117
run-coverage = true
118
omit-patterns = */tests/*,*/venv/*
119
120
# Setup command aliases for convenience
121
[aliases]
122
test = green
123
```
124
125
### pyproject.toml Configuration
126
127
```toml
128
# pyproject.toml
129
[build-system]
130
requires = ["setuptools>=45", "wheel", "green"]
131
build-backend = "setuptools.build_meta"
132
133
[project]
134
name = "mypackage"
135
version = "1.0.0"
136
description = "My Python package"
137
authors = [{name = "Your Name", email = "you@example.com"}]
138
dependencies = [
139
"requests",
140
"click"
141
]
142
143
[project.optional-dependencies]
144
dev = ["green", "coverage", "flake8"]
145
test = ["green"]
146
147
[tool.green]
148
verbose = 2
149
processes = 4
150
run-coverage = true
151
omit-patterns = ["*/tests/*", "*/venv/*"]
152
```
153
154
## Usage Examples
155
156
### Basic Command Line Usage
157
158
```bash
159
# Run tests using Green via setuptools
160
python setup.py green
161
162
# With Green-specific options
163
python setup.py green --verbose 2 --run-coverage
164
165
# Using aliases defined in setup.cfg
166
python setup.py test
167
168
# Run specific test targets
169
python setup.py green --targets tests.test_module
170
```
171
172
### Development Workflow Integration
173
174
```bash
175
# Install package in development mode with test dependencies
176
pip install -e .[dev]
177
178
# Run tests during development
179
python setup.py green --verbose 2
180
181
# Run tests with coverage
182
python setup.py green --run-coverage --verbose 2
183
184
# Run specific test modules during debugging
185
python setup.py green --targets tests.test_auth --verbose 3 --processes 1
186
```
187
188
### Advanced Setup Configuration
189
190
```python
191
# setup.py with custom Green configuration
192
from setuptools import setup, Command
193
import sys
194
195
class GreenTestCommand(Command):
196
"""Custom test command using Green."""
197
198
description = 'Run tests using Green with custom configuration'
199
user_options = [
200
('test-suite=', 't', 'Test suite to run'),
201
('coverage', 'c', 'Run with coverage'),
202
('verbose=', 'v', 'Verbosity level'),
203
]
204
205
def initialize_options(self):
206
self.test_suite = 'tests'
207
self.coverage = False
208
self.verbose = 2
209
210
def finalize_options(self):
211
if self.verbose:
212
self.verbose = int(self.verbose)
213
214
def run(self):
215
"""Run tests with Green."""
216
import green.cmdline
217
218
# Build Green command line arguments
219
green_args = [self.test_suite]
220
221
if self.coverage:
222
green_args.extend(['--run-coverage'])
223
224
if self.verbose:
225
green_args.extend(['--verbose', str(self.verbose)])
226
227
# Run Green
228
exit_code = green.cmdline.main(green_args)
229
sys.exit(exit_code)
230
231
setup(
232
name="mypackage",
233
# ... other setup parameters ...
234
235
cmdclass={
236
'test': GreenTestCommand,
237
'green': GreenTestCommand,
238
},
239
240
setup_requires=['green'],
241
)
242
```
243
244
### Package Distribution with Green
245
246
```python
247
# setup.py for package that uses Green internally
248
from setuptools import setup, find_packages
249
250
setup(
251
name="mypackage",
252
version="1.0.0",
253
packages=find_packages(),
254
255
# Include Green as a dependency for development/testing
256
extras_require={
257
'dev': [
258
'green>=3.0.0',
259
'coverage>=5.0',
260
'flake8',
261
'mypy',
262
],
263
'test': ['green>=3.0.0'],
264
},
265
266
# Specify test command
267
test_suite='tests',
268
269
# Command aliases
270
cmdclass={
271
'test': 'green.command:green',
272
},
273
274
# Package metadata
275
author="Package Author",
276
description="A package that uses Green for testing",
277
long_description=open('README.md').read(),
278
long_description_content_type='text/markdown',
279
python_requires='>=3.8',
280
classifiers=[
281
'Development Status :: 5 - Production/Stable',
282
'Intended Audience :: Developers',
283
'Programming Language :: Python :: 3',
284
'Programming Language :: Python :: 3.8',
285
'Programming Language :: Python :: 3.9',
286
'Programming Language :: Python :: 3.10',
287
'Programming Language :: Python :: 3.11',
288
'Programming Language :: Python :: 3.12',
289
],
290
)
291
```
292
293
## Integration Patterns
294
295
### Tox Integration
296
297
```ini
298
# tox.ini
299
[tox]
300
envlist = py38,py39,py310,py311,py312
301
302
[testenv]
303
deps =
304
green
305
coverage
306
commands =
307
python setup.py green --run-coverage --verbose 1
308
309
[testenv:dev]
310
deps =
311
green
312
coverage
313
flake8
314
mypy
315
commands =
316
python setup.py green --run-coverage --verbose 2
317
flake8 src tests
318
mypy src
319
```
320
321
### Makefile Integration
322
323
```makefile
324
# Makefile
325
.PHONY: test test-verbose test-coverage clean install
326
327
# Basic test running
328
test:
329
python setup.py green
330
331
# Verbose test output
332
test-verbose:
333
python setup.py green --verbose 2
334
335
# Test with coverage
336
test-coverage:
337
python setup.py green --run-coverage --verbose 2
338
339
# Development installation
340
install-dev:
341
pip install -e .[dev]
342
343
# Clean build artifacts
344
clean:
345
python setup.py clean --all
346
rm -rf build/ dist/ *.egg-info/
347
find . -name '*.pyc' -delete
348
find . -name '__pycache__' -delete
349
350
# Full development workflow
351
dev: clean install-dev test-coverage
352
```
353
354
### Docker Integration
355
356
```dockerfile
357
# Dockerfile for development
358
FROM python:3.9
359
360
WORKDIR /app
361
362
# Copy package files
363
COPY setup.py setup.cfg pyproject.toml ./
364
COPY src/ src/
365
COPY tests/ tests/
366
367
# Install package with test dependencies
368
RUN pip install -e .[test]
369
370
# Run tests using Green via setuptools
371
CMD ["python", "setup.py", "green", "--verbose", "2"]
372
```
373
374
```yaml
375
# docker-compose.yml for testing
376
version: '3.8'
377
378
services:
379
test:
380
build: .
381
volumes:
382
- .:/app
383
command: python setup.py green --run-coverage --verbose 2
384
385
test-py38:
386
build:
387
context: .
388
dockerfile: Dockerfile.py38
389
volumes:
390
- .:/app
391
command: python setup.py green --verbose 1
392
393
test-py311:
394
build:
395
context: .
396
dockerfile: Dockerfile.py311
397
volumes:
398
- .:/app
399
command: python setup.py green --verbose 1
400
```
401
402
### CI/CD Integration
403
404
#### GitHub Actions with setuptools
405
406
```yaml
407
# .github/workflows/test.yml
408
name: Tests
409
on: [push, pull_request]
410
411
jobs:
412
test:
413
runs-on: ubuntu-latest
414
strategy:
415
matrix:
416
python-version: [3.8, 3.9, "3.10", 3.11, 3.12]
417
418
steps:
419
- uses: actions/checkout@v3
420
421
- name: Set up Python ${{ matrix.python-version }}
422
uses: actions/setup-python@v4
423
with:
424
python-version: ${{ matrix.python-version }}
425
426
- name: Install package with test dependencies
427
run: |
428
pip install -e .[test]
429
430
- name: Run tests with Green via setuptools
431
run: |
432
python setup.py green --junit-report test-results.xml --run-coverage
433
434
- name: Upload test results
435
uses: actions/upload-artifact@v3
436
if: always()
437
with:
438
name: test-results-${{ matrix.python-version }}
439
path: test-results.xml
440
```
441
442
### Package Testing Best Practices
443
444
#### Test Discovery Configuration
445
446
```python
447
# setup.py with explicit test configuration
448
setup(
449
name="mypackage",
450
451
# Explicit test suite specification
452
test_suite='tests',
453
454
# Alternative: use Green's discovery
455
# Green will automatically discover tests in 'tests/' directory
456
457
# Package structure:
458
# mypackage/
459
# ├── setup.py
460
# ├── src/
461
# │ └── mypackage/
462
# │ ├── __init__.py
463
# │ └── core.py
464
# └── tests/
465
# ├── __init__.py
466
# ├── test_core.py
467
# └── integration/
468
# └── test_integration.py
469
)
470
```
471
472
#### Multi-Environment Testing
473
474
```python
475
# setup.py with environment-specific test configuration
476
import os
477
from setuptools import setup
478
479
# Determine test configuration based on environment
480
if os.environ.get('CI'):
481
# CI environment: fast, minimal output
482
test_config = {
483
'verbose': 1,
484
'processes': 0, # Auto-detect
485
'run_coverage': True,
486
'junit_report': 'test-results.xml'
487
}
488
elif os.environ.get('DEVELOPMENT'):
489
# Development: detailed output, limited processes
490
test_config = {
491
'verbose': 3,
492
'processes': 2,
493
'run_coverage': True,
494
'debug': True
495
}
496
else:
497
# Default configuration
498
test_config = {
499
'verbose': 2,
500
'processes': 4,
501
'run_coverage': False
502
}
503
504
class CustomGreenCommand(Command):
505
def run(self):
506
import green.cmdline
507
args = ['tests/']
508
for key, value in test_config.items():
509
if value is True:
510
args.append(f'--{key.replace("_", "-")}')
511
elif value not in (False, None):
512
args.extend([f'--{key.replace("_", "-")}', str(value)])
513
514
exit_code = green.cmdline.main(args)
515
sys.exit(exit_code)
516
517
setup(
518
# ... package configuration ...
519
cmdclass={'test': CustomGreenCommand},
520
)
521
```
522
523
## Command Line Options
524
525
When using `python setup.py green`, all Green command-line options are available:
526
527
```bash
528
# Verbosity control
529
python setup.py green --verbose 2
530
python setup.py green -v 3
531
532
# Process control
533
python setup.py green --processes 4
534
python setup.py green --processes 0 # Auto-detect
535
536
# Coverage
537
python setup.py green --run-coverage
538
python setup.py green --coverage-config-file .coveragerc
539
540
# Output formats
541
python setup.py green --junit-report test-results.xml
542
python setup.py green --no-color
543
544
# Test selection
545
python setup.py green --targets tests.test_auth
546
python setup.py green --file-pattern "*_test.py"
547
548
# Debug options
549
python setup.py green --debug
550
python setup.py green --keep-reports
551
```
552
553
## Migration from unittest
554
555
### From unittest to Green setuptools integration
556
557
**Before (unittest)**:
558
```python
559
# setup.py
560
setup(
561
name="mypackage",
562
test_suite='tests',
563
)
564
```
565
566
```bash
567
python setup.py test
568
```
569
570
**After (Green)**:
571
```python
572
# setup.py
573
setup(
574
name="mypackage",
575
test_suite='tests',
576
setup_requires=['green'],
577
)
578
```
579
580
```ini
581
# setup.cfg
582
[aliases]
583
test = green
584
585
[green]
586
verbose = 2
587
run-coverage = true
588
```
589
590
```bash
591
python setup.py test # Now uses Green!
592
```