As per Code coverage tool anytime soon? · Issue #1157 · crystal-lang/crystal · GitHub, usage of GitHub - SimonKagstrom/kcov: Code coverage tool for compiled programs, Python and Bash which uses debugging information to collect and report data without special compilation options is currently considered the way forward when it comes to generating code coverage reports in Crystal. However there are a few rough edges I wanted to bring up for discussion to see if they can be improved. Kinda just thinking out loud a bit too.
I started down this path via Code coverage tool anytime soon? · Issue #1157 · crystal-lang/crystal · GitHub, but felt a forum thread was more appropriate moving forward.
For purposes of this ticket, let’s assume we’re working with the following two files:
# src/test.cr
class Tester
def foo
1
end
def bar
2
end
end
# spec/test_spec.cr
require "../src/test"
require "spec"
describe Tester do
it "#bar" do
Tester.new.bar.should eq 2
end
end
LLVM Optimizations
Generating a kcov report for Tester
results in a passing spec but an empty kcov report. From what I can tell Tester#bar
gets inlined/optimized away/never generated? I was under the impression that by default there are no optimizations so this feels a bit unexpected?
Changing the body of #bar
to Random.rand(1..10) + 5
results in:
So seems it’s unable to be optimized away so it works correctly this time.
Dead Code Elimination
In the previous screenshot, notice how the coverage report is “100%” due to the unused Tester#foo
method being removed from the binary. This is confirmed via:
$ crystal tool unreachable spec/test_spec.cr
src/test.cr:2:3 Tester#foo 3 lines
The unreachable
tool is able to output JSON, so might be enough to transform the unreachable report into Codecov Custom Coverage Format using 0
s to denote those lines were missed. Tho having a way to do what Rust does would be a lot simpler/usable: Codegen Options - The rustc book.
EDIT2: TIL about the --tallies
option to the unreachable
command. That in of itself is like a coverage report. Wonder how much this differs from kcov…
EDIT3: Given that tool also has a --format
option, maybe it would be reasonable to support --format=codecov
.
LLVM Coverage
This one is more so for my own learning. I know that kcov uses DWARF debug information to generate its reports. Would there be any functional difference if LLVM Code Coverage Mapping Format — LLVM 20.0.0git documentation was being used instead? Like because its native LLVM it’s able to be more accurate/powerful/etc, or is it more of just a different way to achieve the same result?
EDIT: I guess based on the Rust Issue, it would allow more kinds of coverage to be emitted no matter the platform the user is on. I’m still in the camp that this with native crystal spec --coverage
would be , but kcov handles things quite well in the meantime…