Behavior-driven development testing framework for Python using Gherkin syntax
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Extensible reporting system supporting multiple output formats including plain text, JSON, JUnit XML, and custom formats. Enables integration with CI/CD systems and test reporting tools.
Abstract base class for all output formatters providing the foundation for custom formatter implementation.
class Formatter:
"""
Base class for all output formatters.
Attributes:
- name: str, formatter name
- description: str, formatter description
- stream: file-like object for output
- config: Configuration object
Methods:
- uri(uri): Called when feature file is opened
- feature(feature): Called when feature starts
- background(background): Called when background starts
- scenario(scenario): Called when scenario starts
- scenario_outline(scenario_outline): Called for scenario outlines
- step(step): Called for each step
- match(match): Called when step matches definition
- result(result): Called with step execution result
- eof(): Called at end of feature file
- close(): Called when formatter is closed
"""Simple text output formatter providing basic test results without styling or colors.
class PlainFormatter(Formatter):
"""
Simple text output formatter.
Features:
- Clean text output without colors
- Step-by-step execution display
- Basic pass/fail status reporting
- Suitable for log files and basic CI output
Output format:
- Feature name and description
- Scenario names with step results
- Final summary with counts
"""Enhanced text formatter with colors, styling, and improved readability for interactive terminals.
class PrettyFormatter(Formatter):
"""
Enhanced text formatter with colors and styling.
Features:
- Color-coded output (green=pass, red=fail, yellow=skip)
- Unicode symbols for status indicators
- Indented structure showing hierarchy
- Step timing information
- Multi-line text and table formatting
- Progress indicators during execution
Configuration:
- Respects --color/--no-color options
- Adapts to terminal capabilities
- Configurable indentation and symbols
"""Structured JSON output for programmatic consumption and integration with external tools.
class JSONFormatter(Formatter):
"""
JSON output formatter for structured data.
Output structure:
- features: array of feature objects
- summary: execution statistics
- each feature contains scenarios array
- each scenario contains steps array
- timestamps and duration data included
Features:
- Machine-readable format
- Complete test execution data
- Hierarchical structure preservation
- Timing and status information
- Compatible with JSON processing tools
"""JUnit-compatible XML output for integration with CI/CD systems and test reporting tools.
class JUnitFormatter(Formatter):
"""
JUnit XML format for CI/CD integration.
Output structure:
- testsuite elements for features
- testcase elements for scenarios
- failure/error elements for failed steps
- properties for metadata
- system-out/system-err for captured output
Features:
- Standard JUnit XML schema compliance
- Integration with Jenkins, Azure DevOps, etc.
- Test timing and classification
- Failure details and stack traces
- Support for test suites and test cases
"""Compact progress indicators showing execution status without detailed output.
class ProgressFormatter(Formatter):
"""
Simple progress bar formatter.
Output:
- Single line progress indicator
- Colored dots for step status (. = pass, F = fail, S = skip)
- Final summary with statistics
- Minimal screen space usage
"""
class Progress2Formatter(Formatter):
"""
Compact progress display with scenario names.
Output:
- Scenario names with pass/fail status
- Compact multi-line format
- Step count and timing summary
"""
class Progress3Formatter(Formatter):
"""
Detailed progress display with feature organization.
Output:
- Feature and scenario hierarchy
- Step-level progress indicators
- Detailed timing and status information
"""Formatters for specific use cases and development workflows.
class TagsFormatter(Formatter):
"""
Lists all available tags in the feature files.
Output:
- Alphabetically sorted tag list
- Usage count for each tag
- Feature/scenario association
- Useful for tag management and discovery
"""
class StepsFormatter(Formatter):
"""
Lists all defined step definitions.
Output:
- Step pattern listing
- File location information
- Parameter type information
- Helps identify unused or duplicate steps
"""
class StepsCatalogFormatter(Formatter):
"""
Detailed step definitions catalog with documentation.
Output:
- Step patterns with descriptions
- Parameter documentation
- Usage examples from docstrings
- Source code locations
- Complete step reference documentation
"""
class RerunFormatter(Formatter):
"""
Generates rerun information for failed scenarios.
Output:
- File:line references for failed scenarios
- Command-line options for rerunning
- Tag expressions for failed tests
- Useful for CI/CD retry logic
"""# Single formatter
behave --format pretty
# Multiple formatters
behave --format pretty --format json
# Formatter with output file
behave --format json --outfile results.json
# Multiple formatters with separate files
behave --format pretty --format json:results.json --format junit:junit.xml
# Formatter-specific options
behave --format progress2 --no-timings# .behaverc
[behave]
format = pretty,json
outdir = reports
outfiles = ,results.jsonfrom behave.formatter.base import Formatter
class CustomFormatter(Formatter):
"""Custom formatter for specific reporting needs."""
name = 'custom'
description = 'Custom formatter for special requirements'
def __init__(self, stream_opener, config):
super().__init__(stream_opener, config)
self.current_feature = None
self.statistics = {
'features': 0,
'scenarios': 0,
'steps': 0,
'passed': 0,
'failed': 0,
'skipped': 0
}
def feature(self, feature):
self.current_feature = feature
self.statistics['features'] += 1
self.stream.write(f"Feature: {feature.name}\n")
def scenario(self, scenario):
self.statistics['scenarios'] += 1
self.stream.write(f" Scenario: {scenario.name}\n")
def step(self, step):
self.statistics['steps'] += 1
status_char = {
'passed': '✓',
'failed': '✗',
'skipped': '-',
'undefined': '?'
}.get(step.status, ' ')
self.stream.write(f" {status_char} {step.name}\n")
self.statistics[step.status] += 1
def close(self):
# Write summary
self.stream.write("\nSummary:\n")
for key, value in self.statistics.items():
self.stream.write(f" {key}: {value}\n")# In environment.py or plugin file
def before_all(context):
# Register custom formatter
from behave.formatter._registry import format_registry
format_registry.register('custom', CustomFormatter)# Jenkins integration
behave --format junit --junit-directory $WORKSPACE/test-reports
# GitHub Actions
behave --format json --outfile test-results.json
# Azure DevOps
behave --format junit --junit-directory $(Agent.TempDirectory)/test-results# Allure integration
behave --format allure_behave.formatter:AllureFormatter --outdir allure-results
# ReportPortal integration
behave --format reportportal_behave:Formatter
# Custom dashboard integration
behave --format json --outfile dashboard-data.json# Formatter with output capture
class CaptureFormatter(Formatter):
def step(self, step):
if hasattr(step, 'captured'):
self.stream.write(f"Captured output: {step.captured}\n")
if hasattr(step, 'error_message') and step.error_message:
self.stream.write(f"Error: {step.error_message}\n")class HTMLFormatter(Formatter):
"""Generates HTML test reports."""
def __init__(self, stream_opener, config):
super().__init__(stream_opener, config)
self.features = []
def feature(self, feature):
self.features.append(feature)
def close(self):
html_content = self.generate_html_report(self.features)
self.stream.write(html_content)
def generate_html_report(self, features):
# Generate HTML report from features data
return f"""
<html>
<head><title>Test Report</title></head>
<body>
<h1>Behave Test Report</h1>
<!-- Feature and scenario details -->
</body>
</html>
"""class SlackFormatter(Formatter):
"""Sends test results to Slack."""
def close(self):
summary = self.calculate_summary()
message = f"Test Results: {summary['passed']} passed, {summary['failed']} failed"
self.send_to_slack(message)
def send_to_slack(self, message):
# Implementation for Slack webhook
passclass DatabaseFormatter(Formatter):
"""Logs test results to database."""
def __init__(self, stream_opener, config):
super().__init__(stream_opener, config)
self.db_connection = self.setup_database()
def scenario(self, scenario):
self.log_scenario_to_database(scenario)
def step(self, step):
self.log_step_to_database(step)Install with Tessl CLI
npx tessl i tessl/pypi-behave