6

I am trying to run some acceptance tests in my Laravel application. While functional tests trigger testing environment, acceptance tests do not. Is it a bug or a feature of acceptance tests? The main problem why this is bothering me is the fact, that it is not using(+populating+cleanup) testing database, it only connects to dev database (which is used, when no other ENV is specified e.g. testing, production) and this often fails those tests when I run them multiple times.

This is my configuration:

codeception.yml

paths:
    tests: app/tests
    log: app/tests/_log
    data: app/tests/_data
    helpers: app/tests/_helpers
settings:
    bootstrap: _bootstrap.php
    suite_class: \PHPUnit_Framework_TestSuite
    colors: true
    memory_limit: 1024M
    log: true
modules:
    config:
        Db:
            dsn: 'mysql:host=localhost;dbname=testdb'
            user: 'root'
            password: 'root'
            dump: 'app/tests/_data/dump.sql'
            populate: true
            cleanup: true

acceptance.suite.yml

class_name: WebGuy
modules:
    enabled:
        - PhpBrowser
        - WebHelper
        - Db
    config:
        PhpBrowser:
            url: 'http://localhost/'

functional.suite.yml

class_name: TestGuy
modules:
    enabled: [Filesystem, TestHelper, Laravel4, Db]

Thanks for your help!

rene
  • 41,474
  • 78
  • 114
  • 152
HRcc
  • 81
  • 1
  • 3
  • I am having this same issue. My Codeception acceptance tests do NOT run under the 'testing' environment. I have tried to include Laravel4 in the acceptance.suite.yml - and that does not change anything. – Laurence Apr 18 '14 at 13:05
  • From what I can tell - Codeception runs 'two' cycles of each test. One of them is run as the 'test' environment, but the second is NOT run in the 'test' environment. I can confirm this - because if you force BOTH tests to run in 'test' environment, then your routes dont work correctly (as they are normally disabled for tests). – Laurence Apr 18 '14 at 13:07
  • @Fabrizio - what extra information do you need for this? I've already provided an answer? – Laurence Oct 12 '14 at 07:47
  • @TheShiftExchange I can't make it work, I understand why Codeception and Laravel behave like that, but still the 2 answers below doesn't explain very well how to create a `codeception` environment for run the acceptance tests. Thanks a Lots! – Fabrizio Fenoglio Oct 12 '14 at 14:18
  • I can't tell for codeception, but I hit the same wall. I solved passing a x-unit-testing header which triggers the testing environment (only if the request comes from localhost). – tacone Oct 12 '14 at 21:12

2 Answers2

7

"Acceptance" tests are not run in the testing environment. The reason is when Laravel is in the testing environment, it disables filters by default. So therefore the testing environment is only for unit and functional tests.

Acceptance tests should be run in another environment (like dev or a specific one to Codeception).

Because Codeception 2.x now uses Guzzle to get a page response, it is possible to detect when you are on your host machine and Codeception is doing a specific request. That way you can have a "testing" environment and also a "codeception" environment specifically for your acceptance tests.

If you are using Homestead, I do this in my start.php file to detect if Codeception is running, and specifically put it into a 'codeception' environment, otherwise I let it run my environment detection normally

if ((gethostname() === 'homestead') && (isset($_SERVER['REMOTE_ADDR'])) && ($_SERVER['REMOTE_ADDR'] === '127.0.0.1'))
{
    $env = $app->detectEnvironment(['codeception' => ['homestead']]);
}
else
{
    $env = $app->detectEnvironment(['dev' => ['homestead']]);
}

Then in my 'codeception' environment, I setup a SQLite file database, and run acceptance tests against that (which is faster than mySQL testing).

Laurence
  • 58,936
  • 21
  • 171
  • 212
  • I am having the same issue, but I am using Behat and MAMP. Do you know how can I set the environments correctly? I already have a *_acceptance database and a config/acceptance folder pointing to the correct database. In my featureContext.php file, I am setting the environment to 'acceptance'. When the tests run Behat is using my local DB. :( Thanks in advance. – Bruno Rodrigues Jun 20 '14 at 14:04
  • This doesnt seem to work, is there are further explanation around this? – DavidT Feb 24 '16 at 17:21
5

First, you must understand that Codeception acceptance tests do not run inside the Laravel testing environment. Rather, it uses Guzzle to make external HTTP requests. Assuming your acceptance tests run against localhost, you are running in your standard development environment. It is just like using your browser.

That said, here is how I use Codeception Acceptance tests to run against a Laravel testing environment. I run Vagrant with a LAMP stack on Ubuntu.

  1. Edit your /etc/hosts file. Add test.localhost to the 127.0.0.1 line. Do not remove the other hosts there. If you use WAMP/MAMP/or other, it might be a similar setup.

    /etc/hosts

    127.0.0.1 localhost test.localhost

  2. Setup your environment handling with Laravel. Below is code in the bootstrap/start.php file in your larval root dir. pay attention to the 'testing' line.

    bootstrap/start.php

    $env = $app->detectEnvironment(array(
        'local' => array('your-machine-name'),
        'testing' => array('test.localhost')
    ));
    
  3. Make sure your codeception acceptance test is configured to hit the right domain/url. The code below is from my own acceptance tests for an API. Notice the url: sections have test.localhost. That is the url that Codeception will hit for the tests.

    app/tests/acceptance.suite.yml

    class_name: ApiGuy
    modules:
        enabled: [PhpBrowser, REST, ApiHelper, Db, FileSystem]
        config:
            PhpBrowser:
                url: http://test.localhost/
            REST:
                url: http://test.localhost/api/v1/
    

Putting it all together

  1. We edited the /etc/hosts file so that Codeception can find test.localhost. Editing your web server config to handle test.localhost is outside the scope of this answer.
  2. We edited Laravel's bootstrap/start.php so that it knows that any requests coming into test.localhost should run in the testing environment.
  3. We edited Codeception's acceptance.suite.yml file to tell it to run all tests against http://test.localhost

Now, assuming the above is done correctly, you should be able to run codeception run acceptance and see the output of your tests.

Sam Texas
  • 1,245
  • 14
  • 30