Automated testing in PHP

Work on TDD has obvious advantages: the developer always has a clearly described goal in the form of a test, and he will immediately know when it will be achieved.
However, there are some costs: you must constantly run the same test when changes are made to it or in the corresponding class, so as not to miss the very moment of truth. It seems to be not such a big problem, but constantly switching to the console to check the changes made for operability, and generally remembering the need for these manipulations is an extra dispersion of attention.

Further, how to automate this whole thing.

Why PHP?

A colleague working on PHP development on TDD was looking for an opportunity to automate the launch of tests for the just changed class, but could not find a ready-made system that satisfies his needs, and suggested that I create something similar myself, especially since for other languages ​​this is already there are even several options. "Why not?" - I thought, and now I present to you the result of my work.

What does it look like?

You make changes to the file of the developed class or test and save it. After a few moments, a pop-up message appears with information about the results of passing the corresponding test.

Complete information was deliberately removed in order to report only on the success or failure of the test, so as not to distract the developer with "extra letters", especially since he most often anticipates the result of the test.

What is needed for this?

The system consists of two autotestd and cautotest applications .

autotestd performs the following functions:
  • compares class names with their implementation files and test files
  • monitors file changes
  • runs tests and displays messages with the result
  • takes project management teams

cautotest (console autotest) - console client for autotestd - allows you to send project management commands:
  • receiving information about active projects
  • adding a new project
  • project change
  • delete project


The first step is to download autotestd from this link .

Since this is the very first version of the program and there was no sense in collecting a deb-package, I decided to confine myself to a self-written installation script - install (it is in the archive with the program):
apt-get install python2.6 python-sqlalchemy sqlite3 inotify-tools python-pyinotify python-dbus libnotify-bin python-notify
mkdir /etc/autotestd
cp config.ini /etc/autotestd/
chmod a+w /etc/autotestd
mkdir /usr/share/autotestd
cp ./*.py /usr/share/autotestd/
ln -s /usr/share/autotestd/ /usr/local/bin/autotestd

As you can see, first all the dependencies are installed, then creating directories, copying files, and finally creating a link to launch the application.

Run the script only from sudo: sudo ./install
After installation, you can run the application itself (preferably in the background): autotestd &

(In the next version I plan to make autotestd a real daemon)


Now download the cautotest client .
Installation is done by a similar command: sudo ./install
apt-get install python2.6 python-dbus
mkdir /usr/share/cautotest
cp ./*.py /usr/share/cautotest/
ln -s /usr/share/cautotest/ /usr/local/bin/cautotest

Everything is the same here.
The cautotest -h command will display help for the parameters.

This is all it takes to get started. Now go to the project directory and execute the following command:
cautotest -a project_name ./application/modules ./tests
  • -a is a parameter indicating that we are adding a project
  • project_name - the name of the project under which it will be registered in autotestd
  • ./application/modules - path to the directory containing the classes of your application (classes are searched recursively, starting from this directory)
  • ./tests - path to the directory containing the tests

IMPORTANT! Comparison of application classes and tests is done by class name:

class MyClass extends XXX {
class MyClassTest extends UnitTest {

Such naming is accepted at our work. If it is different for you, you can easily fix it by changing the regular expressions used to match them in the /etc/autotestd/config.ini file.

On this, all preparation ends.

The cautotest -l (“l”) command will display something like this: For more information, use the cautotest -i testp command : Now try changing any class in your project. When saving, the corresponding test will be launched and a message will be displayed.
hdg700@laptop:~$ cautotest -l
Active projects:
- testp
Use '-i project_name' for more information

hdg700@laptop:~$ cautotest -i testp
Project: testp
Code dir: /home/hdg700/work/testproj/code/
Test dir: /home/hdg700/work/testproj/test/
Classes: 1
Tests: 1

How it works?

Both applications are written in Python2.6.

Inotify is used to track file changes and, accordingly, a bundle for python: python-pyinotify.

DBus is used to communicate with the client, which allows you to quickly and painlessly add other interfaces for project management and feedback in the future.

The system calls phpunit with a specific file for testing. You can correct the command and add the necessary arguments in the program config.

Sqlite3 is used to store information about projects; sqlalchemy is used to communicate with sqlite.

What interesting things turned out during work?

  1. Launching external programs: if you do not intercept the stdin, stdout and stderr of the running program, then when your application is running in the background (autotest &), its execution stops at the start of the external program until you do fg. This feature has pretty tattered my nerves, but in the end everything turned out to be logical: it is enough to intercept stdin, stdout and stderr.
  2. Session-bus DBus works in the environment of one user, therefore applications using it should be launched from one user (tautology to enhance attention :). When putting autotestd into daemon mode, you will need to use system-bus.


You have reviewed the first version of the autotest for PHP. I hope someone comes in handy and brightens up the gray days. :)
Those who want to see some additional functionality, or complain about bugs, please write in the issues sections on githab: autotestd-issues and cautotest-issues .

And the last one. Add to watchers to projects: this way you will be able to receive notifications of changes, and I will see whether it is worth developing them (projects) further.

Thanks for attention.

Also popular now: