-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Consider running tests in parallel by deafult #15953
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
Comments
|
Rust doesn’t really allow you controlling whether the tests are threaded or not (there’s a cli option to the test binary controlling how many threads to use, but you can’t say “this test suite requires a single thread”). Regarding whether it makes sense to use parallelism, I think “always” would be a good choice here: just spawn num_cpus threads, and let them eagerly pick up tests to run by atomically fetch-adding a shared test index. Sorbet’s multiplexJob would be a nice API shape for this task. |
I think this could make a lot of sense especially given that the build runner has become a sort of "driver" for the test runner recently: zig/lib/std/Build/Step/Run.zig Lines 936 to 1071 in 7e0a02e
This could be solved in a related way as #1356 which is to execute each test in parallel in a different sub-process. This gives up a bit of efficiency, especially on Windows where spawning child processes is more expensive, but it does enable excellent error reporting, and enable the use case of testing that an expected safety check indeed was triggered. |
I have unfinished code for this here https://github.com/matu3ba/zig/tree/enable_testing_panics, but for now designed to only to spawn a process, if APPENDUM: |
Oh, but this is fantastic! With build.zig in control, this can run multiple build/test jobs concurrently without over subscribing the CPU and avoiding make jobserver complexity! |
Also related is #11080 (global state in testing), which has discussion on randomizing test order (with subprocesses, but only considered sequential execution within one process for now). |
I love this proposal! In addition to everything already mentioned, the practice of running tests in parallel also helps in identifying race conditions. When I develop Go code, I run my tests in parallel with the race detector1, 2 enabled, and often times run all the tests repeatedly in CI. Go uses ThreadSanitizer (#1471) to surface detected data races, if any. It has saved my butt more times than I can count. This already exists in Zig, which is awesome! It looks something like:
There is also a From
|
For the spawn approach, take a look at #15991. This is not yet parallelized or using a seed to keep it simple. |
Today, when I run the tests using
zig test
/zig build test
, tests inside a single translation unit are being run sequentially:zig/lib/test_runner.zig
Line 145 in 629f0d2
I'd love to see the tests being run in parallel.
There are two motivations here:
Directly, I have 14 cores on the laptop I use, and it'd be nice to use all of them when working on well-tested codebases.
More importantly, indirectly defaults shape testing culture. It's very easy to writhe the first three test such that they are order dependent and can't be run in parallel. And this isn't a problem at three tests. However, once you get to 3 000 tests, this becomes a problem, but at that point fixing the tests requires a lot of effort.
In other words, "my tests can't be run in parallel" is a boiling frog kind of problem, and it would help if the language helped to avert this problem before it becomes big, hence "parallel by default". As a case study, Rust went for parallel tests, and, imo, it had lasting positive effects on the ecosystem.
Of course, some software is fundamentally single threaded and it's important to avoid pessimizing this case, but Zig already have single-threaded builds just for that.
One really hard problem here is what to do with test output (logging or direct use of
stderr
). If you run a bunch of tests in parallel, and something gets printing to stderr, how do you know which test is responsible? As far as I know, this problem isn't really solvable, and, to get test output, the tests should be run sequentially.The text was updated successfully, but these errors were encountered: