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

Test name filtering does not allow disambiguating tests with overlapping names #46408

Closed
jonhoo opened this issue Nov 30, 2017 · 9 comments
Closed
Labels
A-libtest Area: `#[test]` / the `test` library C-enhancement Category: An issue proposing an enhancement or a PR with one.

Comments

@jonhoo
Copy link
Contributor

jonhoo commented Nov 30, 2017

Consider the following two tests:

#[test]
fn it_works() { /* ... */ }
#[test]
fn it_works_complexly() { /* ... */ }

There is currently no way to run only it_works, and not it_works_complexly:

$ cargo t it_works
running 2 tests
test it_works ... ok
test it_works_more ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

In Go, the filter is a regular expression, so one can use go test 'it_works$', but this not work in Rust (because the test harness presumably just uses simple substring matching):

$ cargo t 'it_works$'
running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out
@malbarbo
Copy link
Contributor

Try cargo t it_works -- --exact.

@jonhoo
Copy link
Contributor Author

jonhoo commented Nov 30, 2017

Is that documented anywhere outside of cargo test -- --help?
I bet most users have never run that, and probably wouldn't even think to (like me :p).

Also, --exact is still a limited solution. It requires that I type out the entire test name, and means I can only run a single test this way. For example, I can't avoid running just the complexly test here:

#[test]
fn foo_works() { /* ... */ }
#[test]
fn foo_works_complexly() { /* ... */ }
#[test]
fn bar_works() { /* ... */ }

@cuviper
Copy link
Member

cuviper commented Nov 30, 2017

You can also --skip complexly. But I agree it would be nice to have more controls -- if not full regex, maybe just globbing? Even just being able to specify multiple filters would help.

@jonhoo
Copy link
Contributor Author

jonhoo commented Nov 30, 2017

Both globbing and multiple filters seem like good solutions!

@jonhoo
Copy link
Contributor Author

jonhoo commented Dec 1, 2017

I might take a stab at implementing this. A couple of questions though:

  • Is using glob inside of libtest fine?
  • Making this the default is technically a backwards-incompatible change (arguments that didn't previously match any tests, like it*, may now match tests). However, given that it will only make patterns that previously didn't match match (?, *, [, and ] aren't allowed in test names) it is unlikely that anything relies on the current behaviour. How would we feel about making globbing the default?
    • EDIT: on second thought, since globs require matching the full string, whereas the current default is substring matches, this wouldn't be backwards compatible at all. Yet having to specify cargo test -- --glob pattern seems awfully inconvenient. How bad would making this non-backwards-compatible change be? Alternatively I suppose we could use glob either if --glob is passed or if a globbing character is included in the pattern (they can't appear in test names anyway)?
  • Is globbing sufficient? It does address the original concerns outlined above as long as the glob is required to match the entire test name (which is how globs usually behave anyway), but is still more limited than full regexes.
  • Should --exactly apply only to the next pattern, or to all patterns?
    • This is relevant only when/if we get support for multiple patterns.
  • Which takes precedence if both --exact and --glob are given?
  • If --glob is supplied, should --skip patterns also be considered glob patterns? What if a skip pattern contains a special character? Should it automatically be made a glob pattern?

Probably cc @rust-lang/tools and maybe @sfackler judging from #38181.

jonhoo added a commit to jonhoo/rust that referenced this issue Dec 1, 2017
Tests can currently only be filtered by substring or exact match. This
makes it difficult to have finer-grained control over which tests to
run, such as running only tests with a given suffix in a module, all
tests without a given suffix, etc.

This PR adds a `--glob` flag to make test name filters use glob patterns
instead of string substring matching. This allows commands such as:

    --glob mymod::*_fast

or

    --glob --skip *_slow

The `--glob` flag can normally be omitted, as it is inferred whenever a
pattern includes one of the glob special characters (`*`, `?`, or `[`).
These characters cannot appear in ordinary test names, so this should
not cause unexpected results.

If both `--exact` *and* `--glob` are given, `--exact` takes precedence.

Fixes rust-lang#46408.
@jonhoo
Copy link
Contributor Author

jonhoo commented Dec 1, 2017

@cuviper see #46417 if you haven't already.

@pietroalbini pietroalbini added C-enhancement Category: An issue proposing an enhancement or a PR with one. A-libtest Area: `#[test]` / the `test` library labels Jan 23, 2018
@steveklabnik
Copy link
Member

Triage: no changes that I'm aware of.

@RalfJung
Copy link
Member

RalfJung commented Aug 11, 2022

Both globbing and multiple filters seem like good solutions!

Multiple filters already work. You can do cargo test -- filter1 filter2 --skip f3 --skip f4 to run all tests that contain (filter1 and neither f3 nor f4) or (filter2 and neither f3 nor f4).

For more precise filtering, there's a regex feature request at #53278.

@jonhoo
Copy link
Contributor Author

jonhoo commented Aug 11, 2022

In that case I suppose this issue can be closed, as the case from the original post can be achieved with

cargo test -- it_works --skip complexly

@jonhoo jonhoo closed this as completed Aug 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-libtest Area: `#[test]` / the `test` library C-enhancement Category: An issue proposing an enhancement or a PR with one.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants