行为驱动的开发是编写代码测试的好方法,因为它使用的是真实人类可以理解的语言。 了解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 。 您还可以安装其他软件包,这些软件包提供了专门用于调试目的的更多步骤定义,例如Behatch和Nuvole的扩展。 例如,您可以将Behat配置为在测试失败时(如果您使用的驱动程序提供了此功能)对浏览器的状态进行屏幕截图。

关于驱动程序和浏览器模拟器,Goutte不支持JavaScript。 如果某个功能取决于JavaScript,则可以通过将Selenium2Driver与Geckodriver结合使用来对其进行测试 和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

如何使用Behat在Drupal中使用行为驱动的开发相关推荐

  1. Drupal8 社区文档之在Drupal中,查看网页的编辑一个页面的几乎是相同的

    人们熟悉的其他网页编辑器(如FrontPage,Dreamweaver)或者其他CMS软件(如WordPress.Joomla)有时不知道如何访问管理区或"后台"的Drupal,或 ...

  2. drupal ajax 分页,在drupal中使用Ajax时要保持一个404

    你好,我在我的(新手)Drupal站点有一个ajax调用这个问题.我试图从表单字段保存一些数据,通过jQuery发布到我的Drupal模块中的函数.这里是我的代码:在drupal中使用Ajax时要保持 ...

  3. Laragon 在Windows中快速搭建Laravel本地开发环境

    1.应用场景 主要用于快速搭建开发环境,帮助快速开发或者验证一些代码执行等. 优点: 功能更加强大, 更加简便好用 2.学习/操作 简介 对于那些使用 Windows 操作系统的同学来说,Homest ...

  4. ASP.NET 2.0 正式版中无刷新页面的开发

    ASP.NET 2.0 正式版中无刷新页面的开发 在已经发布的 ASP.NET2.0 中,无刷新页面开发相关部分同 beta2 有不少改动.而且在越来越多的 Ajax 开发包被开发出来的情况下, AS ...

  5. QT中树控件QTreeView开发实例

    转自:http://mobile.51cto.com/symbian-268700.htm 本文讲解了QT中树控件QTreeView开发实例,对于QTreeView没有过多的讲解,那么不说废话了,看代 ...

  6. 在Html中使用Requirejs进行模块化开发

    在前端模块化的时候,不仅仅是js需要进行模块化管理,html有时候也需要模块化管理.这里就介绍下如何通过requirejs,实现html代码的模块化开发. 如何使用requirejs加载html Re ...

  7. Maven-Maven中添加Oracle驱动包到本地仓库

    问题 解决办法 1 确认本机安装了Maven 2下载对应版本的数据库驱动 官方下载jar 通过本地安装目录查找 oracle的驱动包说明 3安装驱动到本地仓库 pomxml 中使用Oracle驱动包 ...

  8. ubuntu版php开发工具,Ubuntu 中搭建 LAMP 及 php 开发工具

    Ubuntu 中搭建 LAMP 及 php 开发工具 Step1. 安装 Apache 1.在 terminal 中输入一下命令并执行: sudo apt-get install apache2 2. ...

  9. mysql驱动为什么自动加载_为什么JDBC中加载驱动要使用反射?

    原文链接:https://www.cnblogs.com/homejim/p/8076481.html 在JDBC详解系列(一)之流程中,我将数据库的连接分解成了六个步骤. JDBC流程: 第一步:加 ...

最新文章

  1. Docker系列 五.Docker容器数据卷
  2. Django 框架14: 缓存
  3. Android Activity的理解
  4. angr学习笔记(3)
  5. 《系统集成项目管理工程师》必背100个知识点-15项目章程ITTO
  6. [云炬创业基础笔记]第一章创业环境测试12
  7. 操作电脑小心“伤”手
  8. Linux shell 脚本中”21″的含义解释
  9. 飞畅 Profibus总线光纤中继器产品介绍
  10. windows如何生成ssh密钥
  11. Flask 中的Jinja2模板引擎
  12. python输出print(x+y)_Python语句序列“x='car';y=2;print(x+y)”的输出结果是() (2.0分)_学小易找答案...
  13. tornado异步请求响应速度的实例测试
  14. 计算机编程与数控宏程序实例教程,数控车床编程教程,图文实例详解
  15. less最后一页 linux_linux中less命令使用
  16. LTE网络架构的简单概述
  17. 典型的递归计算费氏数列
  18. Word 通过尾注插入参考文献
  19. gstreamer gst-launch 记录 原理
  20. [Halcon几何] 矩形顶点和对角连线角度计算

热门文章

  1. sklearn中的逻辑回归
  2. AuthenticationManager验证原理分析
  3. kafka消费者分区消费策略
  4. es安装IK中文分词器
  5. 代码同时托管到github和git.oschina.net
  6. [APUE]进程控制(中)
  7. 华为HCNE专题一:网络基础知识
  8. 开账户root远程桌面
  9. mysql 可重复读 更新覆盖_Mysql事务隔离级别之可重复读
  10. 默认web地址_SpringMVC详解----Web层