Despite the fact that "Laravel is build with testing in mind" I find this part not as intuitive as all the other great parts of the Laravel landscape. And the changes for the environment handling doens't make things easier.
I don't know if other devs see it the same way as I do.
So I'am willing to send a pull request to improve the documentation based on the response to this article.
For all the people who are struggling with phpunit and the integrated testing framework here's what to do.
Please keep in mind that most of this tips are related to seeding your database with seeders and not using
model factories directly in your test methods to generate the minimal amount of data needed to get the test green.
1. Define you test database
config/database.php
This can be anything. MySQL, SQLite file based or like this example a SQLite db in memory
'sqlite_testing' => [
'driver' => 'sqlite',
'database' => ':memory:',
'prefix' => '',
],
2. Let phpunit know which database to use
phpunit.xml
This was for me the hardest part to figure out.
You need tp add <env name="DB_CONNECTION" value="sqlite_testing" /> to the definition of environment vars like this.
Now phpunit nows witch connectin to use, because in comparison to codeception phpunit is not reading the .env.testing file .
<php>
<env name="APP_ENV" value="testing"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="QUEUE_DRIVER" value="sync"/>
<env name="DB_CONNECTION" value="sqlite_testing" />
</php>
3. Automatically migrate your database before each test
tests/[YOUR-TEST-FILE]
You can use the provided DatabaseMigrations trait
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Support\Facades\Config;
class [YOUR-TEST-CLASS] extends TestCase
{
use DatabaseMigrations;
public function [YOUR-TEST-FUNCTION]()
{
// do your tests
}
...
4. How to seed your database before each test
Because phpunits setUp() is called before the DatabaseMigrations trait you can't use it to seed the database.
So here are two options:
Don't use the DatabaseMigrations trait
You can write your own setUp() and tearDown() methods
tests/[YOUR-TEST-FILE]
...
public function setUp()
{
parent::setUp();
$this->artisan('migrate');
$this->artisan('db:seed');
}
public function tearDown()
{
$this->artisan('migrate:reset');
}
...
Use your own DatabaseMigrations trait
Write your own DatabaseMigrations trait with an extra call to db:seed.
tests/support/DatabaseMigrations.php
trait DatabaseMigrations
{
/**
* @before
*/
public function runDatabaseMigrations()
{
$this->artisan('migrate');
$this->artisan('db:seed');
$this->beforeApplicationDestroyed(function () {
$this->artisan('migrate:rollback');
});
}
}
Don't forget do add it to composer.json for autoloading
...
},
"autoload-dev": {
"classmap": [
"tests/TestCase.php",
"tests/support/DatabaseMigrations.php"
]
},
...
5. Extra: How to define the database for functional testing with CodeCeption
In codeception for you functional suite you would set your database configuration in functional.suite.yml like this:
config:
Laravel5:
environment_file: .env.testing
6. Extra: How to use define the database for acceptance testing with Behat
The Laracasts Laravel Behat extension allows you to create a .env.behat file to change the environment variables.
This article helped me a lot to figure all this out:
http://stackoverflow.com/a/27986561
Maybe this is helpful for somebody.
If I am partly or even completely wrong please let me know so I can improve this article (and myself)