使用BDD的经验


大约七年前,Dan North在他的文章中描述了BDD方法的实际应用,它使您可以通过建立内部通信来使开发过程更易于理解和管理。 业界每天都对这种方法越来越感兴趣,其目的是使标准团队进行有效的互动,例如“分析-开发-测试”。


但是,现在只有一小部分公司决定使用BDD。 怎么了


所以,让我们弄清楚。 BDD(行为驱动开发)是一种与TDD(测试驱动开发-“通过测试开发”)紧密相关的灵活方法。 根据经验,即使是经验丰富的测试人员也常常看不到这些方法之间的差异。 的确,乍看之下很难隔离:这两种方法都涉及在开发阶段开始之前编写文档和测试。 区别在于:在BDD中,为了描述测试,您需要使用每个项目参与者都可以理解的自然语言,以便实际上将问题说明,测试和文档组合在一起。 换句话说,先定义DSL(面向特定主题的语言),然后创建一组标准的受限短语来描述必要元素的行为。 然后,在他们的帮助下,使用新功能开发了一个方案,每个人都可以理解。


让我们看一下区别,它将变得显而易见:



我们将讨论这个示例,但首先,让我们看一下当前与非零相关性的所有方法。


比较几种方法


下图显示了三种方法的比较:TDD,TLD(测试最新开发)和BDD:



  • 当我们按照BDD方法进行工作时,自动测试和起草规范会伴随软件开发周期的每个阶段,从而确保自动测试和文档的持续相关性。
  • TDD和ATDD(验收测试)方法在一个图中合并在一起,因为 写在分析阶段。 如上所述,TDD基于在开发功能之前编写测试。 开发人员必须编写测试才能编写测试功能。
  • TLD(测试最新开发)包括在功能实施后进行的测试。
  • BDD是通用的,可以包含在开发的任何阶段。

第二张图显示了开发人员在编写脚本时的参与程度。



  • 在BDD中,团队的任何成员都可以在任何阶段连接到测试,例如分析师,业务用户,开发人员和测试人员,因为测试对于流程中的所有参与者都是清楚的。
  • BDD也很有用,因为您不需要花费大量时间来编写各种文档。 经典的开发方案至少需要通常由不同人员编写的规范和测试脚本。 在BDD中,规范既是测试案例,又是自动测试。 测试人员不需要编写单独的测试文档-分析师已经为他们完成了这些工作,他们从自然语言构造中编写了规范(团队的任何成员都可以理解和理解)。

毫无疑问,BDD是实现产品质量的好工具。 测试和文档编写速度更快。 对于一家企业来说,由于自然语言构造使项目变得更加透明,而自然语言构造对于任何人来说都是可以理解的,而无需编程。


这是关于优点。 然而,正如已经说过的,尽管有很多优点,但是很少有人采用这种方法。


BDD对所有人都有好处,但是为什么不使用它呢?


答案很简单:它既长又昂贵。 大多数IT公司都同意这一说法。 首先,我们也不例外。 BDD带来了不便,即使它需要在制定要求的阶段已经由测试专家参与。


BDD颠倒了经典的开发指南(TLD)。 由于执行困难,因此执行不佳。 开发周期正在延长。


BDD无疑是一种获得质量的方法。 但是并不是每个人都愿意为此花费时间和专家。


但是,如果我仍然想实现BDD怎么办?


您可以尝试使用现成的框架。 例如黄瓜,南瓜,Yulup。


BDD复杂性的主要问题不在过程中,而是在实现和现有工具中。 以WEB为例,开发公司信息系统。 通过Web实现,我们遇到了一个WebDriver,它是当前用于自动运行在Web浏览器中的应用程序的标准。 他有很多机会。 为了考虑页面元素的各种自定义,您需要提供用于访问它们的选项。 在这里,为了促进测试的开发,需要使用各种库(例如Selenide等),它会创建您自己需要了解的生态系统。 要使用WebDriver,您需要程序员或测试员自动化,因为 一切都使用代码和狡猾的设计来实现。


BDD框架的入门既困难又耗时。


我们的重点是一种称为仪表的仪器。 这是一个灵活且轻量级的框架,在免费许可下分发。 坦白说,我们并未真正研究替代方案,因为 我们的客户积极要求使用仪表。


在仪表中,测试以规范文件(扩展名为.spec的文件)编写。 规范包含以自然语言编写的测试步骤。 这些步骤以编程语言(我们使用Java编程语言)实现。 在执行步骤时,在脚本和实现文件的名称以及脚本的实现方法和步骤的名称中都必须遵守命名约定,这一点很重要。 该工具的另一个灵活性是步骤可以具有参数。


仪表使我们能够使用BDD的好处。 但是,我们仍然遇到实施复杂性的问题:工具和流程实施的问题。


事实证明,测试人员在早期阶段的参与会对最终结果产生不良影响。 开发测试的时间增加。 使用任何框架都需要测试人员付出巨大的努力,而测试人员无疑必须具有良好的编程命令。 最初,使用脚本的过程如下:分析师将测试告诉测试人员,然后技术编写者将其写下来。 当测试人员处理软件实现时,被测试功能的含义发生了变化。 这会影响入口点的分隔,应该将它分隔为一个,这是因为该过程被划分为一个“正常”过程,我只是想离开该过程。 即 切入点被分割了,沟通层出不穷,测试人员全心投入测试的实施,技术作家以他自己的方式理解,分析师重写了他的坞站并改变了主意,开发人员进入了“他的世界”)。


测试人员在代码上花费了大量时间。 但是,同一位测试人员仍然必须考虑在页面上搜索元素。 这种情况使人想起了著名的儿童游戏:“被破坏的电话”。 发生崩溃。 我们决定:只有分析人员可以编写测试,BDD才能工作。 有必要降低编写测试的复杂度,以简化测试。 但是为此,您需要大大简化测试界面。 测试工具,与所有方法和库一起执行的过程应该更简单。


首先,测试人员的工作如下所示:


  1. 检查文件(如果有);
  2. 拟定清单;
  3. 临时测试
  4. 制定测试计划;
  5. 完善分析师的世界观;
  6. 开发人员完善世界的图片;
  7. 如果一切都一起发展,请在进行测试的同时编写测试文档;
  8. 等待修复错误,测试错误;
  9. 页面说明,控件,使用Web-Driver搜索页面上的元素。 搜索测试系统中已经实现的内容;
  10. 编写测试逻辑;
  11. 放行
  12. 支持错误/回归错误;
  13. 规格更新;
  14. 修正错误
  15. 自动测试更新,更新大量已更改的控件;
  16. 放行
  17. ...
    斜体(1、5、6、7、9、13、15 )导致时间成本。 它们可以并且应该被优化。

此列表在开发流程图中作了简要说明:



我们公司专门从事具有Web界面实现的项目。 基于此,我们使用Web驱动程序工具与Web浏览器进行交互。


实际上,Selenium Web Driver是标准,它用于描述任何框架上的Web对象,包括Gauge,jUnit,Masquerade库等。 他在执行不同任务时具有很大的灵活性,这会在局部类型的问题上造成过多的工作量。 我们需要找到一种降低复杂性的解决方案。


例如,让我们在图中显示Selenium Web Driver,Gauge框架,Masquerade库和Java编程语言之间的关系。



在此方案中,可以使用jUnit,TestNG或任何其他替代BDD框架的方法,根据需要,可以使用任何捆绑软件。 硒和化装舞会依然存在,可以更改编程语言。


加快代码编写速度-连接化装舞会


我们公司正在CUBA平台上开发。 特别是针对该平台,开发了一种用于自动测试的工具: Masquerade是一个库,提供了简洁,方便的API,用于在使用WebDriver实施测试时使用代码。 该库可在Selenium Web Driver上使用,是selenide和任何框架的朋友。


在CUBA项目中,网页的每个元素都包含cuba-id,但不会更改。 CUBA使用一种组件方法,而Masquerade库简化了与网页元素的交互。 该库可以以更简单的方式对使用CUBA实现的网页元素执行操作。 因此,在页面上搜索元素时,无需像以前那样将笨重的结构与XPath结合使用:


$(new By.ByXPath("//*/div/div[2]/div/div[2]/div/div/div[3]/div/div/div[3).click(); 

或更简单的Java构造,但是仍然很麻烦:


 private static void click(String cssClass, String caption) { $(By.cssSelector(cssClass) .$(byText(caption)) .closest(".v-button") .click(); } 

连接Masquerade库后,嵌入式控件的描述看起来很简单并且易于访问。 您甚至不必在页面上查找控件,因为 他已经在项目中拥有它。 这是应用程序中授权表单的按钮描述示例:



在页面代码中,我们看到一个清晰可辨的元素cuba-id=”loginButton”



让我们使用Masquerade库描述按钮:


 @Wire(path = {"WebHBoxLayout", "loginButton"}) private Button loginButton; 

jUnit框架上的一个简单测试实现是在每次测试之前运行的授权块:


 @Before public void loginAdm() { Tests loginTest = _$(Tests.class); loginTest.login(); } 

在登录方法的主体中,以下代码:


 LoginWindow loginWindow = _$(LoginWindow.class); assertNotNull(loginWindow.getLoginField()); loginWindow.getLoginField() .shouldBe(EDITABLE) .shouldBe(ENABLED); loginWindow.loginField.setValue("admin"); loginWindow.passwordField.setValue("admin"); loginWindow.rememberMeCheckBox.setChecked(true); loginWindow.loginButton().click(); 

最重要的是我们如何描述页面,如何引用元素。 LoginWindow页面的描述:


 public class LoginWindow extends Composite<LoginWindow> { @Wire(path = {"loginField"} ) private TextField loginField; @Wire(path = {"passwordField"} ) private PasswordField passwordField; @Wire(path = {"rememberMeCheckBox"} ) private CheckBox rememberMeCheckBox; @Wire(path = {"loginFormLayout", "loginButton"} ) private Button loginButton; } 

查找物品只是Masquerade库的一部分。 访问网页的元素使您可以使用这些元素执行各种操作。 例如,您可以从下拉列表中选择一个项目:


 getMaxResultsLayout().openOptionsPopup().select("5000") 

或排序表格:


 Table tb1 = client.getPaymentsTable(); tb1.sort("column_year", Table.SortDirection.ASCENDING); 

请参阅以下屏幕截图,以获取一些表操作的列表:





使用Masquerade大大简化了测试的编写,现在要编写新功能的测试,您需要:


  1. 使用伪装来描述页面很容易,不需要特殊的编程技能。
  2. 将检查功能时使用的所有页面收集在一个类中。
  3. 从现成的自然语言构造中,收集测试脚本(在其中替换必要元素的名称),即编写一个Gauge规范。

整合化妆舞会和量具


在使用BDD之前,使用了TLD方法,并且为了与其一起使用,我们还优化了编写测试代码的过程。 二手的jUnit / TestNG + WebDriver + Selenide + Masquerade捆绑包。


现在,为了使用Gauge,我们向intellij IDEA添加了相应的插件。 之后,可以创建一种新型的测试-规范。


现在,我们创建规范(脚本)并使用WebDriver,Masquerade和Java的功能实施步骤。



我们单击脚本的步骤,然后转到实现:



在实现中,您可以使用现有的login()方法。


这种完美是什么样的?


回想一下我们在本文开头所研究的示例:



"Navigation.openMenu(menu)”包含使用Masquerade库打开菜单的实现。


库随后进行了扩展,并且出现了可用于任何CUBA应用程序的通用步骤。 这些步骤使您可以使用程序元素:按钮,字段,表格。 这些通用步骤已成为我们在BDD中用于编写脚本的一组标准短语。


多亏了Masquerade + Gauge,我们大大降低了创建测试的复杂性。 现在,那些没有特殊编程技能的人可以编写测试。 测试可以由一个人编写(以前,脚本是由一个人发明的,但由另一个人实施,从而导致混乱)。 因此,我们已经实现了我们的目标-简化了界面,分析人员编写测试脚本将不难。


流程更改如下所示:


那是:

是


它变成了:

已成为


相比之下,可以看出,要求,规范和测试文档合并在一个段落中。 除执行特定测试步骤外,测试文档也是一种自动测试。


总结


目前,我们正在根据上述方案成功开发。 而且,我们设法摆脱了BDD的主要问题-由于实现的复杂性,工具的添加和最终确定,BDD的严重增加。 但是,产品交付的质量有所提高。


维护文档所需的时间与更改的规范数量成比例地减少,因为 规格(系统逻辑)的一项更改会自动导致一次迭代中的自动测试更改。 即 测试人员不需要进入文档系统(例如Confluence等)进行更新,其他团队成员也是如此。


与使用通常的干净Web驱动程序一起工作和重建XP链接的成本相比,在存在简化了页面对象工作的库的情况下实施和支持测试的时间减少了一半。


在任何业务解决方案的开发和质量管理中,消除需求收集和分析中的错误的成本呈指数增长 。 因此,根据迭代开发中的现有条款和进度表,与产品变更相关的问题的可能性以及对问题的早期研究(对需求的良好研究)可以很好地降低开发成本,具体取决于项目。 它既可以是0%,也可以是〜40%。 通过引入BDD可以实现这种改进。 可以在不将其称为BDD的情况下实现此功能,但它确实存在于BDD中。 能够解决问题是质量保证的重要组成部分。


最后,我想指出的是,该开发方案还与持续集成和我们公司开发的QA Lens测试管理系统集成在一起。 在QA Lens中,您可以使用面向主题的语言编写与IDEA中相同的脚本。 该语言由先前编译的词汇表组成,该词汇表先前已实施。 当从开发人员的机器或CI对Gauge执行自动测试时,QA Lens会自动记录哪些脚本步骤已完成,哪些未完成。 因此,在运行了由分析师编写的脚本的自动测试之后,测试部门会立即收到有关产品状态的完整最新信息。


作者:Sunagatov Ildar和Yushkova Julia( Yushkova

Source: https://habr.com/ru/post/zh-CN459134/


All Articles