在 入门 的基础上再来看这一篇。
1、使用注释 @test
来标注需要测试的方法
你的测试方法可以是 test
前缀的方法,也可以是包含 @test
注解的方法。
public function testSomething()
{
$this->assertTrue(true, 'This should already work.');
}/*** @test*/
public function something()
{
$this->assertTrue(true, 'This should already work.');
}
2、测试依赖 @depends
有一些测试方法需要依赖于另一个测试方法的返回值,此时需要使用测试依赖。测试依赖通过注释 @depends
来标记。
public function testReturnA()
{
$this->assertTrue(true, 'This should already work.');return 1;
}public function testReturnB()
{
$this->assertTrue(true, 'This should already work.');return 2;
}/*** @depends testReturnA* @depends testReturnB*/
public function testDepends($a, $b)
{
$this->assertTrue(true, 'This should already work.');var_dump($a+$b);
}
3、数据提供器 @dataProvider
在依赖中,所依赖函数的返回值作为参数传入测试函数。除此之外,我们也可以用数据提供器来定义传入的数据。
/*** @dataProvider additionProvider*/
public function testAdd($a, $b, $expected)
{
$this->assertSame($expected, $a + $b);
}public function additionProvider()
{
return ['adding zeros' => [0, 0, 0], // 0 + 0 = 0 pass'zero plus one' => [0, 1, 1], // 0 + 1 = 1 pass'one plus zero' => [1, 0, 1], // 1 + 0 = 1 pass'one plus one' => [1, 1, 2], // 1 + 1 = 2 pass];
}
测试异常 (expectException)
就是看是否抛出意料之中的异常。需要在测试方法的开始处声明期望,然后执行语句。而不是调用后再声明。
public function testException()
{
$this->expectException(\Exception::class);throw new \Exception('test');
}
测试输出
直接添加期望输出,然后执行相关函数。和测试异常类似,需要先添加期望,再执行代码。
public function testExpectFooActualFoo()
{
$this->expectOutputString('foo');print 'foo';
}public function testExpectBarActualBaz()
{
$this->expectOutputString('bar');print 'baz';
}
基镜
在编写测试时,最费时的部分之一是编写代码来将整个场景设置成某个已知的状态,并在测试结束后将其复原到初始状态。这个已知的状态称为测试的基境(fixture)。
例如在User测试中,我们每次都需要new User进行测试user类,其实我们完全可以使用基镜。
protected $user;function setUp(){
parent::setUp(); // TODO: Change the autogenerated stub$this->user = new User();//例如这个类有很多属性需要自定义,初始化,都可以在这里完成//例如这个类需要查找数据库进行赋值,都可以在这里完成//例如需要新增一条数据用于测试,都可以在这里完成}function tearDown(){
parent::tearDown(); // TODO: Change the autogenerated stubunset($this->user);//销毁类属性,都可以在这里调用//例如测试完需要把数据还原回之前的状态,可以在这里完成//例如测试完需要把数据删除,可以在这里完成}public function testGet(){
$user = $this->user;$data= $user->get(1);$this->assertEquals('1',$data['id']);//断言返回的id为1}
继承
phpunit的测试用例都可以直接继承,进行多继承测试。
BaseTest extends TestCase
BTest extends BaseTest于是 BTest 和 BaseTest 都是测试文件。
有风险的测试 (Risky Tests)
无用测试 (Useless Tests)
默认情况下,如果你的测试函数没有添加预期或者断言,就会被认为是无用测试。
通过设置 --dont-report-useless-tests
命令行参数,或者在 xml 配置文件中配置 beStrictAboutTestsThatDoNotTestAnything="false"
来更改这一默认行为。
测试过程中有输出 (Output During Test Execution)
如果在测试过程中输出文本,则会被认定为有风险的测试。通过设置 --disallow-test-output
命令行参数,或者在 xml 配置文件中配置 beStrictAboutOutputDuringTests="true"
来更改这一默认行为。
待完善的测试
处于一些原因,我们希望跳过或者对某些测试方法标记未待完善,使用 $this->markTestIncomplete
标记待完善的测试
public function testSomething()
{
$this->assertTrue(true, 'This should already work.');$this->markTestIncomplete('This test has not been implemented yet.');
}
跳过的测试
使用 markTestSkipped
来标记跳过的测试。
use PHPUnit\Framework\TestCase;class DatabaseTest extends TestCase
{
protected function setUp(){
if (!extension_loaded('mysqli')) {
$this->markTestSkipped('The MySQLi extension is not available.');}}public function testConnection(){
// ...}
}
关于编辑器集成 PHPUnit
PHPStorm 自然是很智能的检测你的本地环境是否安装了 PHPUnit ,以及当前项目的 phpunit.xml 文件。
但是 vscode 就不会自动识别了,有兴趣的同学可以研究一下,不过我还是习惯在命令行操作。