Reputation: 10134
On my phpunit tests I need to run a cleanup functionality for each test seperately for example:
use PHPUnit\Framework\TestCase;
use MyApp\Database\DatabaseEntryDataGenerator;
use MyApp\Database\Record\User;
use MyApp\Database\Record\Emails;
class MyEmailTest extends TestCase
{
public function testEmailValid()
{
/**
* @var EmailEntries
*/
$emails=DatabaseEntryDataGenerator::table(EmailEntries::TABLE)->generate();
//Do test
$emails->delete();
}
public function testEmailValidOnUser()
{
/**
* @var User
*/
$user=DatabaseEntryDataGenerator::table(User::TABLE)->generateSingle(1);
/**
* @var EmailEntries
*/
$emails=DatabaseEntryDataGenerator::table(EmailEntries::TABLE)->generateMultiple();
//Do test
$emails->delete();
$user->delete();
}
}
Assume that fictional DatabaseEntryDataGenerator
generates data on database and the fictional EmailEntries
and User
represent the record data. The method delete
on EmailEntries
and User
.
But if during the development of the test something brak mucase the delete that is the cleanup code may be deleted. Also the generic tearDown
is way to generid and does not allow to specify a specific method indicain a test the required tearDown logic. For example in my case the teardown logic on testEmailValid
id Different on testEmailValidOnUser
and if something breakd for example due to a typo, may end up not be able to run it aall hence not giving me the test isolation.
So how I can have per-test specific tear down logic that will be executed regardless the test is successfull or not?
Upvotes: 0
Views: 328
Reputation: 3494
I would suggest using database transaction here. You really want to do the same thing in both tests: rollback any changes made to the database.
public function setUp(): void
{
MyDatabaseClass:startTransaction();
}
public function tearDown(): void
{
MyDatabaseClass:rollback();
}
This way you won't need to have special logic for each test, and if you are affecting more tables than expected, you will still be safe.
Upvotes: 0
Reputation: 659
The only way to do this is by using seperate classes. If you are in need of different teardown logic per test, you are either having architectural issues, are testing different functionality or simply don't have a good enough teardown strategy.
Often times, simple truncate logic will suffice during the teardown logic.
Upvotes: 1