symfony icon indicating copy to clipboard operation
symfony copied to clipboard

Task for running (and enforcing passed) tests

Open webdevilopers opened this issue 5 years ago • 3 comments

Maybe it is an interesting feature to run unit tests either locally before deploying or on production after deploy.

I'm no ruby expert so this was my first approach:

namespace :deploy do
  #before :deploy, "deploy:run_tests"
  before :deploy, "tasks:run_tests"
end

namespace :tasks do

  task :run_tests do
      run_locally do
        execute :php, fetch(:vendor_path) + "/phpunit/phpunit/phpunit --configuration " + fetch(:app_path) + "/phpunit.xml " + fetch(:tests_path)
      end
  end

Based on this question:

  • https://stackoverflow.com/questions/6769483/automatically-run-tests-on-deploy-with-capistrano

But I'm not sure how to get a return value to inform cap to continue. Currently this solution will stop deployment even when tests pass.

(Backtrace restricted to imported tasks)
cap aborted!
SSHKit::Command::Failed: php exit status: 256
php stdout: PHPUnit 7.2.4 by Sebastian Bergmann and contributors.

Trace:

/var/lib/gems/2.5.0/gems/sshkit-1.16.1/lib/sshkit/command.rb:99:in `exit_status='
/var/lib/gems/2.5.0/gems/sshkit-1.16.1/lib/sshkit/backends/local.rb:64:in `block in execute_command'
/usr/lib/ruby/2.5.0/open3.rb:205:in `popen_run'
/usr/lib/ruby/2.5.0/open3.rb:95:in `popen3'
/var/lib/gems/2.5.0/gems/sshkit-1.16.1/lib/sshkit/backends/local.rb:46:in `execute_command'
/var/lib/gems/2.5.0/gems/sshkit-1.16.1/lib/sshkit/backends/abstract.rb:141:in `block in create_command_and_execute'
/var/lib/gems/2.5.0/gems/sshkit-1.16.1/lib/sshkit/backends/abstract.rb:141:in `tap'
/var/lib/gems/2.5.0/gems/sshkit-1.16.1/lib/sshkit/backends/abstract.rb:141:in `create_command_and_execute'
/var/lib/gems/2.5.0/gems/sshkit-1.16.1/lib/sshkit/backends/abstract.rb:74:in `execute'
app/config/deploy.rb:70:in `block (3 levels) in <top (required)>'
/var/lib/gems/2.5.0/gems/sshkit-1.16.1/lib/sshkit/backends/abstract.rb:29:in `instance_exec'
/var/lib/gems/2.5.0/gems/sshkit-1.16.1/lib/sshkit/backends/abstract.rb:29:in `run'
/var/lib/gems/2.5.0/gems/capistrano-3.11.0/lib/capistrano/dsl.rb:76:in `run_locally'
app/config/deploy.rb:68:in `block (2 levels) in <top (required)>'
/usr/lib/ruby/vendor_ruby/rake/task.rb:271:in `block in execute'
/usr/lib/ruby/vendor_ruby/rake/task.rb:271:in `each'
/usr/lib/ruby/vendor_ruby/rake/task.rb:271:in `execute'
/var/lib/gems/2.5.0/gems/airbrussh-1.3.0/lib/airbrussh/rake/context.rb:62:in `execute'
/usr/lib/ruby/vendor_ruby/rake/task.rb:213:in `block in invoke_with_call_chain'
/usr/lib/ruby/2.5.0/monitor.rb:226:in `mon_synchronize'
/usr/lib/ruby/vendor_ruby/rake/task.rb:193:in `invoke_with_call_chain'
/usr/lib/ruby/vendor_ruby/rake/task.rb:237:in `block in invoke_prerequisites'
/usr/lib/ruby/vendor_ruby/rake/task.rb:235:in `each'
/usr/lib/ruby/vendor_ruby/rake/task.rb:235:in `invoke_prerequisites'
/usr/lib/ruby/vendor_ruby/rake/task.rb:212:in `block in invoke_with_call_chain'
/usr/lib/ruby/2.5.0/monitor.rb:226:in `mon_synchronize'
/usr/lib/ruby/vendor_ruby/rake/task.rb:193:in `invoke_with_call_chain'
/usr/lib/ruby/vendor_ruby/rake/task.rb:182:in `invoke'
/usr/lib/ruby/vendor_ruby/rake/application.rb:160:in `invoke_task'
/usr/lib/ruby/vendor_ruby/rake/application.rb:116:in `block (2 levels) in top_level'
/usr/lib/ruby/vendor_ruby/rake/application.rb:116:in `each'
/usr/lib/ruby/vendor_ruby/rake/application.rb:116:in `block in top_level'
/usr/lib/ruby/vendor_ruby/rake/application.rb:125:in `run_with_threads'
/usr/lib/ruby/vendor_ruby/rake/application.rb:110:in `top_level'
/usr/lib/ruby/vendor_ruby/rake/application.rb:83:in `block in run'
/usr/lib/ruby/vendor_ruby/rake/application.rb:186:in `standard_exception_handling'
/usr/lib/ruby/vendor_ruby/rake/application.rb:80:in `run'
/var/lib/gems/2.5.0/gems/capistrano-3.11.0/lib/capistrano/application.rb:14:in `run'
/var/lib/gems/2.5.0/gems/capistrano-3.11.0/bin/cap:3:in `<top (required)>'
/usr/local/bin/cap:23:in `load'
/usr/local/bin/cap:23:in `<main>'
Tasks: TOP => deploy => tasks:run_tests

webdevilopers avatar Jun 05 '19 11:06 webdevilopers

Thanks to @radmen I was able to identify the problem. The tests were throwing deprecation notices that would let the process fail. The notices could be hidden by this configuration in phpunit.xml:

<php>
    <env name="SYMFONY_DEPRECATIONS_HELPER" value="weak" />
</php>

Solution provided here by @BigZ:

  • https://stackoverflow.com/questions/35897550/remove-remaining-deprecation-notices-in-symfony-2-8

Symfony 2:

set :tests_path, fetch(:app_path) + "/../tests"
set :vendor_path, fetch(:app_path) + "/../vendor"

namespace :deploy do
  before :starting, "tasks:run_tests"
end

namespace :tasks do

  task :run_tests do
    run_locally do
      execute :php, fetch(:vendor_path) + "/phpunit/phpunit/phpunit --configuration " + fetch(:app_path) + "/phpunit.xml " + fetch(:tests_path)
    end
  end

end

If you are using the PHPUnit Bridge and Symfony >= 3:

set :tests_path, "tests"
set :vendor_path, "vendor"

namespace :deploy do
  before :starting, "tasks:run_tests"
end

namespace :tasks do
  task :run_tests do
    run_locally do
      execute :php, fetch(:vendor_path) + "/bin/simple-phpunit --configuration phpunit.xml " + fetch(:tests_path)
    end
  end
end

Anybody interested in adding this task to this repo?

webdevilopers avatar Jun 07 '19 13:06 webdevilopers

Hi @webdevilopers I think the tests should be run in a Continuous Integration, not in capistrano. just make test && make deploy if you really want to do it on your machine because this task is heavily related to the fact that you use phpunit and a specific configuration file. PS: if you want to force weak deprecation notice, you can set it per-command, like SYMFONY_DEPRECATIONS_HELPER=weak php vendor/bin/phpunit

BigZ avatar Jun 26 '19 11:06 BigZ

SYMFONY_DEPRECATIONS_HELPER=weak php vendor/bin/phpunit

Thanks for the hint @BigZ !

webdevilopers avatar Jun 26 '19 13:06 webdevilopers