Post-Installation Notes after Setting-Up Cucumber-Ruby-Watir Automated Checks with Jenkins on a Windows 10 Amazon EC2 Server

Had a chance to set up cucumber tests to run via Jenkins on a Windows 10 Amazon EC2 server last week. It’s been a while since I installed everything from scratch, so that was good practice. I ran into some problems, which was a bit expected since my local setup was on Windows 7, so this post serves as a guide for possible future installations.

The process:

  • Install desired browsers where the tests will run.
  • Install Java and the latest JDK. Include the JDK path to Window’s system environment variables. This is necessary for running the selenium server.
  • Install the latest Ruby and DevKit versions, required for installing ruby gems and running the test suite.
  • Install Jenkins, which will take care of scheduling and test results reporting. Also install Jenkins as a service, to run automatically after the server boots up.
  • Install Git on the machine, and setup the credentials for retrieving the test code from the remote repository.
  • Check out the test code from the remote repository.
  • Set the selenium server to run automatically after the machine boots.
  • Install the required ruby gems using bundler.
  • Check if cucumber tests run properly by running a sample via the command line interface.
  • Create/Import Jenkins jobs for the cucumber tests. Install the Jenkins plugins necessary for test results reporting. Possibly set up Jenkins to pull the latest test code from the remote repository.
  • Run cucumber tests via Jenkins.

Some reminders for future installs:

  • Install the 32-bit version of Ruby’s DevKit instead of the 64-bit because the latter version creates problems with gem installs.
  • Windows 10 has trouble installing ruby gems (using the bundle install command) from the default HTTPS source. To fix this, replace the gems source list in the Gemfile from HTTPS to HTTP.
  • Install Jenkins using the MSI-based Windows installer on its own directory on the C drive, then install it as a service afterwards.
  • Do not install all suggested Jenkins plugins at first, especially the ones related to Git. These will break Jenkins on Windows so install only those that are actually needed for cucumber tests to run.
  • Via Jenkin’s Configure System module, set the shell executable to the location of the command line’s executable file (i.e., C:\Windows\system32\cmd.exe) so that Jenkins can run cucumber tests via the default Windows command line interface. In addition, each Jenkins job Build needs to be set as “Execute Windows Batch Command” instead of “Execute Shell”.
  • Remember to change the timezone of the machine to the proper timezone.
  • Test a sample basic cucumber project first to see if cucumber is properly running on the machine before retrieving the actual test suite from the Git repository.
  • In saving the machine’s generated public SSH identification (via Putty or the ssh keygen command using Cygwin), do not include a name for the file to be saved so that the system generates the default file.

We Refactor When We Learn Better Ways Of Doing

For the past month or so, inspired by the lessons I learned from Jeff Nyman’s test description language blog post seriesGerard Meszaros’ talk about test abstractions, and Codecademy’s online class about the Ruby programming language, I have been steadily performing good chunks of code refactoring of our existing cucumber-watir-ruby end-to-end functional checks, which included (but not limited to) the following:

  • Cucumber
    • Removing information from cucumber steps that do not directly affect what is being checked in tests
    • Explicitly describing what the cucumber check is for, instead of using vague Then statements
    • Using step commands for re-using repeated cucumber steps
    • Renaming variable, method, and class names used for assertions so they mean what they actually mean
  • Ruby
    • Applying double pipes to set default variable values when necessary
    • Using one-line ifs and unlesses whenever possible, for readability purposes
    • Converting simple multi-line if-else statements to one line whenever helpful using the ternary/conditional operator
    • Replacing + or << operators with string interpolation
    • Using symbols for hash keys instead of string names because they’re faster to process
  • Locators
    • Making xpath locators shorter/readable whenever possible using the // modifier

It’s all difficult work, possibly more strenuous work than writing new checks even though basically I’m just rewriting existing tests into a more readable and maintainable form. I’m breaking existing code because they’re not so easy to understand and then revising them in order for their intent to be more understandable in plain view, finally making sure they’re checking whatever they’re supposed to, so that they act as a better source of truth for knowing how our applications behave and deliver value.

Defining What Cucumber-Watir-Ruby Checks To Run by Passing Parameters

Like any other type of document, automated checks can build up to so many files. There can be many features we would like to run tests on and it can be hard to keep track of all them every time. Maybe we prefer writing varying groups of checks in one single file, which cucumber does not restrict us from doing. We may also like to run our checks on different test environments, browsers, or locations that does not necessarily require a change in a feature to test but rather only an adjustment in configuration. Fortunately, there are ways to perform all of this without remembering numerous commands to run our checks. Here are some of them:

  • Cucumber Tags (-t)
    Using Cucumber tags is an easy way of defining groups of tests in a feature file, so we can choose to only run a select group instead of running everything when we test a particular feature. Here is an example of a feature file (with sample filename of policies.feature) with tags (displayed in bold, characterized by the @ symbol):

      Feature: Booking Engine Rate Plan Policy Copies

       @prepay @partial
       Scenario: ShowRooms Prepayment Policy, DWH Partial
         When guest views the policies for a DWH property for a partial rate plan
         Then a copy of 'Only 10% prepayment is required to confirm your reservation' is displayed in the prepayment policy

       @prepay @full
       Scenario: ShowRooms Prepayment Policy, DWH Full Non-Refundable
         When guest views the policies for a DWH property for a full nonrefundable rate plan
         Then a copy of 'Full prepayment is required to confirm your reservation' is displayed in the prepayment policy

       Scenario: ShowRooms Reservation Policies, DWH Partial, Lead Time Early Modification
         When guest views the policies for a DWH property from 4 DAYS FROM NOW to 6 DAYS FROM NOW for a Public_Partial_LT rate plan
         Then a copy of 'We don't charge you a modification fee if you choose to modify before' is displayed in the modification policy

    If we want to run the prepayment policy copy tests (the first and second scenarios in the example), we can run those checks as:

      cucumber policies.feature -t @prepay

    And if we want to run only the single reservation policy copy check in the example feature, we can run that as:

      cucumber policies.feature -t @reservation

    More information about how to use cucumber tag are found in the Cucumber tags Wiki page.

  • Custom Environment Variables
    We can create custom variables we can use for specifying how we want our tests to run. For example, we might like to run the same feature test for a different browser, or on a mobile application instead of on a desktop web app.

    To define what custom variable we want to use for our checks (say, a browser type), we could write the following code in the env.rb file:

      def browser_type
        (ENV['BROWSER'] ||= 'chrome')

    which means that we are stating a browser type variable of name ‘BROWSER’ we can use for describing which browser we would like to use during the test run.

    If we want to run the policies feature check on a firefox browser (assuming that functionality is built in our test code), we could say that as:

      cucumber policies.feature BROWSER=firefox

    And if we want to run the same checks on a chrome browser, we can either say that the browser type variable should equal to ‘chrome’:

      cucumber policies.feature BROWSER=chrome

    or just omit the browser type variable altogether, since the browser defaults to the value of ‘chrome’ based on the code above:

      cucumber policies.feature

  • Cucumber Profiles (-p)
    Eventually there will be a situation where we would need to use common cucumber commands, tags, or custom environment variables in running our checks, and typing all of those may prove tiring and unproductive. For example, would you feel good typing in

      cucumber policies.feature FIG_NEWTON_FILE=staging.yml --no-source --color --format pretty -t ~@not_ready BROWSER=firefox

    to run the policy copy checks (not including the checks that are not yet ready) for the firefox browser in the staging test environment with test results display in the terminal displayed with color and formatted properly? I personally wouldn’t enjoy writing all of that, and this is where cucumber profiles help. To use profiles, we could state desired profiles in the cucumber.yml file, like so:

      default: FIG_NEWTON_FILE=staging.yml --no-source --color --format pretty --tags ~@not_ready
      dev: FIG_NEWTON_FILE=dev.yml --no-source --color --format pretty --tags ~@not_ready
      uat: FIG_NEWTON_FILE=uat.yml --no-source --color --format pretty --tags ~@not_ready
      parallel: FIG_NEWTON_FILE=staging.yml --no-source --color --format pretty --tags ~@not_ready --format html --out reports/parallel_.html

    where in the example above we can see that there are four profiles, namely: default, dev, uat, and parallel.

    When we want to run the same checks as before in the uat test environment, we would only need to type in the following:

      cucumber policies.feature -p uat BROWSER=firefox

    And when we want to run the same checks in staging (where we would usually run them), we can even omit writing the profile since the default profile runs whenever the profile is not defined:

      cucumber policies.feature BROWSER=firefox

    More information about how to use cucumber profiles are found in the Cucumber cucumber.yml Wiki page.

Steps In Starting A Cucumber-Watir-Ruby ATDD Automation Project using TestGen (Windows)

I said that I was going to lay low on automation this year. However, I was also still curious about implementing a Watir-Ruby counterpart of my existing Java-Webdriver automation framework, including an acceptance-test driven development (ATDD) or a behavior-driven development (BDD) functionality built-in, just so I can understand how different the two frameworks are, based on my own experience. Long story short, I learned how to do it, with help from Jeff Morgan’s “Cucumber & Cheese” ebook, and was surprised how easy it was to start, and eventually write code.

If you ever want to try building a Cucumber-Watir-Ruby project from scratch on a Windows machine, try this:

  1. Download the latest version of Ruby for your machine
  2. Run the installer, ticking the following options when prompted
    • Install Tcl/Tk support
    • Add Ruby executables to your PATH
    • Associate .rb and .rbw files with this Ruby installation
  3. Run the command prompt, a shortcut is by pressing the Window and R keyboard buttons at the same time, typing in cmd, and then pressing Enter
  4. Test the Ruby installation by running ruby -v
  5. Close the command prompt if the Ruby version is displayed in the screen. If not, try re-installing Ruby or checking if Ruby is set in your machine’s Path under system environment variables
  6. Download the Ruby Development Kit for your version of Ruby
  7. Create a new folder under C:\ directory called devkit
  8. Extract the Development Kit files to the newly created directory
  9. Run the command prompt again
  10. In the command prompt, navigate to the devkit directory by running cd C:\devkit
  11. Once inside the directory, type in ruby dk.rb init and then press Enter
  12. After that, type in ruby dk.rb install and press Enter
  13. Then let’s install some gems by running this: gem install cucumber testgen rake bundler yard watir-webdriver page-object fig_newton
  14. When the gems finish installing, go back to the command prompt and run cd C:\Users\Your_Machine_Name or go to a desired directory where you want to house your automation project
  15. Still in the command prompt, run testgen project Project_Name –pageobject-driver=watir. This should create a new directory structure inside your project folder which cucumber will use to run your automated checks.
  16. Create a test_filename.feature file (without anything in it) inside your project directory
  17. Test if the project works by going to the project directory and then running cucumber test_filename.feature in the command prompt

If you encounter problems with a ffi_c file, such as a “cannot load such file — ffi_c (LoadError)” error, doing the following may help:

  1. Run gem uninstall ffi
  2. Then run gem install ffi –platform ruby

If the ffi_c issues persists, uninstalling the latest version of Ruby, installing an older Ruby version (say v2.1.8) and redoing Steps 3-17 may fix the problem.

Note: For a Mac or an Ubuntu machine, the Ruby and Devkit installations may differ.