我对测试世界还很陌生,我想确保自己走在正确的轨道上。

我正在尝试使用phpunit在symfony2项目中设置单元测试。

PHPUnit正在运行,简单的默认 Controller 测试也可以正常工作。 (但是,这与功能测试无关,而是对应用程序进行单元测试。)

不过,我的项目在很大程度上依赖于数据库交互,据phpunit's documentation的理解,我应该基于\PHPUnit_Extensions_Database_TestCase设置一个类,然后为我的数据库创建夹具并从那里开始工作。

但是,symfony2仅提供WebTestCase类,该类仅从\PHPUnit_Framework_TestCase扩展到开箱即用。

那么,我是否应该假设我应该创建自己的DataBaseTestCase,该副本主要复制WebTestCase,而不同之处在于它是从\PHPUnit_Extensions_Database_TestCase扩展并实现了所有抽象方法的?

还是针对基于数据库的测试为symfony2提供了另一个“内置”推荐工作流程?

因为我要确保模型存储和检索正确的数据,所以我不想最终偶然地测试了该学说的细节。

最佳答案

我从未使用过PHPUnit_Extensions_Database_TestCase,主要是因为以下两个原因:

  • 无法很好地扩展。如果您为每个测试设置和拆除数据库,并且您的应用程序严重依赖数据库,那么最终您将一遍又一遍地创建和删除同一模式。
  • 我不仅希望在测试中包含固定装置,而且还希望在开发数据库中包含固定装置,甚至在生产中还需要一些固定装置(初始admin用户或产品类别等)。在我看来,将它们包含在只能用于phpunit的xml中似乎并不对。

  • 我的理论方法...

    我将doctrine/doctrine-fixtures-bundle用于灯具(无论出于什么目的),并使用所有灯具设置整个数据库。然后,我将对此数据库执行所有测试,并确保在测试更改后重新创建该数据库。

    优点是,如果测试仅读取但不更改任何内容,则无需再次设置数据库。对于更改,我必须删除它并再次创建它,或者确保还原更改。

    我使用sqlite进行测试,因为我可以设置数据库,然后复制sqlite文件并将其替换为干净的文件,以恢复原始数据库。这样,我就不必删除数据库,创建数据库并再次加载所有装置来生成干净的数据库。

    ...以及代码

    我写了一个article about how I do database tests with symfony2 and phpunit

    尽管它使用sqlite,但我认为可以轻松地进行更改以使用MySQL或Postgres或其他任何东西。

    进一步思考

    以下是一些可行的其他想法:
  • 我曾经读过一个关于测试设置的信息,其中在使用数据库之前,先启动一个事务(在setUp方法中),然后使用tearDown进行回滚。这样,您无需再次设置数据库,只需初始化一次即可。
  • 我的上述设置的缺点在于,即使您只运行某些单元测试而没有数据库交互,每次执行phpunit时都会建立数据库。我正在尝试一个设置,其中使用了一个全局变量,该变量指示是否已建立数据库,然后在测试中调用一种方法,该方法检查该变量并初始化数据库(如果尚未发生)。这样,仅当测试需要数据库时,设置才会发生。
  • sqlite的一个问题是,在极少数情况下,它与MySQL的工作方式不同。我曾经遇到一个问题,那就是在MySQL和sqlite中某些行为会有所不同,导致在MySQL正常工作时测试失败。我不记得那是什么。
  • 07-26 05:34
    查看更多