Having a framework that is rich in features requires a development environment that will offer all those features and related services. For instance one needs to install MySQL, Postgresql and Sqlite to be able to check whether functionality in the ORM will be the same when using any of these adapters for your database needs. Additionally, the relevant extensions for PHP have to be installed in the development system.
When looking at all the functionality that Phalcon offers, just to run the testing suite, one needs a great number of extensions as well as services installed (Redis, Memcached etc.)
If one considers the PHP version also (PHP 7.4, 8.0 etc.), developing for Phalcon is not an easy task, because of all these prerequisites.
We had a good solution with nanobox in the past but since that project has been discontinued, we redoubled our efforts and used docker for our needs. With a few commands, developers can be contributing to phalcon as well as running the tests in no time.
You will first need to have docker installed on your machine. Instructions on how to do that, can be found here. Additionally, we will need docker-compose. Installation instructions can be found here
Running the Environment
Fork the Repository
Fork the cphalcon to your GitHub account, if you have not done so already. Visit the cphalcon page on your browser and click the Fork button at the top right of the screen.
Clone the Fork
Now you will need to clone the forked repository to a folder of your choice. The example below assumes that the GitHub account is niden - change it to your own.
Once you are in cphalcon folder (or wherever you cloned the repository), you will need to build the containers
This will be a lengthy process, depending on the specifications of your machine. This process is not run frequently, only when there are changes in the dockerfiles.
Start the environment
Once all the containers have been built, you will need to start it. You can start it with the containers exposing ports to your host or without.
docker-compose up -d
The above command uses the docker-compose.yml file from the repository. The -d command runs the environment in the background, and you can reuse your terminal. Without this option, you will have to use Ctrl-C to stop it.
With the above command, the services containers will bind their respective ports to your host.
You can then connect to your environment from your host directly. For example to connect to the mysql database, you will just need localhost as your host, since the 3306 port is bound.
This configuration is very handy and works well for most developers. However, there are developers that work on many projects at the same time, and those projects use the same services (i.e. mysql). Using this configuration will not allow a second environment to work, that uses mysql in the same manner, because the mysql port on the host is already in use.
You can therefore, use the docker-compose-local.yml file, which does not expose ports from the services containers to the host, keeping everything isolated.
docker-compose -f docker-compose-local.yml up -d
If you use the above command to start your environment, you will need to know the IP address of a service container that you need to connect to. If, for instance, you need to connect to the mysql container, using localhost as your host will not work. You will need to find the correct IP address:
docker inspect cphalcon-mysql
cphalcon-mysql is the name for the mysql service. You can check the docker-compose-local.yml file if you are interested in finding the names of the containers. The above command will produce:
Zephir is already installed in the environment. Just check it:
A screen like the one below should appear (output formatted for reading):
_____ __ _
/__ / ___ ____ / /_ (_)____
/ / / _ \/ __ \/ __ \/ / ___/
/ /__/ __/ /_/ / / / / / /
/____/\___/ .___/_/ /_/_/_/
Zephir 0.16.2 by Andres Gutierrez and Serghei Iakovlev (3e961ab)
--dumpversion Print the version of the compiler and don't
do anything else (also works with a single hyphen)
-h, --help Print this help message
--no-ansi Disable ANSI output
-v, --verbose Displays more detail in error messages from
exceptions generated by commands (can also disable with -V)
--vernum Print the version of the compiler as integer
--version Print compiler version information and quit
api Generates a HTML API based on the classes exposed in the extension
build Generates/Compiles/Installs a Zephir extension
clean Cleans any object files created by the extension
compile Compile a Zephir extension
fullclean Cleans any object files created by the extension
(including files generated by phpize)
generate Generates C code from the Zephir code without compiling it
help Display help for a command
init Initializes a Zephir extension
install Installs the extension in the extension directory
(may require root password)
stubs Generates stubs that can be used in a PHP IDE
Phalcon is not compiled yet. We need to instruct Zephir to do that:
Now that the environment is set up, we need to run the tests. The testing framework Phalcon uses is Codeception. For a basic introduction you can check this page. Also, for the list of the commands, you can check here.
We need to first build the Codeception base classes. This needs to happen every time new functionality is introduced in Codeception’s helpers.
Now you can run:
root@cphalcon-81:/srv# codecept build
The output should show:
Building Actor classes for suites: cli, database, integration, unit
-> CliTesterActions.php generated successfully. 152 methods added
\CliTester includes modules: Asserts, Cli, \Helper\Cli, \Helper\Unit
-> DatabaseTesterActions.php generated successfully. 252 methods added
\DatabaseTester includes modules: Phalcon4, Redis, Asserts, Filesystem, Helper\Database, Helper\Unit
-> IntegrationTesterActions.php generated successfully. 251 methods added
\IntegrationTester includes modules: Phalcon4, Redis, Asserts, Filesystem, Helper\Integration, Helper\PhalconLibmemcached, Helper\Unit
-> UnitTesterActions.php generated successfully. 166 methods added
\UnitTester includes modules: Apc, Asserts, Filesystem, Helper\Unit
Now we can run the tests:
This will start running the unit testing suite. You will see a lot of tests and assertions. At the time of this article, we have Tests: 2780, Assertions: 8965, Skipped: 34 unit tests. The reason for so many skipped tests is that we created test stubs for every component and every method in each component. This was to create awareness on what needs to be checked and what components/methods we need to write tests for. Of course some test stubs are duplicate or obsolete. Those will be deleted once the relevant component is checked and tests written for it. Our goal is to get as close to 100% code coverage as possible. If we manage to get to 100% that would be great!
Execute all tests from a folder:
root@cphalcon-81:/srv# codecept run tests/unit/some/folder/
Execute single test:
root@cphalcon-81:/srv# codecept run tests/unit/some/folder/some/test/file.php
To run database related tests you can use the relevant aliases:
You can now open your favorite editor and start developing in Zephir. You can create new functionality, fix issues, write tests etc. Remember though that if you change any of the zep files (inside the phalcon folder), you will need to recompile the extension:
and then you can run your tests
root@cphalcon-81:/srv# codecept run tests/unit/somefolder/somecestfile:sometest
For Zephir documentation, you can visit the Zephir Docs site.
The available services are:
The PHP extensions enabled are:
The database dumps are located under tests/_data/assets/schemas