1、PHPUnit 编写测试的基本惯例与步骤

1、正常而言,一般我们的真实代码都是放置在app目录中,那么在同级目录下,我们就需要新建一个test目录,作为单元测试存放目录,该test目录的内部结构要与app目录保持一致。

2、针对类 Class 的测试写在类 Class Test中。
例如:Class News类的单元测试应该写在 Class NewsTest中。

3、Class Test(通常)继承自 PHPUnit\Framework\TestCase

4、测试都是命名为 test* 的公用方法,例如:testAddOrder
也可以在方法的文档注释块(docblock)中使用 @test 标注将其标记为测试方法,这在后续的文章中会介绍到。

5、在测试方法内,使用类似于 assertEquals()这样的断言方法来对实际值与预期值的匹配做出断言处理。

2、下面我们来编写第一个单元测试案例。

注意:本文包括之后的文章,都是使用的PHPUnit全局安装模式运行的,如果你是局部安装的PHPUnit,需要自行修改命令行代码。
下面,我们在test目录下,新建一个StackTest.php文件,并写入以下代码:

  1. <?php
  2. declare(strict_types=1);
  3. use PHPUnit\Framework\TestCase;
  4. class StackTest extends TestCase {
  5. // 第一个单元测试
  6. public function testPushAndPop() {
  7. $stack = [];
  8. # 第1个case
  9. $this->assertEquals(0, count($stack));
  10. array_push($stack, 'foo');
  11. # 第2个case
  12. $this->assertEquals('foo', $stack[count($stack)-1]);
  13. # 第3个case
  14. $this->assertEquals(10, 1+2);
  15. # 第4个case
  16. $this->assertEquals(1, count($stack));
  17. # 第5个case
  18. $this->assertEquals('foo', array_pop($stack));
  19. # 第6个case
  20. $this->assertEquals(0, count($stack));
  21. }
  22. // 第二个单元测试
  23. public function testAddition() {
  24. # 第1个case
  25. $this->assertEquals(1, 1+2);
  26. }
  27. }

然后使用cd命令进入test目录下,运行以下命令行,执行测试:
phpunit StackTest.php
会发现输出了这样的结果:

3、理解

PHPUnit的断言会中断代码执行,同时会报出对应的错误位置,同时测试结果能够清晰的反馈给我们执行所需时间、测试个数、断言次数、失败次数等重要信息。

4、掌握函数点

assertEquals(mixed $expected, mixed $actual[, string $message = ''])
当两个变量 $expected$actual 不相等时报告错误,错误讯息由 $message 指定。
assertNotEquals() 是与之相反的断言,接受相同的参数。
assertAttributeEquals()assertAttributeNotEquals() 是便捷包装(convenience wrapper),
以某个类或对象的某个 publicprotectedprivate 属性作为实际值来进行比较。

下面我们来进行一个清晰的学习,StackTest.php文件修改成以下代码::

  1. <?php
  2. declare(strict_types=1);
  3. use PHPUnit\Framework\TestCase;
  4. class StackTest extends TestCase {
  5. // 第一个单元测试
  6. public function testFailure() {
  7. # 期望得到1,实际得到0
  8. $this->assertEquals(1, 0);
  9. }
  10. // 第二个单元测试
  11. public function testFailure2() {
  12. # 期望得到 bar,实际得到baz
  13. $this->assertEquals('bar', 'baz');
  14. }
  15. // 第三个单元测试
  16. public function testFailure3() {
  17. # 期望得到 bar,实际得到bah (文字太长,忽略相同点这里只说不同点)
  18. $this->assertEquals("foo\nbar\nbaz\n", "foo\nbah\nbaz\n");
  19. }
  20. // 第四个单元测试
  21. public function testFailure4() {
  22. # 期望得到1,实际得到0,是NO,所以不同则通过
  23. $this->assertNotEquals(1, 0);
  24. }
  25. // 第五个单元测试
  26. public function testFailure5() {
  27. # 期望得到1,实际得到0,是NO,所以不同则通过
  28. $this->assertAttributeEquals('咩咩', 'name', new Demo());
  29. }
  30. // 第六个单元测试
  31. public function testFailure6() {
  32. # 期望得到1,实际得到0,是NO,所以不同则通过
  33. $this->assertAttributeNotEquals('咩咩', 'name', new Demo());
  34. }
  35. }
  36. class Demo {
  37. private $name = '哈哈';
  38. }

直接用PHPUnit执行测试,并查看结果即可。