Welcome Guest, Not a member yet? Register   Sign In
Unit Testing with TOAST - basic implementation
#1

[eluser]mthomas9[/eluser]
I'm just getting into learning about unit testing, and I could really use some clarification on basic implementation.

I'm using codeigniter for my project. I have read several books and forum posts and think I have settled on using TOAST for unit testing.

What I'm having a hard time wrapping my mind around is how to setup tests for existing controllers/methods on my site.

Every example that I've seen does not address to this. For example, the TOAST usage example:
Code:
require_once(APPPATH . '/controllers/test/Toast.php');

class My_test_class extends Toast
{
    function My_test_class()
    {
        parent::Toast(__FILE__); // Remember this
    }

    function test_some_action()
    {
        // Test code goes here
        $my_var = 2 + 2;
        $this->_assert_equals($my_var, 4);
    }
}

That's great.. but say I have a controller that pulls "users" from my database. For example...
Code:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Home extends CI_Controller {
    
    function __construct()
    {
        parent::__construct();    
        $this->load->model('users_model');        
    }
    
    function index()
    {
        $users = $this->users_model->get_all_users();
                if ($users->num_rows() == 0) {
                         return false;
                }
                $this->load->view('home_view',$data);
    }
}

I assume that a logical test would be to make sure that the information is actually being pulled from the database?

I'm also assuming that I would just include the class into the test and create a new instance of it? Something like this...
Code:
require_once(APPPATH . '/controllers/test/Toast.php');
require_once(APPPATH . '/controllers/home.php');

class My_test_class extends Toast
{
    function My_test_class()
    {
        parent::Toast(__FILE__);
    }

    function test_some_action()
    {
        $this->home = new Home();
        $backup = $this->home->backup();
        $this->_assert_true($backup);
    }
}

Or is it necessary to completely re-create the controllers for each test?

I guess I really just want to make sure I'm on the right track before I start to move forward... Thanks Smile
#2

[eluser]toopay[/eluser]
Unit test allow you to have some "measurable environmental" of your application.

It's really not 're-create the controllers for each test', but make measurable environmental to all possible input and inspect result for that.

It's seems simple, and (maybe for now) useless. But dont get it wrong. If every controller had it's own unit testing ,then when you make some change, in a future, the unit testing will help you to assure that the changes isn't break the rest of your code.
#3

[eluser]mthomas9[/eluser]
So would you be able to give an example of how I would test that the $users variable (from the example I gave above) was pulling from the database correctly?

I would set up a "measurable environmental" to test that?

Or is this something that should not be tested with unit testing at all?

Thanks for your help....
#4

[eluser]toopay[/eluser]
Suppose you have some result from database like this
Code:
array(3) {
       ["id"]=> string(2) "13"
       ["name"]=> string(4) "user"
       ["email"]=> string(15) "[email protected]"
}
Then in some controller, you use it like this
Code:
$user_email = $result['email'];
It's a good thing to have unit testing like this...
Code:
// I assume you've already set TOAST properly
// and load some_model in some_test constructor!
$user = $this->some_model->some_function('some_username');
extract($user);
// Add some true stuff
$this->_assert_true($id);
$this->_assert_true($email);
$this->_assert_true($name);
// Add some impossible stuff
$this->_assert_false($daddy_birthday);
$this->_assert_false($mother_name);
Above ilustration unit testing file, means the result from database must have 'id','email' and 'name', and not contain impossible field. If you run it now, it should working fine (i attached the result).

Now, imagine, somehow in the future you rename 'email' field to 'email_user', on your database. That will be break the code, and give you several hours just to identify where is that crap...but...Uh-Oh, because you have unit testing covering your controller, it should be easy to you to know which part of your code needs to modify in order to fix that change.
#5

[eluser]mthomas9[/eluser]
That is extremely helpful. Thank you!

And if you were inserting into a database. Would you test that? And then delete the insert after the test has proven successful?
#6

[eluser]toopay[/eluser]
Yep.
#7

[eluser]mthomas9[/eluser]
Awesome.. good to know I'm on the right track. Thanks Smile
#8

[eluser]toopay[/eluser]
Happy coding then. :coolsmile:
#9

[eluser]Bogsz[/eluser]
What if in your controller you called two models which returns data from database. And that data you got from model is being processed in the controller (i.e merge the data, add some values)

My point is, i want to test the final result of the controller and not the model

Like this example :
Code:
class Home extends CI_Controller {
    
    function __construct()
    {
        parent::__construct();    
        $this->load->model('users_model');        
    }
    
    function index()
    {
        $users = $this->users_model->get_all_users();
                if ($users->num_rows() == 0) {
                         return false;
                }
        $users_2 = $this->users_model->some_users();
                if ($users_2->num_rows() == 0) {
                         return false;
                }
        $data = array_merge($users, $users_2);

        $this->load->view('home_view',$data);
    }
}

I want to test the content of $data..
How would I do it?
#10

[eluser]Mistry007[/eluser]
hi .. I am also want to test my controller method .. Can any one tell me how to do that..
I have implemented model testing. and it works fine. but i want to implement controller method testing. because crud operations is just fine for testing in model. but the business logic is on controller method. so want to test the controller method. I am using toast library for tesing.
Can you tell me how to do that ...
Thanks.




Theme © iAndrew 2016 - Forum software by © MyBB