Table of Contents

Laravel Testing

Laravel Testing

A zombie developer releases code and hopes it doesn't break, whereas a Laravel developer writes automated tests to guarantee that new code does not break any functionality in their app.

Say that you are given a few grenades during the zombie apocalypse and the person giving you these grenades says, "I think they should work, they've been stored away for many years". Wouldn't you rather have them say, "These are our finest top of the line, tested to blow the roof off of anything grenades"

Yeah, of course you would feel better throwing the grenade into a swarm full of zombies that you know are tested to work. That's why testing is so important. We want to guarantee that our app works in any situation.


Testing

Testing your app is essential for ensuring everything works correctly.

I'm sure we've all done some testing to some extent. If we open our application, look at data, or even click a few links then we have tested our application. The only problem with manual testing is that it can be very time consuming.

Imagine for every line of code you change you have to go back and run through your whole application to make sure it's all functioning correctly. That would be absurd, right? Only a zombie would mindlessly perform these repetitive tasks over and over again.

Luckily for us we can automate our testing by using PHPUnit that is included by default with a fresh install of Laravel.

Let's go over an easy example of how testing can help us out. Let's say that we have a page with a simple link called 'Invetory of Weapons' that would bring us to a page that says 'Weapons.'

Well, in that case, we would probably have a view file called artillery.blade.php that contained the following HTML:

<html>
<head>
    <title>Artillery</title>
</head>
<body>

    <a href="/weapons">Inventory of Weapons</a>

</body>
</html>

So, this page is loaded when we go to site.com/artillery and when that link is clicked we go to a page at site.com/weapons, so we would need 2 routes for this, which would look like the following:

{lang="php"}

Route::get('artillery', function(){
  return view('artillery');
});

Route::get('weapons', function(){
  return view('weapons');
});

And each of these will load the view. Now, we want to guarantee that anytime we visit the artillery page we see 'Inventory of Weapons' and when we click on the link, we then end up on the weapons page.

For simplicity sake we will just assume that when you land on the weapons page (located at resources\views\weapons.blade.php) that it has the text 'Weapons' on the page, like so:

<html>
<head>
    <title>Weapons</title>
</head>
<body>

    <h1>Weapons</h1>

</body>
</html>

Next, lets create our first test.

$ php artisan make:test ArtilleryTest

After running the artisan command above, we will end up with the following code inside of a new file created at tests\Feature\ArtilleryTest.php:

<?php

namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;

class ArtilleryTest extends TestCase
{
    /**
     * A basic feature test example.
     *
     * @return void
     */
    public function testExample()
    {
        $response = $this->get('/');

        $response->assertStatus(200);
    }
}

So, by default, we are given a test example. This test example is just hard-coded to be true. So, let's run this test by typing in the following command:

$ vendor/bin/phpunit --filter ArtilleryTest

After running this command you should see a message in your command line that says something similar to:

OK (1 test, 1 assertion)

Which means that we have run 1 test and 1 assertion and everything was fine.

Why don't we go ahead and add a new method to our ArtilleryTest class that looks like the following:

public function testArtilleryPage(){
        $this->get('/artillery')
           ->assertSee('Inventory of Weapons');
}

Notice that each function must be prepended with test. Let's run our test again:

$ vendor/bin/phpunit --filter ArtilleryTest

And we will see a green success message, with the following text:

OK (2 tests, 2 assertions)

Try changing up the text in our test. Say for instance that the link in the artillery.blade.php file said 'Inventory of Kittens' instead of 'Inventory of Weapons'. If we run the test again, we will see a red error message saying that our tests have failed.

Tests: 2, Assertions: 2, Failures: 1.

You can think of this as a game if you like. When we see green we are currently winning! But if we see red that means we have a problem and we need to figure out what needs to be fixed to pass our test.

Just imagine every time we make a modification to our code we could simply run through our tests and guarantee that we have not broken anything. How much easier would it be to sleep at night knowing that the code you just pushed didn't break anything?

This was a very simple example just to give you a quick idea of how tests can work, but there are many more things that you can test besides text on the screen. Be sure to read up more about Laravel tests on the documentation page. We'll also provide some awesome resources you'll want to check out in the next section.