Book 3: For the Developer

For humans, honesty is a matter of degree. Engineers are always honest in matters of technology and human relationships. That's why it's a good idea to keep engineers away from customers, romantic interests, and other people who can't handle the truth.

- Scott Adams, The Dilbert Principle

Real World, The (n.): Where a computer science student goes after graduation; used pejoratively ("Poor slob, he got his degree and had to go out into the REAL WORLD."). Among programmers, discussing someone in residence there is not unlike talking about a deceased person.

Basic Rules of Thumb

All DBI calls should be checked for errors.

All scripts or modules should have "use strict" and preferably "use warnings".

Subroutines should NOT open and close the database every time. The DBI handle (usually $dbh) should be passed as a parameter from the main script running. Opening the DB every time will impose a performance and overhead penalty for large or busy installations, limiting Koha's ability to scale.

Unit Testing

What is unit testing?

Unit testing is a method for verifying that you software does what it is supposed to. The idea is that you have a testing framework (Test::Harness in our case) that will automatically run your tests for you, reporting any failures. You'll then write a series of tests to exercise every function of every module in your program. Instead of boring you with details, let's start with an example.

How do I do it?

I'll start with the Koha.pm module. It contains four functions:

All of our tests should go into the t/ directory, and should be put into a file showing which module we're testing. In this case, we'll create a file t/koha.t to hold our tests. Tests start with a bit of magic to make them work:

BEGIN { $| = 1; print "1..1\n"; }
END {print "not ok 1\n" unless $loaded;}
use C4::Koha;
$loaded = 1;
print "ok 1\n";


This sets up the test, tells the harness that it will be running one test (the 'print "1..1\n"' bit), and ensures that the test can load the module (that would be the first test).

If we run the test now, we'll get:

[pate@gnupate t]$ perl koha.t 
1..1
ok 1
[pate@gnupate t]$


or:

[pate@gnupate koha]$ ./testKoha.pl 
t/koha..............ok 
All tests successful.
Files=1, Tests=1, 1 wallclock secs ( 0.25 cusr + 0.11 csys = 0.36 CPU)
[pate@gnupate koha]$


slashifyDate takes a string representing a (MySQL style) date, replaces '-'s with '/'s and returns it in European style date. We can test it like this:

$date = "02/01/2002";
$newdate = ("2002-01-02");

if ($date eq $newdate) {
print "ok 2\n";
} else {
print "not ok 2\n";
}


We'll also need to let the harness know that we've added a test, so let's change the first line to look like this:

BEGIN { $| = 1; print "1..2\n"; }


Now, running the tests looks like this:

[pate@gnupate koha]$ ./testKoha.pl 
t/koha..............ok 
All tests successful.
Files=1, Tests=2, 1 wallclock secs ( 0.23 cusr + 0.09 csys = 0.32 CPU)
[pate@gnupate koha]$


Then, we can go on and add tests until we end up with something like:

[pate@gnupate koha]$ ./testKoha.pl 
t/format............ok 
t/koha..............ok 
t/output............ok 
t/require...........ok 
All tests successful.
Files=4, Tests=40, 1 wallclock secs ( 1.25 cusr + 0.11 csys = 1.36 CPU)


What needs to be tested?

You don't need to test everything, just the things that can fail.

Ok, so maybe this is overkill. But we really should (and try to) test aggresively. Not only should we right tests for expected input, but also for fringe cases that should produce failures.

Additionally, anytime we fix a bug, we should try to represent it in one (or more) unit tests. That way we can feel comfortable that no one accidentally reintroduces the bug later on.

Who writes the tests?

We do. In fact, it is best if the programmer who sits down to write new code would do well to write some tests first. This way, he (or she) will know they got the code right. It's a tremendously liberating way to write code.

When do I run the tests?

Please, run the tests every time you're ready to check code in! Then fix any errors before you check in. Right now, the tests all pass on the rel_1_2 branch. Let's keep it that way ;)



Using CVS at Sourceforge

Anonymous CVS Access

The Koha CVS repository can be checked out anonymously (via pserver) with the following commands. You must specify a modulename. When prompted for a password for anonymous, simply press the Enter key. This is recommended only for those willing to deal with Alpha and Beta versions of Koha. Do Not use this software on production hardware.

cvs -d:pserver:anonymous@cvs.koha.sourceforge.net:/cvsroot/koha login 
 
cvs -z3 -d:pserver:anonymous@cvs.koha.sourceforge.net:/cvsroot/koha co modulename


Updating from within the directory of the module avoids the -d parameter requirement.

Developer CVS Access via SSH

Only project developers can access the CVS tree via this method. SSH1 must be installed on your client machine. Substitute modulename and developername with the proper values. Enter your site password when prompted.

export CVS_RSH=ssh 
 
cvs -z3 -d:ext:developername@cvs.koha.sourceforge.net:/cvsroot/koha co modulename


Bug Reporting and Tracking

Currently, we are in the process of setting up Bugzilla for bug tracking. More on this later.