The 3 A's of testing

The 3 A's of testing

Applied to Laravel with PEST testing

As I continue to explore testing strategies, one especially effective approach I have discovered is the 3 A's: Arrange, Act, and Assert.

This simple and effective approach is a popular structure for developers to craft meaningful and logical code in Laravel.

Let's break this down:

Arrange

Think of arrange as ensuring your test has access to everything it needs to complete.
Typically, when testing content that would come from a database, this would need to be simulated from a factory. This simulation would be the arranged part of a test, which would happen up front before the assertions.

The Arrange test code is not always essential. An example of arrange not being essential is when testing a page loads (an calls on a rout requiring no additional parameters) and in this case nothing needs to be set up to do so.

Example of arrange

// From my gallery project
Album::factory()->create();

Act

Also before the assertions is the Act. Here is where the test executes the code that is being tested. When working with Laravel, this will either use a route or controller to get the page content.

The Act part of the test code is always essential. Without executing the code being tested, there would be nothing to make assertions on.

Act may, at this point, call on what was set up in the arranging stage to use as an additional parameter in cases where the element that is being tested would require an additional parameter.

Example of Act

$response = $this->get(route('gallery-albums.index'));

Assert

Finally, we come to assert. This is where we compare what the code should do with what it actually does.

In other words, we're making sure that the output or behaviour matches our expectations. This could involve checking for specific values, verifying database changes, or even validating that errors are thrown when expected.

Assert is essential as this is part of the test code where the user receives the feedback, whether the test passes or fails. There may be multiple assertions in a test.

Example of Assert

    $response
        ->assertOk()
        ->assertViewIs('admin.albums.index')
        ->assertViewHas('albums');
💡
This same framework style is sometimes known as given, when, then, which is sometimes thought to be a more teachable explanation.

Putting it into practice

With these three steps in mind, let's walk through an example of how to write a test using PEST PHP in Laravel.

test('loads gallery albums', function () {

    //arrange
    Album::factory()->create();

    //act
    $response = $this->get(route('gallery-albums.index'));

    //assert
    $response
        ->assertOk()
        ->assertViewIs('admin.albums.index')
        ->assertViewHas('albums');
});

If you're just getting started with testing, then a tip is to remember to use keywords like act, arrange, and assert to guide your test writing process.

The Given, When and Then alternative

If you find it easier use the words Given, When and Then. which is effectively the same.

Arrange, Act, Assert is often considered too logical, and the more human approach of Given, When, Then is favoured by many developers.

Here is how it compares:

Given

In a given situation (when code has been arranged in this way).

When

When this (action) has taken place.

Then

Then, this outcome should take place, and the user should receive feedback on the outcome to (assert) this happened.