Covered processes output of code coverage analysis performed by the D programming language compiler (DMD/LDC/GDC).
Usage: covered <options> files dirs
Covered processes output of code coverage analysis performed by the D programming language compiler (DMD/LDC/GDC)
Every option below works with any number of files/directories specified in command line.
If nothing is specified, it looks for '*.lst' files in current working directory
Options:
-c --coverage Reports code coverage (default)
-s --source Shows source code, number of executions of each line, and it's code coverage
-b --blame Shows list of files ordered by code coverage
-a --average Reports average code coverage across all passed files
-j --json Makes a dump in JSON format
-v --verbose Verbose output
-n --hidden When directory is passed, looks for hidden files as well (default: false)
-r --recursive When directory is passed, looks for *.lst files recursively (default: false)
-h --help This help information.
$ dub fetch covered # Downloads covered
$ dub run covered # Runs covered
$ ./covered sample/hello.lst
hello.d is 100.00% covered
$ ./covered --source sample/hello.lst
+-------------------
| File: sample/hello.lst
| Source file: hello.d
| Coverage: 100.00%
+-------------------
import std.stdio;
void main() {
writeln("Hello world!");
}
$ ./covered --blame sample/hello.lst
hello.d | 100.00%
$ ./covered --average sample/hello.lst
Average: 100.00%
$ dub -b unittest-cov
This command will build and run your DUB project. Your program will create many *.lst
files in your working dir. Covered uses those files:
$ dub run covered
You can pass aditional options to covered after --
:
$ dub run covered -- --help
Running dub -b unittest-cov
leads to some problems:
- It pollutes your working directory with tons of
*.lst
files. - Built-in
unittest
s are not that useful. Failedunittest
exits program, so it is impossible to say, how many of them have been failed. - Built-in
assert
s, which are used inunittest
blocks, are not that useful.assert
just throws if value is nottrue
, so it is very hard to say, why assertion failed.
Those problems doesn't make development impossible, but harder and slower.
Add this code to your app:
version(D_Coverage) shared static this() {
import core.runtime : dmd_coverDestPath;
import std.file : exists, mkdir;
enum COVPATH = "coverage";
if(!COVPATH.exists) // Compiler won't create this directory
COVPATH.mkdir; // That's why it should be done manually
dmd_coverDestPath(COVPATH); // Now all *.lst files are written into ./coverage/ directory
}
Do not forget to add ./coverage
directory into your .gitignore
:
coverage/
Ta-Da! Your working directory is no longer polluted
There are lots of them, but I will describe use of unit-threaded.
"configurations": [
{ "name": "executable" },
{
"name": "unittest",
"targetType": "executable",
"preBuildCommands": [
"dub run unit-threaded -c gen_ut_main -- -f .dub/ut.d"
],
"mainSourceFile": ".dub/ut.d",
"dependencies": {
"unit-threaded": "~>0.7.28",
"fluent-asserts": "~>0.6.1"
},
"targetPath": ".dub/",
"targetName": "unittester"
}
],
If you want to use it and move *.lst
into separate directory, copy it's code into some file (cov.d
, for example), and add to your dub.json:
"configurations": [
{ "name": "executable" },
{
"name": "unittest",
....
"sourceFiles": ["cov.d"]
}
],
$ dub test
Will run unittests with help of unit_threaded. Go to it's documentation for more information.
Just use fluent-asserts. And again, go to it's documentation for more.
$ dub -b unittest-cov -c unittest
Will build and run your application with all *.lst
files moved into ./coverage
directory, unittests runned in parallel, and nice messages if something goes wrong.
$ dub run covered -- ./coverage
That's it! Now you're performing code coverage analysis like a pro! Take a cookie: 🍪