bdd cucumber_如何使用BDD构建坚如磐石的Ruby on Rails应用

bdd cucumber

by Marko Anastasov

通过Marko Anastasov

如何使用BDD构建坚如磐石的Ruby on Rails应用 (How to build rock-solid Ruby on Rails apps with BDD)

了解通过行为驱动开发来构建可持续Web应用程序的最佳实践。 (Learn best practices for building sustainable web apps with behavior-driven development.)

Why do we fall sir? So that we can learn to pick ourselves up.

我们为什么要成为先生? 这样我们就可以学会振作起来。

I built my first Rails app ten years ago. I’ve tried all approaches, and if there’s one thing that I’m certain of, it’s that I can’t work without writing tests. And writing tests first is what has helped me advance my programming skills the most.

十年前,我构建了我的第一个Rails应用程序。 我已经尝试了所有方法,如果可以肯定的话,那就是没有编写测试我就无法工作。 首先编写测试是帮助我最大程度地提高编程技能的原因。

It’s pretty simple. We want to feel and be as productive on day 1000 as we are on day 1 of the project. We want to be fast. For that we need clean code.

很简单 我们希望在项目的第一天就感觉和在工作中一样高效。 我们要快。 为此,我们需要干净的代码。

We can’t get everything right in the first pass, so we need to refactor. However, we can’t refactor under a constant fear that we’ll break stuff and ship bugs to production without knowing it. We need confidence that when we do break the code, we can detect and fix the issue right away.

我们不能在一开始就把所有事情都做好,所以我们需要重构。 但是,我们不能一直担心会在不知不觉中破坏东西并将错误运送到生产环境中进行重构。 我们需要确信,当我们确实破坏代码时,我们可以立即检测并解决问题。

Where does confidence come from? The automated test suite gives us confidence. Confidence that we can change, remove, or add new code, and no major problem will happen as long as our tests are passing.

信心从何而来? 自动化测试套件使我们充满信心。 我们可以更改,删除或添加新代码的信心,只要我们的测试通过,就不会发生重大问题。

So if tests are the foundation, let’s write them first. Do that for a while, and you’ll notice how clean and effective both your code and tests come out.

因此,如果测试是基础,让我们先编写它们。 这样做一会儿,您会注意到代码和测试的效率和有效性。

了解“行为”观点 (Understanding the “behavior” point of view)

When applying test-driven development (TDD), developers can easily fall into the trap of using unit tests to test what an object or method is, rather than what it does, which is a lot more useful.

当应用测试驱动开发(TDD),开发人员可以很容易地落入使用单元测试来测试的陷阱什么的对象或方法 ,而不是它什么,这是很多更加有用。

An example would be writing a test which asserts that a collection of comments is specifically an array, and not one of its unique features, such as being sorted by time. In most cases, it shouldn’t matter if we change the implementation of that collection to return a custom enumerable class. More generally:

一个示例就是编写一个测试,该测试断言一个注释集合专门是一个数组,而不是其唯一功能之一,例如按时间排序。 在大多数情况下,是否更改该集合的实现以返回自定义可枚举的类无关紧要。 更普遍:

Changing the implementation of an object shouldn’t break its test suite, as long as what the object does remains the same.
只要对象的行为保持不变,更改对象的实现就不应破坏其测试套件。

Behavior-driven development (BDD) puts focus on behavior — what a thing does — on all levels of development.

行为驱动的开发 (BDD)将注意力集中在所有级别的开发上的行为-一件事情做什么。

Initially, the word “behavior” may seem strange. Another way to frame this is to think about descriptions. We can describe every low-level method, object, button or screen to another person — and what we will be describing is exactly what a behavior is. Adopting this approach changes the way we approach writing code.

最初,“行为”一词可能看起来很奇怪。 框架的另一种方式是考虑描述。 我们可以向另一个人描述每个低级方法,对象,按钮或屏幕,而我们将要描述的正是行为。 采用这种方法会改变我们编写代码的方式。

“给定/何时/然后”通信模式 (The “Given / When / Then” communication pattern)

Most problems in software development are communication problems. For example, product manager fails to describe every use case of a proposed functionality. Developers misunderstand the scope of a feature. Product team doesn’t have a protocol to verify if a feature is done.

软件开发中的大多数问题是通信问题。 例如,产品经理无法描述所提议功能的每个用例。 开发人员误解了功能的范围。 产品团队没有协议来验证功能是否已完成。

BDD simplifies the language we use to describe scenarios in which software should be used:

BDD简化了用于描述应使用软件的方案的语言:

*Given* some context or state of the world,

*给出*一些背景或世界状况,

*When* something happens,

* 当*发生某些事情时,

*Then* we expect some outcome.

* 然后*我们期待一些结果。

Given, When, Then are simple words we can use to describe a complex feature, code object, or a single method equally well. It’s a pattern that all members of the team in various roles can understand.

给定“何时”,“然后”是简单的单词,我们可以很好地描述复杂的功能,代码对象或单个方法。 所有角色的团队中的所有成员都可以理解这种模式。

These expressions are also built-in in many testing frameworks, such as Cucumber. A clear formulation of the problem and the solution that we need to implement helps us write better code.

这些表达式也内置在许多测试框架中,例如Cucumber 。 对问题和解决方案的清晰表述有助于我们编写更好的代码。

Rails的BDD工具概述 (Overview of BDD tools for Rails)

Ruby on Rails was the first web framework to ship with an integrated testing framework. This acted as a springboard for further advancements of the craft.

Ruby on Rails是第一个带有集成测试框架的Web框架。 这充当了该技术进一步发展的跳板。

At the same time, the expressiveness of Ruby and the productivity boost in developing web applications with Rails attracted many experienced and high-profile engineers to the community early on.

同时,Ruby的表现力和使用Rails开发Web应用程序的工作效率提高,在早期就吸引了许多经验丰富的知名工程师进入社区。

When you generate a new Rails application with default options, it sets the scene for testing using test/unit, a testing library that comes with Ruby. However, there are tools which make BDD easier to apply. I recommend using RSpec as the main testing library and Cucumber for writing high-level acceptance tests.

当您使用默认选项生成一个新的Rails应用程序时,它将使用Ruby附带的测试库test/unit设置要进行测试的场景。 但是,有些工具使BDD易于应用。 我建议使用RSpec作为主要测试库,并建议使用Cucumber编写高级验收测试。

规范 (RSpec)

RSpec is a popular BDD testing library for Ruby. Tests written using RSpec — called specs — are executable examples of expected behavior of a piece of code in a specified context. This is much easier to understand by reading the following code:

RSpec是一个流行的Ruby BDD测试库。 使用RSpec编写的测试(称为规范 )是在指定上下文中一段代码的预期行为的可执行示例。 通过阅读以下代码,这将更容易理解:

describe ShoppingCart do  context "when first created" do    it "is empty" do      shopping_cart = ShoppingCart.new      expect(shopping_cart).to be_empty    end  endend

Well-written specs are easy to read, and as a result, understand. Try reading the code snippet above out loud. We are describing a shopping cart, saying that, given a blank context, when we create a new shopping cart, we expect(shopping_cart).to be_empty.

规范良好的规范易于阅读,因此易于理解。 尝试大声阅读上面的代码片段。 我们正在描述一个购物车,说,给定空白上下文,当我们创建一个新的购物expect(shopping_cart).to be_empty ,我们expect(shopping_cart).to be_empty

Running this spec produces output which resembles a specification:

运行此规范将产生类似于规范的输出:

ShoppingCart  when first created    is empty

We could use RSpec to specify an entire system, however we can also use a tool which helps us write and communicate even more naturally.

我们可以使用RSpec来指定整个系统,但是我们也可以使用一个工具来帮助我们更加自然地编写和交流。

Cucumber (Cucumber)

As I explained in the first chapter of this guide, we want to test-drive the analysis phase of every new feature. To do that, we need customer acceptance tests to drive the development of the code which will actually implement the feature.

正如我在本指南第一章中所解释的那样,我们想测试每个新功能的分析阶段。 为此,我们需要客户验收测试来驱动将实际实现该功能的代码的开发。

If you are a developer working in a sufficiently complex organization, you may want to have somebody else, like a customer or product, manager write acceptance tests for you (disclaimer: I’ve never worked in such environment). In most cases, the developer writes them. This is a good practice, because it helps us understand better what it is that we need to build. Cucumber provides the language and format to do that.

如果您是在足够复杂的组织中工作的开发人员,则可能希望让其他人(例如客户或产品),经理为您编写验收测试(免责声明:我从未在这样的环境中工作过)。 在大多数情况下,开发人员会编写它们。 这是一个好习惯,因为它可以帮助我们更好地了解我们需要构建的内容。 Cucumber提供了这样做的语言和格式。

Cucumber reads plain text descriptions of application features, organized in scenarios. Each step in the scenario is implemented using concrete code, and it automates interaction with your application from the user’s standpoint. For example:

Cucumber读取按场景组织的应用程序功能的纯文本描述。 该场景中的每个步骤都是使用具体代码实现的,并且从用户的角度来看,它可以自动与您的应用程序进行交互。 例如:

Feature: Reading articles
Scenario: Commenting on an article  Given I am logged in  And I am reading an article with "2" comments  When I reply to the last comment  Then the article should have "3" comments  And I should be subscribed to follow-up comments

If this were a web application, the scenario above could automatically boot a test instance of the application, open it a web browser, perform steps as any user would do, and then check if certain expectations have been met.

如果这是一个Web应用程序,则上述方案可以自动启动该应用程序的测试实例,打开它的Web浏览器,像任何用户一样执行步骤,然后检查是否满足某些期望。

Rails中的BDD周期 (The BDD cycle in Rails)

In practice, BDD implies an outside-in approach. We start with an acceptance test, then write code in the views, and work our way down to the models. This approach helps us discover any new objects or variables we may need to effectively implement our feature early on, and make the right design decisions based on this.

在实践中,BDD意味着从外而内的方法。 我们从验收测试开始,然后在视图中编写代码,然后逐步进行建模。 这种方法可帮助我们发现可能需要的任何新对象或变量,以尽早有效地实现我们的功能,并据此做出正确的设计决策。

The BDD cycle in Rails consists of the following steps:

Rails中的BDD周期包括以下步骤:

  1. Start with a new Cucumber scenario. Before you write it, make sure to analyze and understand the problem. At this point you need to know how the user interface allows a user to do a job. Do not worry about the implementation of scenario steps.

    从新的Cucumber方案开始 。 在编写它之前,请确保分析并理解问题。 此时,您需要知道用户界面如何允许用户完成工作。 不必担心方案步骤的实施。

  2. Run the scenario and watch it fail. This will tell you which steps are failing, or pending implementation. At first, most of your steps will be pending (undefined).

    运行该方案并观察它是否失败 。 这将告诉您哪些步骤失败或正在执行。 首先,您的大多数步骤都将待处理(未定义)。

  3. Write a definition of the first failing or pending spec. Run the scenario and watch it fail.

    编写第一个失败或未决规范的定义 。 运行方案并观察它是否失败。

  4. Test-drive the implementation of a Rails view using the red-green-refactor cycle with RSpec. You’ll discover instance variables, controllers and controller actions that the view will need to do its job. This is also the only phase which has been proved to be optional in practice. An alternative approach is to simply prepare the views and controllers before moving on to the next step.

    使用带有RSpec的红绿色重构循环来测试Rails视图的实现 。 您将发现视图完成其工作所需的实例变量,控制器和控制器操作。 这也是实践中被证明是可选的唯一阶段。 另一种方法是简单地准备视图和控制器,然后再进行下一步。

  5. Test-drive the controller using the red-green-refactor cycle with RSpec. Make sure that the instance variables are assigned and that the actions respond correctly. The controllers are typically driven with a mocking approach. With the controller taken care of, you will know what the models or your domain objects should do.

    使用带有RSpec的红绿色重构循环对控制器进行试驱动 。 确保分配了实例变量,并且动作正确响应。 控制器通常通过模拟方法来驱动。 照顾好控制器后,您将知道模型或域对象应该做什么。

  6. Test-drive domain objects using the same red-green-refactor cycle with RSpec. Make sure that they provide the methods needed by the controller and the view. If you are working on a new feature for which a model does not exist yet, you should now generate the model and the corresponding database migrations. At this point you’ll know exactly what you need them to do.

    使用与RSpec相同的红绿重构周期来测试驱动域对象 。 确保它们提供了控制器和视图所需的方法。 如果您正在使用尚不存在模型的新功能,则现在应生成模型和相应的数据库迁移。 此时,您将确切知道您需要他们做什么。

  7. Once you have implemented all the objects and methods you need and the corresponding specs are passing, run the Cucumber scenario you started with to make sure that the step is satisfied.

    一旦实现了所需的所有对象和方法,并且通过了相应的规范,请运行开始的Cucumber场景,以确保满足该步骤

Once the first scenario step passes, move onto the next one and follow the same steps. Once your entire scenario has been implemented — the scenario is passing, along with all underlying specs — take a moment to reflect if there is something that you can refactor further.

一旦第一个方案步骤通过,请移至下一个方案并遵循相同的步骤。 实施完整个方案后(该方案以及所有基本规范都已通过),请花点时间思考是否可以进一步重构

Once you’re sure that you’ve completed the scenario, either move on to the next one, or show your work to others. If you work with a team, create a pull request or an equivalent request for a code review. Opening a pull request should automatically trigger a continuous integration build. When there are no more related scenarios left, show your work to your project manager or client, asking them to verify that you’ve built the right thing by deploying a feature branch to a staging server.

确定完成该方案后,要么继续进行下一个,要么向他人展示您的工作。 如果您与团队合作,请创建拉取请求或等效请求以进行代码审查。 打开拉取请求应自动触发持续集成构建。 如果没有其他相关场景,请向项目经理或客户展示您的工作,要求他们通过将功能分支部署到登台服务器来验证您是否构建了正确的东西。

This post is adapted from Rails Testing Handbook, a free ebook published by Semaphore. If you’ve made it this far and want to see some hands-on examples of writing behavior-driven code, download the book and let me know what you think of it. Thanks!

这篇文章改编自Semaphore出版的免费电子书《 Rails Testing Handbook》 。 如果到目前为止,您想要看一些动手编写行为驱动代码的示例,请下载本书,并告诉我您的想法。 谢谢!

翻译自: https://www.freecodecamp.org/news/how-to-build-rock-solid-ruby-on-rails-apps-with-bdd-735de9319cc6/

bdd cucumber

你可能感兴趣的:(python,java,编程语言,人工智能,spring)