由外而内的 BDD(使用 Specflow)

发布于 2024-12-13 06:32:48 字数 1327 浏览 0 评论 0原文

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

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

我看到的大多数给定当时场景都是用 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 对象的东西来使测试不那么脆弱。但这是另一项工作量。特别是对于具有复杂 UI 的桌面应用程序。

如何在现实项目中实现场景 - 练习 UI,或通过测试控制器/演示器?

3.是否是真实的数据库?

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

等待有经验的解答!

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

I'm new to BDD, but I found it very interesting and want to develop my next project using BDD. After googling and watching screencasts I still have lots of questions about BDD in real life.

1. Declarative or Imperative scenarios?

Most of given-when-then scenarios I saw were written in terms of UI (imperative).

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'

I found those tests extremely brittle and they tell nothing about business value of clicking on buttons. I think its nightmare to maintain. Why most of examples use imperative scenarios?

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

If you prefer declarative style, how do you describe such stuff like 'Home page' or 'Products page'?

2. Exercise UI or not?

Most of steps implementations I saw used WatiN, White or something like that to implement scenarios from user point of view. Starting browser, clicking buttons. I think its extremely slow and brittle. Well, I can use something like Page object to make tests less brittle. But thats another amount of work. Especially for desktop applications with complex UI.

How do you implement scenarios in real-life projects - exercising UI, or via testing controllers/presenters?

3. Real database or not?

When Given part of scenario is implemented, often it needs some data to be in the system (e.g. some products for shop application). How do you implement that part - adding data to real database (full end-to-end testing), or providing repository stubs to controllers?

Waiting for experienced answers!

UPDATE: Added useful links on questions.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

分开我的手 2024-12-20 06:32:48
  1. 声明式是正确的方式,IMO。如果您谈论的是页面 .aspx 文件名,那么您就错了。这个故事的目的是促进开发者和非开发者之间的沟通。非开发人员不关心 products.aspx,他们关心产品列表。您的系统做了一些非开发人员认为有价值的事情。这就是您想要捕获的内容。

  2. 嗯,这些故事讲述了您需要实现的高级功能。这是您的系统必须执行的操作。真正判断您是否已完成此操作的唯一方法是实际使用 UI。对我来说,BDD SpecFlow 故事不会取代单元测试,而是集成测试。如果你打破了这一点,你就破坏了企业从你的软件中获得的价值。单元测试是用户不关心的实现细节,他们只单独测试每个部分。这并不能告诉你 A 和 B 是否真的一直一起工作(理论上应该是这样,在实践中,当你实际上让这两个部分互相配合时,有趣的[阅读:意想不到的]事情就会发生)。自动化的端到端测试也可以帮助您进行质量检查。如果某个功能区域出现问题,您会知道,并且他们可以将时间花在应用程序的其他区域,同时您确定是什么破坏了集成测试。

  3. 这是一个棘手的问题。我们采用了混合方法。我们确实使用数据库(在测试系统作为一件事而不是单个组件之后进行集成测试),但我们不是一直重置配置,而是在需要时使用 Deleporter 用 Moqs 替换我们的存储库。似乎工作正常,但无论哪种方式都有利有弊。我认为我们仍然在很大程度上自己解决这个问题。

  1. Declaritive is the proper way, IMO. If youre talking about page .aspx file names, you're doing it wrong. The purpose of the story is to facilitate communication between developers and non-develoeprs. Non-developers don't care about products.aspx, they care about a product listing. Your system does something the non-developers find value in. This is what you're trying to capture.

  2. Well, the stories tell the high level features you need to implement. Its what your system must do. The only way to really tell if you've done this is to in fact exercise the UI. BDD SpecFlow stories to me don't replace unit tests, rather they're you're integration tests. If you break this, you've broken the value the business gets from your software. Unit tests are implementation details your users don't care about, and they only test each piece in isolation. That can't tell you if A and B actually work together all the time (in theory it should, in practice interesting [read: unexpected] things happen when you actually have the two parts playing with each other). Automated end to end tests can help with your QA as well. If a functional area breaks, you know about it, and they can spend their time in other areas of the application while you determine what broke the integration tests.

  3. This is a tricky one. We've done a hybrid approach. We do use the database (integrate tests after all test the system functioning as one thing, rather than the individual components), but rather than resetting configurations all the time we use Deleporter to replace our repositories with Moqs when we need to. Seems to work ok, but there are certainly pros and cons either way. I think we're still largely figuring this out ourselves.

我做我的改变 2024-12-20 06:32:48

编辑:我发现这篇文章刚刚描述了概念限制自己只谈论特定领域,以避免出现脆弱的情况

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

他还提到绝对的“声明性”或“命令性”模型是一个神话。他谈到了一种称为“分块”的认知模型,表示在任何抽象级别,您都可以“分块”或“分块”。这意味着您可以获得更明确的(如何?)或更多的元(什么或为什么?)。通过询问“我们在做什么?”,您可以从命令式模型中解脱出来。你可以说“我们将如何做到这一点?”所以我想我不会太执着于声明式与命令式——就这个问题而言,它不会让你有任何进展。

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

顺便说一句,他还使用了登录 UI 的场景,因此您可以获得具体的指导:)

编辑之前:(其中一些仍然适用。“DB 或 no DB”和“UI或没有 UI”问题是不相关的)

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

尽可能使用声明式,尽管命令式也有一定的价值(在项目生命周期的某些时刻)。

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

声明式不太容易随着时间的推移而发生变化。由于 GUI 是应用程序中最容易随心所欲地改变的部分,因此这是非常有价值的。一旦确定了问题领域和工作流程,并且更加关注关系概念,思考起来就会更容易。是一种更稳定、更普遍适用的模型。

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

您如何描述“主页”或“产品页面”等内容?

我不确定我是否会了解基本的功能和要求。您可以制定描述实现细节的子功能和子要求,例如特定的 UI 工作流程。如果您正在描述 UI 的一部分,那么您应该定义 UI 功能/要求。

2 - 是否练习 UI?

两个都。

我认为它非常缓慢且脆弱

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

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

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

3 - 是否是真实的数据库?

两个都。

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

你获得的级别越低,我就越提倡模拟对象。

  • 单元测试应该只测试单个类
  • 中级集成测试应该避免昂贵的、脆弱的和有影响力的依赖关系,例如文件系统、数据库、网络等。尝试通过单元测试来测试这些脆弱和有影响力的依赖关系的实现,然后结束仅限最终测试。

Edit: I found this article just now describing the concept of limiting yourself to talking only about specific domains to avoid brittle scenarios.

His main point is that the minimum number of domains you can talk about are the problem domain, and the solution domain. If you're talking about anything outside those two domains then you involve too many stakeholders, you introduce too much noise, and you make your scenarios brittle.

He also mentions an absolute "declarative" or "imperative" model being a myth. He talks about a cognative model called "chunking", saying that at any level of your abstraction, you can "chunk up" or "chunk down". This means you can get more explicit (how?) or more meta (what or why?). You chunk up from an imperative model by asking "what are we doing?" You chunk down by saying "how will we do this?" So I guess I wouldn't get too hung up on declarative vs imperative - it won't get you anywhere as far as this problem goes.

What will get you somewhere is figuring out which domains each term belongs in, possibly by identifying which stakeholder is the expert for the domain that term belongs in. Once you've identified all the domains, you can either pick related terms that are in one of the scenario's most prominent domains, or remove non-fitting statements entirely. If that isn't sufficient, you can split up, further specify, or move the scenario so it can satisfy these requirements.

BTW, he also uses the scenario of logging in on a UI, so you've got concrete guidance :)

Before Edit: (some of this still applies. The "DB or no DB" and "UI or no UI" questions are unrelated)

1 - Declarative or Imperative scenarios?

Declarative when you can, though imperative has some value (at some points in a project lifecycle).

Imperative is an easier way to think for testers and business analysts who aren't as familiar with information theory and design. It is also easier to think about earlier on in a project, before you've nailed down your problem domain and workflows. It can be useful for exploratory thinking.

Declarative is less subject to change over time. Since a GUI is the part of an application most subject to churn at a whim, this is extremely valuable. It is easier to think about once you've nailed down your problem domain and workflows, and are more focused on relational concepts. It is a more stable and more generally applicable model.

If you write test cases with a generic and declarative model, you could implement them using any combination of full app GUI automation, integration tests, or unit tests.

how do you describe such stuff like 'Home page' or 'Products page'?

I'm not sure I would at the base level of features and requirements. You might make sub-features and sub-requirements that describe implementation details, like specific UI workflows. If you're describing a piece of a UI, then you should be defining a UI feature/requirement.

2 - Exercise UI or not?

Both.

I think its extremely slow and brittle

Yes, it is. Perform every high level scenario/requirement with the UI and full DB integration, but don't exercise every single code path with end to end UI automation, and certainly not edge cases. If you do, you'll spend more time getting them working, and a lot less time actually testing your application.

You can architecture your application so you can do lower cost integration tests, including single-piece UI based tests. Unit tests are also valuable.

But the fewer integration tests you do, the more forehead-slapping bugs you're going to miss. It may be easier to write unit tests, and they will certainly be less brittle, but you'll be testing less of your application, by definition.

3 - Real database or not?

Both.

High level end-to-end integration tests must be done with the full system in place. This includes a real DB, running your tests with each system on a different server, etc.

The lower level you get, the more I advocate mock objects.

  • Unit tests should only test individual classes
  • Mid-level integration tests should avoid expensive, brittle, and impactful dependencies such as the file system, databases, the network, etc. Try to test the implementation of those brittle and impactful dependencies with unit tests and end-to-end tests only.
墨落成白 2024-12-20 06:32:48

不要按名称提及页面,而是描述它代表的内容,例如,

Scenario: Customers logs in successfully

  When I log in
  Then I should see an overview of ACME's top selling products

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

Instead of mentioning a page by name, describe what it represents, e.g.

Scenario: Customers logs in successfully

  When I log in
  Then I should see an overview of ACME's top selling products

You can test directly against underlying APIs or models, but the more you do this, the more you risk not catching an integration issue. One approach is to balance things with a small number of full-stack tests, and a larger number which test between two layers only.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文