npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

http-test-runner

v7.2.6

Published

Runs hapi-lab tests that are defined using a simple test specification format.

Downloads

125

Readme

http-test-runner

This project contains code that makes it possible to run hapi-lab tests based on an array of test specifications. Each test specification contains information about what request should be made to the server and what the response should be.

It is also possible to run a mock server based on the test specifications.

Usage example (written in Typescript)

import TestRunner = require("http-test-runner");
import Lab = require("lab");
const lab = exports.lab = Lab.script();

const config: TestRunner.Configuration = {
    lab: lab,
    getServerUrl: () => "http://localhost:8080",
    tests: [
        {
            id: "test1",
            requests: [
                {
                    path: "/user/user1"
                }
            ]
        },
        {
            id: "test2",
            requests: [
                {
                    path: "/user",
                    method: "post",
                    payload: {
                        username: "Test User 2",
                        email: "[email protected]"
                    }
                }
            ]
        }
    ],
    expectedResponses: {
        test1: [
            {
                payload: {
                    username: "Test User 1",
                    email: "[email protected]"
                }
            }
        ],
        test2: [
            {
                statusCode: 401,
                payload: {
                    message: "Unauthorized"
                }
            }
        ]
    },
    testReportFilePath: "./test-report.json",
    responsesFilePath: "./responses.json"
};

lab.experiment("TestRunner example", () => {

    lab.before((done) => {
        /**
         * Starts a mock server on port 8080.
         * The mock server will respond as specified in config.expectedResponses.
        **/
        TestRunner.runMockServer(config, "localhost", 8080).then(() => done());
    });

    // Runs the tests as specified by the configuration
    TestRunner.performTests(config);

});

API

Configuration

These types define the configuration used when running tests:

export interface Headers {
    [name: string]: string;
}

export interface Response {
    payload?: any;
    headers?: Headers;
     /** Defaults to 200. */
    statusCode?: number;
}

export interface Request {
    path: string;
     /** Defaults to GET. */
    method?: string;
    payload?: any;
    /** Query parameters as an object */
    query?: any;
    headers?: Headers;
    /** The response object paths specified here are ignored when validating the response, e.g. ["message", "data.timestamp"] */
    ignoredResponsePaths?: string[];
    /** Only the type ("string", "number", etc) is validated for the response object paths specified here. */
    relaxedResponsePaths?: string[];
    /** Only the type ("string", "number", etc) is validated for the response keys specified here. */
    relaxedResponseKeys?: string[];
}

export type RequestModifier = (previousResponses: Response[], nextRequest: Request) => Request; // Returns a Modified version of the next request based on the response from current request.

export type ValidateResponseFunc = (responses: Response[], expectedResponses: Response[], test: Test) => void; // Should throw  exception if validation fails;

export interface Test {
    /** Unique id used to lookup expected response. */
    id: string;
    label?: string;
    requests: Request[];
    requestModifier?: RequestModifier;
    /** If present, run before test */
    before?: Function;
    /** If presetn, run after test */
    after?: Function;
    /** If present the response is only checked using this function. */
    validateResponseFunc?: ValidateResponseFunc;
    /** If specified, numeric values are compared using delta comparison.
     *  The delta value is the maximum difference between actual and expected result that will be accepted. */
    delta?: number;
    /** Tests marked by serial will be run in serial before the rest of the tests are run */
    serial?: boolean;
    /** DEPRECATED!!! Can't be used in combination with delta. If true, compare arrays unordered. */
    unorderedArrays?: boolean;
}

export interface Defaults {
    request?: {
        path?: string;
        method?: string;
        headers?: Headers;
        ignoredResponsePaths?: string[];
        relaxedResponsePaths?: string[];
        relaxedResponseKeys?: string[];
    };
    response?: Response;
    requestModifier?: RequestModifier;
    validateResponseFunc?: ValidateResponseFunc;
    delta?: number;
    unorderedArrays?: boolean; // DEPRECATED!!!
}

export type GetServerUrlFunc = () => string;

/**
 * Maps Test.id to array of Response objects.
 * Each item in the response array is the response for the corresponing request item for the test with that id.
 * */
export type ExpectedResponses = { [id: string]: Response[]; };

export interface Encoding {
    mimeType: string;
    encode: Function;
    decode: Function;
}

export interface TestReportItem {
    id: string;
    label?: string;
    requests: Request[];
    responses: Response[];
    success: boolean;
    expectedResponses?: Response[];
    requestModifier?: string;
    validateResponseFunc?: string;
    unorderedArrays?: boolean;
}

export interface Configuration {
    tests: Test[];
    expectedResponses: ExpectedResponses;
    /** hapi-lab instance. */
    lab: any;
    /** A function returning the url to the server that will be tested. */
    getServerUrl: GetServerUrlFunc;
    /** Default values for various configuration settings */
    defaults?: Defaults;
    /** If present a responses JSON file is generated containing a map of the actual responses keyed on the tests id. */
    responsesFilePath?: string;
    /** If present only the specified response headers are included in the responses, e.g. ["x-request-id, "content-language] */
    activeResponseHeaders?: string[];
    /** If present a test report JSON file is generated showing the request, response and expectedResponse if the test fails. The format is TestReportItem[] */
    testReportFilePath?: string;
    /** Prefix added to each request path. */
    requestPathPrefix?: string;
    /** Allows for different encodings to be used based on Accept and Content-Type headers. Default is JSON. */
    encodings?: Encoding[];
    /** Array of test id values. If present, only these tests will be performed. */
    activeTests?: string[];
    /** Array of test id values. If present, these tests will be skipped. */
    skipTests?: string[];
    /** Logs information useful for debugging. Defaults to off */
    debugLogging?: boolean;
    /** If set, the tests will be run in parallel with at most parlellCount tests running simultaneously */
    parallelCount?: number;
};

Running the tests

import TestRunner = require("http-test-runner");
import Lab = require("lab");
const lab = exports.lab = Lab.script();

const config: Configutaion = {/*...*/}

lab.experiment("Running http-test-runner tests", () => {
    // Runs the tests as specified by the configuration
    TestRunner.performTests(config);
});

Running the mock server

DEPRECATED!

The mock server is deprecated because it does not support parallel requests fully.

import TestRunner = require("http-test-runner");
const config: Configutaion = {/*...*/}
/**
 * Starts a mock server on port 8080.
 * The mock server will respond as specified in config.expectedResponses.
**/ 
TestRunner.runMockServer(config, "localhost", 8080);