The Order Book has been running for years. Ms. Aydin, the dispatcher, relies on the invoice for Mr. Kowalski's faucet replacement showing, in the end, exactly the amount she knows. In the next module you replace the runtime under the program, the packages and parts of the code. Each of these changes can alter something nobody wanted, and then nobody notices until someone calls.

That is why the safety net comes first. In this lesson you build it for the Order Book, before you change a single line. It consists of five parts: a frozen state, a test copy of the database, tests that record today's behavior, a way to create forms in tests, and a checklist for every step. At the end the program is unchanged (except for two tiny spots) and yet safer to change.

We assume the basics of xUnit (K1, module "Tests", and K2, module 2.7 "Testing on the web"). Here we only cover what is different for a grown program.

Characterization tests: record what is

A normal test describes what a program should do. A characterization test describes what it does today. That is a difference that matters in modernizations, because you often don't know whether a rule is intended or just happened to come out that way. The invoice that Ms. Aydin knows is the result of the program, not of a specification. If the amount changes by one cent, that is a bug for the businesses that work with it, even if the new number would be "more correct".

The procedure is always the same:

  1. You call the code with an input that occurs in operation.
  2. As the expected result you first write down some arbitrary value, and the test turns red.
  3. You read the real value from the error message, enter it, and the test turns green.
  4. You write a comment next to it if the result is surprising.
Normal test Characterization test
Question Does the code do what it should? Does the code still do what it does today?
Expected value from the requirement from the running program
A surprising result is a bug in the code is recorded and decided on later
When it may turn red when the code is wrong when you change the behavior on purpose

An example from the Order Book: The material is charged with a markup of 15 percent and rounded to two places with Math.Round. For 0.30 of material that gives 0.345, and Math.Round without further arguments rounds to the even digit, so to 0.34 and not to 0.35. A person would expect 0.35. The program has been calculating with 0.34 for years, and all printed invoices agree with it. The test writes down 0.34 and marks it as a quirk.