blob: 8d3eac96f81e69f0a598c8c0021d56d201ef0318 [file] [log] [blame] [view] [edit]
# Writing Automated Tests
In his 1972 essay The Humble Programmer,” Edsger W. Dijkstra said that Program
testing can be a very effective way to show the presence of bugs, but it is
hopelessly inadequate for showing their absence.” That doesnt mean we shouldnt
try to test as much as we can!
Correctness in our programs is the extent to which our code does what we intend
it to do. Rust is designed with a high degree of concern about the correctness
of programs, but correctness is complex and not easy to prove. Rusts type
system shoulders a huge part of this burden, but the type system cannot catch
everything. As such, Rust includes support for writing automated software tests.
Say we write a function `add_two` that adds 2 to whatever number is passed to
it. This functions signature accepts an integer as a parameter and returns an
integer as a result. When we implement and compile that function, Rust does all
the type checking and borrow checking that youve learned so far to ensure that,
for instance, we arent passing a `String` value or an invalid reference to this
function. But Rust _cant_ check that this function will do precisely what we
intend, which is return the parameter plus 2 rather than, say, the parameter
plus 10 or the parameter minus 50! Thats where tests come in.
We can write tests that assert, for example, that when we pass `3` to the
`add_two` function, the returned value is `5`. We can run these tests whenever
we make changes to our code to make sure any existing correct behavior has not
changed.
Testing is a complex skill: although we cant cover in one chapter every detail
about how to write good tests, in this chapter we will discuss the mechanics of
Rusts testing facilities. Well talk about the annotations and macros available
to you when writing your tests, the default behavior and options provided for
running your tests, and how to organize tests into unit tests and integration
tests.