当前位置: 首页 > 工具软件 > Behat > 使用案例 >

如何使用Behat在Drupal中使用行为驱动的开发

翟嘉祥
2023-12-01

行为驱动的开发是编写代码测试的好方法,因为它使用的是真实人类可以理解的语言。 了解BDD及其好处之后 ,您可能希望在下一个项目中实现它。 让我们看看如何使用带有Mink扩展的Behat在Drupal中实现BDD。

安装和配置工具

由于使用Composer来管理Drupal网站的依赖关系是一种好习惯,因此可以使用它来安装BDD测试工具:Behat,Mink和Behat Drupal Extension。 Behat Drupal Extension在其依赖项中列出了Behat和Mink,因此您可以通过安装Behat Drupal Extension软件包来获得所有工具:

 composer require drupal/drupal-extension --dev 

Mink允许您以人类可读的格式编写测试。 例如:

鉴于我是注册用户,
当我访问主页时,
然后我应该看到个性化的新闻提要

由于这些测试应该模拟用户交互,因此可以假定它们将在Web浏览器中执行。 那就是Mink发挥作用的地方。 有各种浏览器仿真器,例如Goutte和Selenium,它们的行为各不相同,并且具有非常不同的API。 Mink允许您编写一次测试,然后在不同的浏览器仿真器中执行该测试。 用外行的术语来说,Mink允许您以编程方式控制浏览器以模拟用户的操作。

既然已经安装了工具,那么应该已经有了一个behat命令。 如果运行它:

 ./vendor/bin/behat 

您应该得到一个错误,例如:

 FeatureContext context class not found and can not be used 

首先初始化Behat:

 ./vendor/bin/behat --init 

这将创建两个文件夹和一个文件,稍后我们将对其进行重新访问。 现在,在没有额外参数的情况下运行behat不会产生错误。 相反,您应该看到类似于以下的输出:


   
   
No scenarios
No steps
0m0.00s ( 7.70Mb )

现在,您可以准备编写第一个测试,例如,以验证网站访问者是否可以使用网站范围的联系表留言。

编写测试方案

默认情况下,Behat将在初始化项目时在创​​建的features文件夹中查找文件。 该文件夹中的文件应具有.feature扩展名。 让我们测试站点范围的联系表。 在features文件夹中创建一个具有以下内容的文件contact-form.feature


   
   
Feature : Contact form
  In order to send a message to the site administrators
  As a visitor
  I should be able to use the site-wide contact form

  Scenario : A visitor can use the site-wide contact form
    Given I am at "contact/feedback"
    When I fill in "name" with "John Doe"
    And I fill in "mail" with "john@doe.com"
    And I fill in "subject" with "Hello world"
    And I fill in "message" with "Lorem Ipsum"
    And I press "Send message"
    Then I should see the text "Your message has been sent."

Behat测试以Gherkin编写,Gherkin是一种易于理解的格式,遵循Context-Action-Outcome模式。 它由几个特殊关键字组成,这些特殊关键字在解析后将执行命令来模拟用户与网站的交互。

以关键字GivenWhenThen开头的句子分别表示上下文,动作和结果。 它们被称为“ 步骤” ,应该从用户执行操作的角度来编写它们。 Behat将阅读它们并执行相应的步骤定义 。 (稍后对此有更多介绍。)

本示例指示浏览器访问“联系/反馈”链接下的页面,填写一些字段值,按下按钮,并检查页面上是否存在消息以验证该操作是否有效。 运行测试; 您的输出应类似于以下内容:


   
   
1 scenario ( 1 undefined )
7 steps ( 7 undefined )
0m0.01s ( 8.01Mb )

  >> default suite has undefined steps. Please choose the context to generate snippets:

  [ 0 ] None
  [ 1 ] FeatureContext
  >

在提示符下键入0以选择“无”选项。 这可以验证Behat找到了测试并尝试执行该测试,但是它抱怨未定义的步骤。 这些是“ 步骤定义” ,即PHP代码,将执行完成该步骤所需的任务。 您可以通过运行以下命令检查哪些步骤定义可用:

 ./vendor/bin/behat -dl 

当前没有步骤定义,因此您不应看到任何输出。 您可以编写自己的代码,但是现在,您可以使用Mink扩展程序和Behat Drupal扩展程序提供的功能。 与功能文件夹(不在其中)创建同一级别的behat.yml文件,其内容如下:


   
   
default :
  suites :
    default :
      contexts :
       - FeatureContext
        - Drupal\DrupalExtension\Context\DrupalContext
        - Drupal\DrupalExtension\Context\MinkContext
        - Drupal\DrupalExtension\Context\MessageContext
        - Drupal\DrupalExtension\Context\DrushContext
  extensions :
    Behat\MinkExtension :
      goutte : ~

步骤定义是通过Context提供的。 初始化Behat时,它会创建一个FeatureContext,而没有任何步骤定义。 在上面的示例中,我们正在更新配置文件以包括此空上下文以及Drupal Behat扩展提供的其他上下文。 再次运行./vendor/bin/behat -dl会产生一个120多个可使用步骤的列表。 这是输出的精简版本:


   
   
default | Given I am an anonymous user
default | When I visit :path
default | When I click :link
default | Then I ( should ) see the text :text

现在,您可以执行许多操作。 使用./vendor/bin/behat再次运行测试。测试应失败,并显示类似以下错误:


   
   
  Scenario: A visitor can use the site-wide contact form         # features/contact-form.feature:8
        And I am at "contact/feedback"                           # Drupal\DrupalExtension\Context\MinkContext::assertAtPath()
        When I fill in "name" with "John Doe"                   # Drupal\DrupalExtension\Context\MinkContext::fillField()
        And I fill in "mail" with "john@doe.com"                 # Drupal\DrupalExtension\Context\MinkContext::fillField()
        And I fill in "subject" with "Hello world"               # Drupal\DrupalExtension\Context\MinkContext::fillField()
        Form field with id | name | label | value | placeholder "subject" not found. ( Behat\Mink\Exception\ElementNotFoundException )
        And I fill in "message" with "Lorem Ipsum"               # Drupal\DrupalExtension\Context\MinkContext::fillField()
        And I press "Send message"                               # Drupal\DrupalExtension\Context\MinkContext::pressButton()
        Then I should see the text "Your message has been sent." # Drupal\DrupalExtension\Context\MinkContext::assertTextVisible()

--- Failed scenarios:

        features / contact-form.feature: 8

1 scenario ( 1 failed )
7 steps ( 3 passed, 1 failed, 3 skipped )
0m0.10s ( 12.84Mb )

输出显示,前三个步骤(访问联系人页面并填写名称和主题字段)已完成。 但是,当用户尝试输入主题时,测试将失败,然后跳过其余步骤。 这些步骤要求您使用呈现表单字段HTML标签的name属性。

创建测试时,我故意将正确的值用于名称和地址字段,以便它们通过。 如有疑问,请使用浏览器的开发人员工具检查源代码,并找到应使用的正确值。 通过这样做,我发现我应该使用subject [0] [value]作为主题,并使用message [0] [value]作为消息。 当我更新测试以使用这些值并再次运行它时,它应该以飞色通过并产生类似于以下内容的输出:


   
   
1 scenario (1 passed)
7 steps (7 passed)
0m0.29s (12.88Mb)

成功! 测试通过! 如果您想知道,我使用的是Goutte浏览器。 它是一个命令行浏览器,与Behat一起使用的驱动程序是作为Behat Drupal Extension软件包的依赖项安装的。

其他注意事项

如上所述,应该从用户执行操作的角度编写BDD测试。 用户不会考虑HTML名称属性。 这就是为什么使用subject [0] [value]message [0] [value]编写测试既含糊又不太用户友好的原因。 您可以通过在behat初始化时生成的features / bootstrap / FeatureContext.php中创建自定义步骤来对此进行改进。

另外,如果您多次运行测试,您会发现它开始失败。 这是因为默认情况下,Drupal每小时限制五个提交。 每次运行测试时,就像是真实用户在执行操作。 一旦达到限制,您将在Drupal界面上收到错误消息。 测试失败,因为缺少预期的成功消息。

这说明了调试测试的重要性。 有一些步骤可以帮助您解决此问题,例如, 然后打印最后一个笔刷输出然后我中断 。 最好还是使用真正的调试器,例如Xdebug 。 您还可以安装其他软件包,这些软件包提供了专门用于调试目的的更多步骤定义,例如BehatchNuvole的扩展。 例如,您可以将Behat配置为在测试失败时(如果您使用的驱动程序提供了此功能)对浏览器的状态进行屏幕截图。

关于驱动程序和浏览器模拟器,Goutte不支持JavaScript。 如果某个功能取决于JavaScript,则可以通过将Selenium2DriverGeckodriver结合使用来对其进行测试 和Firefox。 每个驱动程序和浏览器都有不同的功能。 例如,Goutte驱动程序提供对响应的HTTP状态代码的访问,而Selenium2Driver不提供。 (您可以在Mink和Behat中阅读有关驱动程序的更多信息。)为了使Behat能够使用启用了javascript的驱动程序/浏览器,您需要使用@javascript标记来注释方案。 例:


   
   
Feature :
  ( feature description )

  @javascript
  Scenario : An editor can select the author of a node from an autocomplete field
    ( list of steps )

对于Drupal网站有用的另一个标签是@api 。 这指示Behat Drupal扩展程序使用可以执行特定于Drupal的操作的驱动程序; 例如,为您的测试创建用户和节点。 尽管您可以按照注册过程来创建用户和分配角色,但是使用“ 给定我以具有“已认证用户””角色的用户身份登录的步骤就更容易了。 为此,您需要指定是要使用Drupal还是Drush驱动程序 。 确保相应地更新您的behat.yml文件。 例如,使用Drupal驱动程序:


   
   
default :
  extensions :
    Drupal\DrupalExtension :
      blackbox : ~
      api_driver : drupal
      drupal :
        drupal_root : ./relative/path/to/drupal

我希望在Drupal中进行BDD测试的介绍对您有帮助。 如果您有任何疑问,请随时在下面添加评论,给我发送电子邮件到{我的名字} @ {我的名字} .me或通过@dinarcon发送推文。


Mauricio Dinarte将于2019年4月8日至12日在西雅图DrupalCon Behat一起介绍Drupal 8中的行为驱动开发


接下来要读什么

翻译自: https://opensource.com/article/19/3/how-drupal-behat

 类似资料: