【问题标题】:Is testing constructor too much?测试构造函数太多了吗?
【发布时间】:2012-11-11 10:31:48
【问题描述】:

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

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

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

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

另外,我想指出我已经使用了一个开发环境(PHPStorm),我们也在使用 PHPCodeSniffer 之类的工具。

有什么想法/建议吗?

【问题讨论】:

    标签: php unit-testing phpunit software-quality


    【解决方案1】:

    这是一个可以从多个层面回答的好问题:

    1. 语言特征
    2. 测试覆盖率
    3. 案例工具

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

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

    3.案例工具 最终,希望有一个可用的 CASE 工具来检测这些错误,例如缺少参数。如果没有合适的工具,为什么不创建自己的工具。 CASE 工具的创建对于大多数程序员来说并非遥不可及,特别是如果您可以连接到您的语言的开源解析引擎。如果您倾向于开源,这可能是一个很好的开始项目,或者您的公司可能会推销这样的解决方案。

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

    【讨论】:

      【解决方案2】:

      如果设置了无效参数,您是否希望构造函数抛出异常?你希望它明天、下周和明年都以同样的方式表现吗?然后你编写一个测试来验证它是否正确。

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

      【讨论】:

        【解决方案3】:

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

        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
            }
        

        【讨论】:

          猜你喜欢
          • 2012-12-29
          • 2017-04-04
          • 2011-04-11
          • 2013-09-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多