Mahamudul Hasan Rubel
HomeBlogCoursesAboutProjectsSkillsExperiencePhotosContact
Mahamudul Hasan Rubel

Senior Software Engineer crafting high-performance web applications and SaaS platforms.

Navigation

  • Home
  • Blog
  • Courses
  • About
  • Projects
  • Skills
  • Experience
  • Photos
  • Contact

Get in Touch

Available for senior/lead roles and consulting.

bd.mhrubel@gmail.comHire Me

© 2026 Mahamudul Hasan Rubel. All rights reserved.

Built with using Next.js 16 & Tailwind v4

Back to Blog
Lesson 45 of the Laravel Fundamentals: From Zero to Your First App course
LaravelJune 25, 20263 min read

Introduction to Testing: Build Confident Laravel Apps

Stop manually refreshing your browser to verify features. Learn how to write your first Laravel feature test using PEST to automate assertions and save time.

LaravelPHPUnitPESTTestingTDDphpbackend

Previously in this course, we refactored our Task Manager: Refactoring for Clean Code to keep our controllers lean and maintainable. Now, we’ll move from manual browser testing to automated verification.

Testing is the difference between a project that works "on my machine" and one that works in production. By writing tests, you create a safety net that warns you immediately if a new feature breaks an existing one. In Laravel, we primarily use two tools for this: PHPUnit (the industry-standard engine) and PEST (a delightful, expressive testing framework built on top of PHPUnit).

Why Feature Testing?

In Laravel, we distinguish between Unit Tests (testing a single method in isolation) and Feature Tests (testing a full request-to-response cycle). For a beginner, Feature Tests are your best friend. They simulate a real user hitting your routes, filling out forms, and seeing data in the database.

If you’ve explored other ecosystems, you might recognize these concepts from Introduction to Testing: Quality Assurance in React with Jest, but here we apply them to server-side logic and database persistence.

Your First Feature Test

Laravel comes pre-installed with PEST. To create your first test, run this command in your terminal:

Bash
php artisan make:test TaskTest --pest

This generates a file in tests/Feature/TaskTest.php. Open it up, and you'll see a basic test structure. Let’s write a test to ensure our "Index" page loads correctly.

PHP
test('the tasks page returns a successful response', function () {
    $response = $this->get('/tasks');

    $response->assertStatus(200);
});

Here, we are:

  1. Making a request: $this->get('/tasks') simulates a visitor hitting that URL.
  2. Asserting: assertStatus(200) checks that the server responded with an "OK" status.

To run this test, execute php artisan test in your terminal. You should see a green output confirming your test passed.

Testing Database State

Testing the response status is only the beginning. Often, you need to verify that your application is actually saving data to the database. We use the assertDatabaseHas assertion for this.

Let’s add a test to verify that we can create a task:

PHP
use App\Models\Task;

test('a user can create a task', function () {
    $this->post('/tasks', [
        'title' => 'Buy milk',
        'description' => 'Go to the store'
    ]);

    $this->assertDatabaseHas('tasks', [
        'title' => 'Buy milk',
    ]);
});

In this example, we send a POST request to our store route. Immediately after, we check the tasks table to ensure the record exists. Laravel automatically wraps these tests in a database transaction, meaning it rolls back the changes after the test finishes—your database stays clean!

Hands-on Exercise

  1. Open tests/Feature/TaskTest.php.
  2. Write a test that visits the /tasks route and asserts that the page contains the text "My Tasks" (you can use $response->assertSee('My Tasks')).
  3. Run php artisan test to confirm it passes.
  4. If it fails, check if your route or view actually contains that string.

Common Pitfalls

  • Forgetting the Database: If you try to test database interactions but your test isn't hitting the database, ensure your test class uses the Illuminate\Foundation\Testing\RefreshDatabase trait (though PEST usually handles this automatically).
  • The "Green Test" Trap: A test that always passes is useless. Always write a test that fails first, then write the code to make it pass. This is known as "Red-Green-Refactor."
  • Authentication: If your routes are protected by middleware (like we built in Task Manager: Securing the Application), your tests will fail with a 302 redirect. We will cover how to "login" as a user in our next lesson.

Recap

We've covered the basics of automated testing in Laravel. We used PEST to verify that our routes respond with a 200 status code and confirmed that our database operations successfully persist data. By mastering these basics, you're building a foundation for a robust, professional-grade application.

Up next: Testing Forms and Validation — where we'll simulate user input and ensure our validation rules actually catch bad data.

Previous lessonTask Manager: Refactoring for Clean CodeNext lesson Testing Forms and Validation
Back to Blog

Similar Posts

LaravelJune 25, 20263 min read

Database Transactions for Data Integrity in Laravel

Learn to use DB::transaction to ensure data integrity in your Laravel apps. Prevent partial state updates by wrapping complex operations in atomic blocks.

Read more
LaravelJune 25, 20263 min read

Preparing for Production: Laravel Optimization and Security

Learn to prepare your Laravel app for production. Master configuration caching, route optimization, and essential security settings to go live with confidence.

Part of the course

Laravel Fundamentals: From Zero to Your First App

beginner · Lesson 45 of 52

  1. 1

    Setting Up the Local Development Environment

    4 min
  2. 2

    Installing Laravel and Exploring Directory Structure

    3 min
  3. 3

    Understanding the .env File and Configuration

    3 min
Read more
LaravelJune 25, 20264 min read

Implementing Middleware for API Security in Laravel

Learn to build custom middleware in Laravel to enforce resource ownership. Secure your API routes by verifying user access before controllers ever execute.

Read more
  • 4

    The Laravel Application Lifecycle

    4 min
  • 5

    Initializing the Task Manager Project

    3 min
  • 6

    Defining Basic Web Routes

    4 min
  • 7

    Using Route Parameters

    3 min
  • 8

    Creating Your First Controller

    3 min
  • 9

    Returning Responses and Redirects

    3 min
  • 10

    Task Manager: Implementing the Task List Route

    3 min
  • 11

    Introduction to Blade Templating

    3 min
  • 12

    Using Blade Layouts and Sections

    3 min
  • 13

    Implementing Blade Partials

    4 min
  • 14

    Mastering Blade Directives for Loops and Conditionals

    3 min
  • 15

    Task Manager: Building the User Interface

    3 min
  • 16

    Understanding Database Migrations

    3 min
  • 17

    Working with Eloquent Models

    3 min
  • 18

    Performing Basic CRUD Operations

    3 min
  • 19

    Seeding the Database

    3 min
  • 20

    Task Manager: Displaying Real Database Records

    3 min
  • 21

    Capturing User Input from Forms

    4 min
  • 22

    Introduction to Laravel Validation

    3 min
  • 23

    Customizing Validation Error Messages

    3 min
  • 24

    Using Form Requests for Validation

    3 min
  • 25

    Introduction to Authentication

    4 min
  • 26

    Protecting Routes with Middleware

    3 min
  • 27

    Understanding CSRF Protection

    3 min
  • 28

    Preventing Mass Assignment

    3 min
  • 29

    Task Manager: Securing the Application

    3 min
  • 30

    Introduction to Route Model Binding

    3 min
  • 31

    Updating Existing Records

    3 min
  • 32

    Deleting Records

    3 min
  • 33

    Using Named Routes

    3 min
  • 34

    Task Manager: Completing CRUD Functionality

    3 min
  • 35

    Introduction to Database Relationships

    3 min
  • 36

    Querying Related Data

    4 min
  • 37

    Handling File Uploads

    3 min
  • 38

    Using Flash Messages for User Feedback

    3 min
  • 39

    Task Manager: Adding Status and Priorities

    3 min
  • 40

    Introduction to Artisan Commands

    3 min
  • 41

    Debugging with Laravel Tinker

    3 min
  • 42

    Understanding Service Providers

    4 min
  • 43

    Using View Composers

    3 min
  • 44

    Task Manager: Refactoring for Clean Code

    3 min
  • 45

    Introduction to Testing

    3 min
  • 46

    Testing Forms and Validation

    3 min
  • 47

    Using Database Transactions

    3 min
  • 48

    Handling Global Exceptions

    3 min
  • 49

    Preparing for Production

    3 min
  • 50

    Environment Security Best Practices

    4 min
  • 51

    Managing Assets in Production

    Coming soon
  • 52

    Task Manager: Deployment Preparation

    Coming soon
  • View full course