This page looks best with JavaScript enabled

Cargo Test 的测试隔离性;使用 nextest-rs/nextest 来运行 Rust 的单元测试

 ·  ☕ 5 min read

随便写一个测试 mod,包含多个单元测试:

mod tests {
    use std::time::Duration;

    fn print_my_pid_and_tid() {
        let pid = std::process::id();
        let tid = nix::unistd::gettid();

        println!("my pid is {}, tid is {}", pid, tid);
    }

    fn hard_job() {
        std:🧵:sleep(Duration::from_secs(2));
    }

    macro_rules! generate_test_functions {
        ($name:ident) => {
            #[test]
            fn $name() {
                hard_job();
                print_my_pid_and_tid();
            }
        };
    }

    generate_test_functions!(test_0);
    generate_test_functions!(test_1);
    generate_test_functions!(test_2);
    generate_test_functions!(test_3);
    generate_test_functions!(test_4);
    generate_test_functions!(test_5);
    generate_test_functions!(test_6);
    generate_test_functions!(test_7);
    generate_test_functions!(test_8);
    generate_test_functions!(test_9);
    generate_test_functions!(test_10);
    generate_test_functions!(test_11);
    generate_test_functions!(test_12);
    generate_test_functions!(test_13);
    generate_test_functions!(test_14);
    generate_test_functions!(test_15);
    generate_test_functions!(test_16);
    generate_test_functions!(test_17);
    generate_test_functions!(test_18);
    generate_test_functions!(test_19);
}

运行整个测试 mod:

1
cargo test -- --nocapture

执行结果:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
$ cargo test -- --nocapture
    Finished test [unoptimized + debuginfo] target(s) in 0.03s
     Running unittests src/lib.rs (target/debug/deps/test_isolation-64b5602935747ce0)

running 20 tests
my pid is 429416, tid is 429417
my pid is 429416, tid is 429418
test tests::test_0 ... ok
my pid is 429416, tid is 429419
test tests::test_1 ... ok
test tests::test_10 ... ok
my pid is 429416, tid is 429420
test tests::test_11 ... ok
my pid is 429416, tid is 429421
test tests::test_12 ... ok
my pid is 429416, tid is 429422
my pid is 429416, tid is 429424
test tests::test_13 ... ok
test tests::test_15 ... ok
my pid is 429416, tid is 429425
my pid is 429416, tid is 429423
test tests::test_16 ... ok
my pid is 429416, tid is 429426
my pid is 429416, tid is 429427
test tests::test_14 ... ok
test tests::test_17 ... ok
test tests::test_18 ... ok
my pid is 429416, tid is 429428
test tests::test_19 ... ok
my pid is 429416, tid is 429483
my pid is 429416, tid is 429484
test tests::test_2 ... ok
test tests::test_3 ... my pid is 429416, tid is 429485
ok
test tests::test_4 ... ok
my pid is 429416, tid is 429486
my pid is 429416, tid is 429487
test tests::test_5 ... ok
test tests::test_6 ... ok
my pid is 429416, tid is 429488
my pid is 429416, tid is 429489
test tests::test_7 ... ok
test tests::test_8 ... ok
my pid is 429416, tid is 429490
test tests::test_9 ... ok

test result: ok. 20 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 4.00s

可见,这 20 个单元测试,都在在同一个进程中运行的,但是没有在同一个线程中运行。

看看 cargo 提供的 –test-threads 参数:

1
2
3
4
5
6
--test-threads n_threads
                        Number of threads used for running tests in parallel

By default, all tests are run in parallel. This can be altered with the
--test-threads flag or the RUST_TEST_THREADS environment variable when running
tests (set it to 1).

试试将 –test-threads 指定为 1, 会发生什么?

cargo test -- --nocapture --test-threads 1
执行结果:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
$  cargo test -- --nocapture --test-threads 1
    Finished test [unoptimized + debuginfo] target(s) in 0.03s
     Running unittests src/lib.rs (target/debug/deps/test_isolation-64b5602935747ce0)

running 20 tests
test tests::test_0 ... my pid is 435905, tid is 435905
ok
test tests::test_1 ... my pid is 435905, tid is 435905
ok
test tests::test_10 ... my pid is 435905, tid is 435905
ok
test tests::test_11 ... my pid is 435905, tid is 435905
ok
test tests::test_12 ... my pid is 435905, tid is 435905
ok
test tests::test_13 ... my pid is 435905, tid is 435905
ok
test tests::test_14 ... my pid is 435905, tid is 435905
ok
test tests::test_15 ... my pid is 435905, tid is 435905
ok
test tests::test_16 ... my pid is 435905, tid is 435905
ok
test tests::test_17 ... my pid is 435905, tid is 435905
ok
test tests::test_18 ... my pid is 435905, tid is 435905
ok
test tests::test_19 ... my pid is 435905, tid is 435905
ok
test tests::test_2 ... my pid is 435905, tid is 435905
ok
test tests::test_3 ... my pid is 435905, tid is 435905
ok
test tests::test_4 ... my pid is 435905, tid is 435905
ok
test tests::test_5 ... my pid is 435905, tid is 435905
ok
test tests::test_6 ... my pid is 435905, tid is 435905
ok
test tests::test_7 ... my pid is 435905, tid is 435905
ok
test tests::test_8 ... my pid is 435905, tid is 435905
ok
test tests::test_9 ... my pid is 435905, tid is 435905
ok

test result: ok. 20 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 40.00s
 

这么多单元测试,不仅全都在同一个进程中运行的,而且还在同一个线程中运行的。

使用 nextest-rs/nextest,让每个单元测试都在不同的进程中运行

cargo nextest run --hide-progress-bar --success-output immediate
执行结果:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
$ cargo nextest run --hide-progress-bar --success-output immediate
    Finished test [unoptimized + debuginfo] target(s) in 0.04s
  Executable unittests src/lib.rs (target/debug/deps/test_isolation-64b5602935747ce0)
    Starting 20 tests across 1 binaries
        PASS [   2.005s] test_isolation tests::test_0

--- STDOUT:              test_isolation tests::test_0 ---

running 1 test
my pid is 443021, tid is 443027
test tests::test_0 ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 19 filtered out; finished in 2.00s


        PASS [   2.006s] test_isolation tests::test_1

--- STDOUT:              test_isolation tests::test_1 ---

running 1 test
my pid is 443022, tid is 443029
test tests::test_1 ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 19 filtered out; finished in 2.00s


        PASS [   2.009s] test_isolation tests::test_10

--- STDOUT:              test_isolation tests::test_10 ---

running 1 test
my pid is 443023, tid is 443032
test tests::test_10 ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 19 filtered out; finished in 2.00s


        PASS [   2.007s] test_isolation tests::test_12

--- STDOUT:              test_isolation tests::test_12 ---

running 1 test
my pid is 443025, tid is 443034
test tests::test_12 ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 19 filtered out; finished in 2.00s


        PASS [   2.008s] test_isolation tests::test_11

--- STDOUT:              test_isolation tests::test_11 ---

running 1 test
my pid is 443024, tid is 443035
test tests::test_11 ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 19 filtered out; finished in 2.00s


        PASS [   2.010s] test_isolation tests::test_13

--- STDOUT:              test_isolation tests::test_13 ---

running 1 test
my pid is 443026, tid is 443036
test tests::test_13 ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 19 filtered out; finished in 2.00s


        PASS [   2.009s] test_isolation tests::test_14

--- STDOUT:              test_isolation tests::test_14 ---

running 1 test
my pid is 443028, tid is 443039
test tests::test_14 ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 19 filtered out; finished in 2.00s


        PASS [   2.008s] test_isolation tests::test_15

--- STDOUT:              test_isolation tests::test_15 ---

running 1 test
my pid is 443030, tid is 443040
test tests::test_15 ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 19 filtered out; finished in 2.00s


        PASS [   2.009s] test_isolation tests::test_17

--- STDOUT:              test_isolation tests::test_17 ---

running 1 test
my pid is 443033, tid is 443041
test tests::test_17 ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 19 filtered out; finished in 2.00s


        PASS [   2.011s] test_isolation tests::test_16

--- STDOUT:              test_isolation tests::test_16 ---

running 1 test
my pid is 443031, tid is 443042
test tests::test_16 ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 19 filtered out; finished in 2.00s


        PASS [   2.008s] test_isolation tests::test_18

--- STDOUT:              test_isolation tests::test_18 ---

running 1 test
my pid is 443037, tid is 443043
test tests::test_18 ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 19 filtered out; finished in 2.00s


        PASS [   2.007s] test_isolation tests::test_19

--- STDOUT:              test_isolation tests::test_19 ---

running 1 test
my pid is 443038, tid is 443044
test tests::test_19 ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 19 filtered out; finished in 2.00s


        PASS [   2.006s] test_isolation tests::test_3

--- STDOUT:              test_isolation tests::test_3 ---

running 1 test
my pid is 443102, tid is 443106
test tests::test_3 ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 19 filtered out; finished in 2.00s


        PASS [   2.008s] test_isolation tests::test_2

--- STDOUT:              test_isolation tests::test_2 ---

running 1 test
my pid is 443101, tid is 443107
test tests::test_2 ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 19 filtered out; finished in 2.00s


        PASS [   2.007s] test_isolation tests::test_4

--- STDOUT:              test_isolation tests::test_4 ---

running 1 test
my pid is 443104, tid is 443111
test tests::test_4 ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 19 filtered out; finished in 2.00s


        PASS [   2.007s] test_isolation tests::test_6

--- STDOUT:              test_isolation tests::test_6 ---

running 1 test
my pid is 443108, tid is 443113
test tests::test_6 ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 19 filtered out; finished in 2.00s


        PASS [   2.010s] test_isolation tests::test_5

--- STDOUT:              test_isolation tests::test_5 ---

running 1 test
my pid is 443105, tid is 443114
test tests::test_5 ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 19 filtered out; finished in 2.00s


        PASS [   2.006s] test_isolation tests::test_8

--- STDOUT:              test_isolation tests::test_8 ---

running 1 test
my pid is 443110, tid is 443115
test tests::test_8 ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 19 filtered out; finished in 2.00s


        PASS [   2.008s] test_isolation tests::test_7

--- STDOUT:              test_isolation tests::test_7 ---

running 1 test
my pid is 443109, tid is 443116
test tests::test_7 ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 19 filtered out; finished in 2.00s


        PASS [   2.007s] test_isolation tests::test_9

--- STDOUT:              test_isolation tests::test_9 ---

running 1 test
my pid is 443112, tid is 443117
test tests::test_9 ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 19 filtered out; finished in 2.00s


------------
     Summary [   4.023s] 20 tests run: 20 passed, 0 skipped

可以看到,nextest-rs/nextest 会让每个单元测试在独立的进程中运行。

Share on

EXEC
WRITTEN BY
EXEC
Eval EXEC