And eventually, we're done. (Part III of 'Yes, you can' series)

In our previous post, the parent class CITestCase was shown, now it's time for the concrete ones.

A Test Case


This class shows very briefly how to define the test case and how to organise assertions.

final class AttemptsModelTest extends CITestCase
{
    private $model;   

    protected function setUp()
    {
        $this->model = new AttemptsModel();
    }

    protected function getLastAttemptTest()
    {
        $ok = true;
        $fixtures = [                                             
            [
             ['msisdn' => '525531783674', 'id_service' => '2210'], // Fixture
             ['id_attempt' => '456'], // Expected
            ], 
            [
             ['msisdn' => '94000000000', 'id_service' => '1930'],
             ['id_attempt' => '103005514']
            ],
        ];
        
        while (($fixture = array_shift($fixtures)) && $ok) {
            // Invoke the real method to test
            $data = $this->model->get_last_attempt($fixture[0]['msisdn'], 
                                                   $fixture[0]['id_service']);
            
            // We perform all the assertions
            $ok   = $this->assertArray($data) && 
                    $this->assertArrayCount($data, 1) && 
                    $this->assertObject($data[0]) &&
                    $this->assertExpected((array) $data[0], $fixture[1]);
        }
        
        return $ok;
    }
    
    private function assertObject($data)
    {
        return is_object($data);
    }
    
    private function assertArray($data)
    {
        return is_array($data);
    }
    
    private function assertArrayCount(array $data, $count)
    {
        return count($data) === $count;
    }
    
    private function assertExpected(array $data, array $expected)
    {
        return array_key_exists('id_attempt', $data) &&
               $data['id_attempt'] === $expected['id_attempt'];
    }

    protected function tearDown()
    {
        unset($this->model);
    }

}

How to execute the test

As commented in my first post, the test has to be executed via http call:

/test/subscriber_events_model/run 
class Test extends CI_Controller
{
    /**
     * Usage: /test/attempts_model/run
     * 
     * @param string $run
     */
    public function attempts_model($run)
    {
        $data = "Usage: /test/attempts_model/run";
        if ($run == 'run') {
            $printer = new HtmlPrinter();
            $test = new AttemptsModelTest($printer);
            $data = $test->run();
        }
        $this->output
             ->set_header('Content-Length: '.mb_strlen($data))
             ->set_output($data);
    }
}

The Html Printer
final class HtmlPrinter implements OutputPrinter
{

    public function printResults(array $results)
    {
        $output = array_reduce($results,
                               function($carry, $e) {
                                  return $carry.$this->displayLine($e['name'], 
                                                                      $e['assertion']);
                               }, '');
        return $output;
    }

    private function displayLine($name, $result)
    {
        return $name.($result ? 
                     ' <span style="color: green;">PASSED</span>' : 
                     ' <span style="color: red;">FAILED</span>');
    }
}

Of course, there are still features to add, eg display a message with the cause of the test that fails, a console printer, etc ...


Conclusion

I hope my point is made about thinking simple and not being afraid of building what we need to keep going. Sometimes, simply it's not necessary to have a full, rich, awesome, fancy framework to work with, we are programmers, we can do it xD.

These series of posts are dedicated to my former teammate and friend Rubén, who built on his own in 1 month, a 6 month time project at our company, using plain C. That was really awesome.

Comments

Popular posts from this blog

Bulk Inserts and the Performance Holy Grial (Part II)

Legacy code concepts II: the Seam Model

Bulk Inserts and the Performance Holy Grial (Part I)