PHPUnit测试问题 - 如何对我的班级进行单元测试

Ste*_*ose 13 php phpunit unit-testing

我正试图进行单元测试,看看它引入的明显的积极因素,我正在尝试为我前几天写的一个类写一个单元测试.(我知道这与TDD相反,请耐心等待)

我的班级,Image与其他一些人一起用于图像处理.

Image基本上包装GD图像资源并与其一起存储数据.例如,一个实例Image将始终包含它的当前状态,即调整大小时的新宽度/高度,原始图像数据等.

Image班还包含方法,

  • 从文件,字符串数据或URL创建自己,例如 $image->loadFromPath()
  • 从当前Image实例的属性创建新的GD图像资源,例如,用于调整图像大小以保持背景透明度等.
  • 克隆GD图像资源以在操作类中使用

我正在努力的是如何使用PHPUnit正确地测试这个类.我已经完成了一些阅读,我对如何处理它有一些相互矛盾的想法,我不知道什么是正确的.我,我

  1. 为每个类的方法编写一个测试.我在某处读到了我应该测试的每一种方法.但是,有些方法会运行其他方法(我也可以添加),因此您将拥有一系列依赖关系.但我也读到每个单元测试应该独立于另一个.那么如果是这样的话我该怎么办?
  2. 将每个测试写为类的使用路径.我还读到某个地方,每个测试应该代表您可以在课程中使用的1个路径/使用路径.因此,如果您涵盖所有用途,您最终将获得完整的代码覆盖率.

那么,哪些是正确的,如果有的话?

Bry*_* M. 9

应编写单元测试来评估类的公共接口.您的测试用例应该使用该类,因为您打算在程序中使用它.这里的想法是测试类的行为(预期,意外或边缘条件).

你发布的两个想法都是正确的.理论上,您应该有足够的测试用例(通过代码路由),以便运行类中的所有方法.

如前所述,100%的测试覆盖率是一个很好的目标,但并不总是现实的.

此外,在GD的情况下,要小心编写测试GD功能的单元测试(它已经过测试,你不需要浪费时间再次测试它).我会在PHPUnit手册中阅读使用PHPUnit的模拟和存根(以及模拟文件系统).

以下是示例测试的样子:

public function testImageIsResized()
{
    $image = new Image();
    $image->loadFromPath('some/path');
    $image->resize(200, 300);
    $this->assertEquals(200, $image->getWidth());
    $this->assertEquals(300, $image->getHeight());
}
Run Code Online (Sandbox Code Playgroud)

现在,根据图像类的预期行为,此测试可能没有问题,或者可能会失败,因为它期望新维度按比例约束到原始图像维度.但是我们没有显式调用在测试本身中检查该约束的内部方法.


Gor*_*don 5

您可以使用covers注释指定测试是否涵盖多个方法.因此,如果您的某个方法调用另一个方法,您只需将注释添加到测试的docblock中,它就会被添加到您的代码覆盖率统计中,例如

/**
 * @test
 * @covers MyClass::something()
 * @covers MyClass::_somethingElse()
 */
public function somethingWorksAsExpected()
{
    $this->assertSame($expected, $this->testObject->something());
}
Run Code Online (Sandbox Code Playgroud)

对于个人项目,100%的代码覆盖率是好的.但是,我在会议上看到过100%被怀疑是必要的会议.尽管有各种好处,但测试需要时间来编写,在预算项目中,仅测试80/20并省略应用程序的非关键性低优先级功能就足够了.

至于如何测试你的类,请查看PHPUnit手册中关于行为驱动开发的章节.在您的情况下,我会测试您在问题中描述的功能.