I suggest starting with creating a component that calculates position and orientation, given the sequence of control inputs. This component then represents a “unit” for testing purposes. In the test examples for this component, all scenarios that you can imagine will be considered: zero acceleration, constant non-zero acceleration, pulse acceleration commands, etc. If the application does not need speed, then the component will not reveal any functionality related to speed.
When generating the expected results for inclusion in the tests, it is important to have high confidence in the correctness of the expected results. For this reason, it is necessary to minimize the amount of code needed to generate the expected results. In particular, if you find yourself writing test forests that are almost as complex as the component under test, then the problem of errors that occur in the tests becomes a serious problem.
In this case, I would generate test data directly from the equations of motion. I use Mathematica for this purpose, since I can directly enter equations, solve them, and then generate graphs and result tables. The graphs allow me to visualize the results and thereby have the confidence that they are reliably correct. Excel / OpenOffice / Google Apps can be used for the same purpose, as well as open source alternatives for Mathematica, such as Sage. No matter what one chooses, the main problem is to be able to solve equations of motion without having to write non-trivial code.
Once we have a good set of test cases along with the expected results, we can create unit test code. Please note that the test code is very simple without performing any calculations. It simply compares the component result with the hard-coded results we got earlier. Having test cases, we can write the component itself, adding code until all the tests pass. Of course, in strict TDD, these actions occur in that order. I admit that I personally do not stick to the waterfall and, as a rule, refuse to create test data, write tests and write component code.
Mathematica or Excel documents themselves have a useful life beyond the initial creation of tests. They can be used again when new functionality is added or (sky ban) if errors are found later. I would protect documents like source code.
At the end of this exercise, the result is a "bomb-resistant" component, which we have seen will calculate the correct position and orientation for the object under any given set of control inputs. From this foundation, we can build additional components that use this functionality, such as ships, asteroids, plates and snapshots. To avoid a combinatorial explosion of test cases for each component, I would abandon a rigorous approach to black box testing. So, for example, if we tested the ship component, we will write tests, knowing that it uses the position / orientation component. Using this knowledge of the white box, we can avoid re-testing all angular cases associated with movement. Ship unit tests can perform “smoke tests,” which confirm that ships actually respond to control inputs, but the focus will be on testing any functionality that is unique to the ship’s component itself.
So, we summarize:
- make position / orientation calculation the responsibility of one component
- generate data for a complete set of test cases using an external tool that gives high confidence in the data.
- Avoid complex calculation logic in the tests themselves.
- Avoid the combinatorial explosion of test cases in the component hierarchy using white box knowledge.