- Lab
- Core Tech

Guided: Testing Your Laravel Application
In this Code Lab, you will enhance your Laravel testing skills through hands-on tasks. You will explore unit and integration testing, safely interact with databases during tests, validate forms, and enforce authorization rules. This lab provides a practical, step-by-step guide with final code solutions for each stage. By the end, you will be equipped to implement robust testing strategies, ensuring reliable and maintainable Laravel applications.

Path Info
Table of Contents
-
Challenge
Introduction
Welcome to the Guided: Testing Your Laravel Application Code Lab. This lab is designed for web developers and learners eager to enhance their Laravel skills through comprehensive testing practices. You will engage in hands-on tasks, including unit testing, integration testing, database interaction while protecting the primary DB, form and validation testing, and authorization testing. By the end of this Code Lab, you will possess the knowledge and practical experience to implement robust testing strategies in your Laravel applications, ensuring they are reliable, secure, and maintainable. Whether refining your existing projects or embarking on new development challenges, this lab will equip you with the tools to succeed in Laravel testing. Key Takeaways:
-
Learn unit and integration testing in Laravel.
-
Safeguard your primary database during tests.
-
Implement and test form validations effectively.
-
Ensure secure authorization through comprehensive tests. Prerequisites:
-
Foundational PHP Knowledge: Learners should have a basic understanding of PHP, including fundamental concepts like data types, functions, and classes.
-
Basic Laravel Experience: Learners should be familiar with core Laravel features, such as routes, controllers, models, and Blade templates. They should have either built a simple Laravel application or completed a basic Laravel tutorial before this lab.
-
Command-line & IDE Experience: Learners should be able to run commands in the Terminal, including Laravel artisan commands, and be comfortable using an IDE or text editor to work with project files.
__solution
Folder: -
code
: The final code for each step is stored in the__solution/code
folder. For instance, the final code for Step 1 is available in the__solution/code/Step01
directory. -
images
: The folder also contains an image depicting the lab's final state. For example,__solution/images/Step01_final_output.png
contains the image depicting the final state of Step 1.
-
-
Challenge
Creating a Simple Unit Test
In this initial step, you'll implement a basic
GreetingService
class and write a unit test to verify itsgreet
method. This will introduce you to the fundamentals of unit testing in Laravel and help you ensure that individual components of your application function as expected. Navigate to the first Terminal and run the following command to start the development server:php artisan serve --host=0.0.0.0 --port=8000
Once executed, the development server will start, and the application will be accessible for testing at {{localhost:8000}}.
Explanation of the solution above The
GreetingService
service has been created for this task, with a function namedgreet
that accepts a$name
parameter and returns a greeting message in the formatHello, {$name}!
.Explanation of the solution above
The unit test above verifies that the
greet
method of theGreetingService
class returns the expected greeting message. It creates an instance ofGreetingService
, calls the greet method with the nameAlice
as a parameter, and asserts that the result matchesHello, Alice!
.php artisan test tests/Unit/GreetingServiceTest.php
Upon running the test, you should see an output as shown in the example response below indicating that the unit test has passed successfully:
PASS Tests\Unit\GreetingServiceTest ✓ it returns the correct greeting message for a given name 0.01s Tests: 1 passed (1 assertions) Duration: 0.08s
info> Note: Running the
php artisan test
is equivalent to running./vendor/bin/pest
. You can use either command.Congratulations! You have successfully created and executed a simple unit test in Laravel. This foundational exercise sets the stage for more advanced testing scenarios and ensures the application's components behave correctly.
-
Challenge
Creating an Integration Test
In this step, you'll complete a
GreetingController
controller that utilizes theGreetingService
to handle the/greet
route and return a greeting message.You'll also write an integration test using
pest
to ensure that the endpoint functions are working as expected, helping you understand the basics of integration testing in Laravel.Explanation of the solution above
The `greet` method retrieves the `name` parameter from the URL's query string. If no name is provided, it defaults to "Guest". It then calls the `greet` method from the `GreetingService` to create a greeting message using the retrieved name. Finally, it sends back a JSON response containing the greeting message, making it suitable for API responses.{ "message": "Hello, Alice!" }
Explanation of the above solution
The first test verifies that the application responds correctly when a user sends a GET request to the `/greet` route with `Bob` as the `name` parameter. It checks that the server returns a status code of 200, indicating a successful request. It also checks that the JSON response contains `Hello, Bob!`.Explanation of the above solution
The second test ensures that when no `name` parameter is provided to the `/greet` route, the application defaults to greeting `Guest`. It sends a GET request without specifying a name and checks that the response status is 200. It verifies that the JSON response contains the message `Hello, Guest!` confirming that the application correctly handles cases where the user's name is not supplied by providing a default greeting.php artisan test tests/Feature/GreetingControllerTest.php
Upon running the test, you should see an output as shown in the example response below indicating that the feature test has passed successfully:
PASS Tests\Feature\GreetingControllerTest ✓ it returns the correct greeting message for a given name. 0.11s ✓ it returns a greeting message as Guest when no name is provided. 0.01s Tests: 2 passed (8 assertions) Duration: 0.18s
Congratulations! You have successfully created and executed a feature test in Laravel.
-
Challenge
Preventing Tests from Affecting the Primary Database
In this step, you'll configure your Laravel application to use a separate database for tests, ensuring that your primary database remains unaffected.
Explanation of the solution above The above test creates a new task with the title
Navigate to your second **Terminal** and execute the following command to run only the feature test added above:Buy grocery!
and asserts that the tasks table contains this task. Since the testing environment uses the primary database, running this test will initially add the task to your main database. which is a bad practice.php artisan test tests/Feature/TaskModelTest.php
You should see a response in your Terminal, as shown in an example response below:
PASS Tests\Feature\TaskModelTest ✓ it adds a task to the database 0.93s Tests: 1 passed (1 assertions) Duration: 1.28s
Navigate to {{localhost:8000}}/tasks and see that
Buy Grocery!
is in the list, indicating that the primary database was affected. This is a bad practice, as the test should not affect your primary database. TheRefreshDatabase
trait ensures that your database is reset after each test, preventing data from one test from affecting others. By including the trait in your test class, Laravel automatically wraps each test in a database transaction and rolls back any changes once the test completes. This maintains a clean state for every test, enhancing reliability and preventing interference between tests.The
RefreshDatabase
trait is faster than the other two available traits,DatabaseTruncation
andDatabaseMigration
.Navigate to your second Terminal and execute the following command to run only the feature test added above:
php artisan test tests/Feature/TaskModelTest.php
Upon running the test, you should see an output as shown in the example response below indicating that the test has passed successfully:
PASS Tests\Feature\TaskModelTest ✓ it adds a task to the database 0.85s Tests: 1 passed (1 assertions) Duration: 1.14s
Now, navigate to {{localhost:8000}}/tasks and verify that the "Buy grocery!" item does not appear twice in the list. This confirms that the primary database remains unchanged after configuring the testing environment.
Congratulations! You have successfully isolated the primary database for testing.
-
Challenge
Testing Forms and Validation
In this step, you'll test form submissions with valid and invalid data, check for proper redirection, and confirm that error messages are displayed as expected. Navigate to {{localhost:8000}}/tasks/create and you should see a form that allows you to add new tasks.
Explanation of above solution This test ensures that submitting valid data through the form successfully creates a new task. It simulates a POST request to the `/tasks` endpoint with a valid `title` and `is_completed` status. The test then verifies that the user is redirected to the `/tasks` route, a success message is present in the session, and the new task exists in the database. This confirms that the controller's store method correctly handles and stores valid input.Explanation of above solution
This test verifies that submitting invalid data (an empty title) does not create a task and provides appropriate feedback. It simulates a POST request to the `/tasks` endpoint with an empty title, asserts that the user is redirected back to the task creation form, checks for validation errors in the session, and confirms that no task with an empty title exists in the database. This ensures that validation rules are enforced and prevents invalid data from being stored.Explanation of above solution
This test verifies that submitting the form with an empty title triggers validation errors and displays the appropriate message. It simulates a POST request to the `/tasks` endpoint without a title, checks that the user is redirected back to the creation form, and confirms that the error message "The title field is required." is shown. This ensures that the application enforces validation rules and provides clear feedback to users when their input is invalid.php artisan test tests/Feature/TaskCreationFormTest.php
Upon running the test, you should see an output as shown in the example response below indicating that the test has passed successfully:
PASS Tests\Feature\TaskCreationFormTest ✓ it creates a task when valid data is submitted 0.93s ✓ it does not create a task when data is invalid 0.04s ✓ it displays validation errors on the form 0.06s Tests: 3 passed (10 assertions) Duration: 1.31s
Congratulations! You created and executed tests for testing forms and their validation.
-
Challenge
Testing Authorization
In this step, you'll implement authorization to ensure that only authenticated users can access the tasks list. You'll update your routes to require authentication, create authorization tests using
pest
, and verify that unauthorized users are appropriately restricted. This enhances the security of your application by controlling access to sensitive functionalities. Attaching theauth
middleware to the/tasks
route ensures only logged-in users can access the tasks list. This prevents unauthorized access and protects sensitive data. The middleware acts as a gatekeeper, checking user authentication before granting access to the route's functionality.Explanation of the above solution
This test ensures unauthenticated users or guests are redirected to the login page when accessing the tasks list. It simulates a GET request to the `/tasks` route without authentication and checks the response redirects to `/login`, preventing unauthorized access.Explanation of the above solution
This test ensures that authenticated users can see the task list and successfully access it. It creates a user using a factory, authenticates as that user, and simulates a GET request to the
/tasks
route. It confirms that the response status is 200, indicating successful task list access.php artisan test tests/Feature/TaskAuthorizationTest.php
By executing the
TaskAuthorizationTest
tests, it can be verified that the authorization rules for accessing the tasks list are properly enforced. A successful test run will confirm that guests are redirected to the login page and that authenticated users can access the tasks without issues.You should see a response in your Terminal, similar to the example below, confirming that the feature test has been added and is working successfully:
PASS Tests\Feature\TaskAuthorizationTest ✓ it ensures guests cannot see the task list 0.17s ✓ it ensures authenticated users can see the task list 0.03s Tests: 2 passed (3 assertions) Duration: 0.27s
Congratulations! You've successfully implemented authorization tests in your Laravel application.
What's a lab?
Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.
Provided environment for hands-on practice
We will provide the credentials and environment necessary for you to practice right within your browser.
Guided walkthrough
Follow along with the author’s guided walkthrough and build something new in your provided environment!
Did you know?
On average, you retain 75% more of your learning if you get time for practice.