Github repository dedicated for my YT tutorial which shows how to use testing in Laravel

Overview

Testing in Laravel

The following documentation is based on my Laravel Testing for Beginners tutorial we’re going to cover the basics of unit tests, feature tests, HTTP tests, database tests and seeder tests in Laravel.

• Author: Code With Dary
• Twitter: @codewithdary
• Instagram: @codewithdary

Usage

Setup your coding environment

git clone [email protected]:codewithdary/laravel8-tailwindcss2.git
cd laravel8-tailwindcss2
composer install
cp .env.example .env 
php artisan key:generate
php artisan cache:clear && php artisan config:clear 
php artisan serve 

Database Setup

We will be performing database tests which (obviously) needs to interact with the database. Make sure that your database credentials are up and running.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_testing
DB_USERNAME=root
DB_PASSWORD=

Next up, we need to create the database which will be grabbed from the DB_DATABASE environment variable.

mysql;
create database laravelblog;
exit;

Finally, make sure that you migrate your migrations.

php artisan migrate

Why Testing?

We can all agree that testing is a good thing, whether you’re a developer, doctor or fireman. In coding, there are lots of different tools that you can use for testing, think about:
PHPunit
Mockery
PHPSpec
Storyplayer

Instead of setting your test environment manually, Laravel has PHPunit integrated by default. PHPunit is a framework independent library that can be used for unit testing.

What is unit testing?

Unit testing is a method that you can use where small pieces of code will be tested against expected results. If you’re new to testing, you might wonder when you’ll be using it. Think about the following three situations:
• Crawling your site’s URI
• Test when submitting forms
• Tests on status codes

Testing basics

During this tutorial (and the next one as well), you’ll be hearing some new terms that you might not have heard before. Let’s go over a couple of them before we move into coding.

Unit tests

Unit tests verify if individual units of code work as expected.

Feature tests

Feature tests will test the way individual units work together and pass messages.

Application tests

Application tests will test the entire behavior of your application, which eventually leads into releasing a bug-free and robust software application.

Regression tests

With regression tests, you’re going to describe exactly what a user should be able to do and make sure that the application won’t stop.

Folder/file structure

Laravel adds some folders and files by default in the root of your project directory. Wish is awesome, because you don’t need to configure anything for your testing environment. Inside the root of your directory, you will find a folder called /tests.

-tests
-- Feature
-- Unit
>> CreateApplication.php
>> TestCase.php

Subfolders

The feature subfolder consists of tests that will cover the interaction between multiple units. The unit submit consists of tests for one unit of your code. Both subfolders have an ExampleTest.php filde which has a simple sample test inside of it.

Finally, our first unit test. Keep in mind that unit tests should be simple. Right here, you’ll see that the test_example() test simply checks if the assert is true. The method accepts one parameter, which is true. In our case, the test will always return true.

public function test_example()
{
    $this->assertTrue(true);
}

Files

The CreateApplication.php file isn’t a class but a Trait. The same Trait will be used inside the TestCase.php file which will be the base root test that all our other tests will extend.

use CreatesApplication;

Running tests

One of the most important things about tests is obviously running them since you can create as many as you want, but you can’t test anything if it doesn’t work.

Laravel makes it very easy for us to run our tests through the terminal. Keep in mind that you can only perform tests from the root of your project directory. You can run your tests by performing one of the following commands:

./vendor/bin/phpunit
php artisan test

OUTPUT EXAMPLE (./vendor/bin/phpunit):
PHPUnit 9.5.8 by Sebastian Bergmann and contributors.
``		2/2 (100%)
Time: 00:00.200, Memory: 18.00 MB

Tests output

The output of a test might seem weird if you’re seeing it for the first time. PHPunit version is 9.5.8 Is has been created by Sebastian Bergmann and contributors The two dots indicate that we performed two tests, which is true because we performed the ExampleTest.php from the Feature and Unit subfolder.

PHPunit file

Whenever you run your tests, you’ll be running the phpunit.xml file from the root of your directory.

The most important piece of code is the testsuites, which makes sure that PHPunit is able to run the ./tests/Unit and ./tests/Feature subfolders.

<testsuites>
    <testsuite name="Unit">
        <directory suffix="Test.php">./tests/Unit</directory>
    </testsuite>
    <testsuite name="Feature">
        <directory suffix="Test.php">./tests/Feature</directory>
    </testsuite>
</testsuites>

Creating our first test

The easiest way to create a test is through Artisan.

php artisan make:test UserTest

This will create a new file with the name of UserTest inside the /tests/Feature folder with one method called test_example(). It will check if the / URI can be reached, and if it can, it will send back the assertStatus() method.

If you perform the test through the CLI, you’ll see that the unit test has indeed passed the test, because Laravel defines the / URI by default in the web.php file.

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

It’s also good to know what will happen if the unit tests do not pass the test. Let’s change the URI to /test and run the command one more time.

Finally! Our first error message. We received a FAIL message with an in-depth description. The test should receive a status code of 200, but it actually received a 404 because the route has not been found.

Unit tests

Up until this point we worked with a test from the Feature folder. Unit tests obviously get stored inside the Unit folder. We can create a Unit test by performing the same command, with an additional flag.

php artisan make:test UserTest --unit

I personally prefer to run unit tests through the authentication scaffolding because it allows us to use the User model. Let’s perform the following command to pull in an authentication scaffolding (Make sure that you have setup your database).

composer require Laravel/ui 
php artisan ui react –auth
php artisan migrate

Also, make sure that you add the authentication route inside the routes/web.php file.

Auth::routes();

The rest of the Unit tests are available through the video since it makes no sense to copy paste the entire code.

HTTP tests

We have already performed the get() method (which is added by default), but you can also perform the get(), post(), put(), patch() or delete() method.

Keep in mind that you do need to return a response object that will represent the HTTP response. This will not be the Illuminate response object that you’re familiar with, but it will be an instance of the ```Illuminate\Foundation\Testing\TestResponse, which is a wrapper around the Response object with some additional assertions for testing.

If you perform the php artisan route:list command, you’ll see that the /register URI is using an HTTP method of post(). An example of the post() method might look like the following:

public function test_if_it_stores_new_users()
{
    $response = $this->post('/register', [
        'name' => 'Dary',
        'email' => '[email protected]',
        'password' => 'dary1234',
        'password_confirmation' => 'dary1234'
    ]);
    
    $response->assertRedirect('/home');
}

Be aware that you’re performing the post() method from the form of your register view. Therefore, you do need to pass in the password_confirmation, even though it doesn’t exist in the database.

Database test

Laravel offers a lot of tools and assertions in order to make it easier to test your database driven applications. We have already created tests where we’ve checked if we could insert a new user in the database, which honestly isn’t the most effective way. You rather want to make an HTTP call to the store endpoint and then assert that package exists in the database.

There are two assertions you can use.

The first one is the $this->assertDatabaseHas(), which looks inside a database and checks if the given data exists. The second one is the $thid->assertDatabaseMissing(), which checks whether a given value is missing in the database.

Quick exercise. Check if you can find out what the SQL query will be for both methods. Answer 1: the $this->assertDatabaseHas() method looks like an WHERE statement because MySQL will check inside the database whether the given value exists or not.

We do need to make sure that we create a user inside the database. Let’s do this with a Seeder since the Seeder will be used in the next section.

php artisan make:seeder UsersTableSeeder

Add the following method inside the run method of the /database/seeders/UsersTableSeeder.php.

public function run()
{
    DB::table('users')->insert([
        'name' => 'Dary',
        'email' => '[email protected]',
        'password' => bcrypt('password'),
    ]);
}

The last step is to run our database seeder through the CLI.

php artisan db:seed –class=UsersTableSeeder

If we navigate back to our Unit/UserTest.php file, we got to make sure that we create a new method that will use the $this->assertDatabaseHas() method.

The $this->assertDatabaseHas() accepts two parameters, the first one will be the table name where you want to search in. The second parameter will be an array with a key value pair. The key will be the column name inside the users table, and the value will be the value of our name column.

public function test_if_data_exists_in_database() { $this->assertDatabaseHas('users', [ 'name' => 'Dary' ]); }

The $this->assertDatabaseMissing() method works in the same exact way, but you got to search for a name that does not exist in the database.

public function test_if_data_does_not_exists_in_database()
{
    $this->assertDatabaseHas('users', [
        'name' => 'John'
    ]);
}

Seeding tests

The last type of test that we’ll be performing will be seeding tests. We’re going to check whether we can seed a single seeder, or all seeders at the same time.

In order to test all seeders, you simply have to add the following line inside a method.

public function test_if_seeders_works()
{
    $this->seed();
}

This command is equal to the php artisan db:seed command, which will seed all seeders available inside the /database/seeders folder.

Instead of seeding all seeders, you can pass in a parameter inside the seed() method which will be the class name of a single seeder. This command is equal to the command that we performed before.

public function test_if_seeder_works()
{
    $this->seed(UsersTableSeeder::class);
}

Credits due where credits due…

Thanks to Laravel for giving me the opportunity to make this tutorial on Testing.

You might also like...
Providing some testing functionality for Laravel
Providing some testing functionality for Laravel

Laravel TestBench Laravel TestBench was created by, and is maintained by Graham Campbell, and provides some testing functionality for Laravel. It util

Eloquent scope assertion for testing Laravel applications.

Eloquent Scope Assertion This package allows you to assert that the scope of a model is called in your tests. Installation You can install the package

Llum illuminates your Laravel projects speeding up your Github/Laravel development workflow
Llum illuminates your Laravel projects speeding up your Github/Laravel development workflow

Llum illuminates your Laravel projects speeding up your Github/Laravel development workflow

Run multiple websites using the same Laravel installation while keeping tenant specific data separated for fully independent multi-domain setups, previously github.com/hyn/multi-tenant

The unobtrusive Laravel package that makes your app multi tenant. Serving multiple websites, each with one or more hostnames from the same codebase. B

Ghygen is a GitHub Actions configurator for your PHP / Laravel project.
Ghygen is a GitHub Actions configurator for your PHP / Laravel project.

Ghygen Ghygen is a GitHub actions Yaml Generator. Ghygen allows you creating your Yaml file for GitHub Actions, for Laravel/PHP web application, so yo

Generate GitHub pull request preview deployments with Laravel Forge

Forge Previewer WARNING: This package is not ready for production usage. Use at your own risk. This package provides a forge-previewer command that ca

A simple to use query builder for the jQuery QueryBuilder plugin for use with Laravel.
A simple to use query builder for the jQuery QueryBuilder plugin for use with Laravel.

QueryBuilderParser Status Label Status Value Build Insights Code Climate Test Coverage QueryBuilderParser is designed mainly to be used inside Laravel

A Laravel package that allows you to use multiple
A Laravel package that allows you to use multiple ".env" files in a precedent manner. Use ".env" files per domain (multi-tentant)!

Laravel Multi ENVs Use multiple .envs files and have a chain of precedence for the environment variables in these different .envs files. Use the .env

Invite System for GitHub Organizations
Invite System for GitHub Organizations

Invite System for GitHub Organizations OrgManager takes Github Organization invites to a new level! Read more on the OrgManager documentation. Table o

Owner
Code With Dary
I'm a developer & educator who creates online programming courses to help out anyone interested in learning web development.
Code With Dary
A program which shows the match days and results of a sport league developed with HTML, PHP and BladeOne technology

league-table Escribe un programa PHP que permita al usuario introducir los nombres de los equipos que participan un una liga de fútbol. Con dichos nom

ManuMT 1 Jan 21, 2022
Database Repository / PHP Repository / Laravel Repository

Database Repository / PHP Repository / Laravel Repository Installation Use following command to add this package to composer development requirement.

Bakery 6 Dec 21, 2022
Laravel Backend API for the tutorial (Granular permissions with Laravel APIs & React frontend)

Laravel Granular Permissions Backend Getting Started Clone the repository. Install the dependencies composer install Update .env database credentials

Munaf Aqeel Mahdi 4 May 10, 2022
Laracast's awesome larabook tutorial - refreshed with Laravel 5.0 code

Larabook Updated - Laravel 5.0 A light version of Facebook, called Larabook. Updated using new techniques and features of Laravel 5.0 Fixes I tried my

Mike Wu 6 Dec 6, 2020
Multipurpose Laravel and Livewire Application. This is a part of tutorial series on Youtube.

Multipurpose Laravel and Livewire Application This is a part of YouTube tutorial series on building application using Laravel and Livewire. Here is th

Clovon 88 Dec 23, 2022
Shows the path of each blade file loaded in a template

Laravel Tracer Tracer shows the paths of all the Blade files that are loaded into your templates. This could be very convenient for a number of reason

Appstract 97 Oct 1, 2022
Auto-generated Interface and Repository file via Repository pattern in Laravel

Auto-generated Repository Pattern in Laravel A repository is a separation between a domain and a persistent layer. The repository provides a collectio

Ngo Dinh Cuong 11 Aug 15, 2022
A demo of how to use filament/forms to build a user-facing Form Builder which stores fields in JSON.

About Laravel Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experie

Dan Harrin 41 Dec 24, 2022
Laravel Dusk provides simple end-to-end testing and browser automation.

Introduction Laravel Dusk provides an expressive, easy-to-use browser automation and testing API. By default, Dusk does not require you to install JDK

The Laravel Framework 1.7k Jan 5, 2023
Trait for Laravel testing to count/assert about database queries

counts_database_queries Trait for Laravel testing to count/assert about database queries Installing composer require ohffs/counts-database-queries-tra

null 1 Feb 23, 2022