ohdearapp / gitlab-ci-pipeline-for-laravel

A Gitlab CI/CD pipeline optimized for use with Laravel applications
https://ohdear.app
331 stars 108 forks source link

phpunit will fail in testing stage, if database testing presence in tests #3

Closed SadeghPM closed 5 years ago

SadeghPM commented 5 years ago

Hi. If we have database tests in testing stage, phpunit test will be fail. Because no database seeding in this test. How ohdearapp pass phpunit? Adding php artisan migrate:fresh --seed script could be solve this issue. thanks

mattiasgeniar commented 5 years ago

Hi @SadeghPM !

This should still work if you use our example to start from, the database seeding happens before the testing stage.

Are you getting an error message? If so, could you share it?

Thx,

M.

SadeghPM commented 5 years ago

In phpunit test i get database errors and every database relation test will be fail due to missing migration and seeding: all errors is Base table or view not found.

.
.
.
$ php -d short_open_tag=off ./vendor/phpunit/phpunit/phpunit -v --colors=never --stderr
PHPUnit 7.5.2 by Sebastian Bergmann and contributors.

Runtime:       PHP 7.2.14
Configuration: /builds/SadeghPM/digikop/phpunit.xml

.FEEEFFE                                                            8 / 8 (100%)

Time: 403 ms, Memory: 28.00MB

There were 4 errors:

1) Tests\Feature\AdSearchPageTest::testCityWillBeInSession
Illuminate\Database\QueryException: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'digikop_db.cities' doesn't exist (SQL: select * from `cities` order by RAND() limit 1)

pipeline

If migration script presence before phpunit script, then test will be passed! My .gitlab-ci.yaml file:

stages:
  - preparation
  - building
  - testing
  - security

# Variables
variables:
  MYSQL_ROOT_PASSWORD: root
  MYSQL_USER: digikop_user
  MYSQL_PASSWORD: secret
  MYSQL_DATABASE: digikop_db
  DB_HOST: mysql

cache:
  key: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"

composer:
  stage: preparation
  services:
    - mysql:5.7
  image: edbizarro/gitlab-ci-pipeline-php:7.2
  script:
    - php -v
    - composer install --prefer-dist --no-ansi --no-interaction --no-progress --no-scripts
    - cp .env.example .env
    - php artisan key:generate
  artifacts:
    paths:
      - vendor/
      - .env
    expire_in: 1 days
    when: always
  cache:
    paths:
      - vendor/

yarn:
  stage: preparation
  image: edbizarro/gitlab-ci-pipeline-php:7.2
  script:
    - yarn --version
    - yarn install --pure-lockfile
  artifacts:
    paths:
      - node_modules/
    expire_in: 1 days
    when: always
  cache:
    paths:
      - node_modules/

build-assets:
  stage: building
  image: edbizarro/gitlab-ci-pipeline-php:7.2
  # Download the artifacts for these jobs
  dependencies:
    - composer
    - yarn
  script:
    - yarn --version
    - yarn run production --progress false
  artifacts:
    paths:
      - public/css/
      - public/js/
      - public/fonts/
      - public/mix-manifest.json
    expire_in: 1 days
    when: always

db-seeding:
  stage: building
  services:
    - mysql:5.7
  image: edbizarro/gitlab-ci-pipeline-php:7.2
  # Download the artifacts for these jobs
  dependencies:
    - composer
    - yarn
  script:
    - php artisan migrate:fresh --seed
  artifacts:
    paths:
      - ./storage/logs # for debugging
    expire_in: 1 days
    when: on_failure

phpunit:
  stage: testing
  services:
    - mysql:5.7
  image: edbizarro/gitlab-ci-pipeline-php:7.2
  # Download the artifacts for these jobs
  dependencies:
    - build-assets
    - composer
    - db-seeding
  script:
    - php -v
    - sudo cp /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini /usr/local/etc/php/conf.d/docker-php-ext-xdebug.bak
    - echo "" | sudo tee /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
    - ./vendor/phpunit/phpunit/phpunit --version
    - php -d short_open_tag=off ./vendor/phpunit/phpunit/phpunit -v --colors=never --stderr
    - sudo cp /usr/local/etc/php/conf.d/docker-php-ext-xdebug.bak /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
  artifacts:
    paths:
      - ./storage/logs # for debugging
    expire_in: 1 days
    when: on_failure

codestyle:
  stage: testing
  image: lorisleiva/laravel-docker
  script:
    - phpcs
  dependencies: []

phpcpd:
  stage: testing
  image: edbizarro/gitlab-ci-pipeline-php:7.2
  script:
    - test -f phpcpd.phar || curl -L https://phar.phpunit.de/phpcpd.phar -o phpcpd.phar
    - php phpcpd.phar
  dependencies: []
  cache:
    paths:
      - phpcpd.phar

sensiolabs:
  stage: security
  image: edbizarro/gitlab-ci-pipeline-php:7.2
  script:
    - test -d security-checker || git clone https://github.com/sensiolabs/security-checker.git
    - cd security-checker
    - composer install
    - php security-checker security:check ../composer.lock
  dependencies: []
  cache:
    paths:
      - security-checker/
mattiasgeniar commented 5 years ago

It's a tricky one to troubleshoot with only the gitlab file, would need the logs as well - but might be a little beyond the scope of this issue.

Even so, adding your proposed php artisan migrate:fresh --seed in the phpunit section will indeed work and would allow you to remove the db-seeding part too.

SadeghPM commented 5 years ago

No special things in log except Base table or view not found error on different table name!

SadeghPM commented 5 years ago

With artifacts we transfer files to other stages like vendor directory, but how to transfer database to next stage!?

codedge commented 5 years ago

I am experiencing the same problem. Database seeding runs without issues, then phpunit tests are next, but the database tables that were seeded before cannot be found.

As @SadeghPM asks: How can the phpunit step know of the previously seeded database from the previous stage? It seems the database in the phpunit step is freshly created without the previous seeded data.

mattiasgeniar commented 5 years ago

Come to think of it, I think there is a much simpler method by just using the sqlite database and having that artefect cross over to the following build stages, instead of using a custom MySQL container.

At first glance, there are very little reasons to run a full fledged database, unless you want to do custom triggers/functions that are mysql-specific.

How do you all feel about using sqlite over a MySQL/MariaDB container? If there's any consensus, I'll see if I can implement those changes.

SadeghPM commented 5 years ago

thanks @mattiasgeniar . Is phpunit tests depend on seeding In ohdearapp ?

mattiasgeniar commented 5 years ago

Hi @SadeghPM! Yes, our unit tests require data, in our tests the current setup also works perfectly. However, it can be simplified I think with the sqlite idea.

kev-landry commented 5 years ago

I was wondering the same thing as @SadeghPM, since for each stage a new container is created and there is no persistence of the database across stages.

I ended up by seeding the db in the testing stage.

mattiasgeniar commented 5 years ago

Should be fixed by pull request #5.