PHPUnit组织testing的最佳实践

我现在要从一个项目的phpunittesting从头开始。 所以我正在研究一些项目(比如Zend),看看他们是如何做事,以及如何组织他们的testing。

大部分事情都很清楚,唯一的问题是如何正确组织testing套件。 Zend有一个AllTests.php,可以从其中加载其他testing套件。
严格的看类,它使用PHPUnit_Framework_TestSuite来创build一个套件对象,然后将其他套件添加到它,但如果我看在PHPUnit文档中组织3.4以后的PHPUnit版本的testing,只有XML或FileHierarchy的描述。 使用类来组织testing的那个被删除了。
我还没有发现这个方法已经被弃用,像Zend这样的项目仍然在使用它。

但是,如果它被弃用,我将如何能够在与XMLconfiguration相同的结构组织testing? 执行所有testing是没有问题的,但是如果我只想执行一些testing,我将如何组织testing(在xml中)。 也许创build几个xmls,我只指定几个testing/testing套件运行?

所以,如果我只想testing应用程序的module1和module2,我是否会为每个应用程序添加一个额外的xml,并只为这些模块(模块使用的类)定义testing套件。 还有一个定义所有testing的testing套件?

或者在特定的testing中使用@group注释来标记它们是为了模块1还是模块2?

在此先感谢您指点我的一些最佳实践。

我将开始链接到手册,然后进入我在现场看到和听到的。

组织phpunittesting套件

文件系统中的模块/testing文件夹组织

我推荐的方法是将文件系统与xmlconfiguration相结合。

 tests/ \ unit/ | - module1 | - module2 - integration/ - functional/ 

用一个简单的phpunit.xml

 <testsuites> <testsuite name="My whole project"> <directory>tests</directory> </testsuite> </testsuites> 

你可以拆分testing套件,如果你想,但这是一个项目的项目select。

运行phpunit然后执行所有的testing,运行phpunit tests/unit/module1 phpunit将运行phpunit tests/unit/module1所有testing。

组织“单位”文件夹

这里最常用的方法是在tests/unit/文件夹结构中镜像source/目录结构。

无论如何,每个ProductionClass都有一个TestClass,所以这是我书中的一个好方法。

在文件组织中

  • 每个文件一个类

如果你在一个文件中有多个testing类,那么就不会起作用,所以要避免这个错误。

  • 没有testing命名空间

它只是使testing更详细,因为你需要一个额外的使用语句,所以我会说,testClass应该在生产类相同的命名空间,但没有什么PHPUnit迫使你做。 我刚刚发现它更容易,没有缺点。

只执行一些testing

例如, phpunit --filter Factory执行所有FactoryTests,而phpunit tests/unit/logger/执行与日志有关的所有事情。

您可以使用@group标签来查找问题编号,故事或其他内容,但对于使用文件夹布局的“模块”,则可以。

多个XML文件

如果您想要创build多个xml文件可能很有用:

  • 一个没有代码覆盖
  • 一个仅用于unit testing(但不适用于functiontesting或集成testing或长时间运行的testing)
  • 其他常见的“过滤”情况
  • PHPBB3例如为their phpunit.xmls

代码覆盖率为您的testing

因为它涉及到用testing开始一个新项目:

  • 我的build议是使用像我的博客中描述的 @covers标签(仅用于unit testing,总是覆盖所有非公开的function,总是使用覆盖标签。
  • 不要为您的集成testing生成覆盖率。 它给你一种错误的安全感。
  • 总是使用白名单来包括所有的生产代码,所以这些数字不会骗你!

自动加载和引导您的testing

你不需要任何types的自动加载你的testing。 PHPUnit会照顾到这一点。

使用<phpunit bootstrap="file">属性指定您的testing引导程序。 tests/bootstrap.php是个不错的地方。 在那里你可以设置你的应用程序自动加载器等等(或者为你的应用程序调用bootstrap)。

概要

  • 几乎所有的东西都使用xmlconfiguration
  • 单独的单元和集成testing
  • 你的unit testing文件夹应该镜像你的应用文件夹结构
  • 要仅执行phpunit --filtertesting,请使用phpunit --filterphpunit tests/unit/module1
  • 从开始使用strict模式,永远不要closures它。

示例项目来看看

  • 塞巴斯蒂安·伯格曼“银行账户”示例项目
  • 即使如此,他们必须与他们的遗产战斗一些;)
  • Symfony2的
  • Doctrine2

基本目录结构

我一直在尝试将testing代码保存在正在testing的代码旁边,字面上与testing代码的文件名称略有不同。 到目前为止,我喜欢这种方法。 这个想法是你不必花费时间和精力保持你的代码和你的testing代码之间的目录结构同步。 因此,如果您更改代码所在目录的名称,则不需要去查找和更改testing代码的目录名称。 这也会导致您花费更less的时间寻找与代码一起使用的testing代码,因为它就在它旁边。 这甚至可以避免使用testing代码创build文件的麻烦,因为您不必先查找包含testing的目录,也可以创build一个新目录来匹配您正在创buildtesting的目录,然后创buildtesting文件。 您只需在那里创buildtesting文件。

一个巨大的优势就是它意味着其他员工(不是你,因为你永远不会这样做)将不太可能避免编写testing代码,因为这只是太多的工作。 即使他们将方法添加到现有的类中,他们也不会像现有的testing代码那样添加testing。

一个缺点是这使得难以发布你的生产代码,而没有随之而来的testing。 虽然如果你使用严格的命名约定,它仍然是可能的。 例如,我一直在使用ClassName.php,ClassNameUnitTest.php和ClassNameIntegrationTest.php。 当我想运行所有的unit testing时,有一个套件查找以UnitTest.php结尾的文件。 集成testing套件的工作原理类似。 如果我想,我可以使用类似的技术来防止testing发布到生产环境。

这种方法的另一个缺点是,当你只是在寻找实际的代码,而不是testing代码时,需要花费更多的精力来区分两者。

每class一个testingclass:

对于大多数程序员来说,这是远远不够的,但对我来说是这样的。 我正在试验每个类正在testing一个testing类。 在过去,我有一个完整的目录为每个类正在testing,然后我有几个类内的目录。 每个testing类都以某种方式设置正在testing的类,然后有一堆方法,每个方法都有不同的断言。 但是后来我开始注意到一些条件,我会把这些对象与其他testing类的其他条件相提并论。 重复变得太多了,所以我开始创build抽象来远程处理它。 testing代码变得很难理解和维护。 我意识到这一点,但我看不到一个对我有意义的select。 每个类只有一个testing类似乎不能够testing几乎足够的情况,而不会在一个testing类中占据所有的testing代码。 现在我对此有不同的看法。 即使我是对的,这对其他程序员来说也是一个巨大的阻碍,而我自己也想写和维护testing。 现在我正在尝试强迫自己每个类都有一个testing类。 如果我在一个testing课上碰到太多的东西要testing,我正在试验看看这个testing课是不是太多了,应该分解成多个类。 为了消除重复,我试图尽可能地坚持简单的抽象,使一切都可以存在于一个可读的testing类中。