Difference between revisions of "Exploring your first cucumber project"

From Test Automation Wiki
Jump to: navigation, search
(5 intermediate revisions by 3 users not shown)
Line 7: Line 7:
 
<h2>Feature files</h2>
 
<h2>Feature files</h2>
 
<p>
 
<p>
Let's start off by having a look at the feature files. Open <code>./features/example.feature</code> and you should see the following:
+
Let's start off by having a look at the feature files. Open <code>./features/1_basic.feature</code> and you should see the following:
 
<ul>
 
<ul>
<li>Tags <code>@exmaple</code></li>
+
<li>Tags <code>@example</code></li>
<li>a Feature <code>Feature: Example Feature</code>
+
<li>a Feature <code>Feature: Basic Feature</code>
 
<li>A description of the feature <code>When I want (...) the tests below</code>
 
<li>A description of the feature <code>When I want (...) the tests below</code>
 
<li>Multiple sceanrios <code>Scenario: example01 - Spritecloud search</code>
 
<li>Multiple sceanrios <code>Scenario: example01 - Spritecloud search</code>
Line 18: Line 18:
  
 
<h3>Tags</h3>
 
<h3>Tags</h3>
<p>A tag is used to be able to filter certain feature or scenario's when running your script in Cucumber. Try it out:</p>
+
<p>A tag is used to be able to filter certain feature or scenario's when running your script in Cucumber. Open 'CMD', go to your project folder and try it out:</p>
 
<source>
 
<source>
   bundle exec cucumber -t @example
+
   bundle exec cucumber -t @basic
   # Will run the complete Feature: Example
+
   # Will run the complete Feature: Example Feature
   bundle exec cucumber -t @example01
+
   bundle exec cucumber -t @basic_01
 
   # Will only run the first Scenario
 
   # Will only run the first Scenario
   bundle exec cucumber -t @example -t ~@example01
+
   bundle exec cucumber -t @basic -t ~@basic_01
 
   # Will run all scenario's in the Example feature, except for the first one.
 
   # Will run all scenario's in the Example feature, except for the first one.
 
</source>
 
</source>
Line 30: Line 30:
 
<h3>Feature, Scenario, Steps</h3>
 
<h3>Feature, Scenario, Steps</h3>
 
<h4>Features</h4>
 
<h4>Features</h4>
<p>A feature represents a major functionality of a website. This could be a single page or a functionality over multiple pages. Weather something actually is a separate feature is left to your own judgement. You don't want too much scenario's in 1 feature file, but also, you don't want too little. For example:</p>
+
<p>A feature represents a major functionality of a website. This could be a single page or a functionality over multiple pages. Whether something actually is a separate feature is left to your own judgement. You don't want too much scenario's in 1 feature file, but also, you don't want too little. For example:</p>
 
<h5>A product detail page</h5>
 
<h5>A product detail page</h5>
 
<p>This could be a feature on itself with all the functionalities this page could have. Think of:
 
<p>This could be a feature on itself with all the functionalities this page could have. Think of:
Line 44: Line 44:
 
</p>
 
</p>
 
<h4>Scenario's</h4>
 
<h4>Scenario's</h4>
<p>In a scenario, you will confirm 1 functionality. An often made mistake is to confirm multiple functionalities in 1 scenario. On large projects, this will ruin the maintainability of your test automation suite. In <code>example.feature</code> you will see that every scenario just confirms 1 thing.</p>
+
<p>In a scenario, you will confirm 1 functionality. An often made mistake is to confirm multiple functionalities in 1 scenario. On large projects, this will ruin the maintainability of your test automation suite. In <code>1_basic.feature</code> you will see that every scenario just confirms 1 thing.</p>
 
<h4>Steps</h4>
 
<h4>Steps</h4>
 
<p>A step is the part that will actually execute your Selenium code. More about this in the next heading: Step Definitions</p>
 
<p>A step is the part that will actually execute your Selenium code. More about this in the next heading: Step Definitions</p>
Line 51: Line 51:
 
<h3>Organising your files</h3>
 
<h3>Organising your files</h3>
 
<p>If you go to the folder <code>./features/step_definitions/</code> You will see 3 files:
 
<p>If you go to the folder <code>./features/step_definitions/</code> You will see 3 files:
* <code>precondition_steps.rb</code> contains all the "Given ..." steps
+
* <code>account_steps.rb</code> contains all the steps regarding "account" functions.
* <code>interaction_steps.rb</code> contains all the "When ..." steps
+
* <code>basic_steps.rb</code> contains all the steps regarding "basic" functions.
* <code>validation_steps.rb</code> contains all the "Then ..." steps
+
* <code>todo_steps.rb</code> contains all the steps regarding "todo" functions.
 
This is an example of how you can manage your step definitions orderly. In the end, just like features, it's to the TA engineer how they feel is the most organised way. For example, you can create a new file for every feature, or you could even write everything into 1 big step definition file (not recommended).
 
This is an example of how you can manage your step definitions orderly. In the end, just like features, it's to the TA engineer how they feel is the most organised way. For example, you can create a new file for every feature, or you could even write everything into 1 big step definition file (not recommended).
 
</p>
 
</p>
 
<h3>The step definition</h3>
 
<h3>The step definition</h3>
<p>Open <code>./features/step_definitions/interactions_steps.rb</code> and have a look at line number 28: "the user clicks on link ..."</p>
+
<p>Open <code>./features/step_definitions/basic_steps.rb</code> and have a look at line number 33-42: "the user clicks on link ..."</p>
 
<source>
 
<source>
 
When(/^the user clicks on link "(.*?)"$/) do |url|
 
When(/^the user clicks on link "(.*?)"$/) do |url|
Line 70: Line 70:
 
end
 
end
 
</source>
 
</source>
<p>Find out more about how to define a step on [https://github.com/cucumber/cucumber/wiki/Step-Definitions Cucumber Step definitions]. In this case a wildcard is used in the step definition <code>(.*?)</code>. This wildcard is then stored in a variable <code>url</code>.</p>
+
<p>Find out more about how to define a step on [https://docs.cucumber.io/cucumber/step-definitions/ Cucumber Step definitions]. In this case a wildcard is used in the step definition <code>(.*?)</code>. This wildcard is then stored in a variable <code>url</code>.</p>
 
<p>Then bewteen "When" and "end", there is code that will interact with the browser. What it's basically saying is 'Look for an element <code><a href="url"></code> where <code>url</code> is whatever was filled into the step. More about interacting with the browser in the next chapter of this tutorial.</p>
 
<p>Then bewteen "When" and "end", there is code that will interact with the browser. What it's basically saying is 'Look for an element <code><a href="url"></code> where <code>url</code> is whatever was filled into the step. More about interacting with the browser in the next chapter of this tutorial.</p>
  
Line 81: Line 81:
 
<h3>Other advanced files</h3>
 
<h3>Other advanced files</h3>
 
<h4>env.rb</h4>
 
<h4>env.rb</h4>
<p>When running cucumber in the console, <code>./features/support/env.rb</code> is the first file that is loaded. It will start Lapis Lazuli and load all the dependent gems. Also, in this file you can add repeating scripts, that should be ran before or after everything feature, scenario or step. See [https://github.com/cucumber/cucumber/wiki/Hooks Cucumber Hooks] for more information.</p>
+
<p>When running cucumber in the console, <code>./features/support/env.rb</code> is the first file that is loaded. It will start Lapis Lazuli and load all the dependent gems. Also, in this file you can add repeating scripts, that should be ran before or after everything feature, scenario or step. See [https://docs.cucumber.io/cucumber/api/#hooks Cucumber Hooks] for more information.</p>
  
 
<h4>functions.rb</h4>
 
<h4>functions.rb</h4>

Revision as of 13:54, 5 September 2018

This is more of an informative part of the tutorial. If you don't feel like reading, you can skip to part 5: Exercises

Feature files

Let's start off by having a look at the feature files. Open ./features/1_basic.feature and you should see the following:

  • Tags @example
  • a Feature Feature: Basic Feature
  • A description of the feature When I want (...) the tests below
  • Multiple sceanrios Scenario: example01 - Spritecloud search
  • Steps Given the user navigates to "blog"

Tags

A tag is used to be able to filter certain feature or scenario's when running your script in Cucumber. Open 'CMD', go to your project folder and try it out:

  bundle exec cucumber -t @basic
  # Will run the complete Feature: Example Feature
  bundle exec cucumber -t @basic_01
  # Will only run the first Scenario
  bundle exec cucumber -t @basic -t ~@basic_01
  # Will run all scenario's in the Example feature, except for the first one.

Feature, Scenario, Steps

Features

A feature represents a major functionality of a website. This could be a single page or a functionality over multiple pages. Whether something actually is a separate feature is left to your own judgement. You don't want too much scenario's in 1 feature file, but also, you don't want too little. For example:

A product detail page

This could be a feature on itself with all the functionalities this page could have. Think of:

  • Viewing the product image
  • Adding an item to your basket
  • Folding open a detailed description of the product.

Ordering a product

This is not a separate page, but more a flow that a user goes trough. Even though a part of this Feature is the product detail page, the complete flow of ordering a product goes trough multiple functionalities. In the end, on a feature like this, you would want to test specific order types, for example:

  • Ordering 1 product with shipping cost
  • Ordering multiple products, going over the free shipping threshold
  • Ordering a product with a discount code

Scenario's

In a scenario, you will confirm 1 functionality. An often made mistake is to confirm multiple functionalities in 1 scenario. On large projects, this will ruin the maintainability of your test automation suite. In 1_basic.feature you will see that every scenario just confirms 1 thing.

Steps

A step is the part that will actually execute your Selenium code. More about this in the next heading: Step Definitions

Step definitions

Organising your files

If you go to the folder ./features/step_definitions/ You will see 3 files:

  • account_steps.rb contains all the steps regarding "account" functions.
  • basic_steps.rb contains all the steps regarding "basic" functions.
  • todo_steps.rb contains all the steps regarding "todo" functions.

This is an example of how you can manage your step definitions orderly. In the end, just like features, it's to the TA engineer how they feel is the most organised way. For example, you can create a new file for every feature, or you could even write everything into 1 big step definition file (not recommended).

The step definition

Open ./features/step_definitions/basic_steps.rb and have a look at line number 33-42: "the user clicks on link ..."

When(/^the user clicks on link "(.*?)"$/) do |url|
  # Search for the element that includes the expected text
  browser.wait(
    :like => {
      :element => :a,
      :attribute => :href,
      :include => url
    }
  ).click
end

Find out more about how to define a step on Cucumber Step definitions. In this case a wildcard is used in the step definition (.*?). This wildcard is then stored in a variable url.

Then bewteen "When" and "end", there is code that will interact with the browser. What it's basically saying is 'Look for an element <a href="url"> where url is whatever was filled into the step. More about interacting with the browser in the next chapter of this tutorial.

config.yml

The file ./config/config.yml is used to re-used defined variables. Mostly used to store user credentials or to translate a page name into a page URL. Also commonly used to define different data between different test environments. For example, the URL to the test environment is different than the one to the production environment.

Lapis Lazuli has build in functions that loads these variables:

  • env('pages.root') will load the root configuration value from the selected environment, E.G. production -> pages -> root = https://spritecloud.com
  • config('user.default-user.username' will load a configuration value independent from the selected environment, so users -> default-user -> username = test

Other advanced files

env.rb

When running cucumber in the console, ./features/support/env.rb is the first file that is loaded. It will start Lapis Lazuli and load all the dependent gems. Also, in this file you can add repeating scripts, that should be ran before or after everything feature, scenario or step. See Cucumber Hooks for more information.

functions.rb

In this file we've defined multiple repeating functions. It's created this way to prevent too much code in the step_definitions. Also, you don't want to repeat yourself. In the folder ./features/support/ you can add any .rb file and it will be loaded before your cucumber feature files are executed.

Gemfile

Finally, there is the Gemfile, here you can add any Gems that you're using for your project. For example, sometimes you want to directly connect to a SOAP back-end environment, for this there is a Gem. Simply add the gem to your Gemfile and you can start using the Gems functionalities in your step definitions.