Be sure to test your unit and develop higher-quality Laravel applications - (r)

Jul 4, 2024

-sidebar-toc>

The testing of unit functions is crucial when developing software. This ensures that components of the software function when they are in isolation. When you write tests specifically to test unit of code, you are capable of identifying and fixing mistakes early in the development process, leading to more effective and stable software.

In a continuous integration/continuous delivery (CI/CD) pipeline, you can run these tests automatically after making codebase changes. The test ensures that your new code won't introduce bugs or interfere with existing functionality.

An introduction to PHPUnit

Laravel can be tested through PHPUnit and offers a number of useful helper techniques that permit you to check the quality of your application.

Installing PHPUnit in the Laravel project involves minimal configuration. Laravel has a pre-configured testing environment, which includes an phpunit.xml file and the dedicated testdirectory for test files.

It is also possible to modify your phpunit.xml file to give you custom settings to provide an experience that is customized for each test. You can also make an .env.testingenvironment file in the root directory of your project instead of making use of an .env file.

Test layout default in Laravel

It is the phpunit.xml file in the Laravel project is crucial for orchestrating the test procedure. It ensures that the test is consistent across test runs and permitting you to modify PHPUnit's behavior to suit your particular requirements for the project. You can define how you want to conduct tests. This includes creating test suites, specifying the test environment, and creating connection to databases.

It also states that the cache, session and email must be configured to use the array driver, which is to ensure that no data session, cache or email data are stored during the course of tests.

It's possible to conduct various types of tests with the Laravel application.

  • Testing capabilities tests the wider capabilities of your app. Tests mimic HTTP responses and requests, and allow you to test routes along with controllers, as well as the interaction between various elements. These tests make sure that all components of your app work exactly as you would expect.
  • Testing of browsers --goes further by automating the interaction of the browser. Tests are conducted using Laravel Dusk, the automated browser and test software that mimics interaction of the user, like completion of forms or clicking on buttons. Browser tests are crucial for testing the behavior of your app as well as user experience on real browsers.

Test-driven development concepts

The term "test-driven" development (TDD) refers to the type of method of software development that emphasizes tests prior to the implementation of code. The approach is based on a procedure that is known as the red-green-refactor-cycle.

The test-driven development showing red-green-refactor.
A test-driven development cycle that shows the red-green-refactor.

Here is an description of the cycle:

  • Phase Red -- Write a completely new test that describes the functions of or improve an existing one before implementing the code. It should be unable to pass (as "red" signifies) as there isn't a suitable code for it to pass.
  • Phase Green Make just enough code that will let the test fail, turning it from green to red. This may not be ideal, however it should be in line with the requirements of the test case.
  • Refactoring Stage -- Refactor your code in order to increase its readability, maintainability, and performance without changing the way it behaves. It is at this point that it is possible to make modifications to your code without having to be concerned about issues related to regressions as tests that have been run already can detect these issues.

TDD offers many advantages:

  • Early detection of bugs The early detection of bugs TDD helps catch bugs early in the development process and reduces the expense and time to resolve problems late in the process of development.
  • Improved design TDD TDD lets you build flexible and loosely coupled code for better software design. The idea is to think about the interaction and interface between the components before implementing.
  • Refactoring confidence You can have confidence in the process of refactoring codes since you are aware that tests in place already determine any issues that may arise during the procedure of refactoring.
  • Documentation live Test cases function as living documentation and provide instances of how code should to behave. The documentation will always be revised as failing tests can indicate problems within the code.

Within Laravel the development procedure, it is possible to make use of TDD principles by writing tests for the components such as controllers, models, and services prior to the implementation of the parts.

The testing platform of Laravel that includes PHPUnit offers a variety of convenient tools and assertions to support TDD which allows the development of relevant tests and stick to the red-green-refactor cycle efficiently.

Simple Examples of unit tests.

This article outlines the steps to create tests that test your model's capabilities.

The requirements

To be able to follow the instructions, you need the following:

  • A Laravel application. This tutorial is built on the program created in the tutorial mentioned above. This guide is available to followed and then created into a blog, however in case you need only the source code needed for testing the app then follow the instructions below.
  • Xdebug is installed and has been configured using coverage mode enabled.

Begin the project

  1. Run this command from the terminal window in order to copy the entire project.
git clone https://github.com/VirtuaCreative/-laravel-blog.git
  1. Move into the project folder and execute the composer install command to install the project's dependencies.
  2. Rename the file in your env.example file to .env.
  3. Run the script php creator key:generate command to create an app key.

Make and run tests

To begin, you must have all the project code files installed on your computer. The model you'll be testing is the Post model defined in the app/Http/Models/Post.php file. The model includes a variety of elements that can be filled out, including the title, description, and images.

It is your job to write basic unit tests that will examine the design. First test checks that the attributes have been properly set. There is also another test which examines mass assignment by attempting to assign an attribute that is not fillable.

  1. Execute the php artisan make:test PostModelFunctionalityTest --unit command to create a new test case. The unit option indicates that this is a unit test and puts it in the tests/Unitdirectory.
  2. Unlock the tests/Unit/PostModelFunctionalityTest.php File and replace it with the test_example This code will perform the following function:
public function test_attributes_are_set_correctly() // create a new post instance with attributes $post = new Post([ 'title' => 'Sample Post Title', 'description' => 'Sample Post Description', 'image' => 'sample_image.jpg', ]); // check if you set the attributes correctly $this->assertEquals('Sample Post Title', $post->title); $this->assertEquals('Sample Post Description', $post->description); $this->assertEquals('sample_image.jpg', $post->image); public function test_non_fillable_attributes_are_not_set() // Attempt to create a post with additional attributes (non-fillable) $post = new Post([ 'title' => 'Sample Post Title', 'description' => 'Sample Post Description', 'image' => 'sample_image.jpg', 'author' => 'John Doe', ]); // check that the non-fillable attribute is not set on the post instance $this->assertArrayNotHasKey('author', $post->getAttributes()); 

This code outlines two methods to test.

First, you create the Post instance using the attributes you want to use. Additionally, by using the assertEquals assertion method make sure you have set the title, description, and image attributes correctly.

Another method is to provide the the instance include an additional attribute that can't be filled ( author) and claims that the attribute isn't created in the model through the assertArrayNotHasKey assert method.

  1. Include the below Use declaration in the same file:
use App\Models\Post;
  1. Perform the php crafter configuration:clear procedure to clear the configuration cache.
  2. In order to conduct these tests and conduct these tests You must run this command:
php artisan test tests/Unit/PostModelFunctionalityTest.php

Each test should be passed each time, and the computer should be able to display the test's results as well as the complete amount of time required to complete the test.

Tests for debugging

If the tests don't work they can be debugged with these techniques:

  1. Check the error message on the terminal. Laravel provides precise error messages which pinpoint the problem. Make sure you read through the error message for a better understanding of why the test failed.
  2. Review the test code and any tests you are testing to identify any discrepancies.
  3. Make sure you have set up the necessary details and dependencies for running the test.
  4. Once you've pinpointed the problem Make the necessary changes, and then rerun your tests until they're passed.

Databases and tests

  1. Lock the phpunit.xml file and remove the lines that follow of code:
  2. Run this PHP crafter make:test postCreationTest unit command to create the test case.
  3. Open the tests/Unit/PostCreationTest.php file and replace the test_example The method using this code:
public function testPostCreation() // Create a new post and save it to the database $post = Post::create([ 'title' => 'Sample Post Title', 'description' => 'Sample Post Description', 'image' => 'sample_image.jpg', ]); // Retrieve the post from the database and assert its existence $createdPost = Post::find($post->id); $this->assertNotNull($createdPost); $this->assertEquals('Sample Post Title', $createdPost->title); 
  1. Be sure to include the below Use declaration:
use App\Models\Post;

Currently, the PostCreationTest class extends the PHPUnitFrameworkTestCase base class. It is employed for unit tests using PHPUnit alone, and not when used in conjunction with Laravel and also when creating tests for a component that is not closely coupled to Laravel. You must, however, access the database, meaning you have to alter the postCreationTest class to extend it to include testsTestCase. testsTestCase class.

The latter class tailors the PHPUnitFrameworkTestCase class to Laravel applications. It provides further features and settings that are specific to Laravel including the database seeding and the configuration for test environments.

  1. Ensure you replace the use PHPUnitFrameworkTestCase; statement with use TestsTestCase;.Remember that you set the testing environment to use an in-memory SQLite database. This means that you must transfer to the database prior to testing. Use the IlluminateFoundationTestingRefreshDatabase trait to do this. This trait transfers data to a database in case that the schema isn't up-to-date and then resets the database at the end of each test to ensure that any data that was used in the prior test doesn't interfere with future tests.
  2. Incorporate the following use Statement addressed to tests/Unit/PostCreationTest.php File to integrate this attribute within your code
use Illuminate\Foundation\Testing\RefreshDatabase;
  1. Next, add the following code line prior to the testPostCreation method:
utilize RefreshDatabase
  1. Use the php artifice config.clear operation to remove the cache of configurations.
  2. For this test to be to be run, you must execute the following command:
php artisan test tests/Unit/PostCreationTest.php

The test should be passed, and the terminal must show the results of the test and the duration of testing.

Testing features

While unit tests evaluate each component of the application on its own features tests test more extensive portions of the program, which include how different objects work together. Tests for feature interaction are important for a variety of reasons.

  1. End-to-end validation It confirms that the whole function is functioning smoothly, which includes interactions between various components like controllers models, views, controllers, as well as databases.
  2. End-to-end testing provides all aspects of user interaction from initial request to last response. It can uncover issues that unit tests may miss. They are a great test tool to evaluate user-experiences and complex scenario.
  3. User Experience User Experience Assurance is a way to replicate user interaction, which helps verify a consistent user experience. This also helps ensure that this feature functions in the way it was intended.
  4. Regression detection -- Catches codes breaking or regressions, as well as the new software is introduced. When a feature that is already in use begins to fail during a test on a feature, this means the issue is with something.

Now, create a feature test for the PostController in the app/Http/Controllers/PostController.php file. It focuses on the storage method of validating incoming data, and also storing the posts in the database.

This test simulates users posting a new message using web-based interface. It makes sure that the software inserts the new post in the database. It also returns users to the Posts Index page after creation. For this, follow these steps:

  1. Use test PostControllerTest Test PostControllerTest alternative to build the test case entirely from scratch within the tests/features directory.
  2. Unlock the tests/Feature/PostControllerTest.php File and replace it with the test_example Method using this code:
use RefreshDatabase; // Refresh the database after each test public function test_create_post() // Simulate a user creating a new post through the web interface $response = $this->post(route('posts.store'), [ 'title' => 'New Post Title', 'description' => 'New Post Description', 'image' => $this->create_test_image(), ]); // Assert that the post is successfully stored in the database $this->assertCount(1, Post::all()); // Assert that the user is redirected to the Posts Index page after post creation $response->assertRedirect(route('posts.index')); // Helper function to create a test image for the post private function create_test_image() // Create a mock image file using Laravel's UploadedFile class $file = UploadedFile::fake()->image('test_image.jpg'); // Return the path to the temporary image file return $file; 

Test_create_post functions function that tests the creation of a post. function that simulates creating a new post using a POST request to the posts.store route with specific attributes, including the mock image created by uploadedFile, a Laravel uploadedFile class.

The program then validates that the program has successfully saved the post from the database through a check of the number in Post::all(). It also confirms that the application directs the user on Posts Index. Posts Index page after post creation.

The test will verify that the functionality for post-creation works, and that the software correctly manages the database interactions and redirects after post-submission.

  1. Add the following Use statements in the same file
use App\Models\Post; use Illuminate\Http\UploadedFile;
  1. Perform the process of PHP artisan config:clear to clear the configuration cache.
  2. For this test to verify this, you must run this command:
php artisan test tests/Feature/PostControllerTest.php

The test is expected to pass and the terminal has to show both the test's result and the complete amount of time required to complete the test.

Check the coverage of your test

Test coverage refers to the proportion of your codebase that your feature or unit tests, and is calculated as a percentage. This can assist you in determining the areas that haven't been tested and the under-tested areas potentially having bugs.

The PHPUnit Code Coverage feature, along with Laravel's built in coverage report will produce reports which reveal the areas of your codebase which your tests are testing. This provides vital information about the quality of your tests and assists you in focusing on areas that might require testing.

Create an account

  1. Delete the tests/Feature/ExampleTest.php and tests/Unit/ExampleTest.php files, as you have not modified them, and they might cause errors.
  2. Follow the tests for php artisan --coverage The terminal command. Expect to receive an output that looks like this:
Screen capture showing the execution of the command php artisan test --coverage. It shows the total number of tests that passed and the time to execute the results. It also lists each component in your codebase and its code coverage percentage
The command is running PHP artisan test using a coverage.

The code coverage report shows the results of tests and the overall number of tests completed and the length of time to execute the test. It also provides every element of your codebase, along with the percent coverage of each one. The percentages represent the amount of your test program that you have covered.

For instance, Models/Post has 100% coverage. That means that the entire model's methods and codes are included. The report on code coverage will also reveal how much coverage is offered. Complete Coverage -- the overall coverage of the entire codebase. The tests cover only 65.3 percent of the codebase.

  1. To determine a minimum coverage threshold, use the PHP artisan test -coverage --min=85 command. The command will set a minimum threshold of 85%. The following output should be received: output:
Screen capture showing the coverage report with a minimum threshold of 85%.The bottom line notes that the test fails because it does not meet the minimum threshold
The test has to be performed at a level of 85 percent.

The test suites don't pass since the test suites fail to reach the required threshold of 85%..

While achieving higher coverage of the code -- usually 100% coverage is the aim, it's more important to ensure that your program's crucial and complicated components in depth.

Summary

Incorporating the top practices that are discussed in this article such as writing meaningful thorough tests following the red-green-refactoring cycle of TDD using the test features offered with Laravel and PHPUnit You can build strong and reliable applications.

Jeremy Holcombe

Content & Marketing Editor WordPress Web Developer, and Content Writer. Apart from everything connected to WordPress my passion is golf, the beach, and movies. Also, I have height problems ;).

Article was posted on here