3 releases (stable)

2.0.0-pre.1 Jun 12, 2021
1.1.0 Aug 28, 2020
1.0.0 May 29, 2020

#110 in Testing

Download history 8568/week @ 2022-04-21 9797/week @ 2022-04-28 10711/week @ 2022-05-05 11625/week @ 2022-05-12 9804/week @ 2022-05-19 8571/week @ 2022-05-26 11933/week @ 2022-06-02 11096/week @ 2022-06-09 10723/week @ 2022-06-16 9108/week @ 2022-06-23 11056/week @ 2022-06-30 9607/week @ 2022-07-07 8888/week @ 2022-07-14 9272/week @ 2022-07-21 11277/week @ 2022-07-28 11343/week @ 2022-08-04

42,701 downloads per month
Used in 32 crates (11 directly)


105 lines


Verify that your tests exercise the conditions you think they are exercising

fn safe_divide(dividend: u32, divisor: u32) -> u32 {
    if divisor == 0 {
        return 0;
    dividend / divisor

fn test_safe_divide_by_zero() {
    assert_eq!(safe_divide(92, 0), 0);

See the docs for details



This library at its core provides two macros, [hit!] and [check!], which can be used to verify that a certain test exercises a certain code path.

Here's a short example:

fn parse_date(s: &str) -> Option<(u32, u32, u32)> {
    if 10 != s.len() {
        // By using `cov_mark::hit!`
        // we signal which test exercises this code.
        return None;

    if "-" != &s[4..5] || "-" != &s[7..8] {
        return None;
    // ...
#    unimplemented!()

fn test_parse_date() {
        // `cov_mark::check!` creates a guard object
        // that verifies that by the end of the scope we've
        // executed the corresponding `cov_mark::hit`.

//  This will fail. Although the test looks like
//  it exercises the second condition, it does not.
//  The call to `covers!` call catches this bug in the test.
//  {
//      cov_mark::check!(bad_dashes);;
//      assert!(parse_date("27.2.2013").is_none());
//  }


# fn main() {}

Here's why coverage marks are useful:

  • Verifying that something doesn't happen for the right reason.
  • Finding the test that exercises the code (grep for check!(mark_name)).
  • Finding the code that the test is supposed to check (grep for hit!(mark_name)).
  • Making sure that code and tests don't diverge during refactorings.
  • (If used pervasively) Verifying that each branch has a corresponding test.


  • In the presence of threads, [check!] may falsely pass, if the mark is hit by an unrelated thread, unless the thread-local feature is enabled.
  • Names of marks must be globally unique.
  • [check!] can't be used in integration tests.

Implementation Details

Each coverage mark is an AtomicUsize counter. [hit!] increments this counter, [check!] returns a guard object which checks that the mark was incremented. When the thread-local feature is enabled, each counter is stored as a thread-local, allowing for more accurate counting.

Counters are declared using #[no_mangle] attribute, so that [hit!] and [check!] both can find the mark without the need to declare it in a common module. Aren't the linkers horrible wonderful?


Technically, the [hit!] macro in this crate is unsound: it uses extern "C" #[no_mangle] symbol, which could clash with an existing symbol and cause UB. For example, cov_mark::hit!(main) may segfault. That said:

  • If there's no existing symbol, the result is a linker error.
  • If there exists corresponding cov_mark::check!, the result is a linker error.
  • Code inside cov_mark::hit! is hidden under #[cfg(test)].

It is believed that it is practically impossible to cause UB by accident when using this crate. For this reason, the hit macro hides unsafety inside.

No runtime deps


  • enable