Tuesday, October 16, 2012

Unit Testing with Structural Coverage


I don't love spending time testing, so I try to make the best use of my time. I write Unit Tests when I can, and automate any other testing if possible. Sometimes I try to even make writing tests easier on myself by using some techniques I picked up from The Pragmatic Programmer: From Journeyman to Master
Side Note: If you haven't read this book, stop what you're doing, go buy it, rent it from a library, borrow it from a friend I don't care, READ IT, LEARN IT. It's one of the best books I've read about software development hands down, lots of good ideas to improve your craft.

Unit Testing

Unit Testing code is helpful for looking at code you've written in a very controlled environment, you know the inputs and outputs, and being able to duplicate your results should be pretty consistent and easy. Often times this testing puts a single function or procedure through the paces, but depending on what level you are will determine what number of units will be involved.

Primer

After writing some code a few months back, I created what I thought were some good Unit Tests for it. They all passed in the end (and before they did, we found some issues when they weren't passing) which is great. The change got closed and merged into the baseline. I thought I had made a good attempt at ensuring that the software was solid. For the data I used I agree it is solid. Then a bug was found. I hadn't tested every case (even though I thought I had). What would have been a huge help is to have simply combined Structural Coverage with it.

Structural Coverage

Structural coverage is attaching special code to test for running through each path of your code. This is helpful for simply ensuring you've tested each route. This isn't a substitute for proper testing. I'll say it again. A structurally covered program is NOT a bug free program. It's simply a program that has been proven to work as expected for a (pseudo) normal scenario on each path encountered.

Combined Testing

By combining Unit Testing and Structural Coverage, you can prove that the Unit Tests at least are checking each case once. I have since re-ran the unit tests with Structural Coverage, and guess what? I missed a few paths, this didn't explain my particular problem, however it made it easier to see other possible problems I may have in the future. I have since added some unit tests and have made sure that my Unit Testing at the minimum covers each case.No program is bug free, but all we can do is analyze and pick the Unit Tests that we as Engineers believe will cover what's necessary.


If you don't do Unit Testing where you work, I highly recommending starting to do it on your own. From the start make it as easy to setup and run as possible, this will make sure that you will use it, and that your colleagues will use it. Additionally, look for opportunities to make the unit testing automated. If your unit tests run on the system everytime a build is ran, any bugs introduced in those pieces of code can be found quickly. This keeps you from violating the DRY principle, forcing yourself to repeat yourself testing it over and over. OR trying to fix the same thing multiple times because it's not caught at the right time.


Good luck!

Monday, October 8, 2012

Christmas Lights

Description
I finally got fed up. We bought a Christmas light "timer". This thing would do essentially 3 functions, the first was simply turning the outlet on, the second to use a photo sensor and turn off when it's light outside, and the final was a set number of hours (there being anywhere from 1 to 8 hours).  
The Problem
The problem with the hours one is that you have to manually turn it to off, then back to the number of hours you would like. This is frustrating. The photo sensor would seem like a neat idea, however when you don't get good lighting where the photo sensor is, you end up with Christmas lights on all the time. I (and in part due to my wifes request) decided this had to be rectified. 
Attack Number 1
My first run at it was to simply solder onto the point where the timer is on, and try to set and clear the 4 hour timer (but since the system needed to go back to off, then back to on, this failed miserably). 
Attack Number 2
Then I realized that the photo sensor should handle the turning off and on automatically, and I wouldn't need to turn it all the way off. I decided to remove the photo sensor, and put a pair of wires in there and a relay instead. Now the fun part. I have a PIC16F684 that I decided to control this with. With a multimeter I tested putting the photo sensor under the light in my room, when it was under direct light, the resistance went up really high, when I covered it, it seemed to reduce to a low amount of resistance. My guess is that I can put a resistor in line with the relay and whenever there is a high amount of resistance it turns the system off. When the resistance is low it turns the system on. Essentially what I needed was my microcontroller to activate my relay for 4 (or so) hours then turn it off. Then 24 - 4 hours later, it would attempt to turn on the relay again. If I can get this working on a short run, I.E. 10 minutes on, then 2 hours off, then 10 minutes on. I may consider putting in a pseudo random number into there, so the lights are on somewhere between 3 and 7 hours.
Unfortunately I plugged it in, tried shorting the pins for the photosensor (hoping it would activate the lights), well it didn't seem to matter whether the wires were shorted or not, the lights just stayed on.
Final Solution
I finally actually did what any smart engineer* should do. I took a look at what was already there. I saw 2 chips the first was a LM393 a dual voltage comparator. And the second was a programmable timer. JACKPOT. (Here it is for those of you interested: cd4541be). Looking at the datasheet I see there is a master reset line. I tested it out by turning the system on for 1 hour, then when the lights turned off, I simply tapped 3.5 volts to the MR line and bam lights were on again. I now have my "in".

On to the Microcontroller
I decided to use my Pic 16F684, I have a smaller one (can't recall the number at the moment), but I didn't have time to make sure my code ported smoothly as well as verify the timing. I did a couple tests using a couple nested for loops for a wait (I know, I know, I could have used a timer interrupt, and in fact i would like to go fix this, but I didn't have a lot of time to mess around with this and well, hey it was a hack)
So after some timing, I simply put an initial wait in there to get it to hold off to about 7pm from when I plugged it in, and then set the timer to 4 hours. The lights turned on for 4 hours, then a few hours later 7pm hit, and bam we have light.

However over the long term the timing was off for sure, when I got back from vacation it was definately wrong, I'll have to play with it this christmas again!

*Smart engineers keep things simple, and just using a reset line is MUCH simpler then the previous methods I tried.