我正试图让我的团队开始为我们的应用程序做一些单元测试。该应用程序是基于CakePHP构建的。
首先,我要为我们的users表构建测试。我有下面的Fixture来创建一个要测试的用户:
namespace App'Test'Fixture;
use Cake'TestSuite'Fixture'TestFixture;
class UsersFixture extends TestFixture
{
public $connection = 'test';
public $import = ['table' => 'users'];
public $records = [
[
'username' => 'TestPass',
'password' => '',
'email' => 'TestPass@example.com',
'status' => 'active',
'created' => '2015-11-04 12:00:00',
'last_logindate' => null,
'registration_country' => 'AU',
'system_user' => 0
]
];
}
我也有一个TestCase表:
namespace App'Test'TestCase'Model'Table;
use App'Model'Table'UsersTable;
use Cake'ORM'TableRegistry;
use Cake'TestSuite'TestCase;
/**
* App'Model'Table'UsersTable Test Case
*/
class UsersTableTest extends TestCase
{
/**
* Fixtures
*
* @var array
*/
public $fixtures = [
'app.Users'
];
/**
* setUp method
*
* @return void
*/
public function setUp()
{
parent::setUp();
$config = TableRegistry::exists('Users') ? [] : ['className' => 'App'Model'Table'UsersTable'];
$this->Users = TableRegistry::get('Users', $config);
}
/**
* tearDown method
*
* @return void
*/
public function tearDown()
{
unset($this->Users);
parent::tearDown();
}
// ...
}
我第一次运行这个测试时,它工作得很好。如果我尝试再次运行它,那么我得到以下错误:
PHPUnit 4.8.27 by Sebastian Bergmann and contributor .
错误提示:SQLSTATE[42000]:语法错误或访问冲突:1101 BLOB/TEXT列"status"不能有默认值"in ?[/path-to-app/供应商/cakephp/cakephp/src/TestSuite/夹具/TestFixture.php,第232行)
异常:无法插入固定装置"App'Test'TestCase'Model'Table'UsersTableTest"测试用例。SQLSTATE[42S02]: Base table or view not found: 1146"carebook_test。用户不存在[/path-to-app/供应商/cakephp/cakephp/src/TestSuite/夹具/FixtureManager.php,第253行)
我摆脱这个错误的唯一方法似乎是删除我的数据库,重新创建它,然后再次运行我的迁移。之后,测试将再次成功运行,然后再次中断。
我做错了什么?
编辑:这样做的原因似乎是一旦测试结束,表就被删除了。但是如果表不存在,测试不会自动创建表,所以测试只运行一次。我想知道是否有一种方法可以使表被截断而不是被删除。或者让fixture在表不存在的情况下创建它。我对这意味着如何工作有点困惑,因为我希望这个问题影响到每个人。EDIT2:我发现CakePHP确实是为了创建表,如果他们不存在。对我来说,问题是我的列是一个ENUM和CakePHP fixture不支持枚举列,所以它使它作为一个文本列。枚举列可以有默认值(我的列有),但文本列不能。所以我想我必须弄清楚如何使CakePHP接受枚举列
问题在于CakePHP对PHPUnit类的扩展添加了在运行测试后删除测试表的功能。在测试套件的下一次运行中,将使用fixture重新创建表。
此行为不适合我,因为我的数据库表包含枚举列。CakePHP不支持ENUM列,而是将它们视为文本列。这意味着当表被重新创建时,它们有TEXT列而不是ENUM列。
这本来是可以的,只是我的ENUM列有一个默认值,而在Windows MySQL上试图在TEXT列上设置默认值会导致错误。这导致CakePHP的测试运行器出错,导致测试无法运行。
一个同事和我一起为CakePHP创建了一个插件,允许它与ENUM列正常工作。这个插件目前还没有公开发布,但我们计划在工作不那么忙的时候将其作为开源发布。
所以我想我必须弄清楚如何使CakePHP接受枚举列。
是的。CakePHP3默认情况下不支持枚举,因为它们不能在所有受支持的数据库系统上工作。使用Enum Plugin获得Enum支持。
- 如何使用插件
- 如何配置附加类型
我想你会发现枚举问题可以忽略,只要枚举字段在你的测试中不起作用。
丢失表错误是由于DBO驱动程序堆栈中的"新"缓存特性引起的。DBO记住启动时存在的表,默认情况下不识别动态创建的表。
你可以禁用表的缓存:
public function setUp()
{
parent::setUp();
$this->Users = ClassRegistry::init('Users');
$this->Users->setDataSource('test2');
$this->Users->cacheSources = false;
}