1.3.1 • Published 4 years ago

teakozi v1.3.1

Weekly downloads
1
License
ISC
Repository
github
Last release
4 years ago

npm version Build Status

Teakozi

Teakozi is a declarative REST API testing framework for testing micro-services. Here are the capabilities.

  • Writing tests as readable YML files
  • Externalize the configuration / environment specific parameters
  • Dynamic Data - Collect Property and use it in subsequent steps.
  • Scenario based testing. Externalize the test data and validation data from test specification
  • Reuse API calls in multiple tests
  • Validate response schema as per Swagger definitions
  • Library extensions

How to use Teakozi

  • include teakozi in your node application
$ npm install teakozi

create a directory in your project consisting of the following subdirectories

DirectoryPurpose
testscontains the yml files that describe the tests. You can arrange the test yml files in any suitable folder hiererchy. the framework will get all yml files in directory under this tree and ignore all the non .yml files
modulesreusable test steps that can be refered in the test yml file
modelsexternalize the data to drive the tests
configjust one index.js file
payloadthe body of the content that can be called in a post step. This folder also contains the json payload against which you need to validate your responses.

config/index.js

This file contains 1. key value for replacing in the test yml files. 2. The index file can optionally have a tag called swagger pointing to the location of the swagger file from project home directory. 3. Also has extension functions that can be defined and used in the test definition. Take a look at section library functions below. 4. sync flag - whether the test should run sync / async. please refer to section sync / async as the behavior is dependent on test sync attribute and config sync attribute

see the example folder in the repo for reference. you need to update the config/index.js with your github auth to

Externalize data from tests

Teakozi allows you to externalize the data from test definition

Reusable modules

you can refer to the steps in the module as - {{module name}}

Configuration data

{{xxx}} marked content gets replaced from the configuration file keys-> value

Dynamic data

you can collect data in a step and reuse in the subsequent steps. so you can collect title and refer it in subsequent steps like ~title~

Library Functions

Add library functions in your config/index.js file as follows

Sync / Async calling

sync tag can be applied at the config level and also at file level. the framework will execute the test in the following manner |SYNC|Config true|Config false|Config undefined| | - | - |-|-| |Test - true|Sync|Sync|Sync| |Test- false|Sync|Async|Async| |Test - undefined|Sync|Async|Sync|

This behavior is subject to change based on user feeback. Current phillosophy - default to sync when not explicit

module.exports = {
  swagger:'/config/swagger.yml',
  lib:{
    increment : function(i){return ++i},
    decrement : function(i){return --i}
  }
};

you can now use the increment and decrement functions while collecting the parameters from response. example

    collect:
     incremeted_id: increment->$.order[0].id
    print:
     - $.order[0].id
     - incremeted_id

Calling the tests from your node app

in a .js file call

require("teakozi").start("project/example")

Structure of a test yml file (tests directory)

PropertyrequiredtypePurpose
namerequiredstringName of the Test Case
tagsoptionalstringcomma saperated list of tags for the test. you can use thse tags to filter / select the test you would like to take for a test run
syncoptionalboolWhether the test should run sync / async. please refer to section sync / async as the behavior is dependent on this and config sync flag
iterateoptionalstringName of the module file that returns an array of objects. The test steps defined will be repeated for all the elements of this array
stepsrequiredarraySee Steps Section

Steps

PropertyrequiredtypePurpose
get / post / put / delete / local / mongorequiredobjectmethod to be called
namerequiredstringName of the Test Step
delayoptionalint,intDelay in seconds to start this step. Optionally separated by comma, you can specify how may times should you loop before giving up. Example 3,5 means do the step after 3 seconds delay. if fails then retry for 5 times every 3 seconds. if passing move to next step
iterateoptionalstringname of the module that returns array of objects. the call will get repeated for each of the members of the returned array
checkrequiredobjectwhat to do with the response received. What asserts to do and what properties to pick from the response to be used in subsequent calls
collectoptionalobjectthe jsonpaths values that should be collected for use in subsequent calls.
printoptionalarraythe jsonpaths values that should be printed on the console output for debugging purposes
saveoptionalobjectthe jsonpaths values that should be saved and the file name where it should be saved example : $: my_response_content The files are saved in the generated folder on the project
skip_on_erroroptionalboolDefault: true. If entered false, it will execute the step even if the previous steps have failed. Can be used to do cleanup / teardown activities

get / post / put / delete

PropertyrequiredtypePurpose
urlrequiredstringThe API to be called
jsonna -get, optional - for post, optional - put, na - deletestringthe name of file in modules that returns the json to be posted
filena -get, optional - for post, optional - put, na - deletestringName of the file in modules (plain text) that needs to be posted
overridena -get, optional - for post, optional - put, na - deletearrayjsonpaths that need to be updated with value
headersoptional -get, optional - for post, optional - put, optional - deletearrayheaders that go on the http requests. like Authorization content-type etc

example:

post:
     url: "https://api.github.com/gists/~gist_id~/comments"
     json: "create_comment.json"
     override:
      $.body: ~comment_text~
     headers:
      Authorization: Basic xxxx
      content-type: application/json
      User-Agent: Teakozi-test

local

PropertyrequiredtypePurpose
filerequiredstringname of the file in the payload folder

Example:

local:
    file: roads

mongo

PropertyrequiredtypePurpose
serverrequiredstringconnection string / endpoint of the mongo server like "mongodb://localhost:27017"
dbrequiredstringthe name of the database
collectionrequiredstringcollection name in the above db from where the records have to be fetched
queryrequiredobjectthe filter criteria of querying the records from collection

Example:

  - mongo:
     server: "mongodb://localhost:27017"
     db: 'test'
     collection: "test"
     query:
       name: j

collect

Collects the propoerties from the payload response that would be used in the subsequent steps

    collect:
     title: $..[0].name
     project_id: $..[0].id

collect also supports reading complete or subset of json recieved like

    collect:
     all_roads: $..Name

this will collect all the Name fields comming at any part of the json. using JSON path expression on the right hand side you can collect specific sections of json for comparision

print

Enables debugging of the call by printing the jsonpaths from the response

  - get:
     url: "http://localhost:3060/k.json"
    name: "Get Auth K"
    print:
     - status
     - $.mykey
    check:
     status: 200
    collect:
     auth_key: $.mykey

print also supports checking the objects / subset of json as defined by json path like

print:
 - status # status of the header
 - $..Name # All names appearing in the json
 - $[0].Name # Prints name value of the first record
 - $ # Prints complete JSON

check

PropertyrequiredtypePurpose
statusoptionalnumberwhat status code is expected in response
schemaoptionalstringyou can add the name of the Model corresponding to the expected response. The swagger definition should be done in config/index.js
eqoptionalobjectthe jsonpaths that should be equal to
neqoptionalobjectthe jsonpaths that should notbe equal to
nulloptionalarraythe jsonpaths that should be null
deepEqualoptionalarrayThe jsonpaths and what collected objects to check against.
shallowEqualoptionalarraycompare two collected json to match and validate such that each element of A is present in the B (A is a subset B is a superset)
regexoptionalarrayThe jsonpaths and their matching regex. The regex expression can be external mentioned as ~regex_for_currency~ or mentioned inline

example:

    check:
     status: 200
     schema: Domain
     body:
      eq:
       $.length: 20
       $..[0].name: "devops_best_practices"
      regex:
       $.domain: "^Ji[a-z]*"
      neq:
       $.length: 0
      null:
       - $.nonexistant
       - $.someother_nonexistant
      deepEqual:
        $: full_roads_payload
        $..Name: all_roads
      shallowEqual:
        - sub: sub
          super: super
          ar: empid
          permissionList: permissionId

where full_roads_payload is collected in a previous step

The check expression can be json path expression or can also represent a collected value from a previous or current step

shallowEqual

Shallow Equal is a way to compare two collected jsons to match and validate such that each element of A is present in the B (A is a subset B is a superset).

PropertyrequiredtypePurpose
subrequiredstringthe name of the object collected in this or previous steps that should be the subset
superrequiredstringthe name of the object collected in this or previous steps that should be the superset
keyoptional / multistringkey is the arrays in the object and value is the attribute of the object that should be used to compare and identify the object

example JSON A (subset)

{
    organization:"abc",
    address:"outer ring road",
    city:"bangalore",
    employees:[{
        emp: 123,
        name: "Ned Stark"
    },{
        emp: 234,
        name: "John Snow"
    }]
}

JSON B (superset)

{
    organization:"abc",
    address:"outer ring road",
    city:"bangalore",
    pin: 560102
    employees:[{
        emp: 123,
        name: "Ned Stark",
        cool: true
    },{
        emp: 234,
        name: "John Snow"
    },{
        emp: 345,
        name: "Sansa"
    }]
}

if test.yml

  shallowEqual:
    - sub: A
      super: B
      employees: empid

Result: Pass

Save

Save is a utility that allows the resoponse recieved from the step into a file. you have control to save the full payload or partial payload using jsonpath

example:

    save:
      $: "file_mongo_recs"
      $..name: "names_in_response"

More on Schema Validation

Define the location of the swagger file in your config/index.js with the name

 swagger: /config/swagger.yaml

In your check attribute you can add the name of the Model corresponding to the expected response.

 check:
   schema: Domain

The framework will add an assertion step to check if the schema of the response is matching with the schema as defined in the swagger. the assertion fails if the schema is not found or schema mismatch. the details of which all attribute are not matching schema is described in the test log JSON and viewable in the teakozi-viewer.

Running a subset of your test suits based on tags

in your index.js file

var tags_list = "a,b,c,d"
require("teakozi").start("project/github",working dir,{tag:tags_list})

run the test cases

$ node index.js

Chaining test execution

The start function returns a promise that is resolved when tests complete. you can chain further tests like following or handle the test end event for any other handling

var dir = "/home/jitendra/code/teakozi-examples"
var t = require("teakozi")
t.start("project/github",dir,{tag:"cars"})
  .then(()=>{
    t.start("project/github",dir,{tag:"swagger"})
  })

The test logs are shown on screen and the logs are written into the project directory/log with a timestamped folder containing all and individual test run information

Teakozi-Viewer

This supporting project enables you to view the HTML reports from the collected logs in the log directory (all.js). Please clone and install from the following github repository https://github.com/jpthethi/teakozi-viewer

Teakozi-Editor

Teakozi editor https://github.com/jpthethi/teakozi-editor is a companion to Teakozi framework. The editor helps in providing a GUI for creating and editing the yml files that describe the tests.

Feedback

Please submit your suggestions / bugs via Github. You are welcome to fork and submit back your pull requests

License

ISC

1.3.1

4 years ago

1.3.0

4 years ago

1.2.9

5 years ago

1.2.8

5 years ago

1.2.7

5 years ago

1.2.6

5 years ago

1.2.5

5 years ago

1.2.4

5 years ago

1.2.3

5 years ago

1.2.2

5 years ago

1.2.1

5 years ago

1.2.0

5 years ago

1.1.11

6 years ago

1.1.10

6 years ago

1.1.9

6 years ago

1.1.8

6 years ago

1.1.7

6 years ago

1.1.6

6 years ago

1.1.5

6 years ago

1.1.4

6 years ago

1.1.3

6 years ago

1.1.2

6 years ago

1.1.0

6 years ago

1.0.6

6 years ago

1.0.5

6 years ago

1.0.4

6 years ago

1.0.3

6 years ago

1.0.2

6 years ago

1.0.1

6 years ago

1.0.0

6 years ago