Testing Laravel Applications Like a Pro with PHPUnit

Testing Laravel Applications Like a Pro with PHPUnit

Testing Laravel Applications Like a Pro with PHPUnit

Introduction

Test-Driven Development (TDD) is an approach to software development that utilizes a test-first environment where you write tests before writing proper code to fulfill the test and then refactoring. It’s a way to think through what your application is required or designed to do before you write code to build out the functionalities. This article is an introduction to testing Laravel Applications using PHPUnit, the most popular testing framework designed for PHP developers. This tutorial shows you why test-driven development is important in day to day activities as well as how to get started with writing tests in a Laravel application using PHPUnit,

Why you should write tests for your application

Testing is necessary because we all are bound to make mistakes. Some of these mistakes made in development carry no heavy consequences while some tend to be very costly or dangerous if neglected. The advantages of Test Driven Development poses are numerous, here are a few reasons why it is necessary to implement Test-driven development.

  • TDD helps avoid errors and bugs when introducing new features in an application
  • Project processes are made easier to track in a test-driven environment
  • TDD helps ease the process of documenting software
  • TDD inspires confidence when writing code
  • Bugs are easier to spot and fix in an environment where tests are written.

Prerequisites

This tutorial assumes you have the following:

  • Intermediate knowledge of Laravel and web development in general
  • A Laravel compatible development environment with Composer installed.

Introducing PHPUnit

PHPUnit is a developer-focused framework for testing applications built with PHP and its numerous frameworks. PHPUnit is built following the xUnit architecture for unit testing frameworks.

Laravel is built with testing in mind and as a result, PHPUnit is a testing utility included by default in a fresh installation of Laravel so there is no need to go through so much of a hassle in setting up a testing environment. All you need to do is ensure the default values (which are usually good to go) are modified to your taste. For example, you might need to have a different database driver for your testing needs.

Getting Started

Our demo Laravel app will be a simple tasks manager API that will allow users to create tasks and delete them as necessary. To get started, create and navigate to a new Laravel project using composer by running:

Configuring a Testing Database

When testing, it is very handy to have a testing database setup as you do not want to run tests against your actual database, and as a result, we will be making use of an in-memory SQLite database that keeps things simple and fast.

To configure SQLite as your testing database, open up the phpunit.xml file and uncomment the following lines of code from the file

Running Tests

To run tests using PHP unit in your Laravel Application, navigate to your projects root directory and run either the /vendor/bin/phpunit command or the php artisan test command. Alternatively, you can create a custom alias (composer test) by adding "test": "vendor/bin/phpunit" to the scripts object in your project’s composer.json file as demonstrated in the code block below.

When you run the initial tests pre-written by Laravel using the php artisan test or composer test command, you get something similar to the screenshot below:

The default Laravel tests pass

The default Laravel tests pass

The output above tells us that the two default tests: one unit & one feature test ran and passed successfully.

Let’s dissect any of the ExampleTest.php files in the units Proceed to delete the ExampleTest.php files in both the Feature and Unit directories in our tests folder as we will create our own tests shortly.

As explained above, our demo-project is a simple tasks manager app with the following requirements:

  • A /api/tasks/create route that accepts a POST request to create tasks
  • A /api/task{id}/complete endpoint that marks a given task as complete
  • A final /api/task/{id}/delete endpoint that deletes the given task from the database

Now that we have our requirements clear let’s proceed to write tests accordingly that ensure our API does just that!

Create a test file named EndpointsTest.php  by running:

Inside this file, delete the content of the default testBasicTest() method and add the following method instead.

Let’s run through what the code above does:

$this->withoutExceptionHandling() tells PHPUnit not to handle exceptions that we may get. This is to disable Laravel’s exception handling to prevent Laravel from handling exceptions that occur instead of throwing it, we do this so we can get a more detailed error reporting in our test output.

$this->post('/task/create', []) makes a POST request to the task/create endpoint with the values given in the array.

$response->assertStatus(201) instructs PHPUnit to confirm that the HTTP status code returned from the post request is a 201 i.e resource created.

Next, we use the $this->assertTrue() method to confirm that the task was really saved in the database.

On running the tests with php artisan test, we get the following feedback as our tests fail as expected.

We get a 404 not found exception

We get a 404 not found exception

The tests result (with exception-handling disabled) tells us that our tests fail because a POST request sent to http://localhost/task/create threw a NotFoundException as the route could not be found.

Let’s fix that by registering the route in our project’s web.php file.

On running the tests further, we get the following error that tells us that the Task model/class inline 24 could not be found. This is because we have not created the class yet.

All tests pass successfully now

All tests pass successfully now

Let’s create the Task class and its corresponding migration, factories and controllers by running php artisan make:model Task -a and then importing the created class by adding ” use App\Models\Task; ” at the top of our InsertionTest.php file.

On running the tests once more, we get a result saying the tasks table could not be found which is expected because we do not have migrations created and run.

Let’s create the table and run our migrations by adding the following migration to the public function up() method in the  create_tasks_table migration file.

Next, modify your Models/Task.php file to allow the name, description, and status fields to become mass assignable by adding them to the fillable array as such:

On running the tests we have written so far, you should see them failing as expected

Test that a Task can be deleted

In order to test if a task can be deleted, we will create some dummy tasks and attempt to delete them from the database. We can create dummy tasks using laravel factories as seen below.

Our test should look like this

As expected, the test fails. Let’s write the corresponding code to pass the test

Testing that a Task can be marked as completed

In order to test that tasks can be marked as completed, we need to create a test task and then make a PATCH request to the endpoint responsible for that.

As expected, our tests fail, add the following methods to the Task model so our model is able to mark tasks as completed.

Lastly, add the corresponding code in the controller:

When we run our tests now, we should get them all passing as expected. If an update is made to the codebase, tests should be written and run to ensure our application is still intact.

Further Reading:

We sure have covered a lot in this walkthrough. We got started by getting our project up and running using composer. Then, we configured PHPUnit to use a local SQLIte file for database related tests. Finally, we wrote our own test to make sure our API would work the way we expected.

While we covered a lot, this is just the tip of the PHPUnit iceberg. To continue learning about testing Laravel application, I recommend that you check out Jeffery Way’s Testing Laravel course on Laracasts. Another wonderful resource is the Laravel testing docs.

If you’d like to learn more about using PHPUnit, feel free to check out the official docs as well as a cheat-sheet of common PHPUnit utilities and functions here.

About the author

Stay Informed

It's important to keep up
with industry - subscribe!

Stay Informed

Looks good!
Please enter the correct name.
Please enter the correct email.
Looks good!

Related articles

Development With LAMP Stack Illustrated Address Book Project

Lamp stack Address Book Project is a sample software development project which is to showcase how to develop a web application utilizing Linux, ...

Top 6 Features of PHP 7.4 – Explained with Examples

PHP 7.4 is a minor version, but it includes plenty of new features. Here I show you the top 6 of them with examples. They can make a significant ...

No comments yet

Sign in

Forgot password?

Or use a social network account

 

By Signing In \ Signing Up, you agree to our privacy policy

Password recovery

You can also try to

Or use a social network account

 

By Signing In \ Signing Up, you agree to our privacy policy