This week I worked more on understanding the "Gherkin" phrasing of conditions that would allow a user to define what they'd like to see in a feature, and hand this definition to a developer who would then translate it into code. The Gherkin language of "GIVEN" a precondition, "AND" a precondition, "WHEN" action, "AND" action .. (ect) "THEN" result.
I understood all that and watched this tutorial to understand phrasing better. Then I started thinking about cucumber and watch a few tutorials about how cucumber plays into implementing the Gherkin language into a kind of testing suite that uses language more similar to english than rspec or some of the others I'm familier with.
I watched this demo of cucumber to get an understanding of how it works. Read some setup guides for ruby/rspec like this one and other installation guides.
Finally settled on following this documentation that gave more of a framework for making cucumber "feature files" and let me run my first tests to see how the gherkin and testing suite interplay. Here is my first run of things:
/Users/lesliewilson/.gem/ruby/2.3.3/gems/cucumber-1.3.8/lib/cucumber/ast/step.rb:80: warning: circular argument reference - name
#encoding: utf-8
Feature: Showcase the simplest possible cucumber scenario
In order to verify that cucumber is installed and configured correctly
As an aspiring BDD fanatic
I should be able to run this scenario and see that the steps pass (green like a cuke)
Scenario: Cutting vegetables # features/first.feature:8
Given a cucumber that is 30 cm long # features/first.feature:9
When I cut it in halves # features/first.feature:10
Then I have two cucumbers # features/first.feature:11
And both are 15 cm long # features/first.feature:12
1 scenario (1 undefined)
4 steps (4 undefined)
0m0.004s
You can implement step definitions for undefined steps with these snippets:
Given(/^a cucumber that is (\d+) cm long$/) do |arg1|
pending # express the regexp above with the code you wish you had
end
When(/^I cut it in halves$/) do
pending # express the regexp above with the code you wish you had
end
Then(/^I have two cucumbers$/) do
pending # express the regexp above with the code you wish you had
end
Then(/^both are (\d+) cm long$/) do |arg1|
pending # express the regexp above with the code you wish you had
end
..So it was interesting to see how it counts "scenarios" (essentially keeping track of the colons) and also the numbers of steps per scenario..
I guess I don't understand the significance of "features" in this yet. Must explore more
So I googled more cucumber syntax and got this:
When(/^I go to the homepage$/) do
visit root_path
end
Then(/^I should see the welcome message$/) do
expect(page).to have_content("Hello Cucumber")
end
and I focused more on interpreting it and, I believe it's saying visit root_path in your website, and expect the content in the html somewhere to have the string "hello cucumber". and when you run it from the command line so its hiding the execution - it looks like this:
$ cucumber -s
Using the default profile…
Feature: Hello Cucumber
Scenario: User sees the welcome message
When I go to the homepage
Then I should see the welcome message
1 scenario (1 passed)
2 steps (2 passed)
0m0.168s
..so the method .to have_content searches the html. OK I feel like I'm coming closer and closer to kind of understanding how this all connects. Its basically a really high level api for convenient readable testing that is doing some pretty specific things. I would be interested to see some other testing suites and the differences between them because cucumber is blowing my mind.
In summary, it seems that the main difference between RSpec and Cucumber are the business readability factor. Cucumber's main draw is that the specification (features) are separate from the test code, so your product owners can provide or review the specification without having to dig through code. These are the .feature files that you make in Cucumber. RSpec has a similar mechanism, but instead you describe a step with a Describe, Context or It block that contains the business specification, and then immediately have the code that executes that statement. This approach is a little easier for developers to work with but a little harder for non-technical folks.
This source helped me understand it better..