At Akademy today I held a talk about Unit testing of model view components. The talk was well attended and well received, and went without a technical hitch, so thanks to the organizers and chairs for that.
My slides are here for your enjoyment and amusement. The main take-aways of the talk are to inject the object store into your model implementation polymorphically to allow the injection of fake objects, and to implement proxy models generically so that they can be unit tested against fake or easily test-drivable source models. There will eventually be a video of the talk uploaded to the internet I’m sure.
During the demo section of the talk I briefly mentioned a model logging class I wrote which deserves a more detailed description than I could fit into the talk.
The problem with proxy models is, they crash. Sometimes the reason for that is an assert being hit in the class itself, or in an observing class such as another proxy or a view (or something else entirely). Sometimes such asserts are only hit on certain conditions, such as never on the developers computer, and always on the computer of an unfortunate user. A bug which can’t be reproduced can’t be easily fixed.
The solution I came up with was to create a class to listen to to all signals that the model emits and keep track of them. When the application closes or an assert gets hit, the event log is written out as a compilable file. The file can be compiled with a trivial CMakeLists file and should hit the same assert, which the developer can use to reproduce and fix the bug, and which serves as a unit test afterward. The great thing is there is no information leak. The log does not contain the names of the folders in your kmail, or the subjects of your emails. All it shows is a number tree representing the structure of the model. Here is a log created when I started kmail on my computer, and another using a different application.
The logger is very easy to use. It follows the same pattern as the ModelTest class. Simply new the Logger with the class under test as an argument.
new ModelEventLogger(sourceModel, this);