1/26/2006

Chicago Ruby Meeting - Marcel Molina and Testing

I'm really excited about this Ruby meeting ...
--
Great news! Spread the word!

Our February meeting will be quite a treat. Marcel Molina, one of the esteemed Rails committers and member of the 37signals crew, will be speaking about Ruby's test/unit library and its use in testing Rails applications.

Marcel has some excellent insights and recently taught a course at the Big Nerd Ranch, so come with your learning hat on.

ThoughtWorks is graciously providing pizza and pop, so please RSVP so they can get a good headcount:

http://ruby.meetup.com/55/events/4824278/

We'll be working through a coding exercise or two, so bring your laptop if you can.

February 6, 6:30 pm
ThoughtWorks, Desplaines and Washington in Chicago
Map

Directions:
Take the Washington exit off of 94/90. We are at the corner of Desplaines and Washington.

The building entrance on Desplaines will be open until 7. The elevators will be on until 7 as well so that people can get to the 6th floor. After that, please feel free to call Joe at 614/906-1394 and he'll have someone get you.

If you have any questions or concerns, feel free to shout out to the list. We're on it and certainly you aren't the only one with the question.

Hope to see you there! Bring a friend!

Everyone, please post this announcement anywhere where people might like to hear about this event.

Response to Test Freak.

Update: Chris Shiflett posted an informative reponse on Test-More for PHP and testing in general

I started responding to the comment to my last post, then realized it was going to be long. So I put it in a post.

Thanks Damien Gilles, I have looked at that. Problem is, I have some resistance at work to using outside code. So I would need to work up a case for it beforehand and analyize it.

For really simple tests, this sort of testing (my friend Keith calls it Sanity testing) works fine. I don't really see the need to use a Unit Test framework. I have used PHPUnit before and it works fine, but ends up being just more typing (I think, but I'll try it and compare my results).

Here's an example of how I used it..

include_once("config.php");
include_once("User_Model.class.php");

$t = new Test_Simple(array("tests" => 20, "eol"=>"\ n"));

connect_db();
test_setup();

// Test object get/set methods
$user = new User_Model();
$user->setUserName("jdoe");
$user->setRealName("John Doe Test");
$user->setEmail("john@doe.com");
$user->setPermission("1");

// test true values
$t->ok( $user->getRealName() == "John Doe Test", "get RealName" );
$t->ok( $user->getUserName() == "jdoe", "get UserName" );
$t->ok( $user->getEmail() == "john@doe.com", "get Email" );
$t->ok( $user->getPermission() == 1, "get Permission");

// test false values
$t->ok( $user->getRealName() != "Susie Doe", "Not Realname Suzie Doe" );
$t->ok( $user->getUserName() != "sdoe", "Not Username sdoe" );
$t->ok( $user->getEmail() != "suz@doe.com", "Not email suz@doe.com" );
$t->ok( $user->getPermission() != 0, "Not Permission 0" );

// Save user
$saveResult = $user->save();
$t->ok( $saveResult == true, "Save was successful");

// Get ID of last user
$id = $user->id;

// clear object
$user = null;

// load user again and test again
$user = new User_Model($id);

// test true values
$t->ok( $user->getRealName() == "John Doe Test", "get RealName after load" );
$t->ok( $user->getUserName() == "jdoe", "get UserName after load" );
$t->ok( $user->getEmail() == "john@doe.com", "get Email after load" );
$t->ok( $user->getPermission() == 1, "get Permission after load");

// change username
$user->setRealName("Mary Jane Test");
$user->setUserName("mjane");
$user->setEmail("mary@jane.com");
$user->setPermission("2");
$updateResult = $user->save();

// test true values
$t->ok( $updateResult == true, "Update was successful");
$t->ok( $user->id == $id, "ID stayed the same");
$t->ok( $user->getRealName() == "Mary Jane Test", "get RealName after update" );
$t->ok( $user->getUserName() == "mjane", "get UserName after update" );
$t->ok( $user->getEmail() == "mary@jane.com", "get Email after update" );
$t->ok( $user->getPermission() == 2, "get Permission after update");

$deleteResult = $user->delete();
$t->ok( $deleteResult == true, "Delete was successful");

test_teardown();
$t->report();


// Clean up our mess before and after
function test_setup() {
connect_db();
$result = mysql_query("DELETE FROM users WHERE real_name like '%test%'");
}

function test_teardown() {
connect_db();
$result = mysql_query("DELETE FROM users WHERE real_name like '%test%'");
}

I did do a test_setup and test_teardown, similar to what you would have in a unit test. I only need to do this at the start of my "suite" and the end.

Of course, the main reason there's a test more (copied from Perl) for php is so you can use Perl to run the test suites. See this presentation by Geoffrey Young and Chris Shiflett on Power PHP Testing(tgz file) which, if you have a site with mixed PHP and Perl, would be a excellent way to test all your code with the same method.

1/25/2006

Test Freak!

My two loyal readers know I like testing. Some say I'm sick.

I'm writing a PHP class for a user, and then think.. oh gee, how do I know if this works?? oh I'll write a Test::Simple for PHP. Yes, I know there exists one already that uses the power of Perl to test PHP files, but I didn't have time to figure out how to set that up and probably won't be able to use perl anyways on the production system. I can't stand to have global variables, so I made a class. Uber simple. There's probably better ways to do it (I can imagine something much more elegant in PHP 5). But, what do you expect on a whim and 40 minutes...

Code:

// Nola's Wanna Be PHP Test Framework

class Test_Simple {
var $tests_to_run;
var $success_count;
var $failure_count;
var $test_count;

function Test_Simple($params) {
if (isset($_SERVER['HTTP_HOST'])) {
// we're on a server use a

$params['eol'] = "\ n "; //take out spaces, had to have them for this blog
}
$this->tests_to_run = $params["tests"];
$this->eol = empty($params['eol']) ? "\n" : $params['eol'] ;
$this->success_count = 0;
$this->failure_count = 0;
$this->test_count = 0;
print "1..{$this->tests_to_run}{$this->eol}";
}

function ok ($expression, $message) {
$this->test_count++;
if ($expression == false) {
print "not ";
$this->failure_count++;
} else {
$this->success_count++;
}
print "ok {$this->test_count} - $message" . $this->eol;
}

function report() {
print $this->eol;
if ($this->test_count <= $this->tests_to_run) {
print "You ran {$this->success_count} out of "
. "{$this->tests_to_run} tests " . $this->eol;
} else {
print "Opps, looks like you meant to run {$this->tests_to_run} "
. "tests but ran {$this->test_count} instead" .$this->eol;
}
print "Success Rate: "
. (($this->success_count *100)/ $this->test_count)
. "%".$this->eol;
}

}

And.. I made some code to test itself..

$t = new Test_Simple(array("tests" => "4"));

$t->ok($t->test_count == 1, "one test run");
$t->ok($t->tests_to_run == 4, "running 4 tests");
$t->ok($t->eol == "\n", 'end of line is \n');
$t->ok(true, "its true!");
$t->ok(!false, "its not false");

$t->report();


I will probably make improvements upon this... suggestions? .. my test "report" is a bit more verbose than the standard Test::* in Perl.

I made it so you can run it with the php executable ... or with the web browser.

I tried to install Perl's class Apache::TestRunPHP but had a few problems getting it setup on windows. I think I need mod_perl installed on my Apache. I did find out that it takes a different approach than my simple class, and starts apache, runs tests, prints report and shuts down apache. Interesting. My tests I only intended to run individually (actually didn't know how TestRunPHP worked till after I wrote my class).

1/21/2006

See what happens ...

when you don't keep your big mouth shut (and leave before meeting is over)?

Email sent to PHP Group after meeting:

At the end of our meeting Wednesday, several Topics / Speakers were planned out for coming months.

WED FEB 15 Sara[h?] | Smarty
WED MAR 15 Rich | PHP5 SOAP
WED APR 19 Nola | We volunteered you to talk about, ummm, something you seemed to know a lot about at the meeting that I forgot already...

Sara[h?] e back so I can spell your name right on the website.

Anybody remember what we volunteered Nola to do?

Is Nola willing?

Yes.... Nola is willing. I was talking about XmlHTTPRequest, AJAX and the Prototype library.

1/05/2006

One thing

Learned something today... if you ask a question relating to programming and you are in a chat room where that particular thing is not the main topic of discussion to prepare to be made fun of. Good to know.

1/04/2006

Get it? Set it? Good!!

I don't know where this idea settled into my little head, probably back in college. I sold practically every book from my college days, keeping only a few books (For anyone who had a blue book by Blum with a picture of driftwood on it for Software Engineering, you have my sypathies. Can't believe its still $97 bucks) so I can't look back to see if any of my classes was the culprit (could it be java? it sure wasn't assembler!). I have always defined get/set methods for my classes with get/set in the name.

class Card {
var $name;

function set_name($name = "") {
$this->name = $name;
}

function get_name() {
return $this->name;
}
// etc
}


I've seen some people do this:

class Card {
var $name;

function name($name = "") {
if (empty($name)) {
return $this->name = $name;
} else {
$this->name = $name;
}
}
// etc
}


Using the same method for getting or setting, the deciding factor is if a parameter is passed.

I mentioned this in a Codesnipers post about how Ruby does get/set for attributes. Caleb Tennis showed a way I could customize the get/set methods of Ruby so it DOES allow you to do getName or setName.

My recent language crush is Perl, and I've seen many modules doing it the second way.

But "name" isn't a function so I don't really like doing it the second method. But is it an "okay" convention that I should wave a white flag and accept? I guess I could look at it this way, if a function name is just a noun, then it’s for an get/set method, if not then it’s a regular method.

Should I change my mind on this? what do you do?

Article about Selenium

I posted an article about Selenium over at CodeSnipers.com .. check it out, its a very cool tool :)

Oh and fortune cookie for yesterday was:

He who enjoys doing and enjoys what he has done is happy.

I enjoy programming ... and looking back at some my of code I wrote -- I'm not happy. But I'm getting better everyday. :)

1/02/2006

Beware of the violent psychopath




Reading this right now at Safari ...
Talking about coding style, readablity etc.

Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.

Hahah.. I love that.


Fortune Cookie

To make up for going to the gym for 1.25 hours today (ever see anyone reading a perldoc print out on her lap while doing the chest press?), I went and got a container full of yummy food at the chinese buffet (and divided my booty in 3 contains, so now I have lunch the next two days as well, all for only $8). My fortune cookie for today said:


If you don't program yourself, life will program you.


Funny I would get one relating to programming. hehe

Brand New Year

Happy 2006!! I can't believe it’s a new year already! Here's how I spent the last few days of 2005 and first day of 2006.

Background
When I was in college, around 1999 my co-worker did some Perl to process forms and email the data. I was more of their graphics person. He hated it, I'd say.. Oh Jayson! I have another form for you! I don't know if he disliked Perl so much or processing forms is just a boring task (I agree now). I dabbled a little in Perl but thought it was difficult and obsecure. I thought Perl geeks wrote it so they could boast about how clever they were because their code did X function in ONLY 25 characters! NYAH! Then I happened to find PHP, learned it, did a site for my then boyfriend (now husband) and that got me a job as a PHP programmer and like a horse with blinders, pretty much just did PHP (and JavaScript) until this the second half of this year, err last year.

I've been learning (re-learning? I don't know how much Perl I really knew at any one time) I've made some friends who are Perl programmers (Andy Lester and Liz) and they aren't like that at all, although they tell keep telling me that Perl is the "One True Language". Even the folks in the chatterbox at PerlMonks.org have been very nice in answering my noob questions.

I'm digging Perl. Once you get through "The Gory Details" in Programming Perl aka The Camel Book.

Goal
Maybe I'm a strange person, but I like testing. I've been working with Selenium to write tests for DotProject. Watch for an upcoming article on it at CodeSnipers.com this week. Andy Lester has a project called Phalanx which has the goal of getting 100 or so Perl modules with complete tests and documentation. Since I don't have any grand idea of a module that doesn't already exist in the 9283 modules in CPAN, I thought hey if I can help with testing a little bit than I can contribute in some tiny part.

Tools
Test::More - a uber simple test mod which should work for test in most cases. I asked Andy Lester if I should be using Test::Unit for testing a module (in PHP I would use PHPUnit) but he said that Test::More is all I need.

POD::Coverage - a mod that compares how much POD (plain old documentation) is in the module. Its good to have each subroutine documented (called "covered" as a opposed to "uncovered") and gives you a percentage, 100% is good. It will also list the subs that are uncovered. There is a way to set it to skip certain subs (private subs for example). You can run the POD::Coverage as part of the Test::More suites as well. Nifty.

Devel::Cover - a mode that checks your code coverage. I couldn't get this to work, since this is not compiled for windows and my Perl version on my server is a few points behind. Looking at the docs, it can check the statements, branch, condition, path, subroutine, pod and time. Was not able to find out too much about how it works it since I can't get it to run. This module is in alpha stage at this point, so I'm sure more information will be available soon.

I also made my first module, which was just a simple class I stole from an example. I couldn't get my module to run, so I went to PerlMonks.org and asked them. The said OH, you have your code after the __END__ it should be before - doh - So once I did that, it was fine.

Well, that’s about it for now.