I recently needed to write some tests in which test code needed to interact with database (which is usually the case with integration tests*). These tests were for the core business logic of one of the applications i am working on, so i had to be sure that whatever is happening in code, is reaching the database properly. Laravel 4 Provides a pretty good base class for all your application’s tests which can be found in
1 |
app/tests/TestCase.php |
However this base class does not provide any helpers to deal with setting up and tearing down the database. So i put in some quick helper methods for the same in it, and with an in memory sqlite database, all the tests that touched the database were running at a decent speed. I am sharing the class below, use it, modify it, do whatever.
(* by the way, the best place to get a jump-start on testing concepts is http://guides.rubyonrails.org/testing.html , don’t worry if its in ruby, there is very less and simple code and the way testing theory is described there is pretty pragmatic )
TestCase.php (with database setup helpers):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
<?php use Mockery as m; class TestCase extends IlluminateFoundationTestingTestCase { protected $useDatabase = true; /** * Creates the application. * * @return SymfonyComponentHttpKernelHttpKernelInterface */ public function createApplication() { $unitTesting = true; $testEnvironment = 'testing'; return require __DIR__.'/../../bootstrap/start.php'; } public function setUp() { parent::setUp(); if($this->useDatabase) { $this->setUpDb(); } } public function teardown() { m::close(); } public function setUpDb() { Artisan::call('migrate'); Artisan::call('db:seed'); } public function teardownDb() { Artisan::call('migrate:reset'); } } |
First: Why don’t you need to call teardownDb() ? Because, as ShawnMcCool pointed out, the in memory db clears itself up on application-refresh performed by laravel after each test.
And How do you use it ? Well, below is an example of a class that needs to use the database for testing:
1 2 3 4 5 6 7 8 9 10 11 12 |
<?php class FooTest extends TestCase { protected $useDatabase = true; public function testFooBar() { ... } } |
Another thing, For testing purposes, you should switch to an in memory sqlite database, which can be easily setup in laravel’s config/database.php :
1 2 3 4 5 |
'test' => array( 'driver' => 'sqlite', 'database' => 'memory:', 'prefix' => '', ), |