This post originated from an RSS feed registered with Agile Buzz
by Keith Ray.
Original Post: Filters
Feed Title: MemoRanda
Feed URL: http://homepage.mac.com/1/homepage404ErrorPage.html
Feed Description: Keith Ray's notes to be remembered on agile software development, project management, oo programming, and other topics.
I once needed to make three "filters" works. They each took an image
file and several parameters as input, and produced an output PDF file.
For most manual tests for various parameter settings, they did not
produce correct output. So I refactored the big filter function to do
the filtering in two steps (two subroutine calls).
The first subroutine works on the parameters to compute the values
needed to be passed into the image processing library, and the second
subroutine calls the image processing library with the input image,
those computed values, and produces the output image.
Then I wrote a parameterized unit test that took all the parameters as
input to the first subroutine, also took into expected output values,
and asserted that the actual output values were equal to the expected
output values.
Then I wrote 900 one-line unit tests to this parameterized unit test
with the various permutations of the input parameters and expected
output values. (I actually worked in a spreadsheet for a while and
copied-pasted from the spreadsheet to the unit test source code.) The
test would also generate the output PDF file, which I could visually
examine
About 80% of the tests failed.
Then I started working on the first subroutine to fix its problems. I
got to where only 60% of the tests failed, then only 50%, 30%, 25%,
10%, the only 2 failures, and then 100% passing. Sometimes a change
causes more tests to fail than before, and I could examine my latest
modification and fix it, or undo it to try something else.
That was the first of the three filters.
The other two were similar, but with fewer parameters and options,
each of those only needed about 600 one-line unit tests. Note that I
didn't test EVERY combinations of options and settings. That would
have required several billion test cases. By making an intelligent
selection of the "input space" I could exercise the filter algorithm
along all of its dimensions with a minimum of effort.
Fixing all three filters with the aid of automated tests only took a
few days each. Trying to make the algorithm work with manual testing
would have taken months or years.