0
# Coverage Processing
1
2
The coverage processing module extends coverage.py functionality to generate coveralls-specific reports with line-by-line coverage data and source file information. It handles data transformation, source file reading, and optional merging of JavaScript coverage results.
3
4
## Capabilities
5
6
### Extended Coverage Control
7
8
Extends the standard coverage.py `Coverage` class with coveralls-specific report generation functionality.
9
10
```python { .api }
11
class coveralls(Coverage):
12
"""
13
Extended Coverage class with coveralls report generation.
14
15
Inherits all standard coverage.py functionality and adds:
16
- coveralls() method for generating coveralls-formatted reports
17
- Integration with CoverallsReporter for data formatting
18
"""
19
20
def coveralls(self, base_dir, ignore_errors=False, merge_file=None):
21
"""
22
Generate coveralls-formatted coverage report.
23
24
Args:
25
base_dir (str): Project root directory for relative path calculation
26
ignore_errors (bool): If True, skip files that cannot be read or analyzed
27
merge_file (str, optional): Path to JSON file containing additional coverage data
28
29
Returns:
30
list[SourceFile]: List of source files with coverage information
31
"""
32
```
33
34
### Coverage Reporter
35
36
Specialized reporter that transforms coverage.py data into the coveralls.io format with line-by-line coverage arrays and source content.
37
38
```python { .api }
39
class CoverallsReporter(Reporter):
40
"""
41
Coverage reporter that generates coveralls.io compatible format.
42
43
Extends coverage.py Reporter to produce JSON-compatible data structure
44
with source content and line-by-line coverage arrays.
45
"""
46
47
def report(self, base_dir, ignore_errors=False, merge_file=None):
48
"""
49
Generate detailed coverage report for coveralls.io.
50
51
Args:
52
base_dir (str): Project root directory for relative paths
53
ignore_errors (bool): Skip files with read/analysis errors
54
merge_file (str, optional): JSON file with additional coverage data to merge
55
56
Returns:
57
list[dict]: List of source file dictionaries with:
58
- name: str - relative file path
59
- source: str - complete file content
60
- coverage: list[int|None] - line coverage (None=non-executable, 0=missed, 1=hit)
61
62
Raises:
63
IOError: If source files cannot be read and ignore_errors=False
64
NotPython: If files cannot be analyzed and ignore_errors=False
65
"""
66
```
67
68
## Data Processing Pipeline
69
70
### Coverage Analysis Flow
71
72
1. **File Discovery**: Uses coverage.py file reporters to identify measured files
73
2. **Source Reading**: Reads complete source content for each file
74
3. **Analysis**: Analyzes coverage data to identify statements and missing lines
75
4. **Transformation**: Converts to line-by-line coverage arrays
76
5. **Merging**: Optionally merges additional coverage data from JSON files
77
78
### Coverage Array Format
79
80
```python { .api }
81
# Line-by-line coverage representation
82
coverage_array: list[int | None]
83
# None: Line is not executable (comments, blank lines, etc.)
84
# 0: Line is executable but was not executed (missed)
85
# 1: Line is executable and was executed (hit)
86
87
# Example for a 5-line file:
88
coverage_example = [None, 1, 1, 0, None]
89
# Line 1: Non-executable (None)
90
# Line 2: Hit (1)
91
# Line 3: Hit (1)
92
# Line 4: Missed (0)
93
# Line 5: Non-executable (None)
94
```
95
96
## Usage Examples
97
98
### Basic Coverage Processing
99
100
```python
101
from coveralls.control import coveralls
102
103
# Create coverage instance
104
cov = coveralls()
105
cov.load()
106
107
# Generate coveralls report
108
source_files = cov.coveralls(
109
base_dir='/path/to/project',
110
ignore_errors=False
111
)
112
113
# Each source file contains:
114
for file_info in source_files:
115
print(f"File: {file_info['name']}")
116
print(f"Lines: {len(file_info['coverage'])}")
117
print(f"Source length: {len(file_info['source'])}")
118
```
119
120
### Error Handling Options
121
122
```python
123
# Ignore files that cannot be read or analyzed
124
source_files = cov.coveralls(
125
base_dir='/path/to/project',
126
ignore_errors=True # Skip problematic files
127
)
128
129
# Strict mode (default) - raise exceptions
130
try:
131
source_files = cov.coveralls(base_dir='/path/to/project')
132
except IOError as e:
133
print(f"Source file read error: {e}")
134
except NotPython as e:
135
print(f"File analysis error: {e}")
136
```
137
138
### Merging JavaScript Coverage
139
140
```python
141
# Merge JavaScript coverage data
142
source_files = cov.coveralls(
143
base_dir='/path/to/project',
144
merge_file='coverage/js-coverage.json'
145
)
146
147
# The merge file should contain JSON in format:
148
merge_format = {
149
"source_files": [
150
{
151
"name": "src/app.js",
152
"source": "function hello() { return 'world'; }",
153
"coverage": [1, 1, 1]
154
}
155
]
156
}
157
```
158
159
### Direct Reporter Usage
160
161
```python
162
from coverage.control import Coverage
163
from coveralls.report import CoverallsReporter
164
165
# Standard coverage.py setup
166
cov = Coverage()
167
cov.load()
168
169
# Create coveralls reporter
170
reporter = CoverallsReporter(cov, cov.config)
171
reporter.find_file_reporters(None)
172
173
# Generate report directly
174
source_files = reporter.report(
175
base_dir='/path/to/project',
176
ignore_errors=False,
177
merge_file=None
178
)
179
```
180
181
## Integration with Coverage Tools
182
183
### Coverage.py Integration
184
185
The module integrates seamlessly with coverage.py configuration:
186
187
```ini
188
# .coveragerc
189
[run]
190
source = mypackage
191
omit =
192
*/tests/*
193
*/venv/*
194
setup.py
195
196
[report]
197
exclude_lines =
198
pragma: no cover
199
def __repr__
200
raise AssertionError
201
```
202
203
### Supported Coverage Workflows
204
205
```bash
206
# Standard coverage.py
207
coverage run -m pytest
208
coverage report
209
coveralls
210
211
# pytest-cov
212
pytest --cov=mypackage
213
coveralls
214
215
# nose with nosexcover
216
nosetests --with-xcoverage --cover-package=mypackage
217
coveralls
218
```
219
220
## Error Conditions and Handling
221
222
### File Access Errors
223
224
- **IOError**: Source files cannot be read (permissions, missing files)
225
- **NotPython**: Files cannot be analyzed by coverage.py (binary files, etc.)
226
- **Handling**: Use `ignore_errors=True` to skip problematic files
227
228
### Data Quality Issues
229
230
- **Empty coverage data**: No measured files found
231
- **Malformed merge files**: Invalid JSON format in merge_file
232
- **Path resolution**: Incorrect base_dir causing path calculation errors
233
234
### Best Practices
235
236
```python
237
# Robust coverage processing
238
try:
239
cov = coveralls()
240
cov.load()
241
242
source_files = cov.coveralls(
243
base_dir=os.path.abspath('.'),
244
ignore_errors=True, # Skip problematic files
245
merge_file='coverage.json' if os.path.exists('coverage.json') else None
246
)
247
248
if not source_files:
249
print("Warning: No coverage data found")
250
251
except Exception as e:
252
print(f"Coverage processing failed: {e}")
253
```