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
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.
What Is the Difference between QA and QC/Software Testing
If you work in IT or, at least, had any experience in this area, you definitely know that there are multiple terms to define the testing world. The biggest competitors here are QA (Quality Assurance) and QC (Quality Control) which is basically the same as Software Testing.
Let's see how these are defined:
Quality Assurance (QA) is a part of quality management focused on providing confidence that quality requirements will be fulfilled. [ISO 9000]
Quality Control/Testing is a process that consisting of all the life cycles activities, both static and dynamic, concerned with planning, preparing and evaluating software products and related work products. It tries to determine if they satisfy specified requirements in order to demonstrate that they are fit for purpose and to detect defects. [ISTQB glossary]
Quality Assurance
This is about process oriented and preventive activities. It means that these activities are focused on improving the software development process and that the system will meet its objectives. The QA Engineer is active throughout the product’s lifecycle and communicates with all the people involved in the process, from Project Manager to Software Developer and QC Engineer. The QA analyses and seeks the continuous improvement of both process and product while ensuring all tasks demonstrate appropriate quality and that are finished on time.
Quality Control/Software testing
Well, this is about product orientated activities and it is a corrective process (testing is a process rather than a single activity - there are a series of activities involved). The QC Engineer must find bugs in the system before users do, investigate and report on how well the software performs relative to its expectations and is generally active at the end of a coding cycle.
Conclusions
QA and QC both have to make the software better, however, QA is about process orientated and preventive activities, while QC involves a corrective process and product orientated activities.