0
# Hardhat Plugin
1
2
The primary interface for solidity-coverage, providing seamless integration with Hardhat's compilation and testing pipeline. The plugin registers a `coverage` task that instruments contracts, runs tests, and generates comprehensive coverage reports.
3
4
## Capabilities
5
6
### Plugin Registration
7
8
Automatically registers with Hardhat when required in configuration.
9
10
```javascript { .api }
11
// In hardhat.config.js
12
require('solidity-coverage');
13
14
// Or in hardhat.config.ts
15
import 'solidity-coverage';
16
```
17
18
### Coverage Task
19
20
The main coverage analysis task with extensive configuration options.
21
22
```bash { .api }
23
/**
24
* Generates a code coverage report for tests
25
* Instruments Solidity contracts, runs tests, and generates Istanbul reports
26
*/
27
npx hardhat coverage [options]
28
29
// Task options:
30
--testfiles <path> // Glob path to subset of test files to run
31
--solcoverjs <path> // Relative path to .solcover.js configuration file
32
--temp <path> // Relative path to temporary directory for artifacts
33
--sources <path> // Relative path to contracts directory
34
--matrix // Generate test matrix data instead of coverage reports
35
--abi // Generate human readable ABI list for analysis
36
```
37
38
**Usage Examples:**
39
40
```bash
41
# Basic coverage run
42
npx hardhat coverage
43
44
# Run coverage on specific test files
45
npx hardhat coverage --testfiles "test/unit/**/*.js"
46
47
# Use custom configuration file
48
npx hardhat coverage --solcoverjs .solcover.custom.js
49
50
# Generate test matrix instead of coverage
51
npx hardhat coverage --matrix
52
53
# Generate ABI analysis
54
npx hardhat coverage --abi
55
```
56
57
### Network Configuration
58
59
The plugin automatically configures the Hardhat network for coverage analysis.
60
61
```javascript { .api }
62
/**
63
* Network configuration applied during coverage runs
64
* These settings are automatically applied when SOLIDITY_COVERAGE env var is set
65
*/
66
interface HardhatNetworkConfig {
67
allowUnlimitedContractSize: boolean; // Allow large instrumented contracts
68
blockGasLimit: number; // Set to 0x1fffffffffffff for coverage
69
gas: number; // Set to 0xffffffffff for transactions
70
gasPrice: number; // Set to 0x01 for predictable costs
71
}
72
```
73
74
### Compilation Integration
75
76
The plugin hooks into Hardhat's compilation process to instrument contracts.
77
78
```javascript { .api }
79
/**
80
* Compilation subtasks modified by the plugin:
81
* - TASK_COMPILE_SOLIDITY_GET_COMPILER_INPUT: Injects instrumented source code
82
* - TASK_COMPILE_SOLIDITY_GET_COMPILATION_JOB_FOR_FILE: Configures compiler settings
83
* - TASK_COMPILE_SOLIDITY_LOG_COMPILATION_ERRORS: Suppresses instrumentation warnings
84
*/
85
86
// Compiler settings automatically applied for coverage:
87
interface SolidityCompilerSettings {
88
metadata: {
89
useLiteralContent: false; // Reduce metadata size for instrumented contracts
90
};
91
optimizer: {
92
enabled: boolean; // Disabled unless viaIR is true
93
details?: OptimizerDetails; // Custom optimizer configuration
94
};
95
}
96
```
97
98
### Environment Variables
99
100
Configuration through environment variables.
101
102
```bash { .api }
103
# Environment variables that affect plugin behavior:
104
SOLIDITY_COVERAGE=true # Activates coverage mode and network configuration
105
VIA_IR=true # Enables Solidity viaIR compilation mode
106
```
107
108
**Usage Examples:**
109
110
```bash
111
# Run tests with coverage enabled
112
SOLIDITY_COVERAGE=true npx hardhat test
113
114
# Enable viaIR compilation mode for coverage
115
VIA_IR=true npx hardhat coverage
116
```
117
118
### Configuration File Support
119
120
Loads configuration from `.solcover.js` file in project root.
121
122
```javascript { .api }
123
/**
124
* .solcover.js configuration file structure
125
* All options are optional and have sensible defaults
126
*/
127
module.exports = {
128
skipFiles: string[]; // Files/folders to exclude from instrumentation
129
istanbulReporter: string[]; // Report formats: html, lcov, text, json
130
istanbulFolder: string; // Custom output directory for reports
131
measureStatementCoverage: boolean; // Enable statement coverage measurement
132
measureFunctionCoverage: boolean; // Enable function coverage measurement
133
measureModifierCoverage: boolean; // Enable modifier coverage measurement
134
measureLineCoverage: boolean; // Enable line coverage measurement
135
measureBranchCoverage: boolean; // Enable branch coverage measurement
136
modifierWhitelist: string[]; // Specific modifiers to measure
137
configureYulOptimizer: boolean; // Configure Yul optimizer for coverage
138
viaIR: boolean; // Enable Solidity viaIR compilation
139
irMinimum: boolean; // Use minimal IR optimization settings
140
solcOptimizerDetails: object; // Custom Solidity optimizer configuration
141
142
// Workflow hooks for custom integration
143
onServerReady: (config) => void; // Called when coverage server is ready
144
onCompileComplete: (config) => void; // Called after contract compilation
145
onTestsComplete: (config) => void; // Called after all tests complete
146
onIstanbulComplete: (config) => void; // Called after coverage reports generated
147
onPreCompile: (config) => void; // Called before contract compilation
148
149
// Mocha test runner configuration
150
mocha: {
151
timeout: number; // Test timeout in milliseconds
152
reporter: string; // Mocha reporter to use
153
// ... other Mocha options
154
};
155
};
156
```
157
158
**Configuration Examples:**
159
160
```javascript
161
// Basic configuration
162
module.exports = {
163
skipFiles: ['contracts/mocks/', 'contracts/test/'],
164
istanbulReporter: ['html', 'lcov'],
165
};
166
167
// Advanced configuration with hooks
168
module.exports = {
169
skipFiles: ['contracts/mocks/'],
170
istanbulReporter: ['html', 'lcov', 'text', 'json'],
171
measureStatementCoverage: true,
172
measureFunctionCoverage: true,
173
measureModifierCoverage: true,
174
viaIR: true,
175
configureYulOptimizer: true,
176
onServerReady: () => {
177
console.log('Coverage analysis server started');
178
},
179
onTestsComplete: (config) => {
180
console.log('Tests completed, generating reports...');
181
},
182
mocha: {
183
timeout: 100000,
184
reporter: 'spec',
185
},
186
};
187
```
188
189
### Report Generation
190
191
Automatically generates Istanbul coverage reports in multiple formats.
192
193
```javascript { .api }
194
/**
195
* Default report formats and locations:
196
* - HTML report: ./coverage/index.html (interactive web interface)
197
* - LCOV report: ./coverage/lcov.info (for CI/CD integration)
198
* - Text report: console output (terminal summary)
199
* - JSON report: ./coverage/coverage-final.json (machine readable)
200
* - Coverage summary: ./coverage.json (simplified format)
201
*/
202
203
// Output files created by coverage run:
204
interface CoverageOutputs {
205
'coverage/': {
206
'index.html': 'Interactive HTML coverage report';
207
'lcov.info': 'LCOV format for CI/CD tools';
208
'coverage-final.json': 'Detailed JSON coverage data';
209
};
210
'coverage.json': 'Simplified coverage summary';
211
'testMatrix.json'?: 'Test-to-code mapping (if --matrix flag used)';
212
'humanReadableAbis.json'?: 'ABI analysis (if --abi flag used)';
213
'mochaOutput.json'?: 'Mocha test results in JSON format';
214
}
215
```
216
217
### Error Handling
218
219
The plugin provides detailed error messages for common issues.
220
221
```javascript { .api }
222
/**
223
* Common error scenarios and handling:
224
* - HardhatPluginError: Thrown for configuration and execution errors
225
* - Compilation errors: Invalid Solidity syntax preventing instrumentation
226
* - Network errors: Issues connecting to or configuring Hardhat network
227
* - File system errors: Missing contracts or insufficient permissions
228
* - Test failures: Coverage run fails if tests fail (unless configured otherwise)
229
*/
230
231
// Error message types:
232
interface PluginErrors {
233
'network-fail': 'Error when --network flag is used (not supported)';
234
'hardhat-viem': 'Compatibility warning for hardhat-viem plugin';
235
'tests-fail': 'Error when tests fail during coverage run';
236
'solcoverjs-fail': 'Error loading .solcover.js configuration';
237
'mocha-parallel-fail': 'Error when Mocha parallel mode is enabled';
238
}
239
```
240
241
### Integration with Test Frameworks
242
243
Works seamlessly with popular Ethereum testing frameworks.
244
245
```javascript { .api }
246
/**
247
* Supported testing frameworks and libraries:
248
* - Hardhat (native integration)
249
* - Ethers.js (full compatibility)
250
* - Waffle (full compatibility)
251
* - Web3.js (full compatibility)
252
* - Truffle contract abstractions (compatibility layer)
253
* - Mocha (test runner integration)
254
* - Chai (assertion library support)
255
*/
256
257
// Test configuration considerations:
258
interface TestingConfig {
259
timeout: number; // Increase timeout for instrumented contracts
260
gas: number; // Use unlimited gas for coverage runs
261
gasPrice: number; // Use minimal gas price for predictable costs
262
allowUnlimitedContractSize: boolean; // Allow large instrumented contracts
263
}
264
```
265
266
**Testing Examples:**
267
268
```javascript
269
// Hardhat + Ethers.js
270
const { ethers } = require("hardhat");
271
272
describe("MyContract", function() {
273
it("should work with coverage", async function() {
274
const MyContract = await ethers.getContractFactory("MyContract");
275
const contract = await MyContract.deploy();
276
await contract.deployed();
277
278
const result = await contract.myFunction();
279
expect(result).to.equal(42);
280
});
281
});
282
283
// Hardhat + Waffle
284
const { waffle } = require("hardhat");
285
286
describe("MyContract", function() {
287
it("should work with coverage", async function() {
288
const [wallet] = waffle.provider.getWallets();
289
const contract = await waffle.deployContract(wallet, MyContract);
290
291
await expect(contract.myFunction()).to.emit(contract, 'MyEvent');
292
});
293
});
294
```