Skip to main content

Black Friday 2025! Only until December 1st: coupon FRIDAY25 for 40% off Yearly/Lifetime membership!

Read more here

Automated Tests and Git Feature Branches

Premium
14 min read

We've finished the Links CRUD feature but haven't actually tested it.

A common question I get is how to write automated tests and WHEN to write them. After all the project is done? Before the code, with TDD? The truth is somewhere in the middle.

I prefer to write tests immediately after the feature is finished. At that moment, the code is still fresh in your head or IDE, so it's easier to write the test cases.

In my experience, TDD forces you to guess the functionality before you know how it would work. On the other hand, when writing tests for the full project afterward, it will be hard to remember the functionality of the features created a long time ago.

So, we'll be working on the tests in this lesson.


Introducing Feature Branches

In the example of this course, we separated the Links CRUD feature and its automated tests in separate lessons. I did it to demonstrate the different approaches to branching:

  • Links CRUD code is pushed to the dev branch
  • Links CRUD tests will be pushed to a new feature branch (which later will be merged into dev)

From here, we will use feature branches for the following lessons.

git checkout -b feature/links-tests

Notice: In real life, you should push Code and Tests in one commit. We separated them for educational purposes.


Writing Tests: CRUD, Validation and Multi-Tenancy

Let's discuss the question of WHAT to write tests for.

For this Links CRUD functionality, we will write three kinds of tests.

First, for a typical CRUD, we should simulate the situations for each Controller method: index(), create(), edit(), etc. This is the so-called "happy path".

But, on top of that, we need to test the scenarios when something goes wrong. These are often overlooked by developers who focus only on the "shiny scenario". However, the majority of bugs happen precisely when someone enters unexpected data. So, our goal is to come up with those "bad scenarios" and ensure that our application deals with them properly, showing the errors.

Finally, we require that every user see only their links. This is the most simple definition of multi-tenancy, so we need to test whether this condition works well.

To illustrate these three concepts separately, we decided to generate three different test files:

php artisan make:test Links/LinksCrudTest
php artisan make:test Links/LinksValidationTest
php artisan make:test Links/TenancyTest

It's your preference; you may prefer to have one longer LinksTest.

Also, you choose whether to use Pest (Laravel default now) or PHPUnit. I will use Pest in this course.


IMPORTANT: Separate Database for Testing

Our tests will create fake data in the database to simulate the scenarios. So, we must ensure it works on a separate testing database to avoid...

The Full Lesson is Only for Premium Members

Want to access all of our courses? (31 h 16 min)

You also get:

55 courses
Premium tutorials
Access to repositories
Private Discord
Get Premium for $129/year or $29/month

Already a member? Login here

Comments & Discussion

T
tr100 ✓ Link copied!

In the course, you present two branches, but there is no mention of tagging. Could you explain how to use tags on these branches in the context of deployments? For example, when and why should we tag a commit, and how does it help during the deployment process

M
Modestas ✓ Link copied!

We haven't used tagging ourselves since it's not really common to have it on Forge (and Envoyer). They are working directly with branches on the assumption that:

Master is ALWAYS ready to be deployed Other branches are ready to be deployed with latest code at all times, but can break

And we used this workflow ourselves for the most part. We always made sure that as soon as stuff lands in master - we are 100% confident that it contains no unfinished tasks.

As for using tags - I've personally seen people do complete messes out of them, and some people who did it amazing. But there was just something off for me. We might investigate this deeper at a later date, but for now:

https://www.codingwithcalvin.net/git-tag-based-released-process-using-github-actions/ - Shows you how to set up tags with Actions. That way, you could trigger the deployment manually. https://docs.github.com/en/actions/use-cases-and-examples/deploying/deploying-with-github-actions - GitHub has some resources on that too (even for php, but only on azure https://docs.github.com/en/actions/use-cases-and-examples/deploying/deploying-php-to-azure-app-service

ps. I haven't found anything too specific for Laravel, sorry!

M
mint ✓ Link copied!

Thanks for this course! I have a question: after the merge of the feature branch, do you usually delete it? In this scenario: after merged the feature/links-tests into dev do you delete feature/links-tests itself? Thanks!

M
Modestas ✓ Link copied!

Yes! Clean up branches that were already merged to have less clutter in your system :) It's already merged, so it's not required anymore

A
Aleksandr ✓ Link copied!

There was no routes provides so all tests fail. Not sure if it was intended since you provided controllers and views, but forgot about routes. I'm assuming the code should look something like this:

Route::resource('links', LinkController::class)->middleware(['auth']);