How to test a scheduling program in php

codeigniter, mysql, php

Solution

This is something that I pondered for quite a while - and then I realized my problem! I was concentrating on time as if it was something I couldn't control and measure. Time is just like any other calculation that happens in our applications. So, time based testing is easy - we just have to change the way we think about it - and how we construct our application.

First off, the number one thing to do is to separate out the current time generation sequence to a method. This way, we can mock this out later (that is, generate our own method that always returns a predetermined 'time' for testing). This can be as simple as something like...

protected function _getCurrentTime()
{
     return time();
}

What is the benefit: in our code, we will call this to get the current time to do calculations. However, in testing, we can always generate the exact same time.

that's important - we can always generate the exact same time, every time.

Now, I'm not entirely certain how to put this into practice in your particular application, but let me explain a 'fake' application - and see if you can adapt it to your specifications.

Ok, first off, we have this method that puts an entry in our database that is a 'reminder' for 3 weeks from now.

this is the old code

public function addReminderToDB()
{
    $this->_executeSQL('insert into mytable values (1,2,date_add(now(), interval 3 week))');
}

So, how do we test this? It's obviously going to be different each time?

Well, let's break it up. This is our new code...

new code

public function addReminderToDB()
{
    $currentDate = date('m-d-Y h:i:s', $this->_getCurrentTime());
    $sql = "insert into mytable values (1,2,date_add('{$currentDate}', interval 3 week))";
    $this->_executeSQL($sql);
 }

Now, when it comes to testing... you can set up your test db. Next, mock out the method _getCurrentTime() to always return an integer that you know. Then, run the addReminderToDB() (it will use that integer you know). Finally, query the datasource to validate the row inserted has the proper values you'd expect.

I know this isn't exactly spot on with what you're asking, but the question is kind of vague too :-/ Best of luck!

Problem

I have a codeigniter app that schedules events for specific dates and times in a mysql DB, sometimes weeks in advance, with another part that will send email reminders and perform other actions when those dates occur. How would one approach time based testing? Is there a testing suite I could use or read about?

Original source