繁体   English   中英

测试构造函数太多了吗?

[英]Is testing constructor too much?

首先,我会说我来自Java世界(这很重要,真的)。

我已经编写了一段时间的PHP,我遇到的一个问题是由于缺少编译,有时可能在编译时很容易检测到错误(例如,给定函数的参数数量错误),可以默默地通过。

通过添加单元测试,可以轻松检测到代码覆盖率增加。 问题是,例如测试构造函数以检查传递的参数是否正确是否有意义? 我不是指参数的数量,而是指这些参数的内容(例如,如果参数为null,某些对象应该启动异常以避免创建“脏”对象)。

问题是,我是否被多年的Java代码污染了? 因为毕竟,增加代码覆盖率以“发现”错过的函数感觉就像(真正)原始的编译方式。

另外,我想说明我已经使用了开发环境(PHPStorm),我们也使用了像PHPCodeSniffer这样的工具。

有什么想法/建议吗?

这是一个很好的问题,可以在许多层面上得到解答:

  1. 语言特征
  2. 测试范围
  3. CASE工具

1.语言特征正如您所指出的,PHP语言的特征与Java等强类型语言明显不同。 这引发了一个严重的问题,即来自Java和C#等强类型语言的程序员可能不会意识到PHP行为的含义(例如你所描述的那些)。 这引入了程序员错误的可能性(例如,程序员可能不太小心使用Java,因为他们知道编译器会捕获不正确的参数,但在PHP开发时可能不会应用适当的注意事项)。 因此,需要更好的程序员教育/监督来解决这个问题(例如内部公司编码标准,结对编程,代码审查)。 它(正如你所指出的那样)提出了一个问题,即是否应该增加测试覆盖率以检查编译器会捕获的错误。

2.测试覆盖率测试覆盖率的参数是特定于项目的。 在现实世界中,测试覆盖水平主要取决于客户的容错能力(由系统中发生错误的后果决定)。 如果您正在开发在实时控制系统上运行的软件,那么显然您将测试更多。 在您的问题中,您将PHP视为首选语言; 这同样适用于关键系统基础架构中不断增加的基于Web的前端数量。 另一方面,如果您正在为模型铁路俱乐部开发一个简单的网站,并且正在开发一个时事通讯应用程序,那么您的客户可能不会关心构造函数中存在错误的可能性。

3. CASE工具最终,CASE工具可用于检测这些错误,例如缺少参数。 如果那里没有合适的工具,为什么不创建自己的工具呢? 大多数程序员都无法创建CASE工具,特别是如果您可以使用您的语言的开源解析引擎。 如果你是开源倾向,这可能是一个很好的项目,或者你的公司可能推销这样的解决方案。

结论在你的情况下,是否测试构造函数基本上归结为一个问题:我的系统失败的后果是什么? 如果在测试构造函数上花费额外资源以避免此类失败具有经济意义,那么您应该这样做。 否则,可能会通过较少的测试来完成,例如结对编程或代码审查。

如果设置了无效参数,您是否希望构造函数抛出异常? 你希望明天,下周和明年的行为方式相同吗? 然后你编写一个测试来验证它确实存在。

测试验证您的代码是否按照您的意愿运行。 失败的无效参数是代码行为,与计算销售税或显示用户的个人资料页面一样多。

我们测试构造函数,参数的顺序,未提供的默认值,然后是一些实际设置。 例如:

class UTIL_CATEGORY_SCOPE extends UTIL_DEPARTMENT_SCOPE
{
    function __construct($CategoryNo = NULL, $CategoryName = NULL)
    {
        parent::__construct();              // Do Not Pass fields to ensure that the array is checked when all fields are defined.
        $this->DeclareClassFields_();

        $this->CategoryName = $CategoryName;
        $this->CategoryNo   = $CategoryNo;
    }

    private function DeclareClassFields_()
    {
        $this->Fields['CategoryNo']             = new UTIL_ICAP_FIELD_PAIR_FIRST('CCL', 6, ML('Category'), 8);
        $this->Fields['CategoryName']           = new UTIL_ICAP_FIELD_PAIR_SECOND('CCL', 32, ML('Name'), 15, array(), array(), NULL, UTIL_ICAP_FIELD::EDIT_DENY, UTIL_ICAP_FIELD::UPDATE_DENY, 'DES');
    }
}

然后我们创建我们的测试,不仅检查构造函数及其顺序,而且该类和继承没有改变。

public function testObjectCreation()
    {
        $CategoryInfo = new UTIL_CATEGORY_SCOPE();
        $this->assertInstanceOf('UTIL_CATEGORY_SCOPE', $CategoryInfo);
        $this->assertInstanceOf('UTIL_DEPARTMENT_SCOPE', $CategoryInfo);
        $this->assertInstanceOf('UTIL_DATA_STRUCTURE', $CategoryInfo);     // Inherited from UTIL_DEPARTMENT_SCOPE
    }

    public function testConstructFieldOrder()
    {
        $CategoryInfo = new UTIL_CATEGORY_SCOPE(1500, 'Category Name');
        $this->assertEquals(1500, $CategoryInfo->CategoryNo);
        $this->assertEquals('Category Name', $CategoryInfo->CategoryName);
    }

    public function testConstructDefaults()
    {
        $CategoryInfo = new UTIL_CATEGORY_SCOPE();
        $this->assertNull($CategoryInfo->CategoryNo);
        $this->assertNull($CategoryInfo->CategoryName);
    }

    public function testFieldsCreated()
    {
        $CategoryInfo = new UTIL_CATEGORY_SCOPE();
        $this->assertArrayHasKey('CategoryNo', $CategoryInfo->Fields);
        $this->assertArrayHasKey('CategoryName', $CategoryInfo->Fields);
        $this->assertArrayHasKey('DeptNo', $CategoryInfo->Fields);      // Inherited from Parent
        $this->assertArrayHasKey('DeptName', $CategoryInfo->Fields);    // Inherited from Parent
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM