Inline coverage not interpreting Cobertura source path
Summary
I'm trying to gather code coverage on a PHP project using PHPUnit's Cobertura reporter. However, I can only get the inline coverage visualizations to appear if the <source>
element contains just the repository root and the filename
for each covered class exactly matches the full path within the repository.
For example, assume we have a repository with the following files:
src/Foo/Bar.php
src/Baz.php
public/index.php
When checked out on my CI runner they might live at paths like:
/builds/my/project/src/Foo/Bar.php
/builds/my/project/src/Baz.php
/builds/my/project/public/index.php
When PHPUnit creates the cobertura coverage report, it sets the source
to whatever path the covered classes have in common. The individual filename
is then set to the full absolute path minus that shared <source>
path For example:
Files Tested | Reduced <source> path |
Individual filename paths |
---|---|---|
src/Foo/Bar.php |
/builds/my/project/src/Foo |
Bar.php |
src/Foo/Bar.php and src/Baz.php
|
/builds/my/project/src |
Foo/Bar.php and Baz.php
|
All three files | /builds/my/project |
src/Foo/Bar.php , src/Baz.php , public/index.php
|
I only see inline coverage data rendered in the MR in that last case. When that happens, the cobertura XML file looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE coverage SYSTEM "http://cobertura.sourceforge.net/xml/coverage-04.dtd">
<coverage line-rate="0.0032243618450515" branch-rate="0" lines-covered="36" lines-valid="11165" branches-covered="0" branches-valid="0" complexity="4498" version="0.4" timestamp="1609110724">
<sources>
<source>/builds/my/project</source>
</sources>
<packages>
<package name="" line-rate="0" branch-rate="0" complexity="11">
<classes>
<class name="App\Foo\Bar" filename="src/Foo/Bar.php" line-rate="0" branch-rate="0" complexity="11">
<methods>
<!-- output truncated -->
Steps to reproduce
Provide a cobertura coverage report where <source>
contains a subpath:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE coverage SYSTEM "http://cobertura.sourceforge.net/xml/coverage-04.dtd">
<coverage line-rate="0.0032243618450515" branch-rate="0" lines-covered="36" lines-valid="11165" branches-covered="0" branches-valid="0" complexity="4498" version="0.4" timestamp="1609110724">
<sources>
<source>/builds/my/project/src</source>
</sources>
<packages>
<package name="" line-rate="0" branch-rate="0" complexity="11">
<classes>
<class name="App\Foo\Bar" filename="Foo/Bar.php" line-rate="0" branch-rate="0" complexity="11">
<methods>
<!-- output truncated -->
Search for <source>
and filename
in the two examples above and you'll see what I mean.
What is the current bug behavior?
No inline code coverage appears in the MR.
What is the expected correct behavior?
Ideally: Inline code coverage should appear
Not ideal but better than nothing: Gitlab should give some kind of warning/error that it couldn't map the coverage data to repo files
Possible fixes
I think Gitlab needs to concatenate the <source>
and filename
together (with a /
in between) to determine the absolute path and then use its knowledge of where CI checked the file out to trim that part off the left side.
In other words, given all of these three possibilities...
<source> |
filename |
---|---|
/builds/my/project/src/Foo |
Bar.php |
/builds/my/project/src |
Foo/Bar.php |
/builds/my/project |
src/Foo/Bar.php |
... Gitlab should interpret the file path as src/Foo/Bar.php
Issue #233144 might be related since it deals with <source>
paths but I'm honestly not sure. Regardless, I think this issue here should be considered a ~bug and not a feature since the coverage report seems accurate (and PHPUnit's path outputs make sense) but Gitlab is failing to interpret those paths.