Code coverage for Solidity testing
—
Direct access to the coverage instrumentation and reporting engine for custom workflows, advanced integrations, and non-Hardhat environments. The API class provides complete control over the coverage collection process.
The main coverage runner and instrumentation engine.
/**
* Main API class for programmatic coverage control
* Provides instrumentation, data collection, and report generation
*/
const API = require('solidity-coverage/api');
class API {
/**
* Creates a new coverage API instance
* @param config - Configuration object for coverage behavior
*/
constructor(config?: CoverageConfig);
// Core instrumentation methods
instrument(targets: Target[]): InstrumentedTarget[];
getInstrumentationData(): InstrumentationData;
setInstrumentationData(data: InstrumentationData): void;
// Report generation
report(folder?: string): Promise<void>;
// Provider integration
attachToHardhatVM(provider: HardhatProvider): Promise<void>;
// Test matrix data collection
collectTestMatrixData(testInfo: MochaTestInfo): void;
// File I/O operations
saveCoverage(data: CoverageData): void;
saveTestMatrix(): void;
saveMochaJsonOutput(data: MochaData): void;
saveHumanReadableAbis(data: AbiData): void;
// Path utilities
makeKeysRelative(map: CoverageMap, workingDir: string): CoverageMap;
// Configuration
setLoggingLevel(isSilent: boolean): void;
// Cleanup
finish(): Promise<void>;
}Usage Examples:
const API = require('solidity-coverage/api');
// Basic API usage
const api = new API({
skipFiles: ['contracts/mocks/'],
istanbulReporter: ['html', 'lcov'],
});
// Instrument contracts
const targets = [
{
source: contractSource,
canonicalPath: '/path/to/Contract.sol',
relativePath: 'contracts/Contract.sol'
}
];
const instrumented = api.instrument(targets);
// Generate reports after tests
await api.report('./coverage');Instruments Solidity source files for coverage collection.
/**
* Instruments a set of Solidity source files for coverage tracking
* @param targets - Array of contract source objects to instrument
* @returns Array of instrumented contract objects
*/
instrument(targets: Target[]): InstrumentedTarget[];
interface Target {
source: string; // Solidity source code to instrument
canonicalPath: string; // Absolute path to source file
relativePath?: string; // Relative path for display purposes
}
interface InstrumentedTarget {
canonicalPath: string; // Absolute path to original source file
relativePath?: string; // Relative path for display purposes
source: string; // Instrumented Solidity source code
}Usage Examples:
const fs = require('fs');
const path = require('path');
// Prepare targets for instrumentation
const contractPath = path.resolve('./contracts/MyContract.sol');
const targets = [
{
source: fs.readFileSync(contractPath, 'utf8'),
canonicalPath: contractPath,
relativePath: 'contracts/MyContract.sol'
}
];
// Instrument the contracts
const instrumented = api.instrument(targets);
// Use instrumented source in compilation
instrumented.forEach(target => {
fs.writeFileSync(target.canonicalPath.replace('.sol', '.instrumented.sol'), target.source);
});Manages the hit map data used for coverage collection.
/**
* Returns a copy of the hit map created during instrumentation
* Useful for delegating coverage collection to multiple processes
* @returns Deep copy of instrumentation data
*/
getInstrumentationData(): InstrumentationData;
/**
* Sets the hit map object for pre-existing instrumentation
* Useful for collecting data across multiple test runs
* @param data - Instrumentation data from previous run
*/
setInstrumentationData(data: InstrumentationData): void;
interface InstrumentationData {
[hash: string]: {
contractPath: string; // Path to the contract file
type: CoverageType; // Type of coverage point
id: number; // Unique identifier for coverage point
hits: number; // Number of times this point was hit
locationIdx?: number; // Index for branch coverage points
};
}
type CoverageType = 'line' | 'function' | 'statement' | 'branch' | 'and-true' | 'or-false' | 'requirePre' | 'requirePost';Usage Examples:
// Save instrumentation data for later use
const instrumentationData = api.getInstrumentationData();
fs.writeFileSync('instrumentation.json', JSON.stringify(instrumentationData));
// Load instrumentation data in another process
const savedData = JSON.parse(fs.readFileSync('instrumentation.json', 'utf8'));
api.setInstrumentationData(savedData);Generates Istanbul-compatible coverage reports.
/**
* Generates coverage reports using Istanbul
* Creates HTML, LCOV, text, and JSON reports based on configuration
* @param folder - Optional output folder (defaults to config.istanbulFolder)
* @returns Promise that resolves when reports are complete
*/
report(folder?: string): Promise<void>;Usage Examples:
// Generate reports with default configuration
await api.report();
// Generate reports to specific directory
await api.report('./custom-coverage');
// Generate reports after configuring reporters
api.istanbulReporter = ['html', 'json', 'text'];
await api.report();Integrates with Hardhat's EVM provider for data collection.
/**
* Attaches coverage data collector to Hardhat's EVM
* Hooks into VM execution to track coverage hits
* @param provider - Hardhat network provider instance
* @returns Promise that resolves when attachment is complete
*/
attachToHardhatVM(provider: HardhatProvider): Promise<void>;
interface HardhatProvider {
// Hardhat provider interface (simplified)
init?(): Promise<void>;
_wrapped?: HardhatProvider;
_node: {
_vm: {
evm: {
events: EventEmitter;
};
};
};
}Usage Examples:
const { ethers } = require('hardhat');
// Attach to Hardhat provider
await api.attachToHardhatVM(ethers.provider);
// Run tests - coverage data will be collected automatically
// ... run your tests here ...
// Generate reports
await api.report();Collects test-to-code mapping data for analysis.
/**
* Collects mapping data between test cases and code coverage
* Useful for understanding which tests exercise which code paths
* @param testInfo - Mocha test information object
*/
collectTestMatrixData(testInfo: MochaTestInfo): void;
interface MochaTestInfo {
title: string; // Test case title
file: string; // Test file path
fullTitle?(): string; // Full test hierarchy title
}
/**
* Saves collected test matrix data to JSON file
* Creates testMatrix.json with test-to-coverage mapping
*/
saveTestMatrix(): void;Usage Examples:
// In a custom Mocha reporter
class CoverageReporter {
constructor(runner) {
runner.on('test end', (test) => {
api.collectTestMatrixData({
title: test.title,
file: test.file,
});
});
runner.on('end', () => {
api.saveTestMatrix();
});
}
}Saves various coverage-related data files.
/**
* Saves coverage data to coverage.json file
* @param data - Coverage data object from Istanbul
*/
saveCoverage(data: CoverageData): void;
/**
* Saves Mocha test output to JSON file
* @param data - Mocha test results data
*/
saveMochaJsonOutput(data: MochaData): void;
/**
* Saves human-readable ABI data to JSON file
* @param data - Processed ABI information
*/
saveHumanReadableAbis(data: AbiData): void;
interface CoverageData {
[contractPath: string]: {
path: string;
statementMap: object;
fnMap: object;
branchMap: object;
s: object; // Statement hits
f: object; // Function hits
b: object; // Branch hits
l: object; // Line hits
};
}Utilities for working with file paths in coverage data.
/**
* Converts absolute paths to relative paths in coverage maps
* Ensures coverage reports work correctly on different systems
* @param map - Coverage map with absolute paths as keys
* @param workingDir - Working directory to make paths relative to
* @returns Coverage map with relative paths as keys
*/
makeKeysRelative(map: CoverageMap, workingDir: string): CoverageMap;
interface CoverageMap {
[path: string]: CoverageData;
}Usage Examples:
const path = require('path');
// Make coverage paths relative for portability
const absoluteCoverage = {
'/Users/dev/project/contracts/MyContract.sol': coverageData
};
const relativeCoverage = api.makeKeysRelative(absoluteCoverage, process.cwd());
// Result: { 'contracts/MyContract.sol': coverageData }Configuration object structure for API initialization.
interface CoverageConfig {
// File handling
cwd?: string; // Working directory (default: process.cwd())
skipFiles?: string[]; // Files to exclude from instrumentation
// Output configuration
istanbulFolder?: string; // Output directory for reports
istanbulReporter?: string[]; // Report formats: html, lcov, text, json
abiOutputPath?: string; // Path for ABI output file (default: "humanReadableAbis.json")
matrixOutputPath?: string; // Path for test matrix output (default: "testMatrix.json")
mochaJsonOutputPath?: string; // Path for Mocha JSON output (default: "mochaOutput.json")
matrixReporterPath?: string; // Path to matrix reporter module (default: "solidity-coverage/plugins/resources/matrix.js")
// Server configuration
client?: object; // Client configuration
host?: string; // Server host
port?: number; // Server port
providerOptions?: object; // Provider configuration
autoLaunchServer?: boolean; // Auto-launch server flag
// Coverage measurement toggles
measureStatementCoverage?: boolean; // Enable statement coverage
measureFunctionCoverage?: boolean; // Enable function coverage
measureModifierCoverage?: boolean; // Enable modifier coverage
measureLineCoverage?: boolean; // Enable line coverage
measureBranchCoverage?: boolean; // Enable branch coverage
modifierWhitelist?: string[]; // Specific modifiers to measure
// Compilation options
viaIR?: boolean; // Enable Solidity viaIR compilation
usingSolcV4?: boolean; // Compatibility for Solidity v0.4.x
irMinimum?: boolean; // Use minimal IR optimization
solcOptimizerDetails?: object; // Custom optimizer configuration
// Workflow hooks
onServerReady?: (config: Config) => void; // Server ready callback
onCompileComplete?: (config: Config) => void; // Compilation complete callback
onTestsComplete?: (config: Config) => void; // Tests complete callback
onIstanbulComplete?: (config: Config) => void; // Reports complete callback
onPreCompile?: (config: Config) => void; // Pre-compilation callback
// Logging
silent?: boolean; // Disable console output
log?: (message: string) => void; // Custom logging function
}Configuration Examples:
// Minimal configuration
const api = new API({
skipFiles: ['contracts/test/']
});
// Full configuration with hooks
const api = new API({
cwd: process.cwd(),
skipFiles: ['contracts/mocks/', 'contracts/test/'],
istanbulReporter: ['html', 'lcov', 'json'],
istanbulFolder: './coverage',
measureStatementCoverage: true,
measureFunctionCoverage: true,
measureModifierCoverage: true,
measureLineCoverage: true,
measureBranchCoverage: true,
viaIR: true,
silent: false,
onCompileComplete: (config) => {
console.log('Compilation finished');
},
onTestsComplete: (config) => {
console.log('Tests completed, generating reports...');
},
onIstanbulComplete: (config) => {
console.log('Coverage reports generated');
}
});Install with Tessl CLI
npx tessl i tessl/npm-solidity-coverage