writing tests in Ruby

Start writing tests in Ruby: useful gems

Being a QA engineer is a continuous struggle in finding the right resources in order to get the job done easier and more efficiently. If you are planning to write automated tests in RSpec (Ruby's testing framework), then you should take a look over these gems. Please notice that I am most of the time automating backend tests only, so the libraries I am using are for this purpose mainly.

 

1. RestClient

 

gem install rest-client

If you want to make API calls on RESTful endpoints this should definitely be your choice. This library is easy to use and the response includes code, cookies, headers and body.

Let me show you how to make some calls (GET, PUT, POST, DELETE):

response = RestClient.get(url, header){|response, request, result | response}
response = RestClient.put(url, payload, header){|response, request, result | response}
response = RestClient.post(url, payload, header){|response, request, result | response}
response = RestClient.delete(url, header){|response, request, result | response}

Now you simply use this response for your purposes (response.code, response.body, etc.).

 

2. JSON

 

gem install json

If I told you about RestClient, then the next one should be json. RESTful services will return JSON format in body most of the times so you should parse that response to be easier to work with.

response = RestClient.post(url, payload, header){|response, request, result | response}
parsed_response = JSON.parse(response.body)
expect(parsed_response['errors'][0]['message']).to eq "Not Found"

See how simple this is? You only JSON.parse that response and that's all!

Since we are talking about JSON, let me show you how to build one:

payload_hash = {
            :key1 => :value1,
            :key2 => :value2
        }
payload_json = payload_hash.to_json

 

3. Nokogiri

 

JSON and XML are the most used formats in web development. So you probably guessed that now I will show you some tricks on how to use XML in your awesome tests.

gem install nokogiri

When I have installed this gem on my ubuntu (v14.04) virtual machine, I have had the following error:

ERROR: Error installing nokogiri:
ERROR: Failed to build gem native extension.

/usr/bin/ruby1.9.1 extconf.rb
/usr/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require': cannot load such file -- mkmf (LoadError)
from /usr/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
from extconf.rb:4:in `'

But this was quickly fixed after installing ruby-dev and ruby1.9.1-dev:

sudo apt-get install ruby-dev
sudo apt-get install ruby1.9.1-dev

Now let's say you have the following XML:

<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
    <Body>
        <Login>
            <username>username</name>
            <password>secret_password</password>
        </Login>
    </Body>
</Envelope>

If you want to access the values for username and password, simply do this:

your_file = Nokogiri::XML(your_XML_file)
your_file.remove_namespaces!
puts your_file.css('username').text
puts your_file.css('password').text

Also, you can use xpath instead of css.

Let me show you how to build the previous XML file using Nokogiri:

builder = Nokogiri::XML::Builder.new do |xml|
  xml.Envelope {
    xml.Body {
      xml.Login {
        xml.username "username"
        xml.password "secret_password"
      }
    }
  }
end
puts builder.to_xml

 

4. Sinatra

 

This gem is used to mock endpoints. See more about it here.

 

5. Dotenv

 

gem install dotenv

It is recommended to keep environment variables and stuff like usernames, passwords and URLs in a .env file. In order to load those variables in your tests, you must use this gem.

Dotenv.load

login_url = ENV['VAR_NAME']
signup_url = ENV['VAR_NAME']

First you load the .env file, then use those variables in your tests.

 

6. Mysql

 

gem install mysql

The name itself says what this is used for. See below how to open a connection to a MySql database and do a simple operation:

con = Mysql.new(db_host, db_user, db_pass, db_schema, db_port)

rs = con.query("UPDATE table_references SET col_name1= ... WHERE where_condition")

con.close

 

I will update this post when I will use some new awesome Ruby library. What gems are you using?


How To Mock Endpoints in Automated Acceptance Tests

The purpose of acceptance testing is to reproduce production environment as much as possible in order to evaluate the software in a 'real-world' situation similar to what the customers will experience and this includes using real endpoints.

But using real endpoints has some disadvantages. In automated acceptance tests, the endpoint will be stressed out and this is not performance testing. Also, you must use production data (even usernames and passwords) and this is not good because you might break something there. The list with the reasons could go on and on and this is why you should mock some endpoints in automated acceptance tests. Also, you should keep your endpoint's URL stored in environment variables to be able to change it easily (production URL or mock URL).

I will show you some basic examples of mocking endpoints written in Ruby, Python and GO.

Mock endpoint in Ruby

I have used Sinatra (DSL for quickly creating web applications in Ruby) which is very easy to use.

Install the gem:

gem install sinatra

#myapp.rb

require ‘json’
require ‘sinatra’

get '/:username' do
  if params[:username] != 'your_username'
  	status 404
  else
  	content_type :json
  	{'message' => 'success'}.to_json
  end
end

 

ruby myapp.rb -o 0.0.0.0 -p 5000 > /dev/null 2>&1 &

This will start the process in background and your endpoint on http://localhost:5000.

If you make a GET request on http://localhost:5000/your_username you will get a ‘success’ message, else a 404 status code.

Mock endpoint in Python

In Python it is very easy to create an endpoint with Flask.

To install it you have to run:

pip install flask-restful

#myapp.py

#!flask/bin/python
from flask import Flask, jsonify
from flask import Response
import json

app = Flask(__name__)

@app.route("/<username>", methods=['GET'])
def put_username(username):
    if username == 'your_username':
        resp = Response("success!\n", mimetype='application/json')
    else:
        resp = Response("", status=404, mimetype='application/json')

    return resp

if __name__ == '__main__':
    app.run(debug=True)

 

As you can see, this does the exact same thing as the endpoint created in Ruby.

You simply run it with

python myapp.py

Mock endpoint in GO

//myapp.go
package main

import (
	"fmt"
	"net/http"
	"github.com/julienschmidt/httprouter"
)

func username(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
	if p.ByName("username") == "your_username" {
		w.Header().Set("Content-Type", "application/json")
		w.WriteHeader(200)
		fmt.Fprint(w, `{"message":"success"}`)
	} else {
		w.WriteHeader(404)
	}
}

func main() {
	r := httprouter.New()
	r.GET("/:username", username)
	http.ListenAndServe("localhost:5000", r)
}

This does the same thing as the previous two endpoints and you run it with:

go run myapp.go

Thanks for reading this. What other ways of mocking an endpoint did you find?


How to Fix Common Errors When Testing in RSpec

How to Fix Common Errors When Testing in RSpec

If you are a Software Test Engineer or Quality Control Engineer and you want to automate your API call tests, then you should try RSpec (Ruby's testing framework). I didn’t exactly chose it (the QC team was already using it), but I tend to believe that I would have picked it in the future for my own tests because when it comes to the installation of the program, the process is not that complicated at all.

How to Fix Common Errors When Testing in RSpec

Actually, let me show you how little you need to do in order to start writing your own tests:

gem install rspec
rspec --init

Yep, that’s all. Now you can automate your tests and run them with the following command:

rspec your_test_suite.rb

I will now show you some common error messages that I've encountered, so that you can avoid them during your work. These errors are caused by very small mistakes, but usually in the rush of delivering quality we skip some things or words.

 

1. syntax error, unexpected keyword_end, expecting end-of-input (SyntaxError)

Let’s take a look at the following examples:

describe 'Test Suite' 
   it 'Validate successful response' do
      response = RestClient.get('www.intelligentbee.com')
      expect(response.code).to eq(200)
   end
end
describe 'Test Suite' do
   it 'Validate successful response' 
      response = RestClient.get('www.intelligentbee.com')
      expect(response.code).to eq(200)
   end
end

So, if you get the above error, you most probably forgot to put a ‘do’ after ‘describe’ or ‘it’ methods.

 

2. syntax error, unexpected end-of-input, expecting keyword_end (SyntaxError)

I will use the same example again:

describe 'Test Suite' do
   it 'Validate successful response' do
      response = RestClient.get('www.intelligentbee.com')
      expect(response.code).to eq(200)
   
end

What is wrong with this? Well, I missed an ‘end’. I’ll take it you can figure out by yourself where it should be placed.

 

3. JSON::ParserError: 757: unexpected token

Take a look:

describe 'Test Suite' do
   it 'Validate successful response' do
      response = RestClient.get('www.intelligentbee.com')
      parsed_response = JSON.parse(response)
      expect(parsed_response['message']).to eq "Some message"
   end
end

Supposedly, sometimes you will get as an answer a JSON and you will want to parse it for better tests. You will get the above error if the answer is not a JSON and the parser can’t find there what it expects.

I hope you will find this short guide useful, I plan to continue writing about common errors that we may encounter while using RSpec.


How to (Easily) Debug a Rails Application

Hello all you party people! This article will show you how you can easily debug your Rails code.
If you're using the default Rails Rack server, Webrick - the best debugging tool I've been able to find out there is pry. Its use is pretty straightforward:

First off you'd need to add the pry gem to your Gemfile. Since this is used for development purposes, it should be added in the :development group:Read more


How I Came to Love Ruby

It wasn’t so long ago that I had no idea how everything worked in world of WWW. But that all changed when I got a technical support job at IntelligentBee. Working in a web development company (even though your job doesn’t have any tangency to the actual development role) opens a whole set of learning opportunities that will ultimately describe a whole new wonderful world. From that point on, my task was pretty simple: be curious about how stuff works and don’t be afraid to ask questions.

How I Came to Love Ruby

Why Ruby ? It's incredibly similar to English. Yes, to the actual English language. Read more


Create a mailer in Rails 4

Create a mailer in Rails 4

Hello party people and polar bears! You were probably wondering how it is you send email using Ruby on Rails. Here's how you create an automated email system that sends a confirmation email to each new user that registers to your app:Read more


Setup A Simple Ruby 2 On Rails 4 Environment With Vagrant And Virtual Box

Ruby 2 on rails 4 environment

Since a developer time is most valuable when dealing with actual ... development tasks, setting up the environment for a new project better take less or no time, so that the developer can focus on building the actual product rather than focusing on setting up things.Read more