Testing Environment


Overview

Phalcon has always had a small development community and not that many pull requests, offering bug fixes and enhancements, compared to other PHP frameworks. 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 we announced this plan and a few months later we released the language and rewrote all the Phalcon code in Zephir. We have been using Zephir ever since for developing Phalcon.

The problem

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, Beanstalkd etc.)

If one considers the PHP version also (PHP 7.2, 7.3 etc.), developing for Phalcon is not an easy task, because of all these prerequisites.

Solution

We have tried in the past to create a development environment based on docker, but after a while, maintaining this environment was very taxing for the core team.

Recently however, we have redoubled our efforts to create this environment and we decided to use nanobox. For those that do not know, nanobox is a “wrapper” to docker which creates a unique environment in your machine, ready to use. The environment is folder based so you could potentially have two folders where you have cloned Phalcon, and use the PHP 7.2 on one and the 7.3 on the other. Each of those environments is completely isolated. We have been using nanobox for a while now and it is working extremely well.

Installation

You will first need to have docker installed on your machine. Instructions on how to do that, can be found here.

Go to and create an account if you do not have one already, so that you can download the nanobox installation file for your platform.

Once the file is downloaded, install it.

Running the environment

Fork the 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.

  1. git clone [email protected]:niden/cphalcon

Copy the boxfile

Nanobox reads a file called boxfile.yml and located in the root of your folder. There are two files supplied in Phalcon that you can use to develop with. One for PHP 7.2 and one for 7.3. Copy one of them to the root of the folder you have cloned your repository.

  1. cd ./cphalcon
  2. cp -v ./tests/_ci/nanobox/boxfile.7.2.yml ./boxfile.yml

You will now end up with a boxfile.yml file at the root of your project.

Configure nanobox

Now we need to run nanobox for the first time. Since this will be the first time you run nanobox, it will ask you to configure it. The installation is very simple

  1. nanobox run

It will ask you to log in first. Type your nanobox username and password, the same credentials you used when creating the nanobox account, so that you can download the installation file.

  1. $ nanobox login
  2. Nanobox Username: niden
  3. Nanobox Password:
  • a lightweight VM (Virtualbox)
  • docker nativeIt is highly recommended you use docker (hence the requirement above to ensure that you have docker installed).

Please answer the following questions so we can customize yournanobox configuration. Feel free to update your config at anytime by running: 'nanobox configure'

(Learn more at : )

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:

Run nanobox

After finishing the configuration, you will see nanobox trying to download a lot of packages and containers. This is normal and it is going to take a while depending on the connection speed you have. After packages and containers are downloaded, subsequent runs will use cached copies of those packages (unless there is an update).

Once the whole process finishes, you will end up with a screen that looks like this:

  1. Preparing environment :
  2. **
  3. ********
  4. ***************
  5. *********************
  6. *****************
  7. :: ********* ::
  8. :: *** ::
  9. ++ ::: ::: ++
  10. ++ ::: ++
  11. ++ ++
  12. +
  13. _ _ ____ _ _ ____ ___ ____ _ _
  14. |\ | |__| |\ | | | |__) | | \/
  15. | \| | | | \| |__| |__) |__| _/\_
  16. --------------------------------------------------------------------------------
  17. + You are in a Linux container
  18. + Your local source code has been mounted into the container
  19. + Changes to your code in either the container or desktop will be mirrored
  20. + If you run a server, access it at >> 172.18.0.2
  21. --------------------------------------------------------------------------------

You are now inside the environment with all the extensions and services you need. Please note that the IP shown will most likely be different than the one displayed above.

Composer

Just in case update composer:

Check Zephir

Zephir is already installed in the environment. Just check it:

  1. zephir help

A screen like the one below should appear:

  1. Usage:
  2. help [options] [--] [<command_name>]
  3. Arguments:
  4. command The command to execute
  5. command_name The command name [default: "help"]
  6. Options:
  7. --format=FORMAT The output format (txt, xml, json, or md) [default: "txt"]
  8. --raw To output raw command help
  9. -q, --quiet Do not output any message
  10. -V, --version Display this application version
  11. --ansi Force ANSI output
  12. --no-ansi Disable ANSI output
  13. -n, --no-interaction Do not ask any interactive question
  14. --dumpversion Print the Zephir version and don't do anything else
  15. -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
  16. Help:
  17. The help command displays help for a given command:
  18. php /data/bin/zephir help list
  19. You can also output the help in other formats by using the --format option:
  20. php /data/bin/zephir help --format=xml list
  21. To display the list of available commands, please use the list command.

Phalcon is not compiled yet. We need to instruct Zephir to do that:

  1. zephir fullclean
  2. zephir build

Check extensions

Type

  1. php -m

and you will see:

  1. [PHP Modules]
  2. apcu
  3. Core
  4. ctype
  5. ....
  6. PDO
  7. pdo_mysql
  8. pdo_pgsql
  9. pdo_sqlite
  10. phalcon
  11. Phar
  12. psr
  13. redis
  14. ...
  15. [Zend Modules]
  16. Xdebug

Note that Phalcon v4+ requires the 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.

Running tests

Unit

We need to first build the Codeception base classes. This needs to happen every time new functionality is introduced in Codeception’s helpers.

  1. codecept build

The output should show:

Now we can run the tests:

  1. 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 blog post, we have Tests: 2884, Assertions: 6987, Skipped: 1478 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!

Integration

Integration tests need to access the databases. These databases are already available in the environment. To populate the databases you will need to run the following script:

  1. ./tests/_ci/nanobox/setup-dbs-nanobox.sh

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:

  1. cd ./cphalcon/
  2. nanobox info local

You will see an output as the one below:

  1. cphalcon (dev) Status: up
  2. ----------------------------------------
  3. Mount Path: /Work/niden/cphalcon
  4. Env IP: 172.18.0.2
  5. data.beanstalkd
  6. IP : 172.18.0.4
  7. data.memcached
  8. IP : 172.18.0.5
  9. data.mongodb
  10. IP : 172.18.0.6
  11. data.mysql
  12. IP : 172.18.0.7
  13. User(s) :
  14. root - MvquBdnJkv
  15. nanobox - 12oK9JHiyT
  16. data.postgres
  17. User(s) :
  18. nanobox - ohhtrUaMEu
  19. data.redis
  20. IP : 172.18.0.37
  21. Environment Variables
  22. DATA_BEANSTALKD_HOST = 172.18.0.4
  23. DATA_MEMCACHED_HOST = 172.18.0.5
  24. DATA_MONGODB_HOST = 172.18.0.6
  25. DATA_MYSQL_ROOT_PASS = MvquBdnJkv
  26. DATA_POSTGRES_USER = nanobox
  27. DATA_POSTGRES_PASS = ohhtrUaMEu
  28. DATA_POSTGRES_USERS = nanobox
  29. DATA_REDIS_HOST = 172.18.0.37
  30. APP_NAME = dev
  31. DATA_MYSQL_NANOBOX_PASS = 12oK9JHiyT
  32. DATA_MYSQL_PASS = 12oK9JHiyT
  33. DATA_MYSQL_USERS = root nanobox
  34. DATA_POSTGRES_HOST = 172.18.0.8
  35. DATA_POSTGRES_NANOBOX_PASS = ohhtrUaMEu
  36. DATA_MYSQL_HOST = 172.18.0.7
  37. DATA_MYSQL_USER = nanobox
  38. DNS Aliases
  39. none

You can use these variables to connect to your databases or other services such as Mongo, Redis etc.

Development

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:

  1. zephir fullclean
  2. zephir build

and then you can run your tests

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

Services

The available services are:

  • Memcached
  • Mongodb
  • Mysql
  • Postgresql
  • RedisThe PHP extensions enabled are:

  • apcu

  • ctype
  • curl
  • dom
  • fileinfo
  • gd
  • gmp
  • gettext
  • imagick
  • iconv
  • igbinary
  • json
  • memcached
  • mbstring
  • mongodb
  • opcache
  • phar
  • pdo
  • pdo_mysql
  • pdo_pgsql
  • pdo_sqlite
  • redis
  • session
  • simplexml
  • tokenizer
  • yaml
  • zephir_parser
  • xdebug
  • xml
  • xmlwriter
  • zip
  • zlibThe database dumps are located under tests/_data/assets/db/schemas

<3 Phalcon Team