2011-01-03 14 views
10

私はPHPunitを使ってユニットテストに少し集中しようとしています。データベースを使ったPhpunitテスト

私はここにhttp://blog.nickbelhomme.com/php/phpunit-training-course-for-free_282

上で非常に良いチュートリアルを発見した。しかし、私は欠場し、まだ行う方法を理解していないものがあります。

私はユーザーに関するすべての情報を管理するユーザーモジュールを用意しています。そして、ユーザーをデータベースに保存する関数saveがあります。だから、私はtestFunctionを持っています

public function testCanCreateUser() 
{ 
    $userData = array(
     'userName' => 'User1', 
     'firstName' => 'Joey', 
     'lastName' => 'Hendricks', 
     'email'  => '[email protected]', 
     'password' => 'f$tfe8F' 

    ); 
    $user = new Model_User($userData); 
    $user->save(); 

} 

私は初めてこのテストを実行します。データベースが空であるため。しかし、2回目のテストを実行すると、私のシステムでは同じユーザーがdbで2回使用できないため、動作しません。ですから、これを行うには、テストを実行する前に毎回テストデータベースを再作成する必要があります。これを行う最善の方法は何ですか? この問題は別の方法で解決されますか?

Tnx。

答えて

21

あなたのビジネス・ロジックをテストする場合:あなたは、SQL文(そして、あなたは可能性が私見を発射するクラスをテストする場合は、データベースクラスをモックを離れや偽のデータ

を返します(

  • セットアップを使用して:それは少し複雑になります)私のコードは、バックエンドでの実際のデシベルで正常に動作している場合、私はちょっとたくは知っているので、あまりにもそれをテストするが、それを行うための方法があります)とtearDown()を使用して、テストを実行する前にデータを一貫性のある状態にすることができます(imho)db-driven unittestを作成する上で最適な方法です。しかし、手作業でたくさんのカスタムSQLを書こうとすると迷惑になることがあります。

  • あなたのライブをより簡単にするには、DbUnit extensionを調べて、それがアプリケーションに適しているかどうかを確認してください。

  • あなたが本当には単体テストデータベースとの対話に主体で最高の読み取りをダイビングしたい場合は、(私見)Sebastian Bergmanns phpqa bookでDB-単体テストの章です。

  • アプリケーションでカスタムデータベース名とすべてのテーブルの自動セットアップが許可されていれば、多くのテストデータで一度dbを設定し、そのデータをすべてのテストで使用することもできます。 1つのテストが別のテストによって書き込まれたデータに依存していないにもかかわらず、注意深くできるかもしれません。

+2

Sebastion Bergmannsの本にはまだ記事がありません。しかし、それは複雑なものです。 – sanders

7

setUp()またはtearDown()の方法で空であるか、またはクリアされたデータベースの他のコピーでテストを実行しますが、何も実行しないように注意してください。github did

あなたが良いデータベース(MyISAMテーブルとすなわちないのMySQL)を使用している場合は、トランザクションでテストをラップし、試験後、それをロールバックすることができます

function setUp() { $this->db->exec("BEGIN"); } 
function tearDown() { $this->db->exec("ROLLBACK"); } 

欠点は、あなたができないということですトランザクションを使用するテストコード(それを抽象化してセーブポイントでエミュレートしない限り、iffy)

理想的には、偽のデータベースクラスに依存性の注入と実行テストを使用する必要があります。

$fakedb = new DatabaseThatDoesntReallySaveThings(); 
$user = new Model_User($fakedb, $userData); 
$user->save(); 
$this->assertTrue($fakedb->wasAskedToSaveUser()); 
2

私はあなたが保存したデータをきれいにするtearDown()メソッドを使用することができると思います。

protected $_user; 

public function testCanCreateUser() 
{ 
    ... 

    $this->_user = new Model_User($userData); 
    $this->_user->save(); 
} 

public function tearDown() 
{ 
    $this->_user->delete(); 
} 
関連する問題