diff --git a/Cargo.lock b/Cargo.lock
index 19d93a5b..ce55dcbb 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -692,7 +692,7 @@ dependencies = [
 
 [[package]]
 name = "ui_test"
-version = "0.13.0"
+version = "0.14.0"
 dependencies = [
  "anyhow",
  "bstr",
diff --git a/Cargo.toml b/Cargo.toml
index ef5096f2..09874fca 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "ui_test"
-version = "0.13.0"
+version = "0.14.0"
 edition = "2021"
 license = "MIT OR Apache-2.0"
 description = "A test framework for testing rustc diagnostics output"
diff --git a/src/config.rs b/src/config.rs
index 918d146b..66faafa7 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -5,7 +5,6 @@ pub use color_eyre;
 use color_eyre::eyre::Result;
 use std::{
     ffi::OsString,
-    num::NonZeroUsize,
     path::{Component, Path, PathBuf, Prefix},
 };
 
@@ -45,8 +44,6 @@ pub struct Config {
     /// The command to run can be changed from `cargo` to any custom command to build the
     /// dependencies in `dependencies_crate_manifest_path`
     pub dependency_builder: CommandBuilder,
-    /// How many threads to use for running tests. Defaults to number of cores
-    pub num_test_threads: NonZeroUsize,
     /// Where to dump files like the binaries compiled from tests.
     /// Defaults to `target/ui` in the current directory.
     pub out_dir: PathBuf,
@@ -88,7 +85,6 @@ impl Config {
             )),
             dependencies_crate_manifest_path: None,
             dependency_builder: CommandBuilder::cargo(),
-            num_test_threads: std::thread::available_parallelism().unwrap(),
             out_dir: std::env::var_os("CARGO_TARGET_DIR")
                 .map(PathBuf::from)
                 .unwrap_or_else(|| std::env::current_dir().unwrap().join("target"))
diff --git a/src/lib.rs b/src/lib.rs
index fb129718..66561e64 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -132,7 +132,8 @@ pub fn run_tests(config: Config) -> Result<()> {
     };
 
     run_tests_generic(
-        config,
+        vec![config],
+        std::thread::available_parallelism().unwrap(),
         args,
         default_file_filter,
         default_per_file_config,
@@ -142,7 +143,7 @@ pub fn run_tests(config: Config) -> Result<()> {
 
 /// The filter used by `run_tests` to only run on `.rs` files
 /// and those specified in the command line args.
-pub fn default_file_filter(path: &Path, args: &Args) -> bool {
+pub fn default_file_filter(path: &Path, args: &Args, _config: &Config) -> bool {
     path.extension().is_some_and(|ext| ext == "rs") && default_filter_by_arg(path, args)
 }
 
@@ -156,13 +157,11 @@ pub fn default_filter_by_arg(path: &Path, args: &Args) -> bool {
 }
 
 /// The default per-file config used by `run_tests`.
-pub fn default_per_file_config(config: &Config, path: &Path) -> Option<Config> {
-    let mut config = config.clone();
+pub fn default_per_file_config(config: &mut Config, file_contents: &[u8]) {
     // Heuristic:
     // * if the file contains `#[test]`, automatically pass `--cfg test`.
     // * if the file does not contain `fn main()` or `#[start]`, automatically pass `--crate-type=lib`.
     // This avoids having to spam `fn main() {}` in almost every test.
-    let file_contents = std::fs::read(path).unwrap();
     if file_contents.find(b"#[proc_macro").is_some() {
         config.program.args.push("--crate-type=proc-macro".into())
     } else if file_contents.find(b"#[test]").is_some() {
@@ -172,7 +171,6 @@ pub fn default_per_file_config(config: &Config, path: &Path) -> Option<Config> {
     {
         config.program.args.push("--crate-type=lib".into());
     }
-    Some(config)
 }
 
 /// Create a command for running a single file, with the settings from the `config` argument.
@@ -220,24 +218,29 @@ struct TestRun {
 
 /// A version of `run_tests` that allows more fine-grained control over running tests.
 pub fn run_tests_generic(
-    mut config: Config,
+    mut configs: Vec<Config>,
+    num_threads: NonZeroUsize,
     args: Args,
-    file_filter: impl Fn(&Path, &Args) -> bool + Sync,
-    per_file_config: impl Fn(&Config, &Path) -> Option<Config> + Sync,
+    file_filter: impl Fn(&Path, &Args, &Config) -> bool + Sync,
+    per_file_config: impl Fn(&mut Config, &[u8]) + Sync,
     status_emitter: impl StatusEmitter + Send,
 ) -> Result<()> {
-    config.fill_host_and_target()?;
+    for config in &mut configs {
+        config.fill_host_and_target()?;
+    }
 
     let build_manager = BuildManager::new(&status_emitter);
 
     let mut results = vec![];
 
     run_and_collect(
-        config.num_test_threads.get(),
+        num_threads,
         |submit| {
             let mut todo = VecDeque::new();
-            todo.push_back(config.root_dir.clone());
-            while let Some(path) = todo.pop_front() {
+            for config in configs {
+                todo.push_back((config.root_dir.clone(), config));
+            }
+            while let Some((path, config)) = todo.pop_front() {
                 if path.is_dir() {
                     if path.file_name().unwrap() == "auxiliary" {
                         continue;
@@ -250,28 +253,22 @@ pub fn run_tests_generic(
                         .unwrap();
                     entries.sort_by_key(|e| e.file_name());
                     for entry in entries {
-                        todo.push_back(entry.path());
+                        todo.push_back((entry.path(), config.clone()));
                     }
-                } else if file_filter(&path, &args) {
+                } else if file_filter(&path, &args, &config) {
                     let status = status_emitter.register_test(path);
                     // Forward .rs files to the test workers.
-                    submit.send(status).unwrap();
+                    submit.send((status, config)).unwrap();
                 }
             }
         },
         |receive, finished_files_sender| -> Result<()> {
-            for status in receive {
+            for (status, mut config) in receive {
                 let path = status.path();
-                let maybe_config;
-                let config = match per_file_config(&config, path) {
-                    None => &config,
-                    Some(config) => {
-                        maybe_config = config;
-                        &maybe_config
-                    }
-                };
+                let file_contents = std::fs::read(path).unwrap();
+                per_file_config(&mut config, &file_contents);
                 let result = match std::panic::catch_unwind(|| {
-                    parse_and_test_file(&build_manager, &status, config)
+                    parse_and_test_file(&build_manager, &status, &config, file_contents)
                 }) {
                     Ok(Ok(res)) => res,
                     Ok(Err(err)) => {
@@ -351,7 +348,7 @@ pub fn run_tests_generic(
 /// A generic multithreaded runner that has a thread for producing work,
 /// a thread for collecting work, and `num_threads` threads for doing the work.
 pub fn run_and_collect<SUBMISSION: Send, RESULT: Send>(
-    num_threads: usize,
+    num_threads: NonZeroUsize,
     submitter: impl FnOnce(Sender<SUBMISSION>) + Send,
     runner: impl Sync + Fn(&Receiver<SUBMISSION>, Sender<RESULT>) -> Result<()>,
     collector: impl FnOnce(Receiver<RESULT>) + Send,
@@ -373,7 +370,7 @@ pub fn run_and_collect<SUBMISSION: Send, RESULT: Send>(
         let mut threads = vec![];
 
         // Create N worker threads that receive files to test.
-        for _ in 0..num_threads {
+        for _ in 0..num_threads.get() {
             let finished_files_sender = finished_files_sender.clone();
             threads.push(s.spawn(|| runner(&receive, finished_files_sender)));
         }
@@ -389,8 +386,9 @@ fn parse_and_test_file(
     build_manager: &BuildManager<'_>,
     status: &dyn TestStatus,
     config: &Config,
+    file_contents: Vec<u8>,
 ) -> Result<Vec<TestRun>, Errored> {
-    let comments = parse_comments_in_file(status.path())?;
+    let comments = parse_comments(&file_contents)?;
     // Run the test for all revisions
     let revisions = comments
         .revisions
@@ -413,19 +411,14 @@ fn parse_and_test_file(
         .collect())
 }
 
-fn parse_comments_in_file(path: &Path) -> Result<Comments, Errored> {
-    match Comments::parse_file(path) {
-        Ok(Ok(comments)) => Ok(comments),
-        Ok(Err(errors)) => Err(Errored {
+fn parse_comments(file_contents: &[u8]) -> Result<Comments, Errored> {
+    match Comments::parse(file_contents) {
+        Ok(comments) => Ok(comments),
+        Err(errors) => Err(Errored {
             command: Command::new("parse comments"),
             errors,
             stderr: vec![],
         }),
-        Err(err) => Err(Errored {
-            command: Command::new("parse comments"),
-            errors: vec![],
-            stderr: format!("{err:?}").into(),
-        }),
     }
 }
 
@@ -467,7 +460,8 @@ fn build_aux(
     config: &Config,
     build_manager: &BuildManager<'_>,
 ) -> std::result::Result<Vec<OsString>, Errored> {
-    let comments = parse_comments_in_file(aux_file)?;
+    let file_contents = std::fs::read(aux_file).unwrap();
+    let comments = parse_comments(&file_contents)?;
     assert_eq!(
         comments.revisions, None,
         "aux builds cannot specify revisions"
@@ -495,7 +489,7 @@ fn build_aux(
         }
     });
 
-    let mut config = default_per_file_config(&config, aux_file).unwrap();
+    default_per_file_config(&mut config, &file_contents);
 
     // Put aux builds into a separate directory per path so that multiple aux files
     // from different directories (but with the same file name) don't collide.
@@ -615,7 +609,12 @@ impl dyn TestStatus {
             .stdout(Stdio::piped())
             .stdin(Stdio::null())
             .spawn()
-            .unwrap_or_else(|err| panic!("could not execute {cmd:?}: {err}"));
+            .unwrap_or_else(|err| {
+                panic!(
+                    "could not spawn `{:?}` as a process: {err}",
+                    cmd.get_program()
+                )
+            });
 
         let stdout = ReadHelper::from(child.stdout.take().unwrap());
         let mut stderr = ReadHelper::from(child.stderr.take().unwrap());
diff --git a/tests/integration.rs b/tests/integration.rs
index daeb4f21..750e1e24 100644
--- a/tests/integration.rs
+++ b/tests/integration.rs
@@ -1,24 +1,12 @@
 use std::path::Path;
 
-use colored::Colorize;
 use ui_test::color_eyre::Result;
 use ui_test::*;
 
 fn main() -> Result<()> {
-    run("integrations", Mode::Pass)?;
-    run("integrations", Mode::Panic)?;
-
-    eprintln!("integration tests done");
-
-    Ok(())
-}
-
-fn run(name: &str, mode: Mode) -> Result<()> {
-    eprintln!("\n{} `{name}` tests in mode {mode}", "Running".green());
     let path = Path::new(file!()).parent().unwrap();
-    let root_dir = path.join(name);
+    let root_dir = path.join("integrations");
     let mut config = Config {
-        mode,
         ..Config::cargo(root_dir.clone())
     };
     let args = Args::test();
@@ -85,9 +73,19 @@ fn run(name: &str, mode: Mode) -> Result<()> {
     };
 
     run_tests_generic(
-        config,
+        vec![
+            Config {
+                mode: Mode::Pass,
+                ..config.clone()
+            },
+            Config {
+                mode: Mode::Panic,
+                ..config
+            },
+        ],
+        std::thread::available_parallelism().unwrap(),
         args,
-        |path, args| {
+        |path, args, config| {
             let fail = path
                 .parent()
                 .unwrap()
@@ -102,7 +100,7 @@ fn run(name: &str, mode: Mode) -> Result<()> {
             }
             path.ends_with("Cargo.toml")
                 && path.parent().unwrap().parent().unwrap() == root_dir
-                && match mode {
+                && match config.mode {
                     Mode::Pass => !fail,
                     // This is weird, but `cargo test` returns 101 instead of 1 when
                     // multiple [[test]]s exist. If there's only one test, it returns
@@ -112,11 +110,11 @@ fn run(name: &str, mode: Mode) -> Result<()> {
                 }
                 && default_filter_by_arg(path, args)
         },
-        |_, _| None,
+        |_, _| {},
         (
             text,
             ui_test::status_emitter::Gha::<true> {
-                name: format!("{mode:?}"),
+                name: "integration tests".into(),
             },
         ),
     )
diff --git a/tests/integrations/basic-bin/Cargo.lock b/tests/integrations/basic-bin/Cargo.lock
index 867aeb37..cfdd4f22 100644
--- a/tests/integrations/basic-bin/Cargo.lock
+++ b/tests/integrations/basic-bin/Cargo.lock
@@ -700,7 +700,7 @@ dependencies = [
 
 [[package]]
 name = "ui_test"
-version = "0.13.0"
+version = "0.14.0"
 dependencies = [
  "anyhow",
  "bstr",
diff --git a/tests/integrations/basic-bin/tests/ui_tests.rs b/tests/integrations/basic-bin/tests/ui_tests.rs
index 6bb84d77..253fc82f 100644
--- a/tests/integrations/basic-bin/tests/ui_tests.rs
+++ b/tests/integrations/basic-bin/tests/ui_tests.rs
@@ -23,7 +23,8 @@ fn main() -> ui_test::color_eyre::Result<()> {
     config.path_stderr_filter(tmp_dir, "$$TMP");
 
     run_tests_generic(
-        config,
+        vec![config],
+        std::num::NonZeroUsize::new(1).unwrap(),
         Args::test(),
         default_file_filter,
         default_per_file_config,
diff --git a/tests/integrations/basic-fail-mode/Cargo.lock b/tests/integrations/basic-fail-mode/Cargo.lock
index 6cceb5ac..24687c06 100644
--- a/tests/integrations/basic-fail-mode/Cargo.lock
+++ b/tests/integrations/basic-fail-mode/Cargo.lock
@@ -700,7 +700,7 @@ dependencies = [
 
 [[package]]
 name = "ui_test"
-version = "0.13.0"
+version = "0.14.0"
 dependencies = [
  "anyhow",
  "bstr",
diff --git a/tests/integrations/basic-fail-mode/tests/ui_tests.rs b/tests/integrations/basic-fail-mode/tests/ui_tests.rs
index c3805404..1a2fd23d 100644
--- a/tests/integrations/basic-fail-mode/tests/ui_tests.rs
+++ b/tests/integrations/basic-fail-mode/tests/ui_tests.rs
@@ -19,7 +19,8 @@ fn main() -> ui_test::color_eyre::Result<()> {
     config.path_stderr_filter(&std::path::Path::new(path), "$DIR");
 
     run_tests_generic(
-        config,
+        vec![config],
+        std::num::NonZeroUsize::new(1).unwrap(),
         Args::test(),
         default_file_filter,
         default_per_file_config,
diff --git a/tests/integrations/basic-fail/Cargo.lock b/tests/integrations/basic-fail/Cargo.lock
index 44faf890..65382e3a 100644
--- a/tests/integrations/basic-fail/Cargo.lock
+++ b/tests/integrations/basic-fail/Cargo.lock
@@ -700,7 +700,7 @@ dependencies = [
 
 [[package]]
 name = "ui_test"
-version = "0.13.0"
+version = "0.14.0"
 dependencies = [
  "anyhow",
  "bstr",
diff --git a/tests/integrations/basic-fail/Cargo.stderr b/tests/integrations/basic-fail/Cargo.stderr
index 2a9b947f..8c242db2 100644
--- a/tests/integrations/basic-fail/Cargo.stderr
+++ b/tests/integrations/basic-fail/Cargo.stderr
@@ -591,7 +591,7 @@ test result: FAIL. 1 failed; 2 passed;
 thread 'main' panicked at 'invalid mode/result combo: yolo: Err(tests failed
 
 Location:
-    $DIR/src/lib.rs:LL:CC)', tests/ui_tests_bless.rs:52:18
+    $DIR/src/lib.rs:LL:CC)', tests/ui_tests_bless.rs:50:18
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 error: test failed, to rerun pass `--test ui_tests_bless`
 Error: failed to parse rustc version info: invalid_foobarlaksdfalsdfj
@@ -607,26 +607,26 @@ error: test failed, to rerun pass `--test ui_tests_invalid_program`
 Caused by:
   process didn't exit successfully: `$DIR/target/ui/debug/ui_tests_invalid_program-HASH` (exit status: 1)
 Building dependencies ... ok
-thread '<unnamed>' panicked at 'could not execute "invalid_foobarlaksdfalsdfj" "tests/actual_tests/bad_pattern.rs" "--edition" "2021": No such file or directory', $DIR/src/lib.rs
+thread '<unnamed>' panicked at 'could not spawn `"invalid_foobarlaksdfalsdfj"` as a process: No such file or directory', $DIR/src/lib.rs
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 tests/actual_tests/bad_pattern.rs ... FAILED
-thread '<unnamed>' panicked at 'could not execute "invalid_foobarlaksdfalsdfj" "tests/actual_tests/executable.rs" "--edition" "2021": No such file or directory', $DIR/src/lib.rs
+thread '<unnamed>' panicked at 'could not spawn `"invalid_foobarlaksdfalsdfj"` as a process: No such file or directory', $DIR/src/lib.rs
 tests/actual_tests/executable.rs ... FAILED
-thread '<unnamed>' panicked at 'could not execute "invalid_foobarlaksdfalsdfj" "tests/actual_tests/executable_compile_err.rs" "--edition" "2021": No such file or directory', $DIR/src/lib.rs
+thread '<unnamed>' panicked at 'could not spawn `"invalid_foobarlaksdfalsdfj"` as a process: No such file or directory', $DIR/src/lib.rs
 tests/actual_tests/executable_compile_err.rs ... FAILED
-thread '<unnamed>' panicked at 'could not execute "invalid_foobarlaksdfalsdfj" "tests/actual_tests/exit_code_fail.rs" "--edition" "2021": No such file or directory', $DIR/src/lib.rs
+thread '<unnamed>' panicked at 'could not spawn `"invalid_foobarlaksdfalsdfj"` as a process: No such file or directory', $DIR/src/lib.rs
 tests/actual_tests/exit_code_fail.rs ... FAILED
 tests/actual_tests/filters.rs ... FAILED
-thread '<unnamed>' panicked at 'could not execute "invalid_foobarlaksdfalsdfj" "tests/actual_tests/foomp.rs" "--edition" "2021": No such file or directory', $DIR/src/lib.rs
+thread '<unnamed>' panicked at 'could not spawn `"invalid_foobarlaksdfalsdfj"` as a process: No such file or directory', $DIR/src/lib.rs
 tests/actual_tests/foomp.rs ... FAILED
-thread '<unnamed>' panicked at 'could not execute "invalid_foobarlaksdfalsdfj" "tests/actual_tests/foomp2.rs" "--edition" "2021": No such file or directory', $DIR/src/lib.rs
+thread '<unnamed>' panicked at 'could not spawn `"invalid_foobarlaksdfalsdfj"` as a process: No such file or directory', $DIR/src/lib.rs
 tests/actual_tests/foomp2.rs ... FAILED
 tests/actual_tests/pattern_too_many_arrow.rs ... FAILED
 
 tests/actual_tests/bad_pattern.rs FAILED:
 command: "<unknown>"
 
-A bug in `ui_test` occurred: could not execute "invalid_foobarlaksdfalsdfj" "tests/actual_tests/bad_pattern.rs" "--edition" "2021": No such file or directory
+A bug in `ui_test` occurred: could not spawn `"invalid_foobarlaksdfalsdfj"` as a process: No such file or directory
 
 full stderr:
 
@@ -635,7 +635,7 @@ full stderr:
 tests/actual_tests/executable.rs FAILED:
 command: "<unknown>"
 
-A bug in `ui_test` occurred: could not execute "invalid_foobarlaksdfalsdfj" "tests/actual_tests/executable.rs" "--edition" "2021": No such file or directory
+A bug in `ui_test` occurred: could not spawn `"invalid_foobarlaksdfalsdfj"` as a process: No such file or directory
 
 full stderr:
 
@@ -644,7 +644,7 @@ full stderr:
 tests/actual_tests/executable_compile_err.rs FAILED:
 command: "<unknown>"
 
-A bug in `ui_test` occurred: could not execute "invalid_foobarlaksdfalsdfj" "tests/actual_tests/executable_compile_err.rs" "--edition" "2021": No such file or directory
+A bug in `ui_test` occurred: could not spawn `"invalid_foobarlaksdfalsdfj"` as a process: No such file or directory
 
 full stderr:
 
@@ -653,7 +653,7 @@ full stderr:
 tests/actual_tests/exit_code_fail.rs FAILED:
 command: "<unknown>"
 
-A bug in `ui_test` occurred: could not execute "invalid_foobarlaksdfalsdfj" "tests/actual_tests/exit_code_fail.rs" "--edition" "2021": No such file or directory
+A bug in `ui_test` occurred: could not spawn `"invalid_foobarlaksdfalsdfj"` as a process: No such file or directory
 
 full stderr:
 
@@ -672,7 +672,7 @@ full stderr:
 tests/actual_tests/foomp.rs FAILED:
 command: "<unknown>"
 
-A bug in `ui_test` occurred: could not execute "invalid_foobarlaksdfalsdfj" "tests/actual_tests/foomp.rs" "--edition" "2021": No such file or directory
+A bug in `ui_test` occurred: could not spawn `"invalid_foobarlaksdfalsdfj"` as a process: No such file or directory
 
 full stderr:
 
@@ -681,7 +681,7 @@ full stderr:
 tests/actual_tests/foomp2.rs FAILED:
 command: "<unknown>"
 
-A bug in `ui_test` occurred: could not execute "invalid_foobarlaksdfalsdfj" "tests/actual_tests/foomp2.rs" "--edition" "2021": No such file or directory
+A bug in `ui_test` occurred: could not spawn `"invalid_foobarlaksdfalsdfj"` as a process: No such file or directory
 
 full stderr:
 
diff --git a/tests/integrations/basic-fail/tests/ui_tests.rs b/tests/integrations/basic-fail/tests/ui_tests.rs
index 3d25a920..11f495a8 100644
--- a/tests/integrations/basic-fail/tests/ui_tests.rs
+++ b/tests/integrations/basic-fail/tests/ui_tests.rs
@@ -1,4 +1,3 @@
-use std::num::NonZeroUsize;
 use ui_test::*;
 
 fn main() -> ui_test::color_eyre::Result<()> {
@@ -9,8 +8,6 @@ fn main() -> ui_test::color_eyre::Result<()> {
         output_conflict_handling: OutputConflictHandling::Error(
             "DO NOT BLESS. These are meant to fail".into(),
         ),
-        // Make sure our tests are ordered for reliable output.
-        num_test_threads: NonZeroUsize::new(1).unwrap(),
         ..Config::rustc("tests/actual_tests")
     };
 
@@ -26,7 +23,8 @@ fn main() -> ui_test::color_eyre::Result<()> {
     config.path_stderr_filter(&std::path::Path::new(path), "$DIR");
 
     run_tests_generic(
-        config,
+        vec![config],
+        std::num::NonZeroUsize::new(1).unwrap(),
         Args::test(),
         default_file_filter,
         default_per_file_config,
diff --git a/tests/integrations/basic-fail/tests/ui_tests_bless.rs b/tests/integrations/basic-fail/tests/ui_tests_bless.rs
index e0c48471..2bbdf15b 100644
--- a/tests/integrations/basic-fail/tests/ui_tests_bless.rs
+++ b/tests/integrations/basic-fail/tests/ui_tests_bless.rs
@@ -1,4 +1,3 @@
-use std::num::NonZeroUsize;
 use ui_test::*;
 
 fn main() -> ui_test::color_eyre::Result<()> {
@@ -19,8 +18,6 @@ fn main() -> ui_test::color_eyre::Result<()> {
 
         let mut config = Config {
             dependencies_crate_manifest_path: Some("Cargo.toml".into()),
-            // Make sure our tests are ordered for reliable output.
-            num_test_threads: NonZeroUsize::new(1).unwrap(),
             mode,
             ..Config::rustc(root_dir)
         };
@@ -39,7 +36,8 @@ fn main() -> ui_test::color_eyre::Result<()> {
         config.stderr_filter(r"[^ ]*/\.?cargo/registry/.*/", "$$CARGO_REGISTRY");
         config.path_stderr_filter(&std::path::Path::new(path), "$DIR");
         let result = run_tests_generic(
-            config,
+            vec![config],
+            std::num::NonZeroUsize::new(1).unwrap(),
             Args::test(),
             default_file_filter,
             default_per_file_config,
diff --git a/tests/integrations/basic-fail/tests/ui_tests_invalid_program.rs b/tests/integrations/basic-fail/tests/ui_tests_invalid_program.rs
index 4514a005..991d9e17 100644
--- a/tests/integrations/basic-fail/tests/ui_tests_invalid_program.rs
+++ b/tests/integrations/basic-fail/tests/ui_tests_invalid_program.rs
@@ -1,4 +1,3 @@
-use std::num::NonZeroUsize;
 use ui_test::*;
 
 fn main() -> ui_test::color_eyre::Result<()> {
@@ -8,13 +7,12 @@ fn main() -> ui_test::color_eyre::Result<()> {
         output_conflict_handling: OutputConflictHandling::Error(
             "DO NOT BLESS. These are meant to fail".into(),
         ),
-        // Make sure our tests are ordered for reliable output.
-        num_test_threads: NonZeroUsize::new(1).unwrap(),
         ..Config::rustc("tests/actual_tests")
     };
 
     run_tests_generic(
-        config,
+        vec![config],
+        std::num::NonZeroUsize::new(1).unwrap(),
         Args::test(),
         default_file_filter,
         default_per_file_config,
diff --git a/tests/integrations/basic-fail/tests/ui_tests_invalid_program2.rs b/tests/integrations/basic-fail/tests/ui_tests_invalid_program2.rs
index b997a47b..fbe1d5fd 100644
--- a/tests/integrations/basic-fail/tests/ui_tests_invalid_program2.rs
+++ b/tests/integrations/basic-fail/tests/ui_tests_invalid_program2.rs
@@ -1,4 +1,3 @@
-use std::num::NonZeroUsize;
 use ui_test::*;
 
 fn main() -> ui_test::color_eyre::Result<()> {
@@ -9,13 +8,12 @@ fn main() -> ui_test::color_eyre::Result<()> {
         output_conflict_handling: OutputConflictHandling::Error(
             "DO NOT BLESS. These are meant to fail".into(),
         ),
-        // Make sure our tests are ordered for reliable output.
-        num_test_threads: NonZeroUsize::new(1).unwrap(),
         ..Config::rustc("tests/actual_tests")
     };
 
     run_tests_generic(
-        config,
+        vec![config],
+        std::num::NonZeroUsize::new(1).unwrap(),
         Args::test(),
         default_file_filter,
         default_per_file_config,
diff --git a/tests/integrations/basic/Cargo.lock b/tests/integrations/basic/Cargo.lock
index d44d82d7..e24c206c 100644
--- a/tests/integrations/basic/Cargo.lock
+++ b/tests/integrations/basic/Cargo.lock
@@ -700,7 +700,7 @@ dependencies = [
 
 [[package]]
 name = "ui_test"
-version = "0.13.0"
+version = "0.14.0"
 dependencies = [
  "anyhow",
  "bstr",
diff --git a/tests/integrations/basic/tests/ui_tests.rs b/tests/integrations/basic/tests/ui_tests.rs
index a3975b1e..a7f0acdc 100644
--- a/tests/integrations/basic/tests/ui_tests.rs
+++ b/tests/integrations/basic/tests/ui_tests.rs
@@ -1,11 +1,9 @@
-use std::num::NonZeroUsize;
 use ui_test::*;
 
 fn main() -> ui_test::color_eyre::Result<()> {
     let path = "../../../target";
     let mut config = Config {
         dependencies_crate_manifest_path: Some("Cargo.toml".into()),
-        num_test_threads: NonZeroUsize::new(1).unwrap(),
         ..Config::rustc("tests/actual_tests")
     };
     if std::env::var_os("BLESS").is_some() {
@@ -23,7 +21,8 @@ fn main() -> ui_test::color_eyre::Result<()> {
     config.path_stderr_filter(tmp_dir, "$TMP");
 
     run_tests_generic(
-        config,
+        vec![config],
+        std::num::NonZeroUsize::new(1).unwrap(),
         Args::test(),
         default_file_filter,
         default_per_file_config,