Video Tutorial Introduction and configuration

I suggest you discover how to test its code in a Symfony application. The objective of this training is to discover both the techniques but also the objectives behind the tests.

Why test?

The tests fulfill two main objectives:

  • Check that the code works as expected.
  • Simplify the updating of our code with an automated means to ensure that we do not break anything with each modification (this is particularly relevant if we work with others because not everyone is necessarily aware of the work of others)
  • Communicate on how the code works. Reading the tests can help understand usage scenarios.

How to test?

There are several ways to test our code / application using tests.

Unit tests

They allow you to test a "unit" of code (usually a method or a function) to ensure that a piece of our code works as expected. For this type of testing we will test the code in total isolation from the rest of the system. If a method interacts with an object we will create a duplicate of this object which will simulate the different behaviors (this is called a mock or a stub).

These tests will have the advantage of being simple to write and quick to execute, but it only covers part of our system. Indeed, a component can function in isolation but not function once connected to the rest of the application. For example, an event listener may work properly but not be wired correctly in our application (for example the service might not be detected).

Functional tests

The functional tests will allow you to test a code that interacts with an external element. For example, in the case of Symfony if you want to test a repository you will have to connect it to a database to make sure that it works properly. We will no longer test our code in isolation but we will test it in the context of our application. It is also a type of test that we will use for controllers where we will try to send a false request by verifying that the response returned is indeed the expected one. We will not necessarily mock the different services but we will test our entire system.

These tests are interesting because they make it possible to ensure that our code works when it communicates with the various components of our application. However it can be more difficult to identify an error as it can come from any of these components. In general, we will reserve the use of this type of tests for controllers and repositories.

End to end tests

End to end testing involves testing the application as a standard user. We are not necessarily going to try to test code but rather our interface as a whole. These are the most complex tests to set up because we will have to control a browser in order to automate our test scenarios. There are different libraries and tools that allow you to do this, but these tests will generally take more time because you have to navigate the full application. In the same way it will be necessary to set up a system which will allow to reset the data so that each test is done on a completely virgin environment.

These tests allow you to easily see if our application contains a bug but do not allow you to quickly identify the exact cause of the problem. If for example a form cannot be submitted correctly it is difficult to know if the problem comes from the interface or if it comes from a problem on the server side or a problem from a third party service. These types provide a general overview of the proper functioning of the application.

When to test?

Now we can wonder at what stage of the project we are going to write the tests. Is it better to write the tests at the beginning or at the end of the project?

Test to verify

Tests can be used after the code and in this case are used simply to verify the code. It is not necessarily a method that is recommended because it is quite boring to write and we will tend to influence the code of the tests compared to the logic that we have already written. We can however use this method to validate the code written by someone else or when we retrieve a project.

Test then code

Also called Test driven development, this method consists of writing the tests before writing the code. This ensures that the code we write is functional before even integrating it into our application.

It is also interesting to write the tests at the same time as you write the code in order to better understand a problem.
For example, when creating a controller, we can imagine doing things this way:

  • We write a first test which verifies that the response has a status of 200.
  • We will then write the code which makes this test work (we return a simple Response instance).
  • We are now writing a second test where we are waiting for a very specific title
  • We write the code to validate this test
  • We write a third test to explain that we are waiting for a listing of 9 products
  • We write the code to validate this test
  • And so on...

This approach, also called tests first, allows testing to be used as a way to break down complex problems into smaller, easy-to-solve problems.

And symfony in all this?

Symfony has by default a configuration allowing to quickly launch the tests using PHPUnit.

php bin / phpunit

So there is nothing to configure to start using the tests. On the other hand, it can be difficult to know what to test and how to test it, this is why I suggest you take an overview of the different components of the framework and the writing of the associated tests.