How to Test PHP/Laravel BackEnd

Image for post
Image for post
Just a Random Illustration. Photo by Caspar Camille Rubin on Unsplash

This is a continuation to my last text, about testing. Our system has a React Front and a PHP Laravel Back with a SQL database. Now I’ll talk about the back-end tests. This will be shorter because the Laravel documentation is pretty good, and this kind of tests are more than a decade old.

Configuration

You can read a lot more details in: https://laravel.com/docs/5.8/testing, Laravel has a really good documentation, and I recommend it.

We’ll focus in a few files, essential to make your development environment possible.

buildMyTestDb.sh

I used “mysqltest” as the test DB name, and I did everything in Fedora 29. Always good to interrupt and delete the old DB to make sure everything is clear. That’s what we are doing now.

Initialize the nginx is necessary and you can also run the build line without “-d” to see the building process of MySQL that make a lot of optimizations and the DB will not be ready when it says so. Wait a couple minutes!

After this couple minutes initialize the php workspace to run your tests with phpunit command followed by your folder or file path.

phpunit.xml

Between PHP tags. Creating your own MySQL DB for test is always recommended. Remember to change it when you’ll need to work with the dev or production DB.

.env

The.env change makes practical to the creation and maintaining the test DB because they use the same ip and port, and you don’t need to take care of the port management.

docker-compose.yml (in laradock folder)

The “.yml” makes the docker recognize it as any other MySQL DB, because the args, the environments are the same and the volumes are analogous.

Unit Tests

Models and Validate the Relationships

The unit tests are one for each model, the purpose is to test its methods and its relationships. An easy and basic example is this, in which we test if the owner of “myModel” is an object type User.

Sometimes it demands an data field especially in the creation methods:

An method test is something like this: That makes sure that totalLikes() method returns an integer.

Feature Tests

Users

The most important thing to understand is the fact that we are running PHP artisan tinker commands.

So to get the user(or users) variables from DB to our code we use the same line of code.

Or use a more generic to don’t depend from hard-coded users, I suggest to search for the first of type “example”.

Uri, Data e Params

The next sections is completely based n the API specification.

You’ll need a variable which I prefer to call uri that will contain the URL section necessary with the HTTP method to run an specific endpoint.

Also some endpoints that require queries like the search ones demands a “URI Params” and the $data field to complete the request body.

Response, Assertions(type, status, message)

After the request body preparation, the response will be generated calling it thought the HTTP method, and the response will be a JSON that we need to make the assertions.

I divide the assertions in 3 types: By Status, by content and by type.

  • Status: These are the basic HTTP Status Code. You can check all them here:

https://www.restapitutorial.com/httpstatuscodes.html

And the assertion has this syntax:

  • Type:
  • Other Assertions you can checkout in the Laravel docs, that are great

https://laravel.com/docs/5.8/http-tests#available-assertions

Final Structure

Dependencies and Simulating Workflow

Some endpoint depend in a DB change cause by another endpoint, so to simulate a workflow we include in our code the following:

In the last line of the parent endpoint:

In the beginning of the son endpoint:

The between /** */ part also documents this test

Considerations

Huge Thanks to Clickideia, Educational Company which this tests belongs to.

Any questions? Comment! I’m not experienced with technical texts in Medium, so it can have some problems.

Written by

On expectation to turn this into a list of Software Developer usefull texts

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store