Unit Testing for Web Projects: Explained

Unit testing is…

Unit testing is a software testing method executed by developers to make sure that code meets its design and requirements and behaves as expected.

Problems Unit Testing is Solving

I’d like to tell you a little bit about unit testing, in particular, I will try to answer the main questions:

Why unit testing is important, and why we should do it.

How we can write a testable code.

In software a common thing happens when you fix a problem in one place, then you test it and everything seemingly works well. Suddenly you find out that something is wrong with your code and you try to fix it while in the meantime the other thing is broken again and you keep running around in circles all the time. In an ideal situation, you would like to test your entire application after every change to ensure that everything works properly. However, it takes a lot of time to do that manually. That’s why it’s important to have a tool which can do that instead of you. At Letzgro, we find that using PHPUnit tool is a great solution. PHPUnit is the most popular programmer-oriented testing framework for PHP. It is an instance of the xUnit architecture for unit testing frameworks.

One more important thing is that the sooner you find a bug, the easier it will be to fix it with less cost.

Basic tips on how to write a testable code:

Small methods

Low complexity

No tight coupling

It will probably make your code better and easier to understand and less tightly coupled allowing its use elsewhere.

A good practice is to write tests for new functionality before writing the code for it.

One of the goals of PHPUnit is that tests should be composable: we want to be able to run any number or combination of tests together, for instance, all tests for the whole project, or for all classes of a component that is a part of the project, or at least a single class.

PHPUnit supports different ways of organizing tests and composing them into a test suite.

Database Testing

The DbUnit extension considerably simplifies the setup of a database for testing purposes and allows you to verify the contents of a database after performing a series of operations. DbUnit currently supports MySQL, PostgreSQL, Oracle, and SQLite. Through Zend Framework or Doctrine 2 integrations, it has an access to other database systems such as IBM DB2 or Microsoft SQL Server.

Testing the database requires you to hook into at least the setup and teardown to clean-up and write the required fixture data into your tables. However, the database extension has good reason to revert the four stages in a database test to resemble the following workflow that is executed for each single test:

1. Clean-Up Database

Since there is always a first test that runs against the database, you do not know exactly if there is already data in the tables. PHPUnit will execute a TRUNCATE against all the tables you specified to reset their status to empty.

2. Set up fixture

PHPUnit will then iterate over all the fixture rows specified and insert them into their respective tables.

3–5. Run Test, Verify outcome and Teardown

After the database is reset and loaded with its initial state, the actual test is executed by PHPUnit. This part of the test code does not require awareness of the Database Extension at all, you can go on and test whatever you like with your code.

Code coverage. PHPUnit can generate HTML-based code coverage report as well as XML-based log files with code coverage information in various formats (Clover, Crap4J, PHPUnit). Code coverage information can also be reported as text (and printed to STDOUT) and exported as PHP code for further processing.

PHPUnit and Selenium. Selenium Server is a test tool that allows you to write automated user-interface tests for web applications in any programming language against any HTTP website using any mainstream browser. It performs automated browser tasks by driving the browser’s process through the operating system. Selenium tests run directly in a browser, just as real users do. These tests can be used for both acceptance testing (by performing higher-level tests on the integrated system instead of just testing each unit of the system independently) and browser compatibility testing (by testing the web application on different operating systems and browsers). The only supported scenario of PHPUnit_Selenium is that of a Selenium 2.x server. The server can be accessed through the classic Selenium RC Api, already present in 1.x, or with the WebDriver API (partially implemented) from PHPUnit_Selenium 1.2. The reason behind this decision is that Selenium 2 is backward compatible and Selenium RC is not maintained anymore.

Codeception uses PHPUnit as a backend for running tests. Thus, any PHPUnit test can be added to Codeception test suite and then executed. Codeception adds some nice helpers and modules to simplify common tasks. For the most of unit and integration testing, PHPUnit tests are just enough. They are fast and easy to maintain.