README
Autokin (Automation by Gherkin)
This is a simple package/library that helps tester to do automation of REST/API using Gherkin without knowing JavaScript coding. All you need to know is Gherkin and you can start working and creating automated test for contract testing, or simple API test.
Mobile testing through Appium introduced starting in v1.9.0
. Basic connection, navigation, and interaction are added to perform series of test on mobile applciations. See documentation for more detailed steps.
Introduced in v1.8.0
, Autokin now supports web based automation using Puppeteer. You may now create Gherkin based test that targets browser application.
One of the simplest item that we do not want to missed is to break contract of front end apps to our service apps. To make sure that we can detect this easy and early on we want the following:
:thumbsup: Validate each endpoints response schema.
:thumbsup: Validate possible response data.
:thumbsup: Validate data fetch with authentications.
:thumbsup: Enable chanining of multiple endpoint calls.
:thumbsup: Validate HTTP status code and header data.
:thumbsup: Ability to drive test using data.
:thumbsup: Supports data generation for inputs.
:thumbsup: Easy to write and not too technical.
:thumbsup: Easy to integrate with CI/CD environment.
:thumbsup: Supported with generated test reports.
If these are something you need then Autokin can help you on that. Explore!
What's New
- Ability to perform test om Mobile application through Appium server
- Ability to perform test on Web application using Puppeteer
- Ability to test response JSON Data against JSON Schema (https://json-schema.org/). See example.
- Allow pre-define variable set that can be loaded use within features
- Autokin Generators: Ability to generate data randomly or based on certain list
Creating an Autokin Project
Make a project folder
mkdir my-autokin-project
Name the folder anything that you see fit. Before proceeding to next step make sure that you are inside the new folder.
cd my-autokin-project
Next, let us install Autokin.
Install Autokin
You can simple do it by:
npm install autokin --save-dev
That simple, and now we are ready to create our first project.
Creating a project
To create a new Autokin project, run the following command.
./node_modules/.bin/autokin -i
This will create the necessary folder structure and sample files.
my-autokin-project
├── features
| ├── support
| ├── steps.js
|
└── first.feature
Let's run the test!
Running the test
Simply, issue the command below to run the test.
./node_modules/.bin/autokin -e
It should have the following output:
./node_modules/.bin/autokin -e
Autokin Test Run
Feature: My Feature > My First Scenario - ✔ Passed
Test Result Summary
┌────────────┬────────┬───────────┬───────┐
│ Features │ Result │ Scenarios │ Steps │
├────────────┼────────┼───────────┼───────┤
│ My Feature │ --- │ 1 │ 0 │
└────────────┴────────┴───────────┴───────┘
┌────────────────────────┬────────┬───────┬────────┬────────┬─────────┬─────────┬───────────┬─────────┐
│ Features / Scenarios │ Result │ Steps │ Passed │ Failed │ Skipped │ Pending │ Ambiguous │ Unknown │
├────────────────────────┴────────┴───────┴────────┴────────┴─────────┴─────────┴───────────┴─────────┤
│ My Feature │
├────────────────────────┬────────┬───────┬────────┬────────┬─────────┬─────────┬───────────┬─────────┤
│ My First Scenario │ --- │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │
└────────────────────────┴────────┴───────┴────────┴────────┴─────────┴─────────┴───────────┴─────────┘
Runtime Options
Options | Shortkey | Description |
---|---|---|
--version |
-V |
Display version number |
--init |
-i |
Initialised new Autokin project structure |
--specs [path] |
-s |
Specify path location of features, --specs myfeatures |
--exec |
-e |
Execute automation test |
--tags [tags] |
-t |
Use with --exec to specify which tags to run, example:"@autokin" |
--junit |
-j |
Output additional result file in JUnit format |
--time |
-d |
Display duration execution for each steps |
--formatter [cucumber-formatter] |
-f |
Use with --exec to specify custom cucumber formatter |
--variable [file-path] |
-v |
Use with --exec to specify variable set from json file |
--html [file-path] |
-w |
Generate test result in html file format using Autokin HTML Formatter |
--help |
-h |
Output usage in console |
--clean |
-c |
Deletes existing reports and snapshots before running new test. |
Creating your first REST Gherkin
For example we do have an endpoint as https://reqres.in/api/users/2, which is to fetch a user information. So let's start writing our Feature and Scenario, open the first.feature
file that was previously generated. The file should have the following content:
@autokin
Feature: My Feature
As Autokin tester
I want to verify that all API are working as they should
Scenario: My First Scenario
Now I want to say that I want to access the endpoint:
@autokin
Feature: My Feature
As Autokin tester
I want to verify that all API are working as they should
Scenario: My First Scenario
Given that a secure endpoint is up at reqres.in
When I GET /api/users/2
We added 2 lines, first we define that we want to access a secure (https) endpoint at the domain reqres.bin
. Then on the second line, we said that we want to do a GET
to /api/users/2
.
At this point we already access the endpoint, and we can run test.
./node_modules/.bin/autokin -e
Autokin Test Run
Feature: My Feature > My First Scenario - ✔ Passed
Test Result Summary
┌────────────┬────────┬───────────┬───────┐
│ Features │ Result │ Scenarios │ Steps │
├────────────┼────────┼───────────┼───────┤
│ My Feature │ 100 │ 1 │ 2 │
└────────────┴────────┴───────────┴───────┘
┌────────────────────────┬──────────┬───────┬────────┬────────┬─────────┬─────────┬───────────┬─────────┐
│ Features / Scenarios │ Result │ Steps │ Passed │ Failed │ Skipped │ Pending │ Ambiguous │ Unknown │
├────────────────────────┴──────────┴───────┴────────┴────────┴─────────┴─────────┴───────────┴─────────┤
│ My Feature │
├────────────────────────┬──────────┬───────┬────────┬────────┬─────────┬─────────┬───────────┬─────────┤
│ My First Scenario │ ✔ Passed │ 2 │ 2 │ 0 │ 0 │ 0 │ 0 │ 0 │
└────────────────────────┴──────────┴───────┴────────┴────────┴─────────┴─────────┴───────────┴─────────┘
Let's add some test on it. We know that the endpoint will return a 200 status code. Let us add that as verification item, but instead of 200 we expect 400 for it to generate an error. We add the new step after the When
.
Scenario: My First Scenario
Given that a secure endpoint is up at reqres.in
When I GET /api/users/2
Then response status code should be 400
Yes, it should be that sentence, we can only change the value that we expect. Let's run the test again.
./node_modules/.bin/autokin -e
Autokin Test Run
Feature: My Feature > My First Scenario - ✖ Failed
Test Result Summary
┌────────────┬───────────────────┬───────────┬───────┐
│ Features │ Result │ Scenarios │ Steps │
├────────────┼───────────────────┼───────────┼───────┤
│ My Feature │ 66.66666666666666 │ 1 │ 3 │
└────────────┴───────────────────┴───────────┴───────┘
┌────────────────────────┬──────────┬───────┬────────┬────────┬─────────┬─────────┬───────────┬─────────┐
│ Features / Scenarios │ Result │ Steps │ Passed │ Failed │ Skipped │ Pending │ Ambiguous │ Unknown │
├────────────────────────┴──────────┴───────┴────────┴────────┴─────────┴─────────┴───────────┴─────────┤
│ My Feature │
├────────────────────────┬──────────┬───────┬────────┬────────┬─────────┬─────────┬───────────┬─────────┤
│ My First Scenario │ ✖ Failed │ 3 │ 2 │ 1 │ 0 │ 0 │ 0 │ 0 │
└────────────────────────┴──────────┴───────┴────────┴────────┴─────────┴─────────┴───────────┴─────────┘
As expected it will generate an error. Fixing the expected value to 200 and running the test will have a clean successful run.
Scenario: My First Scenario
Given that a secure endpoint is up at reqres.in
When I GET /api/users/2
Then response status code should be 200
Yes, it should be that sentence, we can only change the value that we expect. Let's run the test again.
./node_modules/.bin/autokin -e
Autokin Test Run
Feature: My Feature > My First Scenario - ✔ Passed
Test Result Summary
┌────────────┬────────┬───────────┬───────┐
│ Features │ Result │ Scenarios │ Steps │
├────────────┼────────┼───────────┼───────┤
│ My Feature │ 100 │ 1 │ 3 │
└────────────┴────────┴───────────┴───────┘
┌────────────────────────┬──────────┬───────┬────────┬────────┬─────────┬─────────┬───────────┬─────────┐
│ Features / Scenarios │ Result │ Steps │ Passed │ Failed │ Skipped │ Pending │ Ambiguous │ Unknown │
├────────────────────────┴──────────┴───────┴────────┴────────┴─────────┴─────────┴───────────┴─────────┤
│ My Feature │
├────────────────────────┬──────────┬───────┬────────┬────────┬─────────┬─────────┬───────────┬─────────┤
│ My First Scenario │ ✔ Passed │ 3 │ 3 │ 0 │ 0 │ 0 │ 0 │ 0 │
└────────────────────────┴──────────┴───────┴────────┴────────┴─────────┴─────────┴───────────┴─────────┘
Targetting Test with Tags
Let say I have now several features like the two examples below:
my-first-feature.feature
@core
Feature: My Feature
As Autokin tester
I want to verify that all API are working as they should
Scenario: My First Scenario
Given that a secure endpoint is up at reqres.in
When I GET /api/users/2
The above feature file we tag that as @core
feature, while below we tag that as @fix-321
to denote that this is for the fix for 321 issue
.
my-second-feature.feature
@fix-321
Feature: My Feature
As Autokin tester
I want to verify that all API are working as they should
Scenario: Verify if API does not accept character id
Given that a secure endpoint is up at reqres.in
When I GET /api/users/abc
So now we want to run the test but only focus on running @fix-321
. WE can do this by using the following command.
./node_modules/.bin/autokin -e -t @fix-321
If we want to run only @core
then we can use the following:
./node_modules/.bin/autokin -e -t @core
If we are nto passing the tags -t
or --tags
parameter, it will run everything.
What if we want to run everything but not the @core
, then we can also use the following command:
./node_modules/.bin/autokin -e -t "not @core"
See more about tags.
Chaining
Chaining is a way to continue another test that was previously executed. This is some how the nearest to chaining scenarios for Autokin. Let us say that you want to Login the user then use the session token to retrieve user information.
POST https://www.autokinjs.com/login
Headers:
Content-Type: application/json
{
"username": "juan",
"password": "p3dr0"
}
Response:
{
"sessionId": "2AA21boNhOM5zR3Xgn96qw=="
}
GET https://www.autokinjs.com/user/1001
Headers:
Content-Type: application/json
SessionId: 2AA21boNhOM5zR3Xgn96qw==
Response:
{
"id": 1001,
"name": "Juan Pedro",
"age": 30
}
So having that we can have this Feature definition:
@chaining
Feature: My Chaining Feature
As Autokin tester
I want to verify that all API are working as they should
Scenario: Login to the system
Given that a secure endpoint is up at www.autokinjs.com
Given I set Content-Type header to application/json
Given I set the JSON body to
"""
{
"username": "juan",
"password": "p3dr0"
}
"""
When I POST /login
Then response status code should be 200
Then I keep the value of body path "$.sessionId" as "userSessionToken"
Scenario: Get user information
Given that a secure endpoint is up at www.autokinjs.com
Given I set Content-Type header to application/json
Given I set SessionId header from "userSessionToken"
When I GET /user/1001
Then response status code should be 200
As you see in the above example, we login then we store the session token to a variable userSessionToken
, the variable name can be anything as long as a one word. Following to our next scenario, as needed by our API, we set the header SessionId
to the value of the previously stored data by sepcifying that we are getting the stored value from the variable userSessionToken
.
JSON Schema Comparison
It is important that contracts among consumer of the API ensure that the data expected are always correct. With this JSON Schema comparison, we can add assertion on the response data if it conforms to expected schema. We can store the schema to a file and use that as expected schema.
GET https://reqres.in/api/users?page=2
Response:
{
"page": 2,
"per_page": 3,
"total": 12,
"total_pages": 4,
"data": [
{
"id": 4,
"email": "eve.holt@reqres.in",
"first_name": "Eve",
"last_name": "Holt",
"avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/marcoramires/128.jpg"
},
{
"id": 5,
"email": "charles.morris@reqres.in",
"first_name": "Charles",
"last_name": "Morris",
"avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/stephenmoon/128.jpg"
},
{
"id": 6,
"email": "tracey.ramos@reqres.in",
"first_name": "Tracey",
"last_name": "Ramos",
"avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/bigmancho/128.jpg"
}
]
}
Expected Login Response Schema
feature/schema/reqres-response-schema.json
{
"definitions": {},
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://example.com/root.json",
"type": "object",
"title": "The Root Schema",
"required": [
"page",
"max_page",
"per_page",
"total",
"total_pages",
"data"
],
....
"items": {
"$id": "#/properties/data/items",
"type": "object",
"title": "The Items Schema",
"required": [
"id",
"email",
"first_name",
"last_name",
"avatar"
],
"properties": {
"id": {
"$id": "#/properties/data/items/properties/id",
"type": "string",
"default": 0,
"pattern": "^(.*)