Entorno de prueba

Preámbulo
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. Esto se debía principalmente a que la mayoría de desarrolladores no sabe programar en C. Por este motivo se creo Zephir, un nuevo lenguaje con una sintaxis similar a la de PHP o JavaScript. En 2003 se presentó este plan y algunos meses después se lanzó Zephir y Phalcon fue completamente reescrito en él. 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. También deben estar instaladas todas las extensiones relevantes de PHP.
Dada toda la funcionalidad que Phalcon ofrece, sólo para ejecutar la suite de pruebas se necesita tener instalado un gran número de extensiones y servicios (Redis, Memcached, Beanstalkd, etc.)
El problema se vuelve más complejo aún si se piensa además en todas las versiones de PHP (7.2, 7.3, etc.) que se deben probar; con todos estos pre requisitos, el desarrollo de Phalcon no es en definitiva una tarea fácil.
La solución
Originalmente se ensayó a crear un entorno de desarrollo basado en Docker, pero después de cierto tiempo, la manutención de este entorno se volvió muy exigente para el equipo principal.
Sin embargo recientemente, se decidió redoblar los esfuerzos y recrear este entorno mediante el uso de nanobox. Nanobox es un envoltorio sobre Docker que crea un entorno de desarrollo único en el PC, listo para usar. El entorno se vale del sistema de carpetas y archivos, entonces es posible tener dos carpetas donde se ha clonado Phalcon y ejecutar PHP 7.2 en una y 7.3 en la otra. Cada uno de dichos entornos está completamente aislado. Hasta la fecha, Nanobox funciona muy bien.
Instalación
El primer paso es tener Docker instalado. Si necesita ayuda, aquí puede encontrar las instrucciones de instalación.
El segundo es ir a https://nanobox.io y crear una cuenta o ingresar con una existente para descargar la versión de Nanobox indicada para su sistema operativo.
El tercer paso es instalar la versión descargada.
Ejecución del entorno
Clonación (fork) del repositorio
Es necesario clonar (fork) cphalcon en su cuenta de Github (si aún no se ha hecho): En la página cphalcon dé un clic al botón Fork
en la parte superior derecha de la pantalla.
Copia del fork
Ahora es necesario clonar el fork en una carpeta cualquiera del PC. En el siguiente ejemplo se utiliza como cuenta de Github niden
(debe ser remplazada por la apropiada):
Copia del boxfile
Nanobox lee un archivo llamado boxfile.yml
, ubicado en la raíz de la carpeta. Phalcon ofrece dos archivos para facilitar el desarrollo: uno para PHP 7.2 y otro para 7.3. Se debe copiar alguno de ellos a la raíz de la carpeta en la que se clonó el repositorio.
cd ./cphalcon
cp -v ./tests/_ci/nanobox/boxfile.7.2.yml ./boxfile.yml
Aparecerá entonces el archivo boxfile.hml
en la raíz de la carpeta del proyecto.
Configuración de Nanobox
Ahora se puede ejecutar Nanobox. Por ser la primera vez, es necesario seguir los pasos de configuración, muy sencillos:
Ahora se debe iniciar la sesión utilizando los mismos nombre de usuario y contraseña de la cuenta de Nanobox para poder iniciar la descarga del archivo de instalación.
$ nanobox login
Nanobox Username: niden
Nanobox Password:
También es necesario configurar Nanobox. Se debe escoger cómo se quiere que trabaje. Hay dos opciones: * Máquina Virtual (VM, por sus siglas en inglés) liviana utilizando Virtualbox * Docker nativo
Se recomienda escoger la opción b, Docker nativo (de aquí que se aconsejara instalar Docker desde el principio) como respuesta al final de los siguientes párrafos en la terminal, después de Answer
:
CONFIGURE NANOBOX
---------------------------------------------------------------
Please answer the following questions so we can customize your
nanobox configuration. Feel free to update your config at any
time by running: 'nanobox configure'
(Learn more at : https://docs.nanobox.io/local-config/configure-nanobox/)
How would you like to run nanobox?
a) Inside a lightweight VM
b) Via Docker Native
Note : Mac users, we strongly recommend choosing (a) until Docker Native
resolves an issue causing slow speeds : http://bit.ly/2jYFfWQ
Answer:
Ejecución de Nanobox
Terminada la configuración, Nanobox empezará a descargar un montón de paquetes y contenedores. Esto es normal y tardará un poco según la velocidad de conexión del sistema. Finalizada la descarga, todas las ejecuciones posteriores utilizarán estos paquetes y contenedores (salvo que haya alguna actualización disponible).
Al terminar el proceso de instalación, aparecerá una ventana similar a esta:
Preparing environment :
**
********
***************
*********************
*****************
:: ********* ::
:: *** ::
++ ::: ::: ++
++ ::: ++
++ ++
+
_ _ ____ _ _ ____ ___ ____ _ _
|\ | |__| |\ | | | |__) | | \/
| \| | | | \| |__| |__) |__| _/\_
--------------------------------------------------------------------------------
+ You are in a Linux container
+ Your local source code has been mounted into the container
+ Changes to your code in either the container or desktop will be mirrored
+ If you run a server, access it at >> 172.18.0.2
--------------------------------------------------------------------------------
Esto significa que la instalación ha sido exitosa y ahora están a su alcance todas las extensiones y servicios necesarios. Nota: Es probable que la IP 172.18.0.2
que aparece al final del ejemplo sea diferente en su sistema.
Composer
Por precaución es preferible actualizar composer
:
Check Zephir
Zephir is already installed in the environment. Just check it:
Debe aparecer una pantalla similar a la siguiente:
Usage:
help [options] [--] [<command_name>]
Arguments:
command The command to execute
command_name The command name [default: "help"]
Options:
--format=FORMAT The output format (txt, xml, json, or md) [default: "txt"]
--raw To output raw command help
-h, --help Display this help message
-q, --quiet Do not output any message
-V, --version Display this application version
--ansi Force ANSI output
--no-ansi Disable ANSI output
-n, --no-interaction Do not ask any interactive question
--dumpversion Print the Zephir version — and don't do anything else
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
Help:
The help command displays help for a given command:
php /data/bin/zephir help list
You can also output the help in other formats by using the --format option:
php /data/bin/zephir help --format=xml list
To display the list of available commands, please use the list command.
Compilación de Phalcon
Phalcon aún no está compilado. Hay que darle las instrucciones a Zephir para que lo haga:
/app $ zephir fullclean
/app $ zephir build
Check Extensions
Tipo
y se debe recibir:
[PHP Modules]
apcu
Core
ctype
....
PDO
pdo_mysql
pdo_pgsql
pdo_sqlite
phalcon
Phar
psr
redis
...
[Zend Modules]
Xdebug
Note that Phalcon v4+ requires the PSR extension to be loaded before Phalcon. In this environment we have compiled it for you. Once you see phalcon
in the list, you have the extension compiled and ready to use.
Setup databases
First, we need to have a .env
file in the project root.
/app $ cp tests/_ci/nanobox/.env.example .env
To generate the necessary database schemas, you need to run the relevant script:
/app $ php tests/_ci/generate-db-schemas.php
The script looks for classes located under tests/_data/fixtures/Migrations
. These classes contain the necessary code to create the relevant SQL statements for each RDBMS. You can easily inspect one of those files to understand its structure. Additionally, these migration classes can be instantiated in your tests to clear the target table, insert new records etc. This methodology allows us to create the database schema per RDBMS, which will be loaded automatically from Codeception, but also allows us to clear tables and insert data we need to them so that our tests are more controlled and isolated.
If there is a need to add an additional table, all you have to do is create the Phalcon model of course but also create the migration class with the relevant SQL statements. Running the generate script (as seen above) will update the schema file so that Codeception can load it in your RDBMS prior to running the tests.
To populate the databases you will need to run the following script:
/app $ tests/_ci/nanobox/setup-dbs-nanobox.sh
Pruebas en ejecución
Unit
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:
/app $ vendor/bin/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:
/app $ php vendor/bin/codecept run unit
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: 3235, Assertions: 8244, Skipped: 175
unit tests. The reason for so many skipped tests is because we created test stubs for every component and every method in each component. This was so as to create awareness on what needs to be checked and what components/methods we need to write tests for. Of course some of the 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:
/app $ php vendor/bin/codecept run tests/unit/some/folder/
Execute single test:
/app $ php vendor/bin/codecept run tests/unit/some/folder/some/test/file.php
Base de Datos
To run database related tests you need to run the database
suite specifying the RDBMS and group:
/app $ php vendor/bin/codecept run tests/database -g common
/app $ php vendor/bin/codecept run tests/database -g mysql --env mysql
/app $ php vendor/bin/codecept run tests/database -g sqlite --env sqlite
/app $ php vendor/bin/codecept run tests/database -g pgsql --env pgsql
Available options:
--env mysql
--env sqlite
--env pgsql
If you need to access the databases themselves, you will need the connection information. Nanobox creates that for you and stores it in environment variables. You can easily check those variables and if need be write them down.
Open a separate terminal and navigate to the same folder where you have nanobox running from and type:
cd ./cphalcon/
nanobox info local
You will see an output as the one below:
----------------------------------------------
cphalcon (dev) Status: up
----------------------------------------------
Mount Path: /home/niden/cphalcon
Env IP: 172.20.0.20
data.memcached
IP : 172.20.0.23
data.mongodb
IP : 172.20.0.24
data.mysql
IP : 172.20.0.25
User(s) :
root - 9IqTGEVM2M
nanobox - yXOMmf71NS
data.postgres
IP : 172.20.0.21
User(s) :
nanobox - exwjG6g6rm
data.redis
IP : 172.20.0.22
Environment Variables
DATA_MONGODB_HOST = 172.20.0.24
DATA_MYSQL_HOST = 172.20.0.25
DATA_MYSQL_ROOT_PASS = 9IqTGEVM2M
DATA_MYSQL_USER = nanobox
DATA_POSTGRES_PASS = exwjG6g6rm
APP_NAME = dev
DATA_MYSQL_NANOBOX_PASS = yXOMmf71NS
DATA_MYSQL_USERS = root nanobox
DATA_POSTGRES_HOST = 172.20.0.21
DATA_POSTGRES_USER = nanobox
DATA_MEMCACHED_HOST = 172.20.0.23
DATA_POSTGRES_NANOBOX_PASS = exwjG6g6rm
DATA_POSTGRES_USERS = nanobox
DATA_REDIS_HOST = 172.20.0.22
DATA_MYSQL_PASS = yXOMmf71NS
DNS Aliases
none
You can use these variables to connect to your databases or other services such as Mongo, Redis etc.
Desarrollo
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:
/app $ zephir fullclean
/app $ zephir build
and then you can run your tests
/app $ codecept run tests/unit/somefolder/somecestfile:sometest
For Zephir documentation, you can visit the Zephir Docs site.
Servicios
The available services are: - Memcached - Mongodb - 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
The database dumps are located under tests/_data/assets/schemas
If you have any questions, feel free to join us in our Discord server or our Forum.
<3 Phalcon Team