‘Scroll’ in Mobile using Appium

Oh! this was definitely one of the difficult tasks to automate in Mobile (Android) and strangely I did find it sooner rather than later! But spent hours looking for it on the internet. Below is the code which one can use it to scroll in android apps. It takes an argument, specifically the text one wants to search for. And it works like a charm!

Courtesy: Appium discussion forum

def scroll_to(text)
   # This is a workaround for Appium issue 4311,
   # It can and should be replaced by the following when the issue is resolved
   # appium.driver.scroll_to text
   text = %Q("#{text}")
   args = Appium::Android::scroll_uiselector("new UiSelector().text(#{text})")
   find_element :uiautomator, args
end

How to use the above method?

if the above code is defined in a class then do –

<@class_instance>.scroll_to(<text you want to search for>).click

Mobile Testing using Appium

In this article, we will study on how to do Mobile Automation using tools like Appium, we will use Ruby and RSpec BDD framework to write the test scripts. But before diving into the details of it let’s learn why do we need to do Mobile Testing?

As we all are confused sometimes to choose our favorite mobile device and we expect that the one we choose should be flawless in every aspect. Well, to make this happen TESTING is necessary but with so many devices available today, is it humanly possible to test the applications on each and every device? The answer is a big no, and this is where the mobile automation comes into picture which gives the tester an ability to run tests on any device without spending a penny! the answer to this is mobile emulators/simulators available. These are the software that mimics the real device and helps in running the automated tests on them.

In this blog, I will help you in setting up the required environment for mobile testing and also provide you with a simple script of testing an application on Android OS.

Appium – The reason for choosing this software for mobile automation over others is:

  • It is open source (free!)
  • It is compatible with both iOS and Android (Need to install only one software!)
  • Support for vast client libraries like Python, Ruby, Java, C# etc.
  • No need to install any agents to talk with Android apps.

Download the software from Appium downloads page (OS X and Windows) and install it. Make sure you installed Ruby, Android SDK, Java JDK. Launch the Appium server (Note: Appium is an HTTPServer written in Node.js if you get error while launching then install Node.js and try again)

appium_launch_1

After launching the Appium, you will get a UI and click on ‘Play’ button to start the Appium server.

appium_launch_2

Let’s try to launch Android SDK Manager from command line. Go to command prompt and enter ‘android’ and press enter. Android SDK Manager GUI should be launched without error.

android_sdk_launch.gif

If you get an error then make sure you have set the PATH variable for Android executables as below.

Go to Windows Run and type in ‘PATH’, select ‘Edit the System environment variables’.  You will be taken to the below window.

android_sdk_PATH.gif

Install the ‘appium_lib’ and ‘selenium-webdriver’ gems by following the command:

gem install appium_lib
gem install selenium-webdriver

Woah! that’s a lot of effort to set up the things! One more thing, since we will be using a real Android device to test, let’s connect the Android device and from the command prompt give the command, adb devices’, to see the connected devices to the system and also if any emulator is launched. And important thing: Make sure to enable the developer option on your Android device by following the steps:

Enable USB debugging in your phone to be able to run your test scripts. For this, you need to enable “Developer options” by navigating to Settings/About Phone and tapping build number seven times. You will get a notification saying that you’re now a developer. Ignore it. Then navigate to “Developer options” and enable the USB debugging option.

android_sdk_adb_devices.gif

Awesome! We have set up our environment. But how do we launch the application? Well, applications are launched by giving the Package Name and the Activity, to know this without any fuss, install ‘Application Reader’ app by visiting the Play store.

The app we will be testing is , ‘ATP/WTA Live’. From our recently installed app we can find the package name and the activity details of the app under test.

Application_Reader

To inspect the elements of an Android app, we will use ‘UI Automator Viewer’ tool from Android SDK, it is located in ‘tools’ directory of the Android SDK.

UI_Automator.png

Let’s start scripting in RSpec directly. We need to say beforehand that which package we will be launching, follow the below code:

server_url = 'http://localhost:4723/wd/hub'

capabilities =
    {
        platformName: 'Android',
        deviceName: 'XT1063',
        appPackage: 'atpwta.live', # Package Name of the app
        appActivity: '.activity.Main',
        appWaitActivity: '.activity.root.TournamentList'
    }
@driver = Selenium::WebDriver.for(:remote, :desired_capabilities=>capabilities, :url=>server_url)

The above will launch the app in the real device once it is executed. Appium is a wrapper around the Selenium-webdriver and hence it is easy to follow up and write the scripts if one is familiar with it.

Now, what would one test after launching an app? Title! let’s start by verifying it.

it 'Check for homepage title', main_title: true do
  # Go to the navigation bar in the UI Automator Viewer and see the ID.
  expect(@driver.find_element(:id, 'atpwta.live:id/NavBarTitleTextView').text).to eq 'ATP/WTA Live'
end

Awesome, this is our first script in Mobile testing that verify’s the title of an app.

Let’s dive deeper and try to verify the Rankings in ATP Singles category, below is the step by step process to navigate through the contents and verifying them. After doing it manually in our app, let’s try to automate it.

android_app_operations.gif

Below is the RSpec code to test the application and asserting if elements are present.

Android_spec.rb

require 'rspec'
require 'watir-webdriver'
require 'selenium-webdriver'
require 'appium_lib'

describe 'WTA Rankings' do
  before(:each) do
    server_url = 'http://localhost:4723/wd/hub'

    capabilities =
        {
            platformName: 'Android',
            deviceName: 'XT1063',
            appPackage: 'atpwta.live',
            appActivity: '.activity.Main',
            appWaitActivity: '.activity.root.TournamentList'
        }
    @driver = Selenium::WebDriver.for(:remote, :desired_capabilities=>capabilities, :url=>server_url)
  end

  after(:each) do
    @driver.quit
  end

  it 'Check for homepage title', main_title: true do
    expect(@driver.find_element(:id, 'atpwta.live:id/NavBarTitleTextView').text).to eq 'ATP/WTA Live'
  end

  it 'Should check for Title', title: true do
    @driver.find_element(:xpath, "//android.widget.Spinner[@resource-id='atpwta.live:id/NavBarMainMenuSpinner']").click
    @driver.find_element(:name, 'Rankings').click
    @driver.find_element(:name, 'ATP Singles').click
    expect(@driver.find_element(:id, 'atpwta.live:id/NavBarTitleTextView').text).to eq 'Rankings'
  end

  it 'Should check for Rank 1 and corresponding Name', rank: true do
    @driver.find_element(:xpath, "//android.widget.Spinner[@resource-id='atpwta.live:id/NavBarMainMenuSpinner']").click
    @driver.find_element(:name, 'Rankings').click
    @driver.find_element(:name, 'ATP Singles').click
    expect(@driver.find_element(:id, 'atpwta.live:id/RankTV').text).to eq '1'
    expect(@driver.find_element(:id, 'atpwta.live:id/Player1TV').text).to eq 'Novak Djokovic'
  end

  it 'Should check for details for the Rank 1', rank_page: true do
    @driver.find_element(:xpath, "//android.widget.Spinner[@resource-id='atpwta.live:id/NavBarMainMenuSpinner']").click
    @driver.find_element(:name, 'Rankings').click
    @driver.find_element(:name, 'ATP Singles').click
    @driver.find_element(:id, 'atpwta.live:id/RankingItemViewRoot').click
    expect(@driver.find_element(:id, 'atpwta.live:id/NavBarTitleTextView').text).to eq 'Players'
  end

  it 'Should check the table contents and display them', rank_details: true do
    @driver.find_element(:xpath, "//android.widget.Spinner[@resource-id='atpwta.live:id/NavBarMainMenuSpinner']").click
    @driver.find_element(:name, 'Rankings').click
    @driver.find_element(:name, 'ATP Singles').click
    @driver.find_element(:id, 'atpwta.live:id/RankingItemViewRoot').click
    table = @driver.find_element(:class, 'android.widget.TableLayout')
    rows = table.find_elements(:class, 'android.widget.TableRow')
    table_contents = []
    rows.each do |row|
      cols = row.find_elements(:class, 'android.widget.TextView')
      cols.each do |col|
        table_contents.push(col.text)
      end
    end
    expect(table_contents.include? 'Belgrade, Serbia').to eq true
  end

  it 'Should take to previous menu/page', back: true do
    @driver.find_element(:xpath, "//android.widget.Spinner[@resource-id='atpwta.live:id/NavBarMainMenuSpinner']").click
    @driver.find_element(:name, 'Rankings').click
    @driver.find_element(:name, 'ATP Singles').click
    @driver.find_element(:id, 'atpwta.live:id/RankingItemViewRoot').click
    @driver.find_element(:name, 'Back').click
    expect(@driver.find_element(:id, 'atpwta.live:id/NavBarTitleTextView').text).to eq 'Rankings'
  end

end

Results:

android_result.png

Running Specific Test Cases:

android_specific_tc

Hope you enjoyed it!

RSpec, Capybara for Web Automation – Part II

Continuing the automation of the-internet, below is the updated Ruby Code and RSpec. Refer to this to learn more.

File: the_heroku_app.rb
class The_Heroku_App

  def start_browser
    @session = Capybara::Session.new (:selenium)
  end

  def tear_down
    @session.execute_script('window.close();')
  end

  def go_to(site)
    @session.visit site
  end

  def click_on_link(name)
    @session.click_link name
  end

  def checkbox_clicked?
    @session.find(:css, 'input:nth-child(1)[type="checkbox"]').checked?
  end

  def click_checkbox
    @session.find(:css, 'input:nth-child(1)[type="checkbox"]').click
  end

  def clear_checkbox
    @session.find(:css, 'input:nth-child(1)[type="checkbox"]').clear
  end

  def drag_and_drop_script
    dnd_javascript = File.read('C:\...Sachin_Test_Automation' + '\dnd.js')
    dnd_javascript+"$('#column-a').simulateDragDrop({ dropTarget: '#column-b'});"
  end

  def by_id(name)
    @session.find_by_id(name)
  end

  def find_all_drop_down
    #@session.select(option, from: 'dropdown')
    @session.find('#dropdown').all('option').collect(&:text)
  end

  def select_dropdown(x)
    @session.select(x, from: 'dropdown')
  end

  def switch_frames(parent, child)
    @session.within_frame(parent){@session.within_frame(child){@session.text}}
  end

  def single_frame(parent)
    @session.within_frame(parent){@session.text}
  end

end
File: the_heroku_spec.rb

require 'rspec'
require 'capybara'
require 'C:\...\the_heroku_app.rb'

RSpec.configure do |c|
  c.filter_run_excluding valid: true
  c.filter_run_excluding invalid: true
end

describe 'Verifying the components of the_heroku_app' do

  before(:each) do
    @cls_instance = The_Heroku_App.new
    @browser = @cls_instance.start_browser
    @cls_instance.go_to 'https://the-internet.herokuapp.com'
  end

  after(:each) do
    @cls_instance.tear_down
  end

  context 'Title and Body' do

    it 'Check for title of the page', page_title: true  do
      expect(@browser.title).to eq('The Internet')
    end

    it 'Check for the body of page', page_body: true  do
      expect(@browser).to have_content('Welcome to the Internet')
    end

  end

  context 'Checkbox' do

    it 'Verification of Checkbox', chk_box: true  do
      expect(@browser).to have_content('Welcome')
      @cls_instance.click_on_link 'Checkboxes'
      checkbox_1 = @cls_instance.checkbox_clicked?

      if !checkbox_1
        @cls_instance.click_checkbox
        expect(@cls_instance.checkbox_clicked?).to eq TRUE
      else
        @cls_instance.clear_checkbox
        expect(@cls_instance.checkbox_clicked?).to eq FALSE
      end
    end

  end

  context 'Credentials' do

    it 'Verify Basic Auth with VALID credentials', valid: true do
      @cls_instance.click_on_link 'Basic Auth'
      @browser.visit 'http://admin:admin@the-internet.herokuapp.com/basic_auth'
      expect(@browser).to have_content 'Congratulations! You must have the proper credentials.'
    end

    it 'Verify Basic Auth with INVALID credentials', invalid: true  do
      @cls_instance.click_on_link 'Basic Auth'
      @browser.visit 'http://admin:123@the-internet.herokuapp.com/basic_auth'
      expect(@browser).to have_content 'Not authorized'
    end

  end

  context 'Drag and Drop' do

    it 'Should drag and drop Column A to Column B', dnd: true  do
      @cls_instance.click_on_link 'Drag and Drop'
      @browser.execute_script(@cls_instance.drag_and_drop_script)
      expect(@cls_instance.by_id('column-a').text).to eq 'B'
      expect(@cls_instance.by_id('column-b').text).to eq 'A'
    end

  end

  context 'Dropdown box/Select box' do

    it 'Should select all options', drop_down: true  do
      @cls_instance.click_on_link 'Dropdown'
      values = @cls_instance.find_all_drop_down
      nw_vals = values[1..values.length]
      #results = [] #firefox
      #nw_vals.each {|x| results << @cls_instance.select_dropdown(x) == 'ok' ? true: false}#firefox
      #results.each{|x| expect(x).to eq 'ok'}#firefox
      nw_vals.each{|x| @cls_instance.select_dropdown(x)}
    end

  end

  context 'Upload a file' do

    it 'Should upload a file', upload_file: true do
      file = 'Hello.cpp'
      path = File.join(Dir.pwd, file)
      @cls_instance.click_on_link 'File Upload'
      upload_id = @cls_instance.by_id('file-upload')
      upload_id.send_keys path
      @browser.click_button 'Upload'
      uploaded = @cls_instance.by_id('uploaded-files').text
      expect(uploaded).to eq file

    end

  end

  context 'Switch between FRAMES' do

    it 'Should switch to LEFT frame and verify text', left_frame: true do
      @cls_instance.click_on_link 'Nested Frames'
      expect(@cls_instance.switch_frames('frame-top', 'frame-left')).to eq 'LEFT'
    end

    it 'Should switch to MIDDLE frame and verify text', middle_frame: true do
      @cls_instance.click_on_link 'Nested Frames'
      expect(@cls_instance.switch_frames('frame-top', 'frame-middle')).to eq 'MIDDLE'
    end

    it 'Should switch to RIGHT frame and verify text', right_frame: true do
      @cls_instance.click_on_link 'Nested Frames'
      expect(@cls_instance.switch_frames('frame-top', 'frame-right')).to eq 'RIGHT'
    end

    it 'Should switch to BOTTOM frame and verify text', bottom_frame: true do
      @cls_instance.click_on_link 'Nested Frames'
      expect(@cls_instance.single_frame('frame-bottom')).to eq 'BOTTOM'
    end

    it 'Should switch to LEFT frame and verify text', not_left_frame: true do
      @cls_instance.click_on_link 'Nested Frames'
      expect(@cls_instance.switch_frames('frame-top', 'frame-left')).not_to eq '123'
    end

    it 'Should switch to MIDDLE frame and verify text', not_middle_frame: true do
      @cls_instance.click_on_link 'Nested Frames'
      expect(@cls_instance.switch_frames('frame-top', 'frame-middle')).not_to eq 'CENTER'
    end

    it 'Should switch to RIGHT frame and verify text', not_right_frame: true do
      @cls_instance.click_on_link 'Nested Frames'
      expect(@cls_instance.switch_frames('frame-top', 'frame-right')).not_to eq 'LEFT'
    end

    it 'Should switch to BOTTOM frame and verify text', not_bottom_frame: true do
      @cls_instance.click_on_link 'Nested Frames'
      expect(@cls_instance.single_frame('frame-bottom')).not_to eq 'TOP'
    end

  end

end
The result after running the code:

Final

To be updated...

RSpec, Capybara for Web Automation

Why Automate?

Becuase manual testing is boring! Hmm, well in some case it is but we have to accept the fact that a lot of errors do happen when we have to test the same scenarios multiple times with different set of data and on different platforms running different browsers. Woah! that’s something to think about. But remember, automation is very useful only for repetitive tasks that rarely change and for those applications which need to be verified with a variety of datasets. No automation can replace manual testers in the case of exploratory testing and it is evident that any product without manual testing is difficult to trust upon and it is the humans who decide on what to automate and what not to!

automation-300x300

Let’s learn how to automate web applications. Today we have a lot of frameworks for web automation, to name a few famous ones: Selenium-webdriver, Watir-webdriver. And selenium forms the backbone for most of the frameworks.

We will consider Capybara which runs on selenium, RSpec for BDD and the website under test, the-internet, which has all the features necessary for an interactive web application.

Installation

Install Ruby and from the command line run

gem install capybara

Note: By default Capybara will only locate visible elements. This is because a real user would not be able to interact with non-visible elements.

Note: All searches in Capybara are case sensitive. This is because Capybara heavily uses XPath, which doesn’t support case insensitivity.

If you need to know about different frameworks and the methods to learn basics of Capybara then hit the site GitHub. But before we jump in automating the website, it is better to visit the site and explore manually once. Then go ahead, I will be waiting for you…

The Beginning

I believe you got an insight on the website and ready to automate. Wait! do we have any plan for how we are automating, I mean, do we need to follow any rules or just make some script which just automates the task at hand?. Well, that’s a valid question and an important thing to consider before automating any software.

Here, we will use ‘Page Object Model’, a way of grouping together the set of elements so as to keep the code clean and maintainable. If you wish to learn more about POM then I suggest you to Google it, as one can find tons of resource on the internet.

I have written a simple POM for the-internet website as given below. Here, I am imitating the human interaction with the website using Capybara and Ruby and verifying them using RSpec. I believe the below  code is self explanatory.

Create a Class file, 'the_heroku_app.rb':

class The_Heroku_App

  def start_browser
    # This will create a Capybara session and uses the default browser of firefox.
    @session = Capybara::Session.new (:selenium)
  end

  def tear_down
    @session.execute_script('window.close();')
  end

  def go_to(site)
    @session.visit site
  end

  def click_on_link(name)
    @session.click_link name
  end

  def checkbox_clicked?
    @session.find(:css, 'input:nth-child(1)[type="checkbox"]').checked?
  end

  def click_checkbox
    @session.find(:css, 'input:nth-child(1)[type="checkbox"]').click
  end

  def clear_checkbox
    @session.find(:css, 'input:nth-child(1)[type="checkbox"]').clear
  end

  # Save the file which was downloaded from GitHub, the below step will 
  # simulate the drag and drop functionality.
  def drag_and_drop_script
    dnd_javascript = File.read('C:\...\***_Test_Automation' + '\dnd.js')
    dnd_javascript+"$('#column-a').simulateDragDrop({ dropTarget: '#column-b'});"
  end

  def by_id(name)
    @session.find_by_id(name)
  end

  def find_all_drop_down
    @session.find('#dropdown').all('option').collect(&:text)
  end

  def select_dropdown(x)
    @session.select(x, from: 'dropdown')
  end

end

I have used RSpec as the testing framework and all the test scripts are run via RSpec. The scripts can be run as a complete suite or can be run individually using the ‘tags’. I will show how to use both.

Note:

  1. The ‘Basic Auth’ for invalid credentials scenario needs you to click, ‘Cancel’ when prompted for user/pass details. I want you guys to figure out on how to overcome this. (It’s easy tough!!)
  2. To simulate the ‘Drag and Drop’ functionality, I have used the javascript written by rcorreia.
Save the below code in a separate file called, 'the_heroku_spec.rb'

require 'rspec'
require 'capybara'
require 'C:\...\***_Test_Automation\the_heroku_app.rb'

describe 'Verifying the components of the_heroku_app' do

  # The before and after is run everytime for each test cases.
  before(:each) do
    @cls_instance = The_Heroku_App.new
    @browser = @cls_instance.start_browser
    @cls_instance.go_to 'https://the-internet.herokuapp.com'
  end

  after(:each) do
    @cls_instance.tear_down
  end

  context 'Title and Body' do

    it 'Check for title of the page', page_title: true  do
      expect(@browser.title).to eq('The Internet')
    end

    it 'Check for the body of page', page_body: true  do
      expect(@browser).to have_content('Welcome to the Internet')
    end

  end

  context 'Checkbox' do

    it 'Verify Checkbox by clicking', chk_box: true  do
      expect(@browser).to have_content('Welcome')
      @cls_instance.click_on_link 'Checkboxes'
      checkbox_1 = @cls_instance.checkbox_clicked?

      if !checkbox_1
        @cls_instance.click_checkbox
        expect(@cls_instance.checkbox_clicked?).to eq TRUE
      else
        @cls_instance.clear_checkbox
        expect(@cls_instance.checkbox_clicked?).to eq FALSE
      end
    end

  end

  context 'Credentials' do

    it 'Verify Basic Auth with VALID credentials', valid: true do
      @cls_instance.click_on_link 'Basic Auth'
      @browser.visit 'http://admin:admin@the-internet.herokuapp.com/basic_auth'
      expect(@browser).to have_content 'Congratulations! You must have the proper credentials.'
    end

    it 'Verify Basic Auth with INVALID credentials', invalid: true  do
      @cls_instance.click_on_link 'Basic Auth'
      @browser.visit 'http://admin:123@the-internet.herokuapp.com/basic_auth'
      expect(@browser).to have_content 'Not authorized'
    end

  end

  context 'Drag and Drop' do

    it 'Should drag and drop Column A to Column B', dnd: true  do
      @cls_instance.click_on_link 'Drag and Drop'
      @browser.execute_script(@cls_instance.drag_and_drop_script)
      expect(@cls_instance.by_id('column-a').text).to eq 'B'
      expect(@cls_instance.by_id('column-b').text).to eq 'A'
    end

  end

  context 'Dropdown box/Select box' do

    it 'Should select all options', drop_down: true  do
      @cls_instance.click_on_link 'Dropdown'
      values = @cls_instance.find_all_drop_down
      nw_vals = values[1..values.length]
      results = []
      nw_vals.each {|x| results << @cls_instance.select_dropdown(x) == 'ok' ? true: false}
      results.each{|x| expect(x).to eq 'ok'}
    end

  end


end

Run the complete Suite of test cases:

complete_suite

Run particular test case from the suite (use 'tag'):

individual_test_case


If you want to exclude few of the test cases from the suite then add the below code in your RSpec,
above the 'describe':

RSpec.configure do |c|
  c.filter_run_excluding valid: true
  c.filter_run_excluding invalid: true
end
describe 'Verifying the components of the_heroku_app' do

  before(:each) do
    @cls_instance = The_Heroku_App.new
    @browser = @cls_instance.start_browser
    @cls_instance.go_to 'https://the-internet.herokuapp.com'
  end
.
.
.
.

When you run the RSpec it will skip those test cases which you have specified with the tag name.

rspec_exclude

Test Result:

Test_result

Note: Post will be updated...

Continuing on rspec…

As we have seen in the previous post on a simple rspec, it consists of keywords like, ‘describe’, ‘context’, ‘it’, ‘expect’ etc. Let’s try to understand each of them:

describe: It is a keyword which describes the class under test. For example, if we have a class by the name ‘Zoom’ then we can write:

describe Zoom do        
  ...                  
end                     

[OR]

describe "test suites for class zoom" do
  ...
end

context: This is used to have a group of test cases in the same view. Like one can group a set of valid test cases by categorizing them into groups of ‘valid’, ‘invalid’ etc.

context "Set of valid test data" do
  ...
end

it: This is where we write our test scripts for verifying the class under test.

it "is expected to return 'true' after execution" do
  ...
end

expect: The keyword ‘expect’ takes an argument called ‘actual’ value and compares it with the expected value.

expect('<return_value'>).to eq('<expected_value>')

Now let us try to write a new ruby class called ‘Zombie’ in a new file called ‘zombie.rb’that consists of below details:

class Zombie
  attr_accessor :name, :age, :str, :num

  def initialize
    puts "\n New instance of Zombie..."
    @name = "zom"
    @age = 2
  end

  def wish_me(tes)
    "Hello #{tes}"
  end

  def am_i_vowel?(str)
    !!(str =~ /[aeiou]+/i)
  end

  def am_i_greater?(num)
    num > 10 ? true:false
  end
end

Let us write an rspec to test this class and its methods. Create a new file called 'zombie_spec.rb' and fill in the below details:

require 'rspec'
require 'zombie'

describe Zombie do

  before(:each) do
    @class_instance = Zombie.new
  end

  context 'check name and wish_me' do
    #it 'is named zom', :slow => true do
    it 'is named zom', slow: true do
      #zombie = Zombie.new
      #expect(zombie.name).to eq('zom')
      #expect(zombie.age).to eql 2
      #sleep 20
      expect(@class_instance.name).to eq 'zom'
      expect(@class_instance.age).to eq 2
    end

    it 'Tell Zombie to wish_me' do
      #zombie = Zombie.new
      #msg = zombie.wish_me('Ron')
      #expect(msg).to eq('Hello Ron')
      msg = @class_instance.wish_me('Ron')
      expect(msg).to eq 'Hello Ron'
    end
  end

  context 'check if string has vowels' do
    it 'should have vowels' do
      #g = Zombie.new
      #expect(g.am_i_vowel?('Testing')).to be true
      expect(@class_instance.am_i_vowel?('Testing')).to be true
    end

    it 'Should not have VOWELS' do
      #g = Zombie.new
      #expect(g.am_i_vowel?('tyrp')).to be false
      expect(@class_instance.am_i_vowel?('typ')).to be false
    end
  end

  context 'Check if a number is greater than 10' do
    it 'The number should be grater than 10' do
      #number = Zombie.new
      #expect(number.am_i_greater?(5)).to be false
      expect(@class_instance.am_i_greater?(5)).to be false
    end
  end
end

I am using 'RubyMine' IDE to run the code. Below is the output after running the zombie_spec.rb:

      Testing started at 7:57 PM ...

        New instance of Zombie...

        New instance of Zombie...
        New instance of Zombie...

        New instance of Zombie...

        New instance of Zombie...

      5 examples, 0 failures, 5 passed

      Finished in 0.046516 seconds

      Process finished with exit code 0

Learning rspec!

In this blog, we will learn about rspec, a BDD (Behavioural Driven Development) for the Ruby Programming language. It is easy to learn and any person with some programming background can follow it.

Make sure you have Ruby installed.

Follow the below steps to install the rspec gem.

  • Open ‘git bash’.
  • Enter ‘gem install rspec’, it will automatically install all the dependencies.
  • Enter ‘rspec -v’ to see the version.
  • Make a folder, say ‘/Ruby_Testing’ and inside this folder create another folder called ‘spec’.
  • Create a small Hello-world class in Ruby as shown below.
Create a Ruby class called, 'hello_world.rb' with below content in it:

class Hello_World
  def say_hello
    "Hello World"
  end
end

Create another Ruby file called, 'hello_spec.rb' and fill in with:

require 'rspec'
require 'C:\..\..\Desktop\Temporary\spec\hello_spec'

describe Hello_World do
  it "when say_hello function is called, it should say Hello World" do
    wish = Hello_World.new
    expect(wish.say_hello).to eq "Hello W0rld"
  end
end

Now let's run the above code from gitbash command line:

rspec --format doc <test_spec.rb>

The above command will give the detailed output of the test result.

Failing_rspec

Now let's correct it and re-run the program:
require 'rspec'
require 'C:\..\..\Desktop\Temporary\spec\hello_spec'

describe Hello_World do
  it "when say_hello function is called, it should say Hello World" do
    wish = Hello_World.new
    expect(wish.say_hello).to eq "Hello World"
  end
end

Now we get the correct result:

Correct_rspec.png