Database Testing
Database Testing
Laravel provee una variedad de herramientas y aserciones para hacer más fácil el testeo de las aplicaciones basadas en base de datos. Además, los model factories y los seeders hacen más fácil crear registros en la base de datos usando los modelos y las relaciones.
Resetting the Database After Each Test
Vamos a ver como resetear los registros de la base de datos para que los datos de un test no interfieran en los subsiguientes tests. Laravel incluye el trait Illuminate\Foundation\Testing\RefreshDatabase que se encargará por ti:
<?php
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('basic example', function () {
$response = $this->get('/');
// ...
});
El trait Illuminate\Foundation\Testing\RefreshDatabase no migra tu base de datos si el esquema esta actualizado. En cambio, solo ejecutará los tests dentro de una transaction, Por lo tanto, cualquier registro añadido a la base de datos que no use este trait, puede seguir existiendo en la base de datos
Si quieres resetear totalmente la base de datos puedes usar los traits Illuminate\Foundation\Testing\DatabaseMigrations o Illuminate\Foundation\Testing\DatabaseTruncation . Ambos son significativamente mas lentos que RefrestDatabase
Model Factories
Cuando realizas tests, puedes necesitar introducir unos pocos registros en tu base de datos antes de ejecutar el test. En vez de especificar manualmente el valor de cada columna cuando creas esta test data, Laravel te permite definir un conjunto de atributos por defecto por cada uno de tus Eloquent models usando model factories.
Para más detalles acerca de los model factories, consultar model factory documentation.
use App\Models\User;
test('models can be instantiated', function () {
$user = User::factory()->create();
// ...
});
Running Seeders
Si desea utilizar database seeders para poblar tu base de datos durante una feature test, puede invocar el método seed. Por defecto, el método seed ejecutará el DatabaseSeeder, que debería ejecutar todos los demás seeders. Como alternativa, puede pasar un nombre de clase específico al método seed:
<?php
use Database\Seeders\OrderStatusSeeder;
use Database\Seeders\TransactionStatusSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('orders can be created', function () {
// Run the DatabaseSeeder...
$this->seed();
// Run a specific seeder...
$this->seed(OrderStatusSeeder::class);
// ...
// Run an array of specific seeders...
$this->seed([
OrderStatusSeeder::class,
TransactionStatusSeeder::class,
// ...
]);
});
Alternativamente, puede indicar a Laravel que ejecute el seed automáticamente antes de cada prueba que utilice el trait RefreshDatabase. Para ello, defina una propiedad **$seed**en su clase de prueba base:
<?php
namespace Tests;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
abstract class TestCase extends BaseTestCase
{
/**
* Indicates whether the default seeder should run before each test.
*
* @var bool
*/
protected $seed = true;
}
Cuando la propiedad $seed es true, la prueba ejecutará la clase Database\Seeders\DatabaseSeeder antes de cada prueba que utilice el trait RefreshDatabase. Sin embargo, puede especificar un seeder específico que deba ejecutarse definiendo una propiedad $seeder en su clase de prueba:
use Database\Seeders\OrderStatusSeeder;
/**
* Run a specific seeder before each test.
*
* @var string
*/
protected $seeder = OrderStatusSeeder::class;
Available Assertions
Laravel proporciona varias aserciones de base de datos para tus pruebas de Pest o PHPUnit.
assertDatabaseCount
Afirmar que una tabla de la base de datos contiene el número de registros dado:
$this->assertDatabaseCount('users', 5);
assertDatabaseEmpty
Afirmar que una tabla de la base de datos no contiene registros:
$this->assertDatabaseEmpty('users');
assertDatabaseHas
Afirmar que una tabla de la base de datos contiene registros que coinciden con las restricciones de consulta clave / valor dadas:
$this->assertDatabaseHas('users', [
'email' => 'sally@example.com',
]);
assertDatabaseMissing
Afirmar que una tabla de la base de datos no contiene registros que coincidan con las restricciones de consulta clave/valor dadas:
$this->assertDatabaseMissing('users', [
'email' => 'sally@example.com',
]);
assertSoftDeleted
El método assertSoftDeleted puede utilizarse para afirmar que un determinado modelo de Eloquent ha sido “soft deleted”:
$this->assertSoftDeleted($user);
assertNotSoftDeleted
El método assertNotSoftDeleted puede utilizarse para afirmar que un modelo Eloquent dado no ha sido “soft deleted”:
$this->assertNotSoftDeleted($user);
assertModelExists
Afirmar que un modelo dado existe en la base de datos:
use App\Models\User;
$user = User::factory()->create();
$this->assertModelExists($user);
assertModelMissing
Afirmar que un modelo dado no existe en la base de datos:
use App\Models\User;
$user = User::factory()->create();
$user->delete();
$this->assertModelMissing($user);
expectsDatabaseQueryCount
El método expectsDatabaseQueryCount puede invocarse al principio del test para especificar el número total de consultas a la base de datos que se espera ejecutar durante la prueba. Si el número real de consultas ejecutadas no coincide exactamente con esta expectativa, la prueba fallará:
$this->expectsDatabaseQueryCount(5);
// Test...