Today, I want to talk about the importance of testing code while you are writing a program because I recently burnt myself by not doing this. I was writing a wave table synthesizer for my CS245 class about sound synthesis. The assignment was really just a conglomeration of previous assignments with a little extra work involved. I started off by figuring out how I wanted to be able to represent the 16 channels a wave table synthesizer can have. A simple vector of vectors is what I chose. Then I just dove in and began writing how all the sounds would output with their respective DLS-style ADSR envelopes, velocity, and channel volume. I also wrote this cool piece of code that would remove sounds that had finished playing by swapping them with the end of their vector and popping the back off. Keep in mind I had not tested actually playing a sound yet. So when I finally got around to using a circular buffer to play my sounds the result was a very choppy and incorrect result. I took a step back from the code after a while of attempting to debug the problem and realized I could not find the problem and decided to start over.
I was talking to a classmate about how he did the assignment, and he said he just made stuff work in small increments. Of course I realized I had not done that and I really should have. So I restarted the project, but this time I made sure to start off by actually playing a simple sinusoidal sound through the circular buffer first. Then, I moved to playing an actual sound. From there, I just kept adding small portions of the assignment-testing the results each time I added a new piece. I very quickly found what was causing problems in my previous version of the assignment: I was removing finished notes in the code that was supposed to return the sound value for writing to the circular buffer. This caused a very large slow down.
The second version of the code took much less time to develop than the first, partly due to reusing code from the first version, but mainly due to test driven development.
I used this test driven development more recently in a MAT351 assignment that required me to write a quaternion library. First, I wrote what methods I thought the class might need. Then, I stubbed out the methods so they would be incorrect to what they should do. Next, I wrote the unit tests for each method. Test by test, I made sure each one failed and then worked properly by calculating the expected result and seeing if the proper result was returned.
Moral of the stories: Test driven development is a powerful method for writing and testing code to see if it behaves properly.
And here is some food for thought: What do you think will happen if computers become smarter than humans? I think before this happens we will take the route of merging with computers ourselves, similar to cyberbrains found in Ghost in the Shell. This provides new worlds of possibilities for programming, especially for security firms.