Saltar contenido

Pruebas de Base de Datos

Introducción

Laravel ofrece una variedad de herramientas y afirmaciones útiles para facilitar la prueba de tus aplicaciones impulsadas por base de datos. Además, las fábricas de modelos y los sembradores de Laravel hacen que sea muy fácil crear registros de base de datos de prueba utilizando los modelos Eloquent y las relaciones de tu aplicación. Discutiremos todas estas poderosas características en la siguiente documentación.

Restableciendo la Base de Datos Después de Cada Prueba

Antes de avanzar mucho más, hablemos sobre cómo restablecer tu base de datos después de cada una de tus pruebas para que los datos de una prueba anterior no interfieran con las pruebas posteriores. El trait Illuminate\Foundation\Testing\RefreshDatabase incluido en Laravel se encargará de esto por ti. Simplemente usa el trait en tu clase de prueba:

<?php
 
use Illuminate\Foundation\Testing\RefreshDatabase;
 
uses(RefreshDatabase::class);
 
test('basic example', function () {
$response = $this->get('/');
 
// ...
});
<?php
 
namespace Tests\Feature;
 
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
 
class ExampleTest extends TestCase
{
use RefreshDatabase;
 
/**
* A basic functional test example.
*/
public function test_basic_example(): void
{
$response = $this->get('/');
 
// ...
}
}

El trait Illuminate\Foundation\Testing\RefreshDatabase no migra tu base de datos si tu esquema está actualizado. En su lugar, solo ejecutará la prueba dentro de una transacción de base de datos. Por lo tanto, cualquier registro añadido a la base de datos por casos de prueba que no utilicen este trait puede seguir existiendo en la base de datos. Si deseas restablecer completamente la base de datos, puedes usar los rasgos Illuminate\Foundation\Testing\DatabaseMigrations o Illuminate\Foundation\Testing\DatabaseTruncation. Sin embargo, ambas opciones son significativamente más lentas que el rasgo RefreshDatabase.

Fábricas de Modelos

Al probar, es posible que necesites insertar algunos registros en tu base de datos antes de ejecutar tu prueba. En lugar de especificar manualmente el valor de cada columna cuando creas estos datos de prueba, Laravel te permite definir un conjunto de atributos predeterminados para cada uno de tus modelos Eloquent usando fábricas de modelos. Para obtener más información sobre cómo crear y utilizar fábricas de modelos para crear modelos, consulta la documentación completa sobre fábricas de modelos. Una vez que hayas definido una fábrica de modelo, puedes utilizar la fábrica dentro de tu prueba para crear modelos:

use App\Models\User;
 
test('models can be instantiated', function () {
$user = User::factory()->create();
 
// ...
});
use App\Models\User;
 
public function test_models_can_be_instantiated(): void
{
$user = User::factory()->create();
 
// ...
}

Ejecutando Seeders

Si deseas usar seeders de base de datos para poblar tu base de datos durante una prueba de función, puedes invocar el método seed. Por defecto, el método seed ejecutará el DatabaseSeeder, que debería ejecutar todos tus otros seeders. Alternativamente, puedes pasar un nombre de clase de seeder 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,
// ...
]);
});
<?php
 
namespace Tests\Feature;
 
use Database\Seeders\OrderStatusSeeder;
use Database\Seeders\TransactionStatusSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
 
class ExampleTest extends TestCase
{
use RefreshDatabase;
 
/**
* Test creating a new order.
*/
public function test_orders_can_be_created(): void
{
// 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, puedes instruir a Laravel para que siembre automáticamente la base de datos antes de cada prueba que utilice el trait RefreshDatabase. Puedes lograr esto definiendo una propiedad $seed en tu 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 rasgo RefreshDatabase. Sin embargo, puedes especificar un seeder específico que se debe ejecutar definiendo una propiedad $seeder en tu clase de prueba:

use Database\Seeders\OrderStatusSeeder;
 
/**
* Run a specific seeder before each test.
*
* @var string
*/
protected $seeder = OrderStatusSeeder::class;

Afirmaciones Disponibles

Laravel proporciona varias aserciones de base de datos para tus pruebas de características con Pest o PHPUnit. Discutiremos cada una de estas aserciones a continuación.

assertDatabaseCount

Afirmar que una tabla en la base de datos contiene el número dado de registros:

$this->assertDatabaseCount('users', 5);

assertDatabaseHas

Asegúrate de que una tabla en la base de datos contenga registros que coincidan con las restricciones de consulta de clave / valor dadas:

$this->assertDatabaseHas('users', [
'email' => 'sally@example.com',
]);

assertDatabaseMissing

Asegúrate de que una tabla en la base de datos no contenga registros que coincidan con las restricciones de consulta de clave / valor dadas:

$this->assertDatabaseMissing('users', [
'email' => 'sally@example.com',
]);

assertSoftDeleted

El método assertSoftDeleted se puede utilizar para afirmar que un modelo Eloquent dado ha sido "eliminado suavemente":

$this->assertSoftDeleted($user);

assertNotSoftDeleted

El método assertNotSoftDeleted se puede utilizar para afirmar que un modelo Eloquent dado no ha sido "eliminado suavemente":

$this->assertNotSoftDeleted($user);

assertModelExists

Asegúrate de que un modelo dado exista en la base de datos:

use App\Models\User;
 
$user = User::factory()->create();
 
$this->assertModelExists($user);

assertModelMissing

Asegúrate de 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 comienzo de tu prueba para especificar el número total de consultas a la base de datos que esperas que se ejecuten durante la prueba. Si el número real de consultas ejecutadas no coincide exactamente con esta expectativa, la prueba fallará:

$this->expectsDatabaseQueryCount(5);
 
// Test...