PhpUnit / Pest / Laravel Testing Cheat Sheet

Testing

Automated testing is almost like and art more than a science. It's a whole topic on it's own. You can be a great programmer but that doesn't mean you are good with automated testing. The aim of this article is to document common questions and issues when testing with Laravel and PHP. 

How to use SQLite for testing

Let's start with why? Well speed of course. Many of your tests will be around the database or data and having a test compile in one second versus 5 seconds will make a big difference to your day.

That's why I always like to start by uncommenting these two lines in phpunit.xml

<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/>

 Later in this article we'll cover the case where sqlite suddenly falls down as your migration grow. 

When should you use .env.testing?

 At times you need to set a whole new environment. You can do this in phpunit.xml, or you can create an .env.testing file. Please note, if you have conflicting environments, phpunit.xml will take precedence. 

Running an individual test from the command line (using group)

 It's a waste of time to run all your tests every single time. To isolate and be more efficient, you can specify which test to run. Do the following before the method: 

* @group invoice-due-periods
* #[Group('invoice-due-periods')]

 Now you should be able to due this: 

php artisan test --group=invoice-due-periods

Getting your tests on GitHub

 It makes perfect sense to test your application every time it gets pushed to GitHub. To do this, create a file called something like: .github/workflows/run-test.yml with the following content:
name: tests on: push: pull_request: jobs: tests: runs-on: ubuntu-22.04 strategy: fail-fast: true matrix: php: ['8.1'] laravel: [10] name: PHP ${{ matrix.php }} - Laravel ${{ matrix.laravel }} steps: - name: Checkout code uses: actions/checkout@v2 - name: Setup PHP uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php }} extensions: dom, curl, libxml, mbstring, zip, bcmath ini-values: error_reporting=E_ALL tools: composer:v2 coverage: none - name: Install composer dependencies run: | composer require "illuminate/contracts=^${{ matrix.laravel }}" --no-update composer update --prefer-dist --no-interaction --no-progress - name: Copy .env.example and generate the application key run: | cp .env.example .env php artisan key:generate - name: Execute the tests run: vendor/bin/pest
  Please note, should you wish to do actual MySQL testing, you will need a more extensive .yml file. 

Adding a test badge

 It's good practice to add a test badge so that other members of the team can see your code consistency. Here is one example: 

![Tests](https://github.com/fintech-systems/bas3/actions/workflows/run-tests.yml/badge.svg)

Running the test in PhpStorm under the cursor

 There is a keyboard shortcut to run the current test method in PhpStorm under the cursor. I'm not sure what it is, but instead you might be able to press the play button in the sidebar, as below: 


However, this isn't entirely straightforward either, because next you'll encounter the problem below:

Running Tests as an Authenticated User

 The chances are 95% that your application uses authentication and that you need to run tests as an authenticated user. Do it this way: 

$user = User::factory()->create();
$this->actingAs($user);

Model Observers

 Model observers fire during tests. Be careful. 

Session is missing expected key [errors].

 Double check the test results. This obscure error is well documented on Laracasts, but it can essentially mean anything. Basically something fundamental with your validation checking is failing. 

Other Articles on this Website