Previously on Practical Testing: The last entry ended with us having two tests, both of which were in need to a good refactoring. The second test had uncovered an unexpected bug… This time around we’ll refactor the tests, fix the bug and finally write the test for the tick count wrap bug…
Our new test breaks because the CCallbackTimer is failing to keep the timers in the correct order in its queue.
I’m writing some blog entries that show how to write tests for non trivial pieces of code. This is part 5; the one where we find a bug we weren’t expecting…
[Update: Welcome to anyone who’s coming here from the link on Dans Data there’s actually a freely available program that DOES help you work with the TickCount rollover bug, it’s available on my site here.]
Last time I slipped an interface between our object under test and its source of time.
I’m writing some blog entries that show how to write tests for non trivial pieces of code. This is part 4.
We have a test for SetTimer() but it’s not as robust as we’d like. The problem is that the class under test is runs its own thread which reacts based on time and this makes our testing harder and less predictable. What’s more it actually makes testing for our known bug practically impossible; to test for our bug we’d have to have a test which called GetTickCount() to determine the current value and which then slept so that it could execute the test at the point when the counter rolled over to 0.
I’m writing some blog entries that show how to write tests for non trivial pieces of code. This is part 3.
Last time we wrote the first test. It doesn’t test much, but it proves we can test. Now we’ll write a real test for real functionality and along the way we’ll start to deal with some of the issues that come up when you’re trying to test multi-threaded code.
I’m writing some blog entries that show how to write tests for non trivial pieces of code. This is part 2.
In part 1 I introduced the code that we’re going to write a test for. Now we’ll move towards the all important first test. The first test is, in my opinion, vitally important; the first test proves that you can build a test harness that can create the object. This sounds easy, but try picking a class from your current project at random and writing a test that constructs an instance of that class.
I’m writing some blog entries that show how to write tests for non trivial pieces of code. This is part 1.
The code that we’re going to test is CCallbackTimer. This is a class that lives in our Win32Tools library. It’s used by users of our SocketTools library. The class provides a very light-weight timer manager that gets around the various issues we had with using standard Win32 timers.
The timer is designed to be used in vast quantities.
One of the common complaints about TDD and unit testing that I see is that the examples used aren’t real. People often say that the examples used are toys and that writing such tests adds little or no value. To be honest, I often find myself agreeing with them.
Last updated 25th April 2023
41 - GoogleTest - Moving to GoogleTest.
One of the problems of adding unit tests to an existing code-base or driving a new project with TDD is deciding exactly where to spend your testing efforts.
I’ve spent the past month or so helping a corporate client improve code quality in a sprawling application. It’s non-trivial, the code-base is huge, the quality is, at best, questionable and the coupling is excessive and made worse by the fact that much of the system is coupled together using a single huge blob of relatively unstructured XML. Fun, fun, fun…
As with the refactoring project, the first tests have taken some time to build.
Today I’m doing some work for a client that involves writing some blocking sockets code to talk to one of our servers. Blocking mode fits well with the architecture of the client application they use; we’re moving the app from blocking reads on a serial port to blocking reads on a socket and jiggling the protocol it uses a bit.
Testing blocking calls is actually a bit harder than testing non blocking calls because hand cranking the mock objects so that your object under test works correctly is harder to do when your test harness is blocked in a call to read() and wont come back to you until the call times out (and the operation that you’re trying to test fails) or the read completes…
A while back I finally started on the async version of the POP3 client. It ended up as a state machine and seemed to work well. The next step was to write an async version of the mail collector that I used to pull all mail from a mailbox on a server and optionally delete it.
The synchronous version of the mail collector is a fairly simple thing. You pass it the mailbox and server details and it decides how to log in; it uses APOP if the server supports it and USER/PASS if it doesn’t.