PHP Test Driven Development Part 2: Unit Testing

Sameer Nyaupane
5 min readDec 14, 2017

--

All right, welcome to part 2 of “PHP Test Driven Development” series. Today we will go through the PHPUnit setup in detail.

Please check out Part 1, if you have not read it yet: https://hackernoon.com/php-test-driven-development-part-1-introduction-5483362d79b5

If you would also like to check out the accompanying YouTube video, here’s the link:

We will be using the Laravel framework to make it easier for us to get started. It will also help me to show you how to do testing for real life applications.

I will assume you have used Laravel before. This will help me focus on the testing side and make the tutorial easier to grasp. If you are new to Laravel, I highly recommend you to check out the “Laravel From Scratch 2017” series by Jeffery Way.

Here we go, let’s get ready to rumble! ;)

Step 1: Install new Laravel project

You can just run the following command:

composer create-project --prefer-dist laravel/laravel laravel5

where “laravel5” is your target folder.

This will install the latest Laravel version for you.

For other ways to install Laravel, please check the documentation: https://laravel.com/docs/5.7/installation

If you are on Linux/Mac, you also need to set write permissions to storage and the bootstrap/cache directories for your webserver user, usually (www-data).

Step 2: Setup PHPUnit

One of the great things about Laravel is that PHPUnit is already installed by default.

Let’s see what we’ve got by default in the folder structure.

So inside our root directory we have the tests folder. “Unit” folder contains a default unit test. The “Feature” folder, as you guessed, has a default feature test. Feature tests are basically Functional tests we described on part 1, just the naming is different. Since we are focusing on unit tests for this part, you can go ahead and delete the “Feature” folder.

Another file that is of importance is the phpunit.xml file in the root directory.

This file contains all the phpunit settings we need. As you may have noticed, since we removed the “Feature” folder, we can remove that <testsuite> tag contents too. So let’s go ahead and remove the section shown in the image below.

Now, open up your command prompt and navigate to your installation folder, which is the “laravel5” folder mentioned above in step 1. Now type “vendor\bin\phpunit”. FYI, I am using a windows machine for this tutorial, so please make the necessary changes to the command for your OS if you need to.

You should see something like this below:

On a note, the above screen has no colors. TDD is all about the red-green refactor cycle, so a visual feedback will bring us a long way. I recommend you use something like ConEmu for a better console emulator. Below is the same command under ConEmu.

Note I just used the command “phpunit” instead of “vendor\bin\phpunit”. ConEmu supports alias feature, where you can store long commands as a short alias.

All right, let’s move on. Great, one test with one assertion was run successfully! This is the default unit test that comes with Laravel.

Let’s see what it contains:

First thing the unit test has is a namespace. This is a good practice to follow. Namespacing different test types will prevent us from naming conflicts.

The first use statement references the ‘TestCase’ class inside the ‘Tests’ namespace. In the above code snippet, on line 8, we can see that it is being extended by our ExampleTest class. So let’s jump to the file and see what it has.

So TestCase actually extends BaseTestCase which has a bunch of helper functions. And the trait CreatesApplication contains code to instiantiate a class through the Laravel’s IoC container. These will be very helpful for Integration and Functional tests. But since we are currently doing unit tests, we won’t need to extend this TestCase file at all. Let’s keep it minimal. We’ll extend the PHPUnit’s default TestCase class instead.

Also going back to our ExampleTest file, we have another use statement that references RefreshDatabase feature. We won’t need that for unit tests. This is because we do not interact with a database at all when writing unit test cases. So let’s remove that line too.

Now, this is how our ExampleTest file looks like:

The next thing we see here are the method comments. We do not usually write comments for test methods. We instead write annotations that modify the behavior when the test runs. We won’t need any annotations right now, so we’re good for now. So let’s get rid of that too.

Now coming to the method naming standard. Here the convention is camel case because it is a simple test. But I would encourage you to follow a standard. I personally use this standard(combination of camelCase and snake_case:

test_nameOfTheMethodYouAreTesting_WhenCalledWithSomeInput_ShouldReceiveSomeExpectedOutput

So for an example it would be something like this:

test_verifyUser_WhenCalledWithCorrectUserDetails_ShouldReceiveVerifiedMessage

Now, finally we see the assertTrue method being called. Asserts are statements that we use to verify or check if our output is what we need. Here assertTrue is checking if the supplied boolean value of “true” is true. Since “true” is indeed “true” ;), the assertion passes.

assertTrue is one of the assertion methods in around 50 of them.

Check out the “Assertions” section of the official PHPUnit documentation here: https://phpunit.de/manual/current/en/appendixes.assertions.html

Don’t worry, we won’t need to memorize all of them. In fact, you will be reusing most of the same ones for majority of the tests you write. We will be learning about most of the frequently used ones as we go through the series.

This is how our file looks like finally:

All right, we went through the PHPUnit setup and learnt a little bit about unit testing on the way. In the next part we will learn how to mock objects and write real world test cases for you to better grasp the topic.

Thanks for making it until here. Oh yes, did you 👏yet? No? Please do it now then. 😉 Also don’t forget to subscribe for the next episode.

Questions? Leave them on the comments below.

Link to part 3: https://medium.com/@sameernyaupane/php-test-driven-development-part-3-unit-testing-continued-db5d332197ec

Check out my other series at:

--

--