Monday, February 23, 2009

A sidestep into Meetings

I was going to continue on about unit testing but have decided to make this quick little detour about how much meetings suck.

Meetings suck.  That's pretty much the whole post. You will hate meetings with a passion.  Most of the times you get things done and effectively collaborate as a group.  The rest of the time involves people arguing over inane details that do not concern them.

The meetings I am forced to go to typically have nothing to do what I've done or what my project is doing.  They area  a waste of time.  No one pays attention, they either email at their computer or continue working on what they were doing before.  When there is collaboration it can be good but sometimes it is just people not saying anything useful.  They have to voice their opinions about things.

For example I was in a meeting from hell recently.  It was over the discussion over caching all the files I make for my tests or creating them on the fly from a  script.  My point was that I've already made the tests, I don't want to make them again.  Creating a script to create all the necessary files would be some what difficult as I must insure that it is 100% correct to make the existing tests run correctly.  I modify lots of those files in such a manner that takes far too long to do.  Creating all those files takes far too long and increases the wait time before execution of testing can begin.  The files might get messed up as they are created.
The other side claimed that pulling down large files when using "svn checkout blah de blah de blah" will take too long and it clutters up the repository.  And how are we ensuring the existing files are correct.

Well, the test group had to chime in about it wanting to know when their tests would be ready (missing the point completely) and how it will mess up their testing by creating files they would have to test.  The development team (my team) was split over the two ideas and argued with test over something that was interrupting my work.  They never reached a consensus and eventually I will have to rewrite a lot of code.

So while sharing code with the team and everyone has input is a good thing, when it comes down to issues that don't really matter everyone still has input over things that are of no concern to them.

Meetings suck but you still get paid.

Thursday, February 12, 2009

Why Unit Tests Are Awesome

Some background information about me.  I work for a IT company called Crossroads and my job is to write Unit Test in C and perl.  So I theoretically should know something about this topic.

There is a very good reason why the book stresses writing unit tests,  because they do help.  I work on a product called VTS and have to deal with poorly written code that was never intended to ever be unit tested.  The code was written 10 years ago by Electrical Engineers and System administrators who had no idea what they were doing.  Most parts of the code are nearly incomprehensible.  The way it was designed was terrible.  Now you might think that it would be a good idea to rewrite the code.  This doesn't work in the real world.  The team tries to maintain the code while implementing new features.  There isn't time to make the code better and it costs far too much money to do so.  While rewriting parts of the code will destroy functionality of it and break the product and also create new bugs.

So what I do is try to create tests that effectively cover every part of a subprogram, hitting all executable parts, all the branches, take every possible branch and try to return all possibilities.  Like most products, it has calls to outside functions and requires specific data and files.  It is not like the one call to the outside calls a little nice function  that does some small print statements or compute some primes.  No, it runs a 3000 line program, that requires other programs to run first, specific variables set correctly as a result, specific objects to be continuously built before and during execution.  And an large amount of global variables that extend through nearly 16 other programs make it not fun to test effectively.  Then it can run the utility that I'm testing after doing all of that.

This creates a problem.  I don't really care what the thing is doing outside of the utility, or waiting 15 minutes to generate usable data before I can run a test.  So it was decided to stub out or redefine any calls to the outside and falsify them and return false data.  This is the only real way for me to test anything.  Because if I don't, I'm creating functional tests.  I really only want to test the logic of the utility.

So, inside of a the Unit test file, I do a #include of the file I'm wanting to test.  Do a #define on all outside methods and main().  Now I can test.  I create false data (data that I wrote to test the utility, which can be good, bad or just wrong) and feed it through, hoping to hit all statements and hope to get a return code that is expected.  What is important to do first is to try to hit all the returns and get good data back, ensuring that it works as specified.  Then I want to destroy it.  Make it break, make it fail, make it not work.  Only until I do that I can find all of the bugs, increase preconditions and make it more stable.   

I use CUnit to drive the tests, create a suite for each method I test, a Test case for each return expected.  The do the same for trying to fail tests.   The easiest methods to test are the ones that return a boolean value.  Because of this you don't care specifically what it returns and have to match it to an expected value in the asserts.  You can just use Assert() for when it is true, and Assert_False() when it is false.  It defines what you want to return, true or false and no real thinking of what it is returning, just how to break it.

You want to obviously test the functions to ensure they work, but you also want to use Unit Testing to make it fail and identify bugs that you won't think about.  Give your ints a wide variety from the min to the max.  Make your if's fail.  Control how the program works to break it to make it more robust.  It is difficult to test all conditions, you will probably create tests that never intended the thing to run like that, create bugs that won't ever run due to weird data.  But if you are working on code that is low enough, this must be done because the programmers working on the high level stuff can easily pass in bad things continuously unknowing.

Next week: More in depth discussion of Unit Testing.

Thursday, February 5, 2009

Project 2 Primes

Todays Topic:  How to do project 2.

So the current project due in CS 373 is Primes.  It has to deal with how to compute a number from 4 prime numbers by adding them all together.  As discussed in class there are some pretty good ways to do this.  If you took CS 315 with Downing then you might have had to do this problem in java.  The only difference is that now we're not being timed, it has to be used in python and use subversion.  The best way is to start out with a list of prime numbers.

There is a few different ways to get a list of prime numbers.  You could google it  (link: http://tinyurl.com/deehyp) and copy paste that into emacs (or your choice of text editor) then set it up as an array called primes and manually insert commas and remove whitespaces and newlines (\n).  There is another way and that involves computing the primes yourself.  I chose this method since we would need all of the prime numbers slightly past 2500000 since the max number N is 10000000 and can be made up of 4 different numbers.   
Another way to get the primes is to write a loop that will take a number and try to divide it by all numbers that are smaller than it to n/2.  If it can't be divided wholey with integers then it must be prime and then add it to the list.  [Use 2 nested loops to accomplish this]   The other better/faster way is to do the Sieve of Eratosthenes.  (I actually did this in High School yay for me?).  Also wikipedia

Now that you have gotten a list of primes in python (hopefully) the easiest way to get them all out is to do this:  "print primes"   [where primes is you list of primes].  Then just copy all of that printed out stuff and make a global array and paste it in.

To compute the primes Downing suggested this idea.  If the number is even then pick two of the primes are to be even.  If it is odd then pick an odd and then an even prime.  Of course the only even prime out there is 2.

I suggest 4 nest for loops and use the idea above to set the two outer loops to start at those numbers (2 and 2 if even, 2 and 3 if odd). Then just run through the for loops grabbing prime numbers from the list of primes.  You should create a boolean flag for when you find the numbers to easily break out of the loops.  Then print them out. 

However there are exceptions to the summation of 4 primes being the desired number.  If the number is ≤ 7 then the program should print "Impossible.".  Also there might be a few numbers that are not able to compute from a list of prime numbers and should also print "Impossible.".

A few suggestions:
Get a list of all the primes up to 10000000.  It really can't hurt.
Make a big list of unit tests and use high numbers.
Find your list of primes and then submit to subversion.
Ask questions if you need help.

Next week's topic: Unit testing and why it's not annoying.

This is a test do not fear it

Welcome to another Blog for CS 373.   Today's post will be about stuff.  Because stuff is good.  Except when it is free, then it is awesome.






Test Unsuccessful.
ABORT Y/N ?