]> git.proxmox.com Git - rustc.git/blame - src/doc/rust-by-example/src/testing/unit_testing.md
New upstream version 1.38.0+dfsg1
[rustc.git] / src / doc / rust-by-example / src / testing / unit_testing.md
CommitLineData
2c00a5a8
XL
1# Unit testing
2
3Tests are Rust functions that verify that the non-test code is functioning in
4the expected manner. The bodies of test functions typically perform some setup,
5run the code we want to test, then assert whether the results are what we
6expect.
7
8Most unit tests go into a `tests` [mod][mod] with the `#[cfg(test)]` [attribute][attribute].
9Test functions are marked with the `#[test]` attribute.
10
11Tests fail when something in the test function [panics][panic]. There are some
12helper [macros][macros]:
13
14* `assert!(expression)` - panics if expression evaluates to `false`.
15* `assert_eq!(left, right)` and `assert_ne!(left, right)` - testing left and
16 right expressions for equality and inequality respectively.
17
18```rust,ignore
19pub fn add(a: i32, b: i32) -> i32 {
20 a + b
21}
22
23// This is a really bad adding function, its purpose is to fail in this
24// example.
25#[allow(dead_code)]
26fn bad_add(a: i32, b: i32) -> i32 {
27 a - b
28}
29
30#[cfg(test)]
31mod tests {
32 // Note this useful idiom: importing names from outer (for mod tests) scope.
33 use super::*;
34
35 #[test]
36 fn test_add() {
37 assert_eq!(add(1, 2), 3);
38 }
39
40 #[test]
41 fn test_bad_add() {
42 // This assert would fire and test will fail.
43 // Please note, that private functions can be tested too!
44 assert_eq!(bad_add(1, 2), 3);
45 }
46}
47```
48
49Tests can be run with `cargo test`.
50
416331ca 51```shell
2c00a5a8
XL
52$ cargo test
53
54running 2 tests
55test tests::test_bad_add ... FAILED
56test tests::test_add ... ok
57
58failures:
59
60---- tests::test_bad_add stdout ----
61 thread 'tests::test_bad_add' panicked at 'assertion failed: `(left == right)`
62 left: `-1`,
63 right: `3`', src/lib.rs:21:8
64note: Run with `RUST_BACKTRACE=1` for a backtrace.
65
66
67failures:
68 tests::test_bad_add
69
70test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out
71```
72
73## Testing panics
74
75To check functions that should panic under certain circumstances, use attribute
76`#[should_panic]`. This attribute accepts optional parameter `expected = ` with
77the text of the panic message. If your function can panic in multiple ways, it helps
78make sure your test is testing the correct panic.
79
80```rust,ignore
81pub fn divide_non_zero_result(a: u32, b: u32) -> u32 {
82 if b == 0 {
83 panic!("Divide-by-zero error");
84 } else if a < b {
85 panic!("Divide result is zero");
86 }
87 a / b
88}
89
90#[cfg(test)]
91mod tests {
92 use super::*;
93
94 #[test]
95 fn test_divide() {
96 assert_eq!(divide_non_zero_result(10, 2), 5);
97 }
98
99 #[test]
100 #[should_panic]
101 fn test_any_panic() {
102 divide_non_zero_result(1, 0);
103 }
104
105 #[test]
106 #[should_panic(expected = "Divide result is zero")]
107 fn test_specific_panic() {
108 divide_non_zero_result(1, 10);
109 }
110}
111```
112
113Running these tests gives us:
114
416331ca 115```shell
2c00a5a8
XL
116$ cargo test
117
118running 3 tests
119test tests::test_any_panic ... ok
120test tests::test_divide ... ok
121test tests::test_specific_panic ... ok
122
123test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
124
125 Doc-tests tmp-test-should-panic
126
127running 0 tests
128
129test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
130```
131
132## Running specific tests
133
134To run specific tests one may specify the test name to `cargo test` command.
135
416331ca 136```shell
2c00a5a8
XL
137$ cargo test test_any_panic
138running 1 test
139test tests::test_any_panic ... ok
140
141test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out
142
143 Doc-tests tmp-test-should-panic
144
145running 0 tests
146
147test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
148```
149
150To run multiple tests one may specify part of a test name that matches all the
151tests that should be run.
152
416331ca 153```shell
2c00a5a8
XL
154$ cargo test panic
155running 2 tests
156test tests::test_any_panic ... ok
157test tests::test_specific_panic ... ok
158
159test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out
160
161 Doc-tests tmp-test-should-panic
162
163running 0 tests
164
165test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
166```
167
168## Ignoring tests
169
416331ca 170Tests can be marked with the `#[ignore]` attribute to exclude some tests. Or to run
2c00a5a8
XL
171them with command `cargo test -- --ignored`
172
173```rust
174pub fn add(a: i32, b: i32) -> i32 {
175 a + b
176}
177
178#[cfg(test)]
179mod tests {
180 use super::*;
181
182 #[test]
183 fn test_add() {
184 assert_eq!(add(2, 2), 4);
185 }
186
187 #[test]
188 fn test_add_hundred() {
189 assert_eq!(add(100, 2), 102);
190 assert_eq!(add(2, 100), 102);
191 }
192
193 #[test]
194 #[ignore]
195 fn ignored_test() {
196 assert_eq!(add(0, 0), 0);
197 }
198}
199```
200
416331ca 201```shell
2c00a5a8 202$ cargo test
416331ca 203running 3 tests
2c00a5a8 204test tests::ignored_test ... ignored
416331ca
XL
205test tests::test_add ... ok
206test tests::test_add_hundred ... ok
2c00a5a8 207
416331ca 208test result: ok. 2 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out
2c00a5a8
XL
209
210 Doc-tests tmp-ignore
211
212running 0 tests
213
214test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
215
216$ cargo test -- --ignored
217running 1 test
218test tests::ignored_test ... ok
219
220test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
221
222 Doc-tests tmp-ignore
223
224running 0 tests
225
226test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
227```
228
dc9dc135
XL
229[attribute]: ../attribute.md
230[panic]: ../std/panic.md
231[macros]: ../macros.md
232[mod]: ../mod.md