Gitlab CI -Laravel 5.5 - PHPUnit "Tests\TestCase not found" - php

I set up a Gitlab CI Pipeline for a Laravel 5.5 project (files at the bottom of the post) and the build is succeeding, but the tests fail because PHPUnit exits with the error message
Fatal error: Class 'Tests\TestCase' not found in /builds/[User]/[Repo]/tests/Feature/DocumentTest.php on line 8
(Obviously, [User] and [Repo] aren't the real values, just don't wanna make it public here)
I've tried different things already, like installing PHPUnit globally, calling PHPUnit in different ways, it all ends up with the same error message.
PHPUnit is running successfully on my local (no matter HOW I call it, it always works). So anyone knows what the problem here might be?
For reference here are the pipeline files:
.gitlab-ci.yml:
image: woohuiren/php-laravel-env:latest
services:
- mysql:latest
- redis:4.0.2-alpine
before_script:
- apk update
- docker-php-ext-install pcntl
variables:
MYSQL_DATABASE: testdb
MYSQL_ROOT_PASSWORD: root
stages:
- build
- test
build_job:
stage: build
script:
- sh .gitlab-build.sh
artifacts:
paths:
- vendor/
- bootstrap/
- composer.phar
- .env
tags:
- docker
test_job:
stage: test
dependencies:
- build_job
script:
- sh .gitlab-ci.sh
tags:
- docker
.gitlab-build.sh:
#!/bin/bash
set -eo pipefail
php -v
ping -c 3 mysql
php composer.phar install --no-progress --no-scripts
php artisan package:discover
cp -v .env.testing .env
php artisan key:generate
php artisan optimize
php artisan config:clear
php artisan storage:link
php artisan migrate --seed
php artisan jwt:secret
php artisan passport:install --force
.gitlab-ci.sh:
#!/bin/sh
set -eo pipefail
php -v
ping -c 3 mysql
./vendor/phpunit/phpunit/phpunit -v --testdox

What is Tests\TestCase? I'm guessing line 8 in DocumentTest.php is
public class DocumentTest extends TestCase
...where TestCase is PHPUnit\Framework\TestCase. It seems like there's an autoloading problem or the file doesn't import TestCase. Try changing this line to:
public class DocumentTest extends PHPUnit_Framework_TestCase
I can try to give a better answer if you include the phpunit.xml and composer.json.

I got the same error on local though. Make sure your composer.json has
"psr-4": {
"App\\": "app/",
"Tests\\": "tests/"
},
run composer dump-autoload at least once or make it a part of your testing procedure.

Related

Travis composer install issue

I want to use travis with my simple php projects. My project structure is next:
My .travis.yml
language: php
sudo: required
before_install:
- cd http
before_script:
- cd http
install:
- composer self-update
- composer-install --no-interaction
script:
- phpunit --configuration phpunit.xml
and I want to run trevis into http folder, my composer.json and phpunit are there. However, as a result of my build, I received:
How can I solve this issue and run travis correctly? Thanks

Getting failed loading params from .env vlucas/phpdotenv library required, but library is in

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's Happening
Use the official Codeception image. This is the last of the 4.x line, which I use because there isn't great support for CC5 yet.
Enable SSH agent forwarding for this command in the build. This is necessary in order to avoid sharing sensitive info with the image, like SSH certificates which are often necessary for repo authentication.
Remove the lockfile. Doing this means effectively installing all deps from scratch, without worrying about what is upgradable in the scope of present constraints.
Ensure that the output of the subsequent command is as verbose as possible if someting goes wrong.
Add the dependencies.
Update everything in the way that's most optimized for production use.
Further
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.

Travis-Ci not following PSR-4

I am trying to learn how to use Travis-CI. My first attempt is not going well.
I have a project at https://github.com/RogerCreasy/simpleJWT
Here is my .travis.yaml
language: php
php:
- '5.4'
- '5.5'
- '5.6'
- '7.0'
before_script:
- composer self-update
- composer install --prefer-source --no-interaction --dev
script: vendor/bin/phpunit --configuration phpunit.xml
I am using PSR-4 autoloading in my composer.json file.
"autoload": {
"psr-4": {
"RogerCreasy\\SimpleJWT\\": "src"
}
},
PHPUnit tests run successfully locally. But, through Travis they fail. Travis looks for the class I am testing at the full namespace (/RogerCreasy/SimpleJWT/)
Where should I look for the problem?

Continuous integration with Laravel package and Behat

I'm developing a package for Laravel which actually needs the whole Laravel application to run the tests I wrote with Behat.
I'm using Travis as a CI service and I wonder if there is a specific .travis.yml configuration to let the tests created for my package run with a newly created Laravel application.
Basically my package consists in a trait for console commands that cannot be tested without installing Laravel itself.
I know I can install a new Laravel application by setting the install hook in .travis.yml but then I don't know how to integrate and run my tests with the app.
I'm gonna share with you my travis config file (I am using Laravel 5.1).
My file works with PHPUnit however just replace the line that runs PHPUnit with your Behat command, everything else is perfect.
.travis.yml
language: php
php:
- 5.5.9
- 5.6
- 7.0
- hhvm
matrix:
allow_failures:
- php: hhvm
before_script:
- cp .env.travis .env
- mysql -e 'create database homestead;'
- composer self-update
- composer install --prefer-source --no-interaction --dev
- php artisan migrate
- php artisan db:seed
script: vendor/bin/phpunit
You must include .env.travis as well, a sample file would look like this:
APP_ENV=testing
APP_DEBUG=true
APP_KEY=xXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxX
DB_CONNECTION=mysql
DB_HOST=localhost
DB_DATABASE=homestead
DB_USERNAME=root
DB_PASSWORD=
CACHE_DRIVER=array
SESSION_DRIVER=array
QUEUE_DRIVER=sync
you can of course use specific DB_CONNECTION that probably runs with sqlite in memory or so..

Travis configuration for composer packages

While working on a laravel 5.1+ package I have this need to run automated tests through travis-ci.org. The difference with regular automated tests is the requirement to include this package into a framework and set specific configuration options to run the tests.
So the requirement would be:
install laravel
add my package as dependency
set some travis specific configurations like the travis database access
run migrations of laravel
run migrations specific for package or run an artisan command
run package specific unit tests
I searched everywhere; asked on laravel forums, asked in a travis community chat and saw this topic being closed as too localized (although an answer would have certainly been helpful now). I'm hoping my question is fit to remain open.
At this time I have the following configuration:
language: php
php:
- 5.5
- 5.6
- hhvm
addons:
hosts:
- system.hyn.me
- tenant.hyn.me
before_install:
- sudo composer self-update
install:
- composer create-project laravel/laravel
- cd ./laravel
- composer require hyn-me/multi-tenant ~0.1.0
- composer update
before_script:
- cp .env.travis .env
- export APP_ENV="testing"
- php artisan migrate -q -n --path ./vendor/hyn-me/multi-tenant/src/migrations
- cd ./vendor/hyn-me/multi-tenant
script: phpunit
Yet my knowledge of travis (thus far) is limited and before I send in an unneeded number of commits to fix my problems I'd rather have your opinion on what would be a good method to test integration into a framework.
Ps. this concerns the package hyn/multi-tenant.
Advise on how to keep this question as generic as possible would be helpful. I hope without explicitly mentioning best practice and requesting integration into framework examples helps in defining the scope of the answers.
So after weeks of pushing commits into travis, I finally made this work.
The .travis.yml:
language: php
sudo: true
php:
- 5.5
- 5.6
- 7.0
- hhvm
addons:
hosts:
- system.hyn.me
- tenant.hyn.me
install:
# fix ipv6 issue that prevented composer requests and resulted in failing builds
- sudo sh -c "echo 'precedence ::ffff:0:0/96 100' >> /etc/gai.conf"
# updates composer on travis
- travis_retry composer self-update
# clear composer cache, might speed up finding new tags
- travis_retry composer clear-cache
# set the global github token, so connections won't be cancelled
- composer config -g github-oauth.github.com $GITHUB_TOKEN
# create a new database for the hyn connection
- mysql -e 'create database hyn;' -uroot
- mysql -e "grant all privileges on *.* to 'travis'#'localhost' with grant option;" -uroot
# create a new laravel project in the subfolder laravel (default composer behaviour)
- composer create-project laravel/laravel
# set global variables
- export DB_USERNAME=travis DB_DATABASE=hyn DB_PASSWORD= QUEUE_DRIVER=sync
script:
# run the script calling unit tests and so on
- ./scripts/travis.sh
after_script:
- if [[ $TRAVIS_PHP_VERSION != '7.0' ]]; then php vendor/bin/ocular code-coverage:upload --format=php-clover ${TRAVIS_BUILD_DIR}/coverage.clover; fi
And the scripts/travis.sh
#!/bin/bash
# e causes to exit when one commands returns non-zero
# v prints every line before executing
set -ev
cd ${TRAVIS_BUILD_DIR}/laravel
BRANCH_REGEX="^(([[:digit:]]+\.)+[[:digit:]]+)$"
if [[ ${TRAVIS_BRANCH} =~ $BRANCH_REGEX ]]; then
echo "composer require ${TRAVIS_REPO_SLUG}:${TRAVIS_BRANCH}"
composer require ${TRAVIS_REPO_SLUG}:${TRAVIS_BRANCH}
else
echo "composer require ${TRAVIS_REPO_SLUG}:dev-${TRAVIS_BRANCH}"
# development package of framework could be required for the package
composer require hyn-me/framework "dev-master as 0.1.99"
composer require "${TRAVIS_REPO_SLUG}:dev-${TRAVIS_BRANCH}#${TRAVIS_COMMIT}"
fi
# moves the unit test to the root laravel directory
cp ./vendor/${TRAVIS_REPO_SLUG}/phpunit.travis.xml ./phpunit.xml
phpunit
# phpunit --coverage-text --coverage-clover=${TRAVIS_BUILD_DIR}/coverage.clover
This code might change due to new Laravel versions or changes in travis. If this is the case, you will find the latest release here.

Categories