首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TDD,PHPUnit怀疑

TDD,PHPUnit怀疑
EN

Stack Overflow用户
提问于 2013-09-03 11:17:01
回答 2查看 529关注 0票数 1
代码语言:javascript
复制
class MyClass {

    private $numeric;

    public function MyMethod($numeric)
    {

        if (! is_numeric($numeric)) {
            throw new InvalidArgumentException
        }

        $this->numeric = $numeric;

    }

}

1-有必要测试类是否存在?

PHPUnit有几个自动运行的方法,例如assertPreConditions、setUp和其他方法。在这些方法中有必要使用assertTrue和class_exists检查类是否存在?示例:

代码语言:javascript
复制
protected function assertPreConditions()
{

    $this->assertTrue(class_exists("MyClass"), "The class does not exists.");

}

2-是否有必要检查是否存在方法?如果是,这个测试应该是一个单独的测试,或者在每个单元测试中?

假设我们有一个只接受数值类型参数的方法,所以我们有两个测试,一个是带有正确参数的测试,另一个是期望异常的不正确方法,对吗?写这个方法的正确方法是..。

这条路:

代码语言:javascript
复制
public function testIfMyMethodExists()
{
    $this->assertTrue(method_exists($MyInstance, "MyMethod"), "The method does not exists.");
}

/**
* @depends testIfMyMethodExists
* @expectedException InvalidArgumentExcepiton
*/
public function testMyMethodWithAValidArgument()
{
    //[...]
}

/**
* @depends testIfMyMethodExists
* @expectedException InvalidArgumentExcepiton
*/
public function testMyMethodWithAnInvalidArgument()
{
    //[...]
}

还是这边?

代码语言:javascript
复制
public function testMyMethodWithAValidArgument()
{
    $this->assertTrue(method_exists($MyInstance, "MyMethod"), "The method does not exists.");
}

/**
* @expectedException InvalidArgumentExcepiton
*/
public function testMyMethodWithAnInvalidArgument()
{
    $this->assertTrue(method_exists($MyInstance, "MyMethod"), "The method does not exists.");
    //[...]
}

为什么?

3-“封面”和“没有”的真正目的是什么?

我正在读一篇PHPUnit的创建者Sebastian写成良好实践的文档,我们应该始终在方法和类中编写@covers和@coversNothing,并在xml中添加以下选项:

代码语言:javascript
复制
mapTestClassNameToCoveredClassName="true"
forceCoversAnnotation="true"

在白名单中:

代码语言:javascript
复制
<whitelist addUncoveredFilesFromWhitelist="true">
    <directory suffix=".php"></directory>
</whitelist>

但真正需要的是什么呢?

4-测试调用另一个方法的构造函数的正确方法是什么?

看起来一切都很好,但在测试中没有。

即使我使用有效的参数和无效的参数来测试方法"MyMethod“上的异常,如果我在构造函数中输入了一个不正确的值(测试失败),这也不会发生。

如果使用有效参数进行测试,代码覆盖率不会达到100%。

代码语言:javascript
复制
public function __construct($numeric)
{
    $this->MyMethod($numeric);
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-09-03 14:33:22

我为应该存在的方法编写测试,以测试代码是否达到了预期的效果。我还测试了InstanceOf()类(和继承的类定义),以确保对象创建了应该创建的对象。如果FOO()扩展BAR(),则测试创建的对象是InstanceOf(FOO)和InstanceOf(BAR)。如果类被更改为继承其他东西,或者删除了扩展,我的测试将再次通知开发人员检查代码,以确保所需的更改。FOO上可能会调用一些继承的函数,如果没有从条形图的扩展,这段代码就会中断。

我编写要执行的各种代码路径的测试。因此,如果我期望在传递错误数据时函数会抛出一个异常,我会为此编写一个测试。我这样做也是为了帮助文档化我们的源代码。测试显示了预期的行为。如果有人删除了异常(接受不同参数类型的新功能),则应该更新测试以表明这是允许的。对参数的更改可能会在其他地方造成问题。通过这种方式进行测试可以确保数年后,我知道代码要求这是一个数字,如果我要更改参数类型,我肯定应该仔细地重新对代码进行重新分析。

使用测试驱动开发(,TDD)可能会导致您在编写测试时不编写代码抛出异常,然后编写通过测试的代码。因此,您可能并不是在测试所有参数及其类型或值,但我试图尽可能地验证合理的数据输入,以避免垃圾进入/垃圾输出(GIGO)问题。

所有这些测试还为我提供了一个很好的代码覆盖率度量,因为大多数代码库都是经过测试的,并且代码确实通过了类文件中的所有行。然而,测试到这个级别,并试图实现高代码覆盖率度量,实际上是您的团队的一个选择,如果这是需要的或不需要的。

票数 1
EN

Stack Overflow用户

发布于 2013-09-03 13:08:08

我看不出写这种考试有什么理由和好处。如果类或方法不存在,您的测试无论如何都会失败。所以你写它们没有任何利润。

也许上面(第一点)中的一个例外情况是,您总是使用PHPUnit模拟框架构建SUT (理论上说,您的SUT是一个模拟的情况,您不需要在特定的测试中使用其他模拟方法,但我无法想象导致它的实际情况)。

在我看来,如果测试涵盖了流路径,而流路径完全包含在另一个测试中--这意味着测试是多余的和不必要的。

编辑:

因为您想知道特定单元测试究竟调用了哪个流路径。假设您有两个方法A和B。方法B调用方法A。如果您没有@covers注释测试,方法B可以为方法A生成代码覆盖范围,您也不能说A的单元测试是否100%覆盖代码。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18590906

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档