When I try to run my PHP Codeception test environment through Docker in my project, I get the following error:
docker-compose run --rm codecept run ui_automation
SignupCest --env staging --debug
Starting qa-end-to-end-tests_db_1 ... done
Creating qa-end-to-end-tests_codecept_run ... done
==== Redirecting to Composer-installed version in
vendor/codeception. You can skip this using --no-
redirect ====
Command "run ui_automation" is not defined.
So, I run the same command with --no-redirect and I get this error:
In ParamsLoader.php line 51:
Failed loading params from .env
`vlucas/phpdotenv` library is required to parse .env
files.
Please install it via composer: composer require
vlucas/phpdotenv
So I run composer "require vlucas/phpdotenv" and get that it's already installed, which I believe is correct:
~/git/qa-end-to-end-tests $ composer require
vlucas/phpdotenv
Using version ^5.2 for vlucas/phpdotenv
./composer.json has been updated
Running composer update vlucas/phpdotenv
Loading composer repositories with package information
Updating dependencies
Nothing to modify in lock file
Installing dependencies from lock file (including
require-dev)
Nothing to install, update or remove
Package container-interop/container-interop is
abandoned, you should avoid using it. Use psr/container
instead.
Generating autoload files
45 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
I say it's already installed because this is what's in my composer.json:
{
"require-dev": {
"codeception/robo-paracept": "^0.4.2",
"codeception/codeception": "^4.1.9",
"codeception/module-phpbrowser": "^1.0.0",
"codeception/module-asserts": "^1.0.0",
"codeception/module-webdriver": "^1.1",
"phpunit/phpunit": "^9.4"
},
"require": {
"ext-zip": "^1.15",
"guzzlehttp/guzzle": "^7.2",
"vlucas/phpdotenv": "^5.2"
},
"autoload": {
"psr-4": {
"Tests\\Support\\": "tests/_support",
"UiAutomationTester\\": "
"tests/_support/UiAutomation.php"
}
}
}
And there's a vlucas/photoenv folder in my /vendor folder
My environment is as such:
php 7.4.12
Mac OS Catalina 10.15.6
Composer 2.0.5
Codecept 4.1.11
Docker 19.03.13
Docker compose 1.27.4,
This started happening when a dev uploaded a new .env file, but it is working on everyone's machine except mine. I have tried uninstalling and reinstalling docker and uninstalling and reinstalling composer. This is my first PHP work project, I'm not very familiar with PHP in general.
My docker yaml:
version: '3'
services:
codecept:
image: codeception/codeception
depends_on:
selenium-hub:
condition: service_healthy
chrome:
condition: service_healthy
web:
condition: service_started
volumes:
- .:/project
web:
image: php:7-apache
depends_on:
- db
volumes:
- .:/var/www/html
db:
image: percona:5.6
selenium-hub:
image: selenium/hub
ports:
- "4444:4444"
environment:
GRID_MAX_SESSION: 1
GRID_BROWSER_TIMEOUT: 3000
GRID_TIMEOUT: 3000
healthcheck:
test: ["CMD", "curl", "-f",
"http://localhost:4444/grid/api/proxy"]
interval: 10s
timeout: 10s
retries: 6
start_period: 10s
chrome:
image: selenium/node-chrome-debug
container_name: web-automation_chrome
depends_on:
- selenium-hub
environment:
HUB_PORT_4444_TCP_ADDR: selenium-hub
HUB_PORT_4444_TCP_PORT: 4444
NODE_MAX_SESSION: 1
NODE_MAX_INSTANCES: 1
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:5555"]
interval: 10s
timeout: 10s
retries: 6
start_period: 10s
volumes:
- /dev/shm:/dev/shm
ports:
- "5900:5900"
links:
- selenium-hub
The reason this is happening despite the dependency being required in the composer.json
file is that this is the composer.json
file of your project, and not the one Codeception uses. Codeception is installed into its Docker image separately into /codecept
, has its own vendor
, and its own dependencies.
I went around this problem by extending the native image, and adding the necessary deps myself.
FROM codeception/codeception:4.1.21
RUN --mount=type=ssh rm composer.lock; \
set -eux; \
composer require \
vlucas/phpdotenv:^5 \
composer update --no-dev --prefer-dist --no-interaction --optimize-autoloader --apcu-autoloader
What if you want to use some additional extension or helper? Would you have to update and re-build your image every time? What if the helper is specific to the project, and lives in the same repo/package as the code you are going to test? For this, there's another way of loading dependencies.
Codecption can be configured to use a bootstrap script every time it runs. This is just a PHP script, and therefore may load other files via e.g. require
. These files may contain other scripts and classes. One of these scripts can be your project's Composer autoload.php
file. That means you can add something like this to the bootstrap.php
that is being used for your tests, assuming it lives 2 directories under your project root e.g. tests/acceptance
:
$projectDir = dirname(__FILE__, 2);
require_once("$projectDir/vendor/autoload.php");
From here on, the dependencies of your project will be available to any Codeception run that includes your bootstrap.