【问题标题】:What's the state of TDD and/or BDD in PHP? [closed]PHP 中 TDD 和/或 BDD 的状态是什么? [关闭]
【发布时间】:2009-02-10 00:53:16
【问题描述】:

在 PHP 世界中测试的广泛性、支持性和开发程度如何?与Java相提并论?有 Ruby/Rails 吗?我用谷歌搜索并发现测试框架存在,但我想知道它们是否被广泛使用。

主要的 PHP IDE 是否像 Eclipse 的 Java 工具或 NetBeans 的 Ruby/Rails 工具那样内置了测试运行器?测试是否像 Rails 一样内置在 PHP 的 MVC 框架中?

我之所以问,是因为我所在的一个团队想聘请某人为他们开发 PHP 应用程序。我担心质量和维护,因为我可能会被要求支持这件事。

【问题讨论】:

    标签: php testing tdd bdd


    【解决方案1】:

    至少有两个成熟的、独立的、JUnit 风格的测试套件可用,分别命名为PHPUnitSimpleTest

    就 MVC 框架而言,Symfony 有自己的测试框架,名为 lime,Code Igniter 有一个 unit_test 库,CakePHP 依赖于前面提到的 SimpleTest。

    我知道 Zend Studio 已经内置了对 PHPUnit 测试的支持,而且 PHPUnit 和 SimpleTest 都有命令行运行器,因此可以集成到任何工作流中。

    如果开发人员想要利用这些工具,PHP 世界中就有这些工具,而智能商店确实会利用它们。

    注意事项是您对课程 PHP 投诉的标准。有两个 PHP 社区; PHP 作为构建软件的平台,PHP 作为一种与 Web 服务器、Web 浏览器和数据库交互的方式,以在 Web 上生成类似应用程序的东西。它不是一个黑白的东西,而是一个连续体;在软件开发人员方面,单元测试和 TDD 的更多支持和使用与在任何其他平台上一样多。在“拼凑一堆看不懂但还是有结果的人”中,闻所未闻。

    周围有很多非框架/自定义框架的遗留 PHP 代码,很难找到有用的测试工具。 PHP 也很容易适用于依赖浏览器环境来运行的模式。除了我自己的观察之外,我没有任何证据支持这一点,但是许多关心测试的 PHP 商店最终依赖于验收测试(即 Selenium)来代替实际的单元测试、测试优先等. 发展。

    在你的具体情况下,面试你的团队将要雇用的开发人员。

    1. 询问他们使用什么单元测试框架

    2. 请他们笼统地描述他们开发新功能及其支持测试的真实示例

    3. 请他们笼统地描述一个真实世界的示例,说明他们的测试失败的时间以及他们为解决这种情况所做的工作

    您对他们将要描述的具体情况不太感兴趣,而对他们在一般情况下讨论他们的代码测试知识的舒适程度更感兴趣。

    【讨论】:

      【解决方案2】:

      每当我使用 XUnit 风格的工具对项目进行 TDD 时,我都很难把握住正确的位置。我发现使用为行为驱动开发设计的工具或“Specification by example”让我更容易使用do TDD right——即专注于设计、暴露意图和describing behaviour in specific contexts没有测试。

      也就是说,我想在对话中介绍pecs。来自项目网站上的自述文件。

      pecs 是一个用于 PHP 5.3、la RSpec 或 JSpec 的小型行为驱动开发库。

      如果您使用过 JSpec 或更好,Jasmine-BDD(用于 JavaScript)描述行为的 pecs 风格应该非常熟悉。我发现这种风格非常适合组件级别的规范。如果您正在寻找用于功能级别规范(故事或用户验收测试)的 PHP 工具,请考虑 Behat

      回到 pecs,下面是一个从 pecs 项目网站中挑选出来的示例:

      describe("Bowling", function() {
        it("should score 0 for a gutter game", function() {
          $bowling = new Bowling();
          for ($i=0; $i < 20; $i++) {
            $bowling->hit(0);
          }
          expect($bowling->score)->to_equal(0);
        });
      });
      

      是的,这是一个 PHP 规范。查看 pecs 源代码,作者似乎能够通过利用 PHP 5.3+、Lambdas 和闭包中的新热点来实现这一目标。所以我想这意味着你不能在任何基于 PHP

      另外,pecs 不如 PHPUnit 或 SimpleTest 成熟。但是,我认为 PHP 社区中 BDD 的支持者应该支持鼓励“通过示例说明”或 BDD 等工具的发展,而不必使用旧版 XUnit 测试工具带来的混乱。

      这些天我在 Python 中的工作比 PHP 更多。但是,下次我选择 PHP 项目时,如果我有一个成熟的、社区支持的工具(如 pecs)来制定软件规范,我会非常高兴。

      【讨论】:

        【解决方案3】:

        我在 Behat / Mink http://behat.org 方面有过很棒的体验

        我同意其他人的观点 php 作为一个单元测试平台不是一个有趣或经验丰富的 BDD 如果你使用任何 php 框架是最好的方法

        将 Composer 当作一个 repo 构建工具是最大的绊脚石,但我们能够使用 Behat Mink Selenium Webdriver 独立服务器 jar 作为一个了不起的设计和回归测试工具。我们曾经在 Jenkins 服务器上针对我们的 CakePHP 应用程序运行回归套件,但事实证明它不够“快速失败”

        现在我们的工作流程是这样的: 用小黄瓜创造故事 提炼故事 编写功能并删除任何新的步骤定义 开始编写php解决方案进行测试 最后,我们有一个可用的功能或错误修复,并通过 bdd 测试覆盖它

        我们设置了一个带有有效 Behat 设置的 Ubuntu VM,并将其复制到每个工作站。我们将其融入到我们的流程中。我们只是拉下更改运行测试,然后开始编写新的东西。

        我们编写了一个 shell 脚本来自动运行 mysql 转储并在每个功能之前加载它们,这使得重构代码变得轻而易举。

        Mink WebAssert 类为您提供验证行为所需的所有断言 常规会话/CommonContext 类非常适合使用 css 或 xpath。

        我之前在 Java 和 Rails 项目中使用过 Capybara / WebDriver,发现与 Behat 相比,设置开销 / 学习曲线太高了。

        【讨论】:

          【解决方案4】:

          除了Alan 已经提到的库/框架之外,您还可以使用 mod_perl 的 Apache::Test,我将其用作工具。它允许我非常简单地将测试集成到我的发布过程中。该工具使用TAP 输出(测试任何协议)来确定测试是通过还是失败,使用诸如Test::Simple 或Test::More(PerlPHP)之类的库。

          开箱即用的 Apache::Test 支持在 Perl 和 PHP 中编写测试。在我自己的项目中,我花了一点 bit of trickery 和大量阅读才能真正让它工作,但 Test::More in PHP 的实现是内置到工具中的。运行用 PHP 和 Perl 编写的所有测试都是通过一个命令完成的,沿途的任何故障都会被 Apache::Test 捕获,并尽可能地指出哪里出了问题。

          这一切的美妙之处在于,您甚至可以使用 PHPUnit 或 Simple-Test 以及前两个测试框架。通过在每个相应的库中运行测试,您可以使用 Test::More 的 PHP 实现(甚至通过测试标准输出来使用 Perl)并吐出 TAP 以供您的工具解释。

          请务必阅读Apache::Test 文档和mod_perl guide to running Apache::Test。此外,我发现文章here 很有帮助。

          作为一个简单的示例,您可以在 Perl 中用很少的代码行设置一个测试,该测试将运行您网站上的所有页面(包含链接)并验证所有结果是否为“200 OK”响应并且不要没有任何解析错误:

          #!perl
          
          use strict;
          use warnings;
          
          use Apache::Test qw(:withtestmore);
          use Apache::TestRequest;
          use Test::More;
          use Test::WWW::Mechanize;
          use WWW::CheckSite::Validator;
          use WWW::CheckSite::Spider;
          
          plan 'no_plan';
          
          my $config = Apache::Test::config();
          my $host = "http://". Apache::TestRequest::hostport($config) || '';
          
          my $s = WWW::CheckSite::Spider->new(
              uri => $host,
              ua_class => 'Test::WWW::Mechanize',
          );
          my $m = $s->current_agent;
          
          while (my $page = $s->get_page) {
              is($m->status(), "200", $m->uri() ." retrieved successfully.");
              $m->content_lacks("Parse Error", $m->uri() ." does not contain syntax errors.");
          }
          

          【讨论】:

            【解决方案5】:

            在过去的一个项目中,我使用了 PHPUnit,但它让我很想念。 PHPUnit + 命令行运行测试, 这样做以至于花费了太多时间来编写测试代码,速度不够快,并且确实似乎以一种我不喜欢的方式限制了代码的样式(对象更容易测试,所以它似乎有点偏爱对象)。

            Selenium 是我们讨论过但从未开始发挥作用的解决方案,我认为我们真的会从这种输出级测试中受益。

            在这个最新项目中,首席程序员在我们修改软件时采用了更实用的编程方法。当我提到我想通过 TDD 编写代码时,他在一天或更短的时间内制定了一个自定义解决方案,我认为它对我来说与 PHPUnit 一样有效。此外,他真的让我对面向对象与函数式编程的问题大开眼界。

            第一个项目,从头开始,在底层,面向对象编码,大型单元测试框架,它变得单一并很快陷入困境。第二个项目,成熟的 CMS 软件,有 5 年的历史和旧代码,但函数式编程范式和简单的测试框架(我们实际上经常使用 php assert)使它变得更简单,而不是变得复杂。

            第二个项目也从未达到实现 Selenium 的地步(我仍然认为这将是有益的),但函数式编程方法更容易处理代码内测试。

            【讨论】:

            • 我使用过 selenium 并同意它在许多情况下都很有用,但是它也会很快陷入困境,尤其是在高度“流动”的浏览器类型项目中。例如更改盒子的 ID、移动 URL 甚至 DOM 结构都可能会破坏大量测试。 selenium 的不错 之处在于,在许多情况下,您实际上可以通过 Selenium IDE 手动记录测试 - 将其导出为 PHPUnit - 然后根据您的需要进行调整以添加循环和可变性。在这方面它非常强大。 (实际上您可以将其导出为多种不同的语言)
            【解决方案6】:

            我刚刚发现了这个问题,虽然我仍处于“研究阶段”,以弄清楚发生了什么。我刚刚为 Ruby on Rails 发现了一个叫做“Cucumber”的东西http://cukes.info/

            它本质上是 Ruby 的“故事驱动开发”,并且很可能是功能测试领域的黄金标准,至少就我在旅行中看到的而言。 (我把这个公开放在那里,所以如果我错了,专家可以纠正我)

            作为 Cucumber 中的语言示例,您有一些与 SQL 非常相似的东西。 BUT 似乎更具人类可读性。从 cukes 的首页看,他们的语言是这样的:

             Scenario: Add two numbers
                  Given I have entered 50 in the calculator
                  And I have entered 70 in the calculator
                  When I press add
                  Then the result should be 120 on the screen
            

            以上将作为测试编译并运行。

            现在这就是回答您关于 PHP - BDD 和 TDD 问题的序言。

            在回应上面的 cmets 时,PHPUnit 将允许单元测试,根据这篇博文:http://sebastian-bergmann.de/archives/738-Support-for-BDD-and-Stories-in-PHPUnit-3.3.html 还支持“故事风格”BDD 测试。

            为了扩展上面提到的关于“SIMPLETEST”的答案,ST 系统有一个内置的浏览器对象类用于浏览器自动化,而 PHPUnit 有一个 SELENIUM 浏览器自动化的扩展http://seleniumhq.com(Selenium 的优势与 SimpleTest 相比,Selinium 将运行任何页面上的 javascript,而 SimpleTest 不会)。

            我希望这些信息对您有所帮助,因为它是经过数月的个人研究和对上述技术的实际试验和错误的结果。如果有专家可以澄清和提高我对上述内容的理解,我欢迎反馈。

            • 亚历克斯。

            【讨论】:

            • 我建议您查看 [Behat][1]。它是 PHP 中的 Cucumber 实现(它不是端口)。它工作得非常好,现在还支持与 selenium 等工具的集成。 [1]:behat.org
            【解决方案7】:

            Michael Booth 对两种语言的 BDD 测试功能的比较:

            http://mechanicalrobotfish.com/posts/117-ruby-vs-php-bdd-beauty-contest-no-contest

            得出的结论是,此时 PHP BDD 工具和文化还不够成熟。

            当然,无论是在知识(书籍、视频、文章、博客文章)还是工具(Rspec、Shouda、Factory Girl、Mocha、Cucumber)方面,都无法与 Ruby 程序员可用的东西相提并论。

            【讨论】:

              【解决方案8】:

              您可能想查看PHPStorm。我喜欢在 IDE 中使用 PHPUnit 的测试运行器。

              【讨论】:

                【解决方案9】:

                现在我正在为 BDD 测试开发“Spectrum”框架:https://github.com/m-haritonov/spectrum

                【讨论】:

                  猜你喜欢
                  • 2010-09-05
                  • 2015-09-28
                  • 2014-05-11
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-06-10
                  • 2011-05-22
                  • 2017-06-10
                  • 1970-01-01
                  相关资源
                  最近更新 更多