Hatena::ブログ(Diary)

A Day in Serenity @ Kenji

2012-01-18

Database Testing of CodeIgniter Application with PHPUnit (CIUnit)

STOP SOPA

This article explains how to use Database Fixtures of CIUnit.

Database Fixtures is the functionality to load prepared data to testing database before running tests.

If you have not installed PHPUnit/CIUnit, it is better to read How to use PHPUnit (CIUnit) with CodeIgniter 2.1.0 first.

Generate Database Fixtures

To create empty fixture files from testing database,

$ cd tests
$ php generate fixtures

Above command creates "table_fixt.yml" in tests/fixtures/ folder. If the file already exists, nothing happens.

In fixtures/ folder, there is "phone_carrier_fixt.yml" already, so remove it and create fixture file.

$ rm fixtures/phone_carrier_fixt.yml
$ php generate fixtures
generating...
phone_carrier *** fixture fixtures/phone_carrier_fixt.yml written.

"fixtures/phone_carrier_fixt.yml" was created. Open it with your editor, you'll see empty fields:

1:
    name: 
    txt_address: 
    txt_message_length: 

2:
    name: 
    txt_address: 
    txt_message_length: 

3:
    name: 
    txt_address: 
    txt_message_length: 

Add your data into the yaml file, and the fixture file is completed.

"phone_carrier_fixt.yml" contained in CIUnit is like below:

1:
    name: 'Verizon'
    txt_address: '@vzpix.com'
    txt_message_length: 160
2:
    name: 'AT&T'
    txt_address: '@mms.att.net'
    txt_message_length: 160
3:
    name: 'Sprint'
    txt_address: '@pm.sprint.com'
    txt_message_length: 160
4:
    name: 'T-Mobile'
    txt_address: '@tmomail.net'
    txt_message_length: 160
5:
    name: 'Virgin'
    txt_address: '@vmpix.com'
    txt_message_length: 160

If you want to add data with new lines, write as below:

1:
    entry_id: 1
    entry_name: test
    entry_body: |
        This is test.
        2nd line.
    entry_date: '2011-07-25 18:52:33'

Generate Database Fixtures from Table Data

You can create yaml file from table data in testing database, with using "generate.php".

$ php generate.php fixtures

Above command create fixture files in fixtures/ folder. By default, it fetches 5 records. it overwrites existing yaml files.

You can specify how many records do you fetch, using n option below:

$ php generate.php fixtures -n 10

How to use Database Fixtures

$tables property

To use database fixtures, define $tables property in your model test and assign an array with table name and fixture name.

<?php

/**
 * @group Model
 */

class Foo_model_test extends CIUnit_TestCase
{
    protected $tables = array(
        'table1' => 'table1',
        'table2' => 'table2',
    );

Above test file defines to use "table1_fixt.yml" data to table1 table, and use "table2_fixt.yml" data to table2 table. Key of array is table name, value of array is yaml filename (exclude "_fixt.yml").

If you define $tables property, setUp() method in the parent class CIUnit_TestCase class truncates the table and loads the fixture data into the table.

setUp() method is called before each test method runs.

And tearDown() method in CIUnit_TestCase class truncates the table after each test method runs.

dbfixt() method

You can also load the fixture with dbfixt() method blow:

$this->dbfixt(array(
                    'table1' => 'table1',
                    'table2' => 'table2',
                   )
             );
$this->dbfixt('table1', 'table2');

Above two examples mean the same, truncating table1 table and loading table1_fixt.yml data, and truncating table2 table and loading table2_fixt.yml data.

Related

rubdottocomrubdottocom 2012/02/14 02:13 I was wondering what can I do if my database has Foreign Keys because MySQL can't truncate tables with FK's :-S

Kenji_sKenji_s 2012/02/14 08:27 If you have a database with foreign keys, the order of tables to truncate is important.

CIUnit just reverse the tables order, but probably your definition does not fit it.
See dbfixt_unload() method in CIUnitTestCase.php.

rubdottocomrubdottocom 2012/02/14 20:21 Thank you!

I tried about the order and the reversing without success, I think that my schema is well designed :S, I have an intermediate table "Table_AB" that has FK's to Table_A and Table_B, Table_B is a table with master data (data that never changes) and a row from Table A can be related from none to many Table_B rows. Truncate error appears even when tables are empty. Truncates from phpmyadmin fail too :-/ I search about it and seems to be a SQL Restriction: you can check theses responses at StackOverflow: http://stackoverflow.com/questions/1499568/truncate-all-tables-most-of-which-have-constraints-how-to-temoprarily-drop-th http://stackoverflow.com/questions/5452760/truncate-foreign-key-constrained-table

I did a little modification to CIUnitTestCase.php to disable constraints during truncates :-)

投稿したコメントは管理者が承認するまで公開されません。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証