以某种顺序运行PHPUnittesting

有没有办法让TestCase的testing以一定的顺序运行? 例如,我想将一个对象的生命周期从创build到使用分解,但是在运行其他testing之前,我需要确保先设置对象。

也许在你的testing中有一个devise问题。

通常每个testing不能依赖于任何其他testing,因此它们可以以任何顺序运行。

每个testing都需要实例化并销毁所有需要运行的东西,这是完美的方法,你不应该在testing之间共享对象和状态。

你能更具体地说明为什么你需要同一个对象进行N次testing吗?

PHPUnit通过@depends注解支持testing依赖关系。

下面是一个文档示例,其中testing将以满足依赖关系的顺序运行,每个依赖testing都会将parameter passing给下一个:

 class StackTest extends PHPUnit_Framework_TestCase { public function testEmpty() { $stack = array(); $this->assertEmpty($stack); return $stack; } /** * @depends testEmpty */ public function testPush(array $stack) { array_push($stack, 'foo'); $this->assertEquals('foo', $stack[count($stack)-1]); $this->assertNotEmpty($stack); return $stack; } /** * @depends testPush */ public function testPop(array $stack) { $this->assertEquals('foo', array_pop($stack)); $this->assertEmpty($stack); } } 

但是,重要的是要注意, 不会执行具有未解决的依赖性的testing(因为这将快速引起关注失败的testing)。 所以,在使用依赖关系时要特别注意。

如果你想让你的testing共享各种帮助对象和设置,你可以使用setUp()tearDown()添加到sharedFixture属性。

PHPUnit允许使用指定相关testing用例的“@depends”注释,并允许在相关testing用例之间传递参数。

在我看来,采取以下scheme,我需要testing创build和销毁特定资源。

最初我有两种方法,一个。 testCreateResource和b。 testDestroyResource

一个。 testCreateResource

 <?php $app->createResource('resource'); $this->assertTrue($app->hasResource('resource')); ?> 

湾 testDestroyResource

 <?php $app->destroyResource('resource'); $this->assertFalse($app->hasResource('resource')); ?> 

我认为这是一个坏主意,因为testDestroyResource依赖于testCreateResource。 而更好的做法是做

一个。 testCreateResource

 <?php $app->createResource('resource'); $this->assertTrue($app->hasResource('resource')); $app->deleteResource('resource'); ?> 

湾 testDestroyResource

 <?php $app->createResource('resource'); $app->destroyResource('resource'); $this->assertFalse($app->hasResource('resource')); ?> 

如果你的testing需要按照一定的顺序运行,那么你的testing确实有问题。 每个testing应该完全独立于其他testing:它可以帮助您进行缺陷定位,并允许您获得可重复(因此可debugging)的结果。

在这个网站上查看大量的想法/信息,了解如何以避免这些问题的方式来分析testing。

替代解决scheme:在testing中使用静态(!)函数来创build可重用的元素。 比如(我用selenium IDEloggingtesting和phpunit-selenium(github)在浏览器里面运行testing)

 class LoginTest extends SeleniumClearTestCase { public function testAdminLogin() { self::adminLogin($this); } public function testLogout() { self::adminLogin($this); self::logout($this); } public static function adminLogin($t) { self::login($t, 'john.smith@gmail.com', 'pAs$w0rd'); $t->assertEquals('John Smith', $t->getText('css=span.hidden-xs')); } // @source LoginTest.se public static function login($t, $login, $pass) { $t->open('/'); $t->click("xpath=(//a[contains(text(),'Log In')])[2]"); $t->waitForPageToLoad('30000'); $t->type('name=email', $login); $t->type('name=password', $pass); $t->click("//button[@type='submit']"); $t->waitForPageToLoad('30000'); } // @source LogoutTest.se public static function logout($t) { $t->click('css=span.hidden-xs'); $t->click('link=Logout'); $t->waitForPageToLoad('30000'); $t->assertEquals('PANEL', $t->getText("xpath=(//a[contains(text(),'Panel')])[2]")); } } 

好了,现在,我可以在其他testing中使用这个可重用的元素:)例如:

 class ChangeBlogTitleTest extends SeleniumClearTestCase { public function testAddBlogTitle() { self::addBlogTitle($this,'I like my boobies'); self::cleanAddBlogTitle(); } public static function addBlogTitle($t,$title) { LoginTest::adminLogin($t); $t->click('link=ChangeTitle'); ... $t->type('name=blog-title', $title); LoginTest::logout($t); LoginTest::login($t, 'paris@gmail.com','hilton'); $t->screenshot(); // take some photos :) $t->assertEquals($title, $t->getText('...')); } public static function cleanAddBlogTitle() { $lastTitle = BlogTitlesHistory::orderBy('id')->first(); $lastTitle->delete(); } 
  • 通过这种方式,您可以构buildtesting的层次结构。
  • 你可以保留每个testing用例与其他testing用例完全独立的属性(如果你在每次testing后清理数据库)。
  • 最重要的是,例如,如果以后login更改的方式,您只修改LoginTest类,并且在其他testing中不需要正确的login部分(它们应该在更新LoginTest之后工作):)

当我运行testing我的脚本清理数据库广告开始。 上面我使用我的SeleniumClearTestCase类(我做截图()和其他漂亮的function),它是扩展MigrationToSelenium2 (从github,到港口logging的testing在使用seleniumIDE + ff插件“Selenium IDE:PHP格式化”)我的类LaravelTestCase(它是Illuminate \ Foundation \ Testing \ TestCase的副本,但不扩展PHPUnit_Framework_TestCase),这是PHPUnit_Extensions_Selenium2TestCase的扩展,当我们想要在testing结束时清理数据库时,设置laravel以获得口才。 为了设置laravel雄辩,我还在SeleniumClearTestCase函数中创build了应用程序(在setUp调用,我从laral test / TestCase中获取这个函数)

正确的答案是一个正确的testingconfiguration文件。 我有同样的问题,并通过创build必要的testing文件顺序testing套件来解决它:

 phpunit.xml: <phpunit colors="true" bootstrap="./tests/bootstrap.php" convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" strict="true" stopOnError="false" stopOnFailure="false" stopOnIncomplete="false" stopOnSkipped="false" stopOnRisky="false" > <testsuites> <testsuite name="Your tests"> <file>file1</file> //this will be run before file2 <file>file2</file> //this depends on file1 </testsuite> </testsuites> </phpunit>