Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Coverage reporting missing for binaries under-test #9

Open
epage opened this issue May 29, 2018 · 13 comments
Open

Coverage reporting missing for binaries under-test #9

epage opened this issue May 29, 2018 · 13 comments
Labels
bug Not as expected

Comments

@epage
Copy link
Contributor

epage commented May 29, 2018

@mssun

Another issue about testing CLIs is to correctly calculate code coverage. If using std::process::Command to fork and execute a CLI, all existing code coverage tools (tarpaulin, gcov, kcov, etc) will failed to calculate the statistics. There is not a better way to properly calculate the line coverage including unit tests and integration tests.

From https://github.com/rust-lang-nursery/cli-wg/issues/9#issuecomment-385487756

@epage
Copy link
Contributor Author

epage commented May 29, 2018

See also the discussion at assert-rs/assert_cli#104

@glehmann
Copy link
Contributor

I'm exactly in this situation right now, and unfortunately, I have no idea how to fix it.
I've tried kcov, gcov and tarpaulin without success so far. I'm afraid I may have to go back to testing my cli tool directly by calling directly the main function from my crate.
I really like the idea to test the final executable, in order to make sure to not miss anything, and assert_cmd makes is quite pleasant to do, so this is a bit disappointing!

@glehmann
Copy link
Contributor

I've been able to get kcov to report something by calling kcov instead of calling directly my program.

https://github.com/glehmann/hld/blob/f40f3b51f84969cc13714f81451ad17f33fbf2dc/tests/common/mod.rs#L79

I activate it with the kcov feature in my project. kcov doesn't seem to be able to run in parallel, so I force the test to run on a single thread:

cargo test --features kcov -- --test-threads 1

It would be nice to have something similar natively, for example with an environment variable that allow the developer to set a wrapper — in that case, kcov. Something like

RUST_ASSERT_CMD_WRAPPER="kcov --include-pattern=/src --exclude-pattern=/.cargo $PWD/cov" cargo test  -- --test-threads 1

@epage
Copy link
Contributor Author

epage commented Jan 14, 2019

A wrapper sounds like a great way to resolve this since the coverage tools don't follow fork (granted, when running cargo would we want them to)

@epage
Copy link
Contributor Author

epage commented Jan 27, 2019

I'm assuming I'll need to use shlex to separate out the command from the args when calling Command::new

@maxcountryman
Copy link

I’ll add that this would be a very nice feature. I’m currently using assert_cmd and tarpaulin and just like others have noted that this combination doesn’t work.

@brandonkal
Copy link

grcov (and kcov) appears to work with assert_cmd. Other tools failed to mark lines as tested as others have mentioned here.

@pkgw
Copy link

pkgw commented Sep 18, 2020

My project doesn't use assert_cmd, but based on my investigations of kcov I am pretty sure that special support will need to be added to properly track coverage in subcommand executions. You can check out tectonic-typesetting/tectonic#638 to see my approach:

  • Gather the tests that do assert_cmd-type activities into one harness (called executable in my project)
  • Run the test suite inside kcov, but not doing anything special when launching subcommands (I use cargo kcov which currently requires some hacking, but that's a separate issue)
  • For the executable harness, rerun it outside of kcov, but with a special environment variable that causes it to launch the underlying tool inside kcov; it puts the coverage data into a mkdtemp-type directory name so that runs don't stop on each other's toes
  • Merge all of the coverage results together at the end with kcov --merge

@frosklis
Copy link

frosklis commented Feb 6, 2021

Is there any plan on having this solved? Like @maxcountryman , I've seen that it doesn't work with tarpaulin coverage reports.

frosklis added a commit to ledger-rs/dinero-rs that referenced this issue Feb 7, 2021
I already had tests that should have a bigger coverage than reported.
Apparently there is an [issue with
assert_cmd](assert-rs/assert_cmd#9) that makes it not show
coverage correctly for tarpaulin.

So the workaround is to test as needed with assert_cmd and in the same
function call one that re-runs the command executing run_app and only
checks that the result is ok.
@epage
Copy link
Contributor Author

epage commented Mar 10, 2021

Sorry for the delay (Texas storm and life).

I am not actively working on this but would welcome contributions from others.

@milesj
Copy link

milesj commented Jun 6, 2022

@brandonkal I've been unable to get grcov to recognize code coverage from assert_cmd. Are you positive that it did work? Was there something special you did?

@jwodder
Copy link

jwodder commented Apr 19, 2023

I am currently able to get both cargo-llvm-cov and grcov to recognize coverage of crate binaries tested with assert_cmd (though it doesn't work for extra-crate binaries built via test-binary that use the crate under test). For cargo-llvm-cov, I simply ran cargo llvm-cov --all-features --lcov --output-path lcov.info, and for grcov, I ran:

export RUSTFLAGS="${RUSTFLAGS:+$RUSTFLAGS }-Cinstrument-coverage"
cargo build
export LLVM_PROFILE_FILE="target/coverage/prof/%p-%m.profraw"
cargo test --all-features

grcov \
    --source-dir . \
    --binary-path target/debug \
    --branch \
    --excl-start 'mod tests \{' \
    --ignore 'tests/*' \
    -t html \
    -o target/coverage/html \
    target/coverage/prof

An example repository where you can see coverage working: https://github.com/jwodder/ghrepo-rust

@LMH01
Copy link

LMH01 commented Oct 12, 2023

For those that stumble across this issue because they can't find a solution on how to get cargo-llvm-cov to work:

I got it working by using the command from above (cargo llvm-cov --all-features --lcov --output-path lcov.info) and by placing my test file into a seperate tests/ folder instead of src/some_file.rs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Not as expected
Projects
None yet
Development

No branches or pull requests

9 participants