明显的测试崩溃...我想如果你想要一个稍微短一点的单词并且感觉很倾向于,你可以省略 -db- 部分。
Test-DB-Acle 是一个 PHP 库,有助于为数据库层编写简单而简洁的测试。
我相信编写测试对于开发人员来说应该尽可能容易,并且对于其他开发人员来说也应该尽可能容易阅读。
这意味着测试中的任何测试数据都应该仅与测试场景相关。然而,大多数数据库表都有非空列,需要您输入虚拟数据,这只会给测试带来认知噪音。
Test-Db-Acle 旨在减轻开发人员的这一负担。测试框架不会对数据库层类的工作方式做出任何假设,如果它们使用像 Doctrine、存储过程或直接 SQL 这样的 ORM,原理总是相同的,在某些时候代码与数据库表中的数据进行交互,我们确实需要对此进行测试。
通过作曲家安装
禁用数据库中的外键检查
自动处理非空列
当断言值位于数据库表中时,自动修剪 mysql 中的日期/时间列 - 对于插入的时间戳很有用(在 Sqlite 中必须指定这些列)
几乎所有组件都可以更换并替换为定制品种
目前支持Mysql和Sqlite
与框架无关,它不会假设是否使用 ORM,并且应该很容易适应其他单元测试框架。
目前支持的数据库有 MySql(以及扩展的 MariaDB)和 Sqlite。
该架构应该允许添加更多数据库。
该库可以与 PHPUnit 一起开箱即用。通过使用提供的特征并将“assertEquals”方法委托给等效方法,将其与其他测试框架一起使用应该相当容易(例如,我记得它在 SimpleTest 中是“assertEqual”)
如果您使用 PHP 5.4 并且不介意使用特征,我提供了一个简单的 TestDbAclePhpUnitAbstractTestCase 以及 TestDbAclePhpUnitTraitsDatabaseHelperTrait 。
好吧,公平地说,测试数据库层的成本很高,而且会拖慢测试速度,并且只要有可能,就应该模拟对数据库的任何依赖项。但有时我们不得不这样做,希望在结构良好的应用程序中,这种情况可以保持在最低限度。
有许多可用的工具和方法(例如 DBUnit 或在单元测试中使用工厂方法)来帮助进行数据库测试,每种工具和方法都有自己的优点,这种方法对我来说很有效,因为:
我不必担心空列或外键约束
我为我的测试提供了最小的数据集
我可以在测试上方以类似网格的格式看到测试数据,并在断言数据库中的数据时再次看到测试数据。
所以我建立了自己的解决方案。
###那么它是如何工作的以及它是什么样子的?给我举个例子!###
这个想法是使用“管道分隔值”文本字符串,我们称之为 PSV - 与 CSV 中一样,但使用管道 - 来设置测试装置,如下所示:
(PSV的格式与优秀的Behat BDD框架(https://github.com/Behat/Behat)使用的格式非常相似)
$dbTablesToSetup="[table_name]id |date |name |value |dependent_table_id10 |2001-01-01 |foo |900 |60[dependent_table]id |name20 |Bar60 |Baz";//如果您不想使用此值使用提供的特征或抽象测试用例$testDbAcle = TestDbAcleTestDbAcle::create($pdo);$testDbAcle->runCommand(new TestDbAcleCommandsSetupTablesCommand($dbTablesToSetup));//如果您从 TestDbAclePhpUnitAbstractTestCase 扩展测试用例或正在使用TestDbAclePhpUnitTraitsDatabaseHelperTrait:$this->setupTables($dbTablesToSetup);
框架本身知道表中哪些列不能为 NULL,并插入默认值...事实上,我们假设表table_name有 30 列,所有列都是非空的...
此外,后台可能存在各种外键约束。 Test-Db-Acle 暂时禁用外键检查,因此我们不必担心这一点,也不必担心插入测试数据的顺序。
###实际测试一下怎么样?###首先,如果你使用PHP5.4,可以使用traits版本:
类 ExampleTest 扩展 PHPUnit_Framework_TestCase 实现 TestDbAclePhpUnitAbstractTestCaseInterface {使用 TestDbAclePhpUnitTraitsDatabaseHelperTrait; /** * 这个方法需要实现,它应该返回要在数据库装置中使用的 PDO 对象 * * @return Pdo */public function ProvidePdo() {return new Pdo("mysql:dbname=my_db_tests;host=localhost",'myTestUser', 'myTestPassword'); } /* * 示例测试 */public function test_AddressService() {$this->setupTables(" [地址] address_id |公司 1 |me 3 |你 [用户] user_id |姓名 10 |约翰 20 |玛丽 "); $this->setAutoIncrement('地址', 100); $this->addressService->addEntry("them");$this->assertTableStateContains(" [地址] address_id |company 1 |me 3 |you 100 |them [user] user_id |name 10 |John 20 |Mary ", array(),“东西有效”); } }
如果您不使用特征,则可以使用AbstractTestCase
,但是在这种情况下您将无法使用自己的基测试类。
类 ExampleTest 扩展 TestDbAclePhpUnitAbstractTestCase { protected $addressService;function Setup(){parent::Setup();$this->addressService = new ServicesAddressService(); }/** * 这个方法需要实现,它应该返回要在数据库装置中使用的 PDO 对象 * * @return Pdo */public function ProvidePdo() {return new Pdo("mysql:dbname=my_db_tests;host=localhost",'myTestUser', 'myTestPassword'); }函数 test_AddressService() {$this->setupTables(" [地址] address_id |公司 1 |me 3 |你 [用户] user_id |姓名 10 |约翰 20 |玛丽 "); $this->setAutoIncrement('地址', 100); $this->addressService->addEntry("them");$this->assertTableStateContains(" [地址] address_id |company 1 |me 3 |you 100 |them [user] user_id |name 10 |John 20 |Mary ", array(),“东西有效”); } }
好吧,显然这里不存在 ServicesAddressService(嘿,它是测试优先的,对吧?)并且示例非常简单。
在现实生活中,我会将 getPdo 方法放入项目的公共基测试类中,并且它的获取方式可能与此处完全不同。但是,这只是一个例子。
如您所见,setupTables 可以一次设置多个表,assertTableStateContains 也可以同时验证各个表的状态。
与 setupTables 如何设置具有比指定列多得多的列的表类似,assertTableStateContains 也仅比较并断言指定列的值。
安装 Test-Db-Acle 最简单的方法是使用 Composer(在此处了解更多信息:http://packagist.org),我强烈建议使用这种方法,尽管您也可以将包解压缩到文件夹中并启用自动加载以您希望的任何形式手动进行(它使用 psr-0 命名约定)
要与composer一起使用,请将其添加到您的composer.json文件中:
"require": { "test-db-acle/test-db-acle" : "dev-master" }, "repositories" : [ { "type": "git", "url": "https://github.com/malteriesch/test-db-acle.git" } ]
如果您愿意,也可以使用 https://packagist.org/packages/test-db-acle/test-db-acle。
非常欢迎贡献(和批评)......!
###如何运行 Test-Db-Acle 测试### 要运行测试,您需要在您选择的 MySql 服务器上创建一个空数据库,将tests/Functional/config.php.dist 复制到tests/ Function/config.php 并填充您的数据库详细信息。然后,希望所有测试都应该运行。 (数据库其实只是功能冒烟测试才需要)
PSV 语法
抽象测试用例
扩展和自定义 TestDbAcle
变更日志