Overview

Ping-API is a powerful API inspector. We allow you to inspect any HTTP API call with complete request and response data.

Programmable

Ping-API allows you to write test script in JavaScript and CoffeeScript to test your APIs.
Write script to set request url parameters, headers and body. And write script to validate response headers and body.

Script generator

Don't worry about programming. Just set parameter of your API, the generator will give you test script. It is easy!

The use case for web developers

  • Give me a notification when my web is down or the response is unexpected.

    Ping-API will schedule your tests in every minutes or hours.
    If the test is failure, we will send the notification to you.

  • My website is global site, users come from all of the world. I care the response time from different countries.

    Your test script will run on our global servers in U.S., Japan, Germany and Singapore.
    You will known the response time from global users.

  • I want to validate login flow after I deploy my web.

    You can validate login and any CRUD flow on Ping-API.
    The validation logic is programmable. You can pass the variable to the next test case.

The use case for app developers

  • Some times, my app crash after the web was updated.

    You can run tests to validate the API response schema on Ping-API to clarify the issue for the first time.

Getting started

Ping-API is very easy to use. Follow these steps to create a inspector for your API.

Create a project

Every project should be defined a API base URL. The limit of members of each project is 100.

Type your project title and API base URL.

Create a test

Type API path, request headers, parameters and body.

The generator will give you test script.

Run the test

We will run your test script on our global servers. That will send requests to your API server and verify the response.

Read the history

You can get more information about the request. It include test server region, response time, response status code, headers and body...

Initial script

There is one initial script of the each project.
The initial script will be run before the each test. You can set common functions at here.

Test script

There are two section of the test case setup and test. The setup code should be a function and the prefix is setup . The test code should be a function and the prefix is test.

Setup function

this.setupCaseA = function () {
  /*
  The setup function of CaseA. This is optional.
  @return {object}
    params: {object}
      The url query string.
    headers: {object}
    body: {object|string}
      If the body is object Ping-API will convert to JSON by default.
      Set 'Content-Type': 'application/x-www-form-urlencoded' at headers Ping-API will convert to unl-encoded form.
  */
  return {
    params: {
      index: 0
    },
    headers: {
      'User-Agent': 'Chrome'
    },
    body: {
      account: 'test-account',
      password: 'password'
    }
  };
};
params {object}The url query string as a dictionary.
headers {object}The request headers as a dictionary.
body {object|string}If the body is object Ping-API will convert it to JSON by default.
Set Content-Type as application/x-www-form-urlencoded at headers Ping-API will convert it to unl-encoded form.

Test function

this.testCaseA = function (test, response) {
  /*
  The test function of CaseA.
  @params test {Test}
    expect: {function} arguments: num{number}
      How many assertions should be passed.
    equal: {function} arguments: actual{any}, expected{any}, message{string}
      Test with the equal comparison operator ( === ).
    done: {funnction}
      Call this method when the test case was done.
  @params response {Response}
    statusCode: {number}
    headers: {object}  // all keys are lowercase
    body: {object|string}
    request: {object}
  */
  test.expect(2);
  test.equal(response.statusCode, 200, 'response status should be 200.');
  var content = response.body;
  test.ok(!content.error, 'server should not return error messages.');
  test.done();
};
test
test.expect(num)@param num {number}
How many assertions should be passed.
test.equal(actual, expected, message)@param actual {any}
@param expected {any}
@param message {string}
Test with the equal comparison operator (===).
test.done()Call this method when the test case was done.
response
response.statusCode {number}The HTTP status code.
response.headers {object}A dictionary of response headers. All keys are lower case.
response.body {object|string}The response body as a string unless the response body is json.
response.request {object}method: {string}
url: {string}
headers: {object}

Storage

storage is a global variable. The data type is object. You can use storage to pass variable to the next test.

// POST /login
this.setupCase = function () {
  return {
    body: {
      account: 'test-account',
      password: 'password'
    }
  };
};
this.testCase = function (test, response) {
  test.equal(response.statusCode, 200);
  var content = response.body;
  test.ok(content.token);
  storage.token = content.token;  // store the token at storage.token
  test.done();
};

Built-in objects and functions

Objects

Functions

Examples

Here are some examples. You will learn a lot about Ping-API test script programming.

Variable API path

You can type {variableName} at the api path failed and set params at the setup function.

// GET /orgs/{orgName}
this.setupCase = function () {
  return {
    params: {
      orgName: 'ping-api'
    }
  };
};
this.testCase = function (test) {
  test.equal(response.statusCode, 200);
  var content = response.body;
  test.equal(content['login'], "ping-api");
  test.done();
};

Set default User-Agent

Update your Initial script. Set storage.headers['User-Agent'] as you want.

// initial script
storage.headers = {
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) Chrome/46.0.2490.80'
};

Validate login flow

First step: call login API

// test script: POST /login
this.setupCase = function () {
  return {
    body: {
      account: 'test-account',
      password: 'password'
    }
  };
};
this.testCase = function (test, response) {
  test.equal(response.statusCode, 200);
  var content = response.body;
  test.ok(content.token);
  storage.token = content.token;  // store the token at `storage`
  test.done();
};

Second step: get my profile with token

// test script: GET /me
this.setupCase = function () {
  return {
    params: {
      token: storage.token  // append the token
    }
  };
};
this.testCase = function (test, response) {
  // server should return the profile of the token
  test.equal(response.body, {
    account: 'test-account',
    id: 1
  });
  test.done();
};

Multi test case

You can write multi test case at one api path.

// test script: POST /login
this.setupSuccessCase = function () {
  return {
    body: {
      account: 'test-account',
      password: 'password'
    }
  };
};
this.testSuccessCase = function (test, response) {
  test.equal(response.statusCode, 200);
  test.done();
};

this.setupFailureCase = function () {
  return {
    body: {
      account: 'not-exist-account',
      password: 'password'
    }
  };
};
this.testFailureCase = function (test, response) {
  test.equal(response.statusCode, 400);
  test.done();
};

Integrating

HipChat https://www.hipchat.com/

HipChat is hosted group chat and video chat built for teams.

Go to the settings page of the project. Find the HipChat of the Services section. And click the Add button.
Type your HipChat API URL, then save it. Ping-API will post the failure test information to your HipChat room.
This article will help you to install integrations in HipChat rooms:
https://confluence.atlassian.com/hipchat/integrate-other-apps-747831626.html

Slack https://slack.com/

Slack is a cloud-based team collaboration tool.

Go to the settings page of the project. Find the Slack of the Services section. And click the Add button.
Ping-API will post the failure test information to your Slack channel.

Webhook

Webhooks allow external services to be notified when tests were completed. When the tests were completed, we’ll send a POST request to each of the URLs you provide. You can create up to 5 webhooks on each project.

Headers
X-PingAPI-DeliveryUnique ID for this delivery.
X-PingAPI-SecretWebhook secret.

Example payload

{
  "state": "failure",
  "project": {
    "id": "AVKBT0MUX9rtM9M64PCC",
    "title": "Ping-API",
    "memberIds": [
      "AVAUWjVmJ3-o1nW2sPG0"
    ],
    "apiUrl": "https://ping-api.com/",
    "region": "universal",
    "testInterval": 86400,
    "createTime": "2016-01-27T04:20:00.962Z"
  },
  "failureTests": [
    {
      "test": {
        "id": "AVKCZUVIiprTaJ3naNh1",
        "method": "GET",
        "uri": ""
      },
      "histories": [
        {
          "id": "AVMHuuU3T8RTea8PeLKf",
          "region": "us-west-2",
          "method": "GET",
          "url": "https://ping-api.com/",
          "errorMessage": null,
          "testCases": {
            "testCaseA": {
              "responseStatus": 200,
              "responseTime": 22,
              "errorMessages": [
                "Expected 201 got 200."
              ]
            }
          }
        }
      ]
    }
  ]
}

API

API allow your program to access the project on Ping-API with HTTP request.

API Key

You can generate an api key at the project settings page. You should append your api key at the header of the HTTP request.

Headers
AuthorizationM9M64PCC0e3c87f2a7514416b192a2fa66c57c0b (your api key)

Get the project GET https://api.ping-api.com/project

Response

{
  "apiKeys": [
    {
      "description": "test",
      "isEnable": true,
      "key": "M9M64PCC0e3c87f2a7514416b192a2fa66c57c0b",
      "scope": "read,run-test"
    }
  ],
  "apiUrl": "https://ping-api.com/",
  "createTime": "2016-01-27T04:20:00.962Z",
  "id": "AVKBT0MUX9rtM9M64PCC",
  "initialScript": "",
  "isEnableEmailNotification": false,
  "isEnableHipchat": false,
  "isEnableSlack": true,
  "isOverLimit": false,
  "isRunning": false,
  "memberIds": [
    "AVAUWjVmJ3-o1nW2sPG0"
  ],
  "owner": {
    "id": "AVAUWjVmJ3-o1nW2sPG0"
  },
  "region": "us-west-2",
  "scriptLanguage": "java-script",
  "testIds": [
    "AVKCZUVIiprTaJ3naNh1"
  ],
  "testInterval": 86400,
  "title": "Ping-API",
  "webhooks": [
    {
      "id": "c671b2b27941488189cb402a00ab5c77",
      "secret": "",
      "url": "http://example.com"
    }
  ]
}

Add a test POST https://api.ping-api.com/project/tests

Parameters

NameTypeDescription
methodstringRequired. {GET|POST|PUT|DELETE|PATCH|HEAD}
The http request method.
uristringThe http request uri.
testScriptstringThe test script.

Response

{
  "createTime": "2016-01-27T09:23:40.916Z",
  "id": "AVKCZUVIiprTaJ3naNh1",
  "method": "GET",
  "testScript": "this.setupCaseA = function () {\n    return {\n        \"headers\": {},\n        \"params\": {},\n        \"body\": {}\n    };\n};\n\nthis.testCaseA = function (test, response) {\n    test.equal(response.statusCode, 200);\n    test.done();\n};\n",
  "uri": ""
}

Get the test GET https://api.ping-api.com/project/tests/:testId

Response

{
  "createTime": "2016-01-27T09:23:40.916Z",
  "id": "AVKCZUVIiprTaJ3naNh1",
  "method": "GET",
  "testScript": "this.setupCaseA = function () {\n    return {\n        \"headers\": {},\n        \"params\": {},\n        \"body\": {}\n    };\n};\n\nthis.testCaseA = function (test, response) {\n    test.equal(response.statusCode, 200);\n    test.done();\n};\n",
  "uri": ""
}

Update the test PUT https://api.ping-api.com/project/tests/:testId

Parameters

NameTypeDescription
methodstringRequired. {GET|POST|PUT|DELETE|PATCH|HEAD}
The http request method.
uristring The http request uri.
testScriptstringThe test script.

Response

{
  "createTime": "2016-01-27T09:23:40.916Z",
  "id": "AVKCZUVIiprTaJ3naNh1",
  "method": "GET",
  "testScript": "this.setupCaseA = function () {\n    return {\n        \"headers\": {},\n        \"params\": {},\n        \"body\": {}\n    };\n};\n\nthis.testCaseA = function (test, response) {\n    test.equal(response.statusCode, 200);\n    test.done();\n};\n",
  "uri": ""
}

Run all tests of the project. POST https://api.ping-api.com/project/tests/_run

Response

{
  "message": "Tests have been run."
}

Test server regions

  • U.S. Oregon (us-west-2)
  • U.S. Virginia (us-east-1)
  • Japan Tokyo (ap-northeast-1)
  • Singapore (ap-southeast-1)
  • Germany Frankfurt (eu-central-1)