node package manager
Share your code. npm Orgs help your team discover, share, and reuse code. Create a free org »

http-bat

HTTP-BAT

Http Blackbox API Tester (http-bat)

NPM version NPM downloads Build status Test coverage

Describe your platform independient API tests using ATL (Api Testing Language) and run them using http-bat. It also generates coverage reports for your RAML files.

Usage

Install

Install the tool executing npm install -g http-bat

Using command line, useful for CI

Run your tests on api folder:

$ http-bat api/*.spec.yml

Run your tests with a custom remote URI:

$ http-bat github_api/*.spec.yml --uri http://api.github.com

You need it embeded on a Node project? (Useful for coverage and CI)

Install the package

$ npm install http-bat --save-dev

test/api.spec.js <- mocha spec

import { GenericAdapter } from 'http-bat/dist/adapters'
 
require('http-bat/dist/adapters/mocha') 
// Mocha detection should be automatic. But since mocha and node changes a lot, this line may be required.
 
GenericAdapter.runFile('file.yaml')

More details and examples

Execute mocha on your project

$ mocha

Imgur

Current features

You can read the entire list on this page
VSCode extension

Examples

Wiki examples

Test response status code

#%ATL 1.0 
 
tests:
  "Favicon must exists":
    GET /favicon.ico:
      response:
        status: 200
  "Should return 401":
    GET /unauthorized_url:
      response:
        status: 401
  "Should return 404":
    GET /asjdnasjdnkasf:
      response:
        status: 404

Send query string parameters

#%ATL 1.0 
 
tests:
  "Inline query string":
    GET /orders?page=10:
      response:
        status: 200
  "Non inline":
    GET /orders:
      queryParameters:
        page: 10
      response:
        status: 200
  "Override inline query string":
    # The final url will be /orders?page=10&qty=20  
    GET /orders?page={----asd---}&qty=20:
      queryParameters:
        page: 10
      response:
        status: 200

Validate response ´Content-Type´

#%ATL 1.0 
 
tests:
  "Must return text":
    GET /responses/text:
      response:
        content-type: text/plain  
  "Must return json":
    GET /responses/json:
      response:
        content-type: application/json
  "Must return url-encoded":
    GET /responses/url-encoded:
      response:
        content-type: application/x-www-form-urlencoded

Send headers

#%ATL 1.0 
 
tests:
  "Headers":
    GET /profile#UNAUTHORIZED:
      response: 
        status: 401 
        
    GET /profile:
      headers:
        Authorization: Bearer asfgsgh-fasdddss
      response: 
        status: 200 

Validate response headers

#%ATL 1.0 
 
tests:
  "Headers":
    PUT /bounce/headers:
      response:
        headers: 
          Access-Control-Allow-Headers: "Authorization, X-Default-Header, X-Custom-Header" # literal value 

Validate response content

#%ATL 1.0 
 
tests:
  "Must validate response body":
    GET /text:
      response:
        body: 
          content-type: text/plain
          is: "Success"
          # "is" means equals. In this case the response is the text "Success" 
          
    GET /json:
      response:
        body: 
          content-type: application/json
          is: !!map { json: true }
          # "is" means equals. In this case the response is the JSON {"json":true} 
    
    GET /json/v1:
      response:
        body: 
          content-type: application/json
          is: 
            json: true
            # "is" means equals. In this case the response is the JSON {"json":true} 
            # this is the same as the previous example 

Validate response (partially)

#%ATL 1.0 
 
tests:
  "Must validate response body":
    GET /json:
      response:
        body: 
          content-type: application/json
          # In this case the response is the JSON { "json":true, "a": 1, "b": 2 } 
          matches:
            a: 1
          # "json" and "b" properties will be ignored 
          
          
    GET /users:
      response:
        body: 
          content-type: application/json
          # In this case the response is the JSON  
          # [  
          #    { "id": 1, "name": "Agu" },  
          #    { "id": 2, "name": "Dan" }  
          # ] 
          matches:
            "[0].id": 1
            "[1].name": Dan

Execute in sequence. Obtain access token

#%ATL 1.0 
 
variables: # anything can be stored here 
  oauth:
    accessToken: "INVALID_TOKEN"
 
tests:
  "Access control by token, executed in sequence":
    GET /secured_by_token#should-be-unauthorized:
      description: Must be unauthorized
      queryParameters: 
        accessToken: !!variable oauth.accessToken
      response:
        status: 401
 
    POST /get_access_token:
      # the server responds { new_token: "asd" } 
      description: Obtain access token
      response:
        body:
          take: # take "new_token" from response body 
            new_token: !!variable oauth.accessToken
 
    GET /secured_by_token:
      description: Now the status must be 200 OK
      queryParameters: 
        # use the access token obtained previously 
        accessToken: !!variable oauth.accessToken
      response:
        status: 200
        body:
          is:
            success: true

CRUD

This example shows how to create an asset, check that it exists, put new content on it and delete it. Then check 404 for the same asset.
Also shows how use ENVIRONMENTS variables. ENV variables are stored on variables.ENV, can be accessed using !!variable ENV.*

#%ATL 1.0 
 
variables:
  ENV:
    csToken: Bearer <<YOU MUST DEFINE YOUR csToken ON ENV>>
    organizationId: abc123
  flow:
    id: ""
 
tests:
  "Project create and delete":
    POST /organizations/{orgId}/projects#create'first:
      description: Create project
      uriParameters:
        orgId: !!variable ENV.organizationId
      headers:
        Authorization: !!variable ENV.csToken
      request:
        json:
          name: RetrieveEmployeeFlow,
          created: 06-06-06
          updated: 06-06-06
          environmentId: asd1f65dasf656
          organizationId: !!variable ENV.organizationId
      response:
        status: 201
        body:
          # store the whole response (project) in projectNuevo 
          take: !!variable projectNuevo
 
    GET /organizations/{orgId}/projects/{projectId}:
      description: Check that the created project exists
      uriParameters:
        orgId: !!variable ENV.organizationId
        projectId: !!variable projectNuevo.id
      headers:
        Authorization: !!variable ENV.csToken
      response:
        status: 200
        body:
          matches:
            id: !!variable projectNuevo.id
 
    PUT /organizations/{orgId}/projects/{projectId}:
      uriParameters:
        orgId: !!variable ENV.organizationId
        projectId: !!variable projectNuevo.id
      headers:
        Authorization: !!variable ENV.csToken
      request:
        json: !!variable projectNuevo
      response:
       status: 200
        body:
          matches:
            id: !!variable projectNuevo.id
 
    DELETE /organizations/{orgId}/projects/{projectId}:
      uriParameters:
        orgId: !!variable ENV.organizationId
        projectId: !!variable projectNuevo.id
      headers:
        Authorization: !!variable ENV.csToken
      response:
        status: 200
 
    GET /organizations/{orgId}/projects/{projectId}#mustn't exists:
      uriParameters:
        orgId: !!variable ENV.organizationId
        projectId: !!variable projectNuevo.id
      headers:
        Authorization: !!variable ENV.csToken
      response:
        status: 404