Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

madprabh's avatar

Approach to Pest testing

Hey Folks,

So I am pretty new to testing and I am exploring the use of PEST. When I tried it ended up erasing my database which I dont want. Ideally after each feature I would like these tests to even run on production.

Is there a good practice that you guys follow? What approach should I use?

Best

0 likes
7 replies
LaryAI's avatar
Level 58

When it comes to testing with Pest, or any testing framework, there are a few best practices you should follow to ensure your tests are effective and safe, especially when it comes to database interactions.

1. Use a Separate Testing Database

Never run tests on your production database. Instead, configure a separate database specifically for testing. This ensures that your production data remains safe and untouched.

2. Database Transactions

Use database transactions to ensure that any changes made during a test are rolled back once the test completes. This keeps your test database clean and consistent.

3. Environment Configuration

Make sure your tests are running in a test environment. This can be configured in your .env file or directly in your test setup.

Example Configuration for Pest

Here is an example of how you can set up your Pest tests to use a separate database and ensure transactions are rolled back after each test.

Step 1: Configure Your .env.testing File

Create a .env.testing file in the root of your project with the following content:

APP_ENV=testing
DB_CONNECTION=mysql
DB_DATABASE=your_test_database
DB_USERNAME=your_username
DB_PASSWORD=your_password

Step 2: Update phpunit.xml

Ensure your phpunit.xml file is set to use the .env.testing environment:

<phpunit>
    <php>
        <env name="APP_ENV" value="testing"/>
    </php>
</phpunit>

Step 3: Use Database Transactions in Tests

In your Pest.php file or in your test case setup, you can use Laravel's RefreshDatabase trait to handle transactions:

use Illuminate\Foundation\Testing\RefreshDatabase;

uses(RefreshDatabase::class)->in('Feature');

This will ensure that each test runs within a transaction and rolls back any changes after the test completes.

Example Test Case

Here is an example of a simple Pest test case that interacts with the database:

it('creates a new user', function () {
    $user = User::factory()->create([
        'name' => 'John Doe',
        'email' => '[email protected]',
    ]);

    $this->assertDatabaseHas('users', [
        'email' => '[email protected]',
    ]);
});

Running Tests

To run your tests, simply use the Pest command:

./vendor/bin/pest

Summary

  • Never run tests on your production database.
  • Use a separate testing database.
  • Use transactions to keep your test database clean.
  • Ensure your tests run in a test environment.

By following these best practices, you can safely and effectively use Pest for testing your application without risking your production data.

1 like
madprabh's avatar

I did create a new db and then in my phpunit.xml I have this

		<env name="APP_ENV" value="testing"/>
        <env name="APP_MAINTENANCE_DRIVER" value="file"/>
        <env name="BCRYPT_ROUNDS" value="4"/>
        <env name="CACHE_STORE" value="array"/>
        <!-- <env name="DB_CONNECTION" value="sqlite"/> 
        <env name="DB_DATABASE" value=":memory:"/>  -->
        <env name="MAIL_MAILER" value="array"/>
        <env name="PULSE_ENABLED" value="false"/>
        <env name="QUEUE_CONNECTION" value="sync"/>
        <env name="SESSION_DRIVER" value="array"/>
        <env name="TELESCOPE_ENABLED" value="false"/>

And I create a .env.testing

DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=ossurvey_test
DB_USERNAME=postgres

but it still ended up refreshing my primary database.

Any clue on where I am going wrong?

nexxai's avatar

@madprabh Why not just uncomment the two <env entries in the phpunit.xml that you currently have commented which run the DB in memory? The in-memory database is much faster than an actual SQL engine and is the best option for the majority of use cases.

madprabh's avatar

Ok I got it working by basically running this command

php artisan test --env=testing

Please or to participate in this conversation.