我开始使用单元测试。我有一种情况,不知道如何进行:
例如:我有一个打开并读取文件的类。在我的单元测试中,我想测试 open 方法和 read 方法,但是要读取文件我需要先打开文件。
如果“打开文件”测试失败,“读取文件”测试也会失败!
那么,如何明确表示读取失败是因为打开?我测试打开里面读??
我开始使用单元测试。我有一种情况,不知道如何进行:
例如:我有一个打开并读取文件的类。在我的单元测试中,我想测试 open 方法和 read 方法,但是要读取文件我需要先打开文件。
如果“打开文件”测试失败,“读取文件”测试也会失败!
那么,如何明确表示读取失败是因为打开?我测试打开里面读??
单元测试的关键特性是隔离:一个特定的单元测试应该涵盖一个特定的功能——如果它失败了,它应该报告它。
在您的示例中,read
显然取决于open
功能:如果后者被破坏,则没有理由测试前者,因为我们知道结果。此外,报告read
失败只会给您的测试结果添加一些不相关的噪音。
read
在这种情况下可以(并且应该)报告test skipped
什么是或类似的。这就是它在PHPUnit中的完成方式,例如:
class DependencyFailureTest extends PHPUnit_Framework_TestCase
{
public function testOne()
{
$this->assertTrue(FALSE);
}
/**
* @depends testOne
*/
public function testTwo()
{
}
}
这里我们有依赖于 testOne 的 testTwo。这就是运行测试时显示的内容:
There was 1 failure:
1) testOne(DependencyFailureTest)
Failed asserting that <boolean:false> is true.
/home/sb/DependencyFailureTest.php:6
There was 1 skipped test:
1) testTwo(DependencyFailureTest)
This test depends on "DependencyFailureTest::testOne" to pass.
FAILURES!
Tests: 2, Assertions: 1, Failures: 1, Skipped: 1.
解释:
为了快速定位缺陷,我们希望我们的注意力集中在相关的失败测试上。这就是当依赖测试失败时 PHPUnit 跳过测试执行的原因。
一般来说,您不会发现自己在测试您提议的单元测试场景,即读取文件的能力,因为您通常最终会使用某种文件操作库,并且通常可以安全地假设该库的维护者拥有适当的单元测试已经到位(例如,我非常有信心可以在 .NET 中使用 File 类而无需担心)。
话虽如此,一个条件阻碍测试第二个条件的想法当然是有效的。这就是创建模拟框架的原因,以便您可以轻松地设置一个模拟对象,该对象将始终以定义的方式运行,然后可以替换初始依赖项。这使您可以专注于单元测试第二个对象/条件/等。在测试场景中。
打开文件是读取文件的先决条件,因此可以将其包含在测试中。如果文件无法打开,您可以在代码中引发异常。然后,测试中的错误消息将清楚说明测试失败的原因。
我还建议您考虑在测试本身中创建文件以删除对现有文件的任何依赖关系。这样您就可以确保始终有一个有效的文件可供参考。