由外向内的BDD(与Specflow)

本文关键字:Specflow BDD | 更新日期: 2023-09-27 18:13:27

我是BDD的新手,但我发现它非常有趣,并希望使用BDD开发我的下一个项目。在谷歌搜索和观看视频后,我仍然对现实生活中的BDD有很多疑问。

1。声明式还是命令式场景?

我看到的大多数"when-then"场景都是用UI(命令式)编写的。

Scenario: Login
     Given I am on the Login-page
     When I enter 'AUser' in the textbox 'UserName'
       And I enter 'APassword' in the textbox 'Password'
       And I click the 'Login' button
     Then I should see the following text 'You are logged in'

我发现这些测试非常脆弱,它们没有告诉点击按钮的商业价值。我认为维持是一场噩梦。为什么大多数示例使用命令式场景?

Scenario: Login (declarative)
     Given I am not logged in
     When I log in using valid credentials
     Then I should be logged in

如果你喜欢声明式的风格,你如何描述像"首页"或"产品页面"这样的东西?

  • 编写良好规范的技巧

2。是否锻炼UI ?

我看到的大多数步骤实现使用WatiN, White或类似的东西来从用户的角度实现场景。启动浏览器,点击按钮。我认为它极其缓慢和脆弱。我可以使用Page object之类的东西让测试不那么脆弱。但那是另一项工作量。特别是对于UI复杂的桌面应用程序。

您如何在现实生活项目中实现场景-执行UI,或通过测试控制器/演示器?

  • 应用BDD的最佳方式

3。是不是真实的数据库?

当给定的场景部分被实现时,通常需要一些数据在系统中(例如一些用于商店应用的产品)。如何实现这一部分——将数据添加到真实的数据库(完整的端到端测试),还是向控制器提供存储库存根?

等待经验丰富的答案!

更新:增加了有用的问题链接。

由外向内的BDD(与Specflow)

  1. 声明是正确的方式,IMO。如果您谈论的是页。aspx文件名,那么您做错了。故事的目的是促进开发人员和非开发人员之间的交流。非开发者并不关心产品。Aspx,他们关心的是产品列表。你的系统做了一些非开发人员觉得有价值的事情。

  2. 嗯,故事讲述了你需要实现的高级功能。这是你的系统必须做的。判断你是否这样做的唯一方法是实际操作UI。对我来说,BDD SpecFlow故事并不能取代单元测试,相反,它们是你的集成测试。如果你破坏了这一点,你就破坏了企业从你的软件中获得的价值。单元测试是用户不关心的实现细节,他们只单独测试每个部分。这并不能告诉你A和B是否一直在一起工作(理论上应该是这样,但在实践中,当你让两个部分相互配合时,会发生有趣的事情)。自动化的端到端测试也可以帮助你的QA。如果一个功能区域中断了,您知道它,当您确定是什么破坏了集成测试时,他们可以把时间花在应用程序的其他区域。

  3. 这是个棘手的问题。我们采用了混合方法。我们确实使用了数据库(毕竟集成测试测试了系统作为一个整体的功能,而不是单独的组件),但是我们在需要的时候使用Deleporter用Moqs替换我们的存储库,而不是一直重置配置。看起来还行,但两种方法都有利弊。

Edit:我发现这篇文章刚刚描述了限制自己只谈论特定领域的概念,以避免脆弱的场景。

他的主要观点是,你可以谈论的最少数量的域是问题域和解决方案域。如果你谈论的是这两个领域之外的任何事情,那么你就涉及了太多的利益相关者,你就引入了太多的噪音,你就会使你的场景变得脆弱。

他还提到绝对的"声明式"或"命令式"模式是一个神话。他谈到了一种称为"分块"的认知模型,即在任何抽象层次上,你都可以"向上分块"或"向下分块"。这意味着你可以获得更明确的内容(如何?)或更元的内容(是什么或为什么?)你通过问"我们在做什么?"你会说"我们该怎么做?"所以我想我不会太纠结于陈述式和命令式——就这个问题而言,它不会给你带来任何好处。

要让你到达某个地方,就要弄清楚每个术语属于哪个领域,可能是通过确定哪个利益相关者是该术语所属领域的专家。一旦您确定了所有的域,您可以选择在场景中最突出的域之一中的相关术语,或者完全删除不拟合的语句。如果这还不够,您可以拆分、进一步指定或移动场景,以满足这些需求。

顺便说一句,他还使用了登录UI的场景,所以你有具体的指导:)

编辑前:(其中一些仍然适用。"DB还是没有DB"answers"UI还是没有UI"的问题是不相关的)

1 -声明式还是命令式场景?

可以的时候是声明性的,尽管命令式有一些价值(在项目生命周期的某些时候)。

对于不熟悉信息理论和设计的测试人员和业务分析人员来说,命令式是一种更容易的思考方式。在确定问题域和工作流程之前,在项目的早期进行思考也更容易。它对探索性思考很有用。

声明式不太容易随时间变化。由于GUI是应用程序中最容易受到突发奇想影响的部分,因此这是非常有价值的。一旦您确定了问题领域和工作流,并且更加关注关系概念,就更容易思考了。这是一个更稳定、更普遍适用的模型。

如果你用一个通用的和声明性的模型来写测试用例,你可以使用完整的应用程序GUI自动化、集成测试或单元测试的任何组合来实现它们。

你如何描述像"主页"或"产品页面"这样的东西?

我不确定我会在基本的功能和需求层面上。您可以创建描述实现细节的子特性和子需求,比如特定的UI工作流。如果你在描述一个UI的一部分,那么你应该定义一个UI特性/需求。

2 -是否锻炼UI ?

我认为它非常缓慢和脆弱

是的,它是。使用UI和完整的DB集成来执行每个高级场景/需求,但不要使用端到端UI自动化来执行每个代码路径,当然也不要使用边缘情况。如果您这样做,您将花费更多的时间让它们工作,而实际测试应用程序的时间要少得多。

您可以构建您的应用程序,以便您可以进行成本较低的集成测试,包括基于单个UI的测试。单元测试也很有价值。

但是你做的集成测试越少,你错过的bug就越多。写单元测试可能会更容易,而且它们肯定不会那么脆弱,但是根据定义,你将测试更少的应用程序。

3 -真实的数据库或不是?

高层次的端到端集成测试必须在完整的系统到位的情况下完成。这包括一个真正的数据库,在不同的服务器上对每个系统运行测试,等等。

级别越低,我就越提倡模拟对象。

  • 单元测试应该只测试单个类
  • 中级集成测试应该避免昂贵、脆弱和有影响的依赖关系,比如文件系统、数据库、网络等。尝试仅使用单元测试和端到端测试来测试这些脆弱且有影响的依赖项的实现。

不要直接提到一个页面的名称,而是描述它所代表的内容,例如

Scenario: Customers logs in successfully
  When I log in
  Then I should see an overview of ACME's top selling products

您可以直接针对底层api或模型进行测试,但是您这样做的次数越多,您就越有可能无法捕获集成问题。一种方法是用少量的全栈测试和大量的只在两层之间测试来平衡。