【问题标题】:Unit tests for HTML Output?HTML输出的单元测试?
【发布时间】:2011-03-26 15:30:20
【问题描述】:

这可能是个愚蠢的问题,但是您是否对 PHP 函数/脚本的 HTML 输出进行单元测试?

我尝试将我的 HTML 和我的 PHP 分开 - 即 HTML 包含占位符,以及某些重复元素(表格数据/任何类型的循环输出)的函数 - 但我不确定如何去验证这一点。

是否有标准的方法来处理这些事情,或者主要是对 创建插入内容的函数使用常规单元测试,然后确保它在浏览器中看起来正确/W3C 验证器?

谢谢。

编辑:我想一个推论是:这些类型的单元测试甚至值得拥有吗?如果您将内容和结构正确分离,那么您实际上只会在非常有限的场景中测试少数包含(大概,无论如何)。半手工制作完整页面只是为了有一个文件进行比较真的值得吗?

【问题讨论】:

    标签: php html unit-testing templates


    【解决方案1】:

    根据我测试 HTML 的经验,我现在遵循以下三个基本规则:

    1.不要针对正确的模板测试 HTML 输出。 您将过于频繁地修改输出的 HTML,最终会浪费时间来维护您的测试。

    2。检查生成的 HTML 中是否存在重要数据。 如果您正在生成 HTML(而不是您编写一次的静态 HTML),请测试生成的 HTML 中的重要数据。例如:如果您正在生成基于二维数组的表,请检查数组中的值是否在生成的 HTML 中的某处找到。不要费心去验证完整的输出,因为这会违反 #1。

    3.验证输出是否是正确的 HTML。 验证所有输出的正确 HTML 以避免愚蠢的错误,例如缺少结束标记。我为此编写了一个库,可以完全免费使用。

    此 PHP 库可让您验证字符串是否为有效的 HTML5。该库使用 Validator.nu。与 PHPUnit 或任何其他测试框架兼容。

    Download and documentation here.

    易于使用,例如:

    $validator=new HTML5Validate();
    
    // Validate (returns TRUE or FALSE)
    $result=$validator->Assert('<p>Hello World</p>'); 
    
    // Get explanation of what's wrong (if validation failed)
    print $validator->message; 
    

    【讨论】:

      【解决方案2】:

      测试 HTML 输出将被视为覆盖测试。最初,当我开始使用 PHP 时,我正在创建这些测试,但随着时间的推移,我发现这些测试并没有那么有帮助。

      如果我知道一件事,那就是演示文稿将从最初的开发到部署发生很多的变化。

      如果你仔细想想,for 循环真的不是逻辑而是等距变换函数,如果你遵循Separation of Concerns,那么你就是通过某种方法将数据传递到 for 循环中。我建议测试 for 循环是否获取正确的数据,而不是 for 循环的输出。

      如果您发现自己重复生成表格,那么请务必开始对这些表格模板进行单元测试。但是再一次,您会发现这些模板将发生很大变化。

      此时,您应该考虑将迭代与 HTML 输出分开,以帮助您将自己与测试中的这些问题隔离开来。

      一种方法是使用映射函数,它将采用列表和转换函数并对列表中的每个项目执行该函数,然后返回转换后的列表。

      通常,在创建表格时,我会在创建一行时使用两个 for 循环。

      1. 遍历所有行。
      2. 在 (1) 中迭代行中的项目。

      对它进行单元测试非常难看,但是通过闭包,您可以创建函数生成器,该函数生成器真的很容易实现 [这是用一粒盐说的]。

      【讨论】:

        【解决方案3】:

        您可以使用 PHPUnit。它有输出测试。

        http://www.phpunit.de/manual/3.0/en/testcase-extensions.html

        【讨论】:

        • 这引发了一个类似的问题:像这样半手工制作完整页面真的值得只是为了有一个文件来比较几个单元测试吗?断了不可见吗?
        • @Kristina 如果您正在测试程序中巨大的、单一的部分,那么您就错过了unit testing
        • 可以检查组成页面的各个函数和方法,但你是说我不应该对调用它们/呈现页面的方法进行单元测试?
        • 请注意,上面的 URL 指向的是旧版本的 PHP 单元。截至 2013 年 11 月,PHPUnit 的版本已更改为 3.8,不再存在此输出测试。
        【解决方案4】:

        我发现SimpleTest 框架非常有用,通常我将它用于集成测试和 PhpUnit 用于单元测试。他们省去了我很多手动提交的公式,否则我会一遍又一遍地这样做。

        在进行此类集成测试时,遵循以下几点已成为我的习惯:

        1. 尽量不要重复已经用真实单元测试完成的测试。例如,如果您有一个针对电子邮件地址的单元测试验证功能,那么提交所有类型的无效电子邮件地址是没有意义的。如果您被重定向并显示错误消息,只需检查一次。
        2. 不要将生成的 HTML 与完整的参考输出进行比较,您必须在每次重新设计页面时更新测试。而是使用$webTestCase-&gt;assertText('...');$webTestCase-&gt;assertPattern('/.../'); 仅检查关键部分。

        通过一些微小的辅助函数,您可以获得很大的健壮性。以下函数将打开一个页面并检查该页面是否已成功打开而没有警告。由于没有可以在设计时发出警告的 PHP 编译器,您至少可以确保您的代码不会产生错误或警告。

        public static function openPageWithNoWarnings($webTestCase, $page, $landingPage = null)
        {
          // check that page can be opened successfully
          $webTestCase->assertTrue($webTestCase->get($page));
        
          // check that there are no PHP warnings
          $webTestCase->assertNoPattern('/(warning:|error:)/i', 'PHP error or warning on page!');
        
          // check if landed on expected page (maybe a redirect)
          if (!empty($landingPage))
          {
            $url = $webTestCase->getUrl();
            $file = basename(parse_url($url, PHP_URL_PATH));
            $webTestCase->assertEqual($page, $file,
              sprintf('Expected page "%s", got page "%s".',  page, $file));
          }
        }
        

        这样的测试不会给您太多的工作,您可以从非常简单的测试开始,但如果出现问题,它们会立即给您反馈,只需单击鼠标即可。

        【讨论】:

        • 完美! SimpleTest 在这方面确实比 phpunit 更好。 :)
        【解决方案5】:

        这里有一个 PHPUnit 扩展可以进行 html 验证:https://github.com/xvoland/html-validate

        【讨论】:

          【解决方案6】:

          我自己也遇到了这个问题。我认为一种方法可能是使用 phpQuery 之类的东西来使您的测试不那么脆弱。不要测试精确的输出,而是测试输出中是否应该有一个 h3 标签 ~somewhere~。如果它后来被包裹在一个 div 中,因为设计师需要添加额外的背景,或者因为一些 ie6 浮动错误解决方法,那么你的测试仍然有效。

          它不是很纯粹,但仍然可能是一个非常有用的工具。

          【讨论】:

            【解决方案7】:

            在某些情况下(例如 CakePHP Helpers),类或函数的目的是为您生成一致的 HTML。在这种情况下,测试生成的 HTML unit 的预期属性对于给定的输入是否正确非常重要。这个问题在这种情况下绝对有效。

            PHPUnit 为此提供了一个assertTag() 函数。

            但是要回应其他人;重要的是要强调单元测试应该在项目中尽可能小的组件上进行,而不是在整个呈现的网页上进行。还有其他工具(例如Selenium)旨在确保将这些单独的组件正确集成在一起。

            【讨论】:

              【解决方案8】:

              一种非常简单的方法是使用输出缓冲。

              例如

              ob_start();
              function_which_produces_some_output();
              $this->assertEquals( ob_get_clean(), '<p>Expected Output Here</p>');
              

              【讨论】:

                【解决方案9】:

                其中很多链接要么已失效,要么已过时。看看http://phpfui.com/PHPFUI/HTMLUnitTester 它根据 w3.org 标准验证了 HTML 和 CSS。我写它是因为我找不到任何最近和当前支持的 PHP 库来做它。其他解决方案基于旧版本的 PHPUnit 或与现代 PHP 代码不兼容。

                它使用我建议在本地运行的 W3C HTML 验证器服务。这一切都在配置的自述文件中进行了解释。该库的美妙之处在于它不进行实际验证,而是调用 W3C.org 代码,因此如果您保持本地安装最新,它将始终是最新的。

                希望这会有所帮助。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2013-04-25
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多