Secciones

Entorno de prueba


Resumen

La comunidad de Phalcon es pequeña y no cuenta con muchos pull requests, correcciones de errores o mejoras comparada con otros frameworks de PHP. This was primarily due to the fact that most developers do not really know C. To help developers contribute, we have created a new language called Zephir, which has a very similar syntax to PHP or Javascript. In 2003, we announced this plan and a few months later we released the language and rewrote all the Phalcon code in Zephir. Desde entonces se utiliza Zephir para el desarrollo de Phalcon.

El problema

Un framework rico en características necesita un entorno de desarrollo con todos los servicios necesarios para utilizarlas. Por ejemplo, es necesario tener instalados MySQL, Postgresql y Sqlite para comprobar que la funcionalidad del Mapeo objeto-relacional (ORM, por sus siglas en inglés) será igual en todos los adaptadores según la base de datos que necesite la aplicación. 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.

La solución

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.

Instalación

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

Ejecución del entorno

Clonación (fork) del repositorio

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.

Copia del fork

Ahora es necesario clonar el fork en una carpeta cualquiera del PC. The example below assumes that the GitHub account is niden - change it to your own.

git clone [email protected]:niden/cphalcon

Build the environment

Once you are in cphalcon folder (or wherever you cloned the repository), you will need to build the containers

docker-compose build 

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.

Service Port
mysql 3306
postgres 5432
redis 6379

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:

[
    {
        "Id": "121513ec37c31bcb717526b5f792e373534a9d7187db5d919d30e8c89a7cc897",
        "Created": "2022-09-01T16:05:38.440859071Z",
        "Path": "docker-entrypoint.sh",
        "Args": [
            "mysqld"
        ],
//........
        "NetworkSettings": {
            "Networks": {
                "cphalcon_default": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": [
                        "mysql",
                        "121513ec37c3"
                    ],
                    "NetworkID": "3be8b1ff3f87e11bd60c568d3a5ca04d0cd6b07779bcbe585eaac12f60bf26c9",
                    "EndpointID": "d0940c441edf26b573e2f42f7f659666c4c1535394843bc0e115ddbac947420b",
                    "Gateway": "172.18.0.1",
                    "IPAddress": "172.18.0.4",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:12:00:04",
                    "DriverOpts": null
                }
            }
        }
    }
]

Then you can connect to the container using the IPAddress

mysql -uroot -p -h172.18.0.4

Stop the environment

To stop the environment you can press Ctrl-C if you have not used the -d flag. If you have, you will need to tell docker that you no longer wish the environment to be up:

docker-compose down

Enter the Environment

To enter the environment, we will need to tell docker, which one we need. There are three environments built for us:

  • cphalcon-7.4
  • cphalcon-8.0
  • cphalcon-8.1

Each of those represents the PHP version that they have installed.

To enter the PHP 8.1 environment, we need:

docker exec -it cphalcon-8.1 /bin/bash

The following prompt will appear:

Esto significa que la instalación ha sido exitosa y ahora están a su alcance todas las extensiones y servicios necesarios.

To exit the environment, all you need is to type exit and press the enter key.

[email protected]:/srv# exit 

Alias

The environments come with predefined aliases for your terminal. You can find them all in the .bashrc file under the docker/ folder and relevant PHP version subfolder. Some of these are:

Alias Command
g git
h history
l ls -lF ${colorflag}
ll LC_ALL=”C.UTF-8” ls -alF
zephir ./zephir
zf ./zephir fullclean
zg ./zephir generate
zs ./zephir stubs
cpl zf && zg && cd ext/ && ./install && ..
codecept php -d extension=ext/modules/phalcon.so ./vendor/bin/codecept
phpcs php -d extension=ext/modules/phalcon.so ./vendor/bin/phpcs
phpcbf php -d extension=ext/modules/phalcon.so ./vendor/bin/phpcbf
psalm php ./vendor/bin/psalm
test-unit Run all unit tests
test-cli Run all cli tests
test-integration Run all integration tests
test-db-common Run all common database tests
test-db-mysql Run all mysql tests
test-db-pgsql Run all postgesql tests
test-db-sqlite Run all sqlite tests
test-db Run all database tests
test-all Run all tests

Composer

Por precaución es preferible actualizar composer:

[email protected]:/srv# composer install

Comprobar Zephir

Zephir ya está instalado en el entorno. Compruébelo:

[email protected]:/srv# zephir 

A screen like the one below should appear (output formatted for reading):

 _____              __    _
/__  /  ___  ____  / /_  (_)____
  / /  / _ \/ __ \/ __ \/ / ___/
 / /__/  __/ /_/ / / / / / /
/____/\___/ .___/_/ /_/_/_/
         /_/

Zephir 0.16.2 by Andres Gutierrez and Serghei Iakovlev (3e961ab)

Usage:
  command [options] [arguments]

Options:
      --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

Available commands:
  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

Compilación de Phalcon

Phalcon aún no está compilado. Hay que darle las instrucciones a Zephir para que lo haga:

Comprobar Extensiones

Tipo

[email protected]:/srv# php -m

y se debe recibir:

[PHP Modules]
apcu
Core
ctype
....
PDO
pdo_mysql
pdo_pgsql
pdo_sqlite
phalcon
Phar
psr
redis
...

[Zend Modules]
Xdebug

Una vez que vea phalcon en la lista, ya tiene la extensión compilada y lista para usar.

Configuración de bases de datos

Primero, necesitamos tener un fichero .env en la raíz del proyecto.

[email protected]:/srv# cp tests/_config/.env.docker .env

Pruebas en ejecución

Unitaria

Ahora que el entorno está configurado, necesitamos ejecutar las pruebas. 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.

Primero necesitamos construir las clases base de Codeception. Esto debe ocurrir cada vez que se introduce nueva funcionalidad en los ayudantes de Codeception.

Ahora puede ejecutar:

[email protected]:/srv# codecept build

La salida debería mostrar:

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

Ahora puede ejecutar las pruebas:

[email protected]:/srv# test-unit

Esto empezará ejecutando el conjunto de pruebas unitarias. Verá un montón de pruebas y afirmaciones. 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. Estos se eliminarán una vez que el componente relevante se compruebe y se escriban pruebas para él. Nuestro objetivo es acercarnos tanto al 100% de cobertura de código como sea posible. ¡Si conseguimos llegar al 100% sería genial!

Ejecutar todas las pruebas desde una carpeta:

[email protected]:/srv# codecept run tests/unit/some/folder/

Ejecutar una única prueba:

[email protected]:/srv# codecept run tests/unit/some/folder/some/test/file.php

Base de Datos

To run database related tests you can use the relevant aliases:

[email protected]:/srv# test-db-common
[email protected]:/srv# test-db-mysql 
[email protected]:/srv# test-db-pgsql 
[email protected]:/srv# test-db-sqlite
[email protected]:/srv# test-db       

Desarrollo

Ahora puede abrir su editor favorito y empezar a desarrollar en Zephir. Puede crear nueva funcionalidad, arreglar problemas, escribir pruebas, etc. No obstante, recuerde que si cambia cualquiera de los ficheros zep (dentro del directorio phalcon), necesitará recompilar al extensión:

y luego puede ejecutar sus pruebas

[email protected]:/srv# codecept run tests/unit/somefolder/somecestfile:sometest

For Zephir documentation, you can visit the Zephir Docs site.

Servicios

The available services are:

  • Memcached
  • Mysql
  • Postgresql
  • Redis

The PHP extensions enabled are:

  • apcu
  • ctype
  • curl
  • dom
  • fileinfo
  • gd
  • gmp
  • gettext
  • imagick
  • iconv
  • igbinary
  • intl
  • json
  • memcached
  • mbstring
  • mongodb
  • opcache
  • phar
  • pdo
  • pdo_mysql
  • pdo_pgsql
  • pdo_sqlite
  • redis
  • session
  • simplexml
  • sqlite3
  • tokenizer
  • yaml
  • zephir_parser
  • xdebug
  • xml
  • xmlwriter
  • zip
  • zlib

Los volcados de base de datos están ubicados bajo tests/_data/assets/schemas

If you have any questions, feel free to join us in our Discord server or our Discussions.

<3 Phalcon Team