如何使用phpunit运行单个测试方法?

478

我正在努力使用phpunit运行文件escalation/EscalationGroupTest.php中名为testSaveAndDrop的单个测试方法。我尝试了以下组合:

phpunit EscalationGroupTest escalation/EscalationGroupTest.php --filter=escalation/EscalationGroupTest.php::testSaveAndDrop
phpunit EscalationGroupTest escalation/EscalationGroupTest.php --filter=EscalationGroupTest.php::testSaveAndDrop
phpunit EscalationGroupTest escalation/EscalationGroupTest.php --filter=EscalationGroupTest::testSaveAndDrop
phpunit EscalationGroupTest escalation/EscalationGroupTest.php --filter=testSaveAndDrop
在每种情况下都会执行文件escalation/EscalationGroupTest.php中的所有测试方法。如何只选择一个特定的方法呢?
类的名称是EscalationGroupTest,而phpunit的版本是3.2.8。

你的测试类的类名是什么? - sectus
14个回答

660
以下命令对单个方法运行测试:
phpunit --filter testSaveAndDrop EscalationGroupTest escalation/EscalationGroupTest.php

phpunit --filter methodName ClassName path/to/file.php

对于较新版本的phpunit,只需执行以下操作:

phpunit --filter methodName path/to/file.php

2
编写EscalationGroupTest是否必要?它的用途是什么? - mujaffars
3
好的,我明白了是该类的名称。 - mujaffars
27
它还将运行名称为testSaveAndDrop*的测试方法(例如:testSaveAndDropSomething)。要仅运行testSaveAndDrop测试,请使用--filter '/::testSaveAndDrop$/'。 - Farid Movsumov
4
我怀疑,由于空格的缘故,“I got it”在PHP中不是有效的标识符。 - Jon McClung
5
现在这种方法已经不可用了。现在只需要使用 phpunit --filter methodName path/to/testing/file,不需要加上 ClassName - CJ Dennis
显示剩余6条评论

281

我更喜欢在注释中标记测试

/**
 * @group failing
 * Tests the api edit form
 */
public function testEditAction()

然后运行它

phpunit --group failing

命令行中不需要指定完整路径,但是在提交之前必须记得删除它,以防代码混乱。

您还可以为单个测试指定多个组。

/**
  * @group failing
  * @group bug2204 
  */
public function testSomethingElse()
{
}

5
我喜欢这种方法,能否通过注释分配多个组?@group failing, Integration - Dizzy Bryan High
5
可以的,但不要用逗号分隔。编辑回答以说明这一点。 - iamtankist
我更喜欢这种方法... 参考phpunit.xml中的<groups>元素也可以用于过滤测试... 在<phpunit>下面使用类似以下内容:failing - Nicolas Galler
2
但问题是 - 只运行单个测试。另外 - 组名为failing是你可以使用的最糟糕的选项。因为当一些测试失败后,你可以运行phpunit --group failing来运行失败的测试而不给它们分组。这很令人困惑。 - Rafał Mnich
1
最佳答案!如果某个测试案例依赖于另一个测试案例,则没有单独的测试。因此,您必须确定所有相互关联的测试案例,因此使用@group注释。 - centurian
这应该是首选答案。 - clockw0rk

136

以下是通用的答案:

如果你确定方法名称是唯一的,你可以仅按照方法名称进行过滤 (这对我有效)

phpunit --filter {TestMethodName}

然而,最好还是指定文件路径/引用以确保安全

phpunit --filter {TestMethodName} {FilePath}

示例:

phpunit --filter testSaveAndDrop reference/to/escalation/EscalationGroupTest.php

小提示:我注意到如果我有一个名为testSave的函数和另一个名为testSaveAndDrop的函数,使用命令phpunit --filter testSave将同时运行testSaveAndDrop和以testSave*开头的其他函数, 这很奇怪!!


8
这并不奇怪,它基本上是子字符串匹配。如果您想要这种行为,请使用字符串结束符:/testSave$/ - Christian
如果您只想指定文件路径以便运行该文件中的所有测试,该怎么办? - still_dreaming_1
1
@still_dreaming_1 只需提供路径,不要添加 --filter {TestMethodName}。 - Den

59

以下命令将精确地执行testSaveAndDrop测试。

phpunit --filter '/::testSaveAndDrop$/' escalation/EscalationGroupTest.php

8
对我来说没用。使用\b代替$最终解决了问题:--filter '/::testSaveAndDrop\b/' - Joe
1
这两个方法名称结尾的 '/::testSaveAndDrop\b/''/::testSaveAndDrop$/' 对我来说都可以像这样工作 phpunit --filter ClassName::methodName$phpunit --filter ClassName::methodName\b(在Linux上)。 - Valentine Shi
同样在这里:两者都可以工作(在Linux上),而且“/”字符是可选的(PHPUnit 9.5.13)。 - SteeveDroz
@Joe 只是一个直觉:您在 PhpDoc 注释中的方法名称后面是否有 ()?这可能是为什么 $ 不起作用以及 \b 为什么都起作用的原因。 - cautionbug

57
  • 在你的项目根目录中运行此命令,我在 Laravel 根目录中使用。
vendor/bin/phpunit --filter 'Your method name'

自定义方法名称的示例。

 /** @test //Initilize this for custom method name, without test keyword
  *  
  * Test case For Dashboard When User Not logged In it will redirect To login page
  */
  public function only_logged_in_user_see_dashboard()
  {
    $response = $this->get('/dashboard')
                   ->assertRedirect('/login');
  }

测试关键词的例子

/**
* A basic test example.
*
* @return void
*/
 public function testBasicTest()
 {
  $this->assertTrue(true);
 }

47

有多种方法可以在 Laravel 中运行 PHPUnit 测试..

vendor/bin/phpunit --filter methodName className pathTofile.php

vendor/bin/phpunit --filter 'namespace\\directoryName\\className::methodName'

用于测试单个类:

vendor/bin/phpunit --filter  tests/Feature/UserTest.php
vendor/bin/phpunit --filter 'Tests\\Feature\\UserTest'
vendor/bin/phpunit --filter 'UserTest' 

测试单个方法:

 vendor/bin/phpunit --filter testExample 
 vendor/bin/phpunit --filter 'Tests\\Feature\\UserTest::testExample'
 vendor/bin/phpunit --filter testExample UserTest tests/Feature/UserTest.php

运行同一命名空间下所有类的测试:

vendor/bin/phpunit --filter 'Tests\\Feature'

了解更多运行测试的方法,请查看更多


30

1
不,这不起作用。EscalationGroupTest 类中的所有测试都正在处理中。 - Alex
仍在运行所有9个测试。PHPUnit版本为3.2.8。 - Alex
2
--filter 移到文件名之前,应该就可以正常工作了。 - Schleis
在PHPUnit 4.8.10上对我有效。 - Asaph
这在 PHPUnit 4.8.35 上给我返回了 No tests executed!@Schleis 你具体是如何更改命令的? - Andru

9

鉴于您

vendor/bin/phpunit --filter=EscalationGroupTest::testSaveAndDrop

8
如果您使用NetBeans,可以在测试方法上右键单击,然后单击“运行聚焦的测试方法”。 Run Focused Test Method menu

7
您可以尝试这个方法,我可以运行单个测试用例。
phpunit tests/{testfilename}

例如:

phpunit tests/StackoverflowTest.php

如果您想在Laravel 5.5中运行单个测试用例,请尝试:
vendor/bin/phpunit tests/Feature/{testfilename} 

vendor/bin/phpunit tests/Unit/{testfilename} 

例如:

vendor/bin/phpunit tests/Feature/ContactpageTest.php 

vendor/bin/phpunit tests/Unit/ContactpageTest.php

1
问题是如何运行单个测试方法(而不是类)。 - Aleksei Akireikin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接