在Codeception(Laravel)中为验收测试设置测试数据库

时间:2016-07-16 13:20:46

标签: php testing laravel-5 codeception acceptance-testing

我使用Codeception框架在Laravel 5应用程序中执行验收测试。我想使用一个单独的数据库进行测试,以防止真正的数据库通过测试而改变。我根据Codeception文档配置了.yml文件。但无论如何真正的数据库会受到影响。这是我的配置文件:

/codeception.yml

actor: Tester
 paths:
   tests: tests
    log: tests/_output
    data: tests/_data
   support: tests/_support
   envs: tests/_envs
 settings:
   bootstrap: _bootstrap.php
   colors: true
    memory_limit: 1024M
  extensions:
  enabled:
    - Codeception\Extension\RunFailed
  modules:
  config:
     Db:
        dsn: 'mysql:host=localhost;dbname=realDB'
        user: 'root'
        password: 'secret'
        dump: 'tests/_data/dump.sql'

/tests/acceptance.suite.yml

class_name: AcceptanceTester
modules:
  enabled:
    - WebDriver:
        url: 'http://localhost:8000/'
        browser: firefox
    - Laravel5:
        part: ORM
        cleanup: false # can't wrap into transaction
     Db:
      populate: true
      cleanup: true
    - \Helper\Acceptance

realDB是真正的数据库,在执行验收测试后会发生变化。我在acceptance.suite.yml中尝试了不同的清理方法:1)清理:在Laravel模块中清除false并清理:在Db模块中为true 2)清理:在Laravel模块中为true并清理:在Db模块中为true。 Codeception文档说,对于验收测试,我们需要"禁用清理并使用Db模块清理测试数据库"。但无论如何,realDB都会发生变化。

我尝试过不同的PHP测试框架,例如Laravel中的PHPUnit,PHP Selenium驱动程序,Facebook网页驱动程序,在所有情况下,真正的数据库在执行验收测试时都会受到影响。如何正确配置Codeception以防止数据库更改?

任何帮助将不胜感激。

[UPDATE1]

由于@TheFallen建议我使用不同的数据库进行测试,我更改配置文件如下:

/codeception.yml

actor: Tester
 paths:
   tests: tests
    log: tests/_output
    data: tests/_data
   support: tests/_support
   envs: tests/_envs
 settings:
   bootstrap: _bootstrap.php
   colors: true
    memory_limit: 1024M
  extensions:
  enabled:
    - Codeception\Extension\RunFailed
  modules:
  config:
     Db:
        dsn: 'mysql:host=localhost;dbname=testDB'
        user: 'root'
        password: 'secret'
        dump: 'tests/_data/dump.sql'

/tests/acceptance.suite.yml

class_name: AcceptanceTester
modules:
  enabled:
    - WebDriver:
        url: 'http://localhost:8000/'
        browser: firefox
    - Laravel5:
        part: ORM
        environment_file: .env.testing
        cleanup: true
     Db:
      populate: true
      cleanup: true
    - \Helper\Acceptance 

/。env.testing

APPLICATION_URL=http://localhost:8000
APP_DEBUG=true
APP_ENV = testing
MYSQL_MAIN_HOST=localhost
MYSQL_MAIN_DATABASE=realDB
MYSQL_MAIN_USER=root
MYSQL_MAIN_PASSWORD=secret 
CACHE_DRIVER=array 
DB_CONNECTION=test_mysql
TEST_MYSQL_MAIN_DATABASE=testDB

/config/database.php

return [

    'fetch' => PDO::FETCH_CLASS,

    'default' => env('DB_CONNECTION', 'mysql'),

    'connections' => [

        'test_mysql' => [
            'driver'    => 'mysql',
            'host'      => env('MYSQL_MAIN_HOST', 'localhost'),
            'database'  => env('TEST_MYSQL_MAIN_DATABASE', 'testDB'),
            'username' => env('MYSQL_MAIN_USER', 'root'),
            'password' => env('MYSQL_MAIN_PASSWORD', ''),
            'charset'   => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix'    => '',
            'strict'    => false,
        ],
...

.env.testing位于Laravel应用程序的根目录中。 但是真实数据库(realDB)仍然受到影响,只有转储文件被导入测试数据库(testDB)。看起来应用程序没有使用.env.testing。我怎样才能解决这个问题?

请注意,在我的验收测试中,会发送一个AJAX请求来调用更改数据库中的数据的函数。我想回滚由AJAX请求完成的数据库事务。

[UPDATE2]

根据Codeception documentation,接受测试将在开发环境中使用真实的Web服务器执行,因此.env.testing的设置无法传递给它们。 :(

毕竟我已经完成了解决这个问题的工作,我得出的结论是,在执行接受AJAX请求执行数据库事务的验收测试之后,不可能保持真正的数据库不被更改,除非我将默认数据库更改为测试.env文件!

如果有人有更好的解决方案,请分享!

2 个答案:

答案 0 :(得分:4)

由于您的Laravel应用程序可以在多个域下运行,因此请创建一个专门用于验收测试的应用程序,并配置服务器以为此特定域设置环境变量APP_ENV=acceptance(或任何您称之为)。设置APP_ENV后,Laravel将自动为您加载正确的环境文件,在本例中为.env.acceptance

我也看到人们使用cookies(在验收测试的早期设置)来配置Laravel根据这些cookie切换数据库。它似乎有点脏,可能不安全,而且你最终会将代码添加到你的应用程序核心......所以...

答案 1 :(得分:1)

如果在Laravel5模块设置中设置 cleanup:true ,则所有数据库查询都将在事务中运行,该事务将在测试结束时回滚。因此,这是防止真实数据库发生变化的一种方法。

还要确保在 tests / _data / dump.sql 中拥有最新的数据库转储。 Db模块的设置应该是 cleanup:true 以在每次测试后清理数据库,保持真实数据的完整性,并且不确定为什么需要在每次测试后使用重新连接到数据库重新连接:true 但你可能不需要它。