nextest-rs / nextest

A next-generation test runner for Rust.
https://nexte.st
Apache License 2.0
2.11k stars 92 forks source link

Handle tests that should be run within the same process #27

Open sunshowers opened 2 years ago

sunshowers commented 2 years ago

Currently, nextest runs every test in its own process. Should running tests within the same process be supported?

crepererum commented 2 years ago

I think it would be nice if this is not an "all or nothing" flag, but rather that the user can describe multiple groups that should be run within a process, e.g. by specifying:

All tests NOT found within a group are run within their own group.

To illustrate why this is helpful: over in influxdb_iox all tests within the workspace can be run in parallel. However for end2end tests within the influxdb_iox crate start a real server process but try to reuse it for multiple tests, so we pay for the startup costs every time. The tests using the single server process could also be run in parallel though, but currently they need to be executed from the same test process (they "find" and initialize the server process using lazy_static).

sunshowers commented 2 years ago

Yeah, that is the use case that I was thinking of. I agree that an all-or-nothing flag would be bad; the default will always be to run each test in its own process. The same-process opt-in would be per-test-binary using package.metadata.

The main challenges here are still concurrency control and gathering data about individual tests. Currently the only way to gather data about individual tests is to use the JSON format, which is nightly-only. We could certainly add a flag to the configuration to turn on nightly-only features, or just rely on people passing in -Z unstable-features.

sunshowers commented 2 years ago

This is going to require somewhat advanced concurrency-related and stability-related work so is not a good first issue, but I'll mark this as "help wanted" for now. If you'd like to implement it, I'd be happy to accept a PR! We could probably go over further design intricacies once there's a PR for this.

sunshowers commented 2 years ago

Been thinking about this -- I've figured out a way to do this on stable Rust using the --logfile option. We can rely on two things:

  1. cargo test executes tests in lexicographic order
  2. data is written to logfiles as soon as the test passes

So what we can do is:

The time taken would likely be approximate, but that's ok -- we can document that.

sunshowers commented 2 years ago

Update: nextest now sets a NEXTEST_RUN_ID environment variable which should help porting over some use cases to nextest.

I don't plan to work on this for free. However:

To be clear, this is a fundamental rework of how nextest operates. It's going to require considerations throughout the entire stack, and careful integration with every other nextest feature. This is a big, challenging project, and if you hire me to do it I will charge accordingly. I would strongly recommend considering alternative approaches first. (I'm happy to add workarounds like NEXTEST_RUN_ID.)

Edit 2023-01: I'm no longer available for contract work.

sunshowers commented 1 year ago

The ability to run tests with mutual exclusion (similar to the serial_test crate) is now possible with test groups.

tisonkun commented 1 month ago

Does nextest run concurrent cases in different process anyway?

I have a OnceLock logics and notice that it executes N times while it should not happen if tests are running in the same process ..

The once logic contains heavily testcontainers setup logic and I'd like to ensure no regression for testcontainers, so setup script is not an alternative.

sunshowers commented 2 weeks ago

Does nextest run concurrent cases in different process anyway?

Yes, the only supported model with nextest is process-per-test. See https://nexte.st/docs/configuration/test-groups/ for how to configure test groups.