How Use PHPUnit Test in Laravel 5.1

Access all tutorials in sprocket icon.

June 12, 2015 from author Bill Keck.

Sometimes for beginners, the idea of PHPUnit testing code can be scary. You find yourself having to install the test framework, learn a whole new series of commands and methods, and half the time, you have no idea why it doesn’t work.

Fortunately, with Laravel 5.1, testing is incredibly easy, it is already integrated into the framework, ready to go, out of the box. To confirm this, you can run a simple command from the command line:



vendor/bin/phpunit --version

Tip for anyone who gets an error message about composer dependencies from the above. Try running:



vendor/phpunit/phpunit/phpunit --version 

In any event, once you have the correct path, it will return the following, and you know you are good to go:



PHPUnit 4.7.2 by Sebastian Bergmann and contributors.

Use the path that works for the rest of the tutorial.

Ok, great, so how do we run an actual test? Well, let's start by looking at the example test that comes with the Laravel install. Under your project folder, you will see a tests folder. Inside you will see ExampleTest.php:



<?php

use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;

class ExampleTest extends TestCase
{
    /**
     * A basic functional test example.
     *
     * @return void
     */
    public function testBasicExample()
    {
        $this->visit('/')
             ->see('Laravel 5');
    }
}

To run this test, just call it from the command line like so:



vendor/bin/phpunit

That will run all tests in the folder. If have a fresh install of Laravel, the test should find "Laravel 5' on the welcome view, which is where the '/' route points to. You will get a two line response. The first line tells you how many milliseconds it took to run the test and how much memory it consumed.

The second line will be highlighted in green, and look something like this:



OK(1 test, 1 assertion)

Now let's make it fail, so we can see what happens when it fails. Change 'Laravel 5' to 'Laravel 6' inside the test and run it again with:



vendor/bin/phpunit

You can see it gives a lot more output. There's too much for me to include here, so I'll give you the relevant bits. It starts with:



Time: 719 ms, Memory: 15.50Mb

There was 1 failure:

1) ExampleTest::testBasicExample
Failed asserting that '

Then it prints the html from the page. Then you get the following line:



' matches PCRE pattern "/Laravel 6/i".

That's the end of the statement of the failed assertion. So it's telling you precisely how it failed. How cool is that?

And then of course you get the red highlighted summary block:



FAILURES!
Tests: 1, Assertions: 1, Failures: 1.

With the red highlighting, there's no way to miss the fact that it didn't pass. Now you would think that every time you run a test, you would get red or green, but there's actually a third option.

If you have a mistake in the test code itself, the test doesn't run at all and it will simply return a command prompt on a new line. You can test this by removing the semicolon from inside the test method and running the test again.

One of the more time consuming tasks that I hear programmers talk about is testing forms. Laravel has made this incredibly easy. Let's create a test for registration. This assumes you have registration setup for your app. If you don't, set that up first, then come back to this tutorial.

So let's use artisan to make our test stub:



php artisan make:test RegistrationTest

Now, inside the tests folder, let's modify RegistrationTest.php with the following:



<?php

use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;

class RegistrationTest extends TestCase
{

    use DatabaseTransactions;

    public function testNewUserRegistration()
    {
        $this->visit('auth/register')
            ->type('bob', 'name')
            ->type('hello1@in.com', 'email')
            ->type('hello1', 'password')
            ->type('hello1', 'password_confirmation')
            ->press('Register')
            ->seePageIs('/');
    }

}

Look at how intuitive the syntax is! Do I even need to explain what it does? Obviously the first parameter in each chained method is the value and the second is the name of the field.

For a full list of methods, check testing docs, they are well written and clear.

Note that if your path to registration is different than mine, you will have to adjust your test accordingly. Also, if you have different input fields in your form, adjust accordingly.

You'll also note that we are using a trait in our test class named DatabaseTransactions. What this does is rollback the insert to the database, so you don't have to gum it up with test data. Using the DatabaseMigrations trait will rollback the migration, which will drop the table. The WithoutMiddleware trait allows it to skip middleware for testing purposes.

You can read up on PHPUnit on the Official PHPUnit Site. Just remember that inside Laravel, we are extending TestCase for our test classes, not PHPUnit_Framework_TestCase.

Ok, so that's going to wrap up our primer on PHPUnit testing in Laravel 5.1.

I hope you have enjoyed this tutorial and found it useful. Click on the sprocket icon at the top of the page to see all tutorials. Please comment, share, and like if you can, thanks!

I don’t have a donate button, but If you would like to support my work and learn more about Laravel, you can do so by buying one of my books, Laraboot: laravel 5* For Beginners, I really appreciate it.

4 thoughts on “How Use PHPUnit Test in Laravel 5.1

  1. Henri says:

    Nice blog, Bill! Thanks!

    Did you also you use the seeJson() method? I never get a match, because seeJson looks for an exact json conversion of that array. But Response::json() returns always a json object or an array with json objects. Is this a bug? Thanks

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s