Function-level Black-box Testing
is a method of software testing that examines the
functionality of an application (e.g. what the software does) without peering
into its internal structures or workings (Wikipedia). While it’s
usually done at a system level, I think the most obvious place it should be
used is at the function level. It’s even more efficient if you write tests for
someone else’s code.
Here is how I write unit tests for functions.
If you can’t tell what the function roughly does only by looking at its name, it’s usually because it’s badly named or it’s doing too many things, maybe you should break it in smaller functions. Look at its arguments names. Do they make sense to you? Do you understand what’s the function doing only by looking as its name and its arguments?
You sometimes need to read a function’s documentation if its name is unclear or if it’s a complicated code area. This is your latest chance to understand the function, because in function-level black-box testing you can’t read the code, it would not be black-box anymore. If you understand the function, you can now write tests. If not, you should improve its name, its arguments names, and its documentation, in that order because it’s the order one reads it.
Good unit tests are short, incremental, and test only a specific case. Start
with the simplest. Does the function takes a string? Give it an empty one. Does
it take a number? Give it
null for objects. Then move to more edge
cases: negative numbers, un-trimmed strings, uninitialized objects. Add more
simple edge cases, but only once at a time. Then, combine those edge cases.
Write more complex cases. Never combine two cases you never individually tested
before. After all these edge cases, test the legitimate ones. Again start with
the simplest, then add more complexity and combine cases.