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

loaded

v0.1.0

Published

Node.js load and stress testing library for advanced and realistic use cases

Downloads

4

Readme

Loaded.js

Loaded.js is a small Node.js load testing framework with a focus on flexibility and test organization. Loaded.js takes a a very minimal approach on how to specify a load test leaving a lot of work to the developer. This approach is particularly useful when load testing more complex requests and advanced workflows.

In its current form Loaded.js requires

HTTP Request example

The example below requests the google homepage 50 times with a max of 5 concurrent users.

var request = require('request');
var loaded = require('loaded');

var loadTest = loaded.newTest({
    iterations: 50,
    concurrency: 5
});
loadTest.test(function (n, next) {
    request('http://www.google.com', function (error, response, body) {
        if (error) {
            next(error);
        } else if (response.statusCode < 200 || response.statusCode >= 300) {
            next(response.statusCode + ' ' + body);
        } else if (!error && response.statusCode == 200) {
            console.log('Iteration ' + n);
            next();
        }
    });
});
loadTest.run(function () {
    console.log('Finished');
});

To run the test, copy and paste the code snippet in a file (for example test.js) and run the following commands:

$ npm install loaded
$ npm install request
$ node test.js

You can specify timers and multiple beforeAll, afterAll and test functions. See the detailed example below for more information.

Test options

When creating a test you can pass an object with the following options:

  • title: a test title. Defaults to ''.
  • iterations: the number of iterations. Defaults to 1.
  • concurrency: the number of tests to run in parallel. Defaults to 1.
  • errorHandler: an error handling function called when an error is detected in beforeAll, afterAll or test functions. The error handler signature is function(err). Defaults to printing the error to the console.

Performance metrics / stats

Loaded.js does not automatically gather statistics on test execution performance. Gathering stats of the target application's performance is best done directly from the environment itself. If you're serious about your application's performance consider tracking performance metrics from the application using StatsD, Logstash/Kibana or something similar (also in production!).

Having said that, Loaded.js comes with a timer utility able to track execution times in milliseconds.

Single timer

Timers are identified by their name. You can start multiple timers with the same name. Results of timers with the same name are aggregated in the stats report (see below).

var loaded = require('loaded');

var loadTest = loaded.newTest({
    iterations: 200,
    concurrency: 20
});
loadTest.test(function (n, next) {
    var timer = loaded.newTimer('test');
    setTimeout(function () {
        timer.stop();
        next(null);
    }, Math.round(Math.random() * 100));
});
loadTest.run(function () {
    console.log(loaded.stats());
});

Example output:

{
    test: {
        count: 200,
        sum: 10508,
        mean: 52.54,
        median: 55.5,
        min: 1,
        max: 100,
        '90percentile': 90,
        '95percentile': 96,
        '99percentile': 100
     }
 }

Multiple timers (hierarchical)

You can create a timer hierarchy to aggregate statistics of different timers. To do this simply separate timer hierarchy levels with a dot in the timer's name, for example:

var loaded = require('loaded');

var loadTest = loaded.newTest({
    iterations: 200,
    concurrency: 20
});
loadTest.test([
    function (n, next) {
        var timer = loaded.newTimer('test.1');
        setTimeout(function () {
            timer.stop();
            next();
        }, Math.round(Math.random() * 100));
    },
    function (next) {
        var timer = loaded.newTimer('test.2');
        setTimeout(function () {
            timer.stop();
            next();
        }, Math.round(Math.random() * 50));
    }
]);
loadTest.run(function () {
    console.log(loaded.stats());
});

Example output:

{
    test: {
        count: 400,
        sum: 14595,
        mean: 36.4875,
        median: 32,
        min: 1,
        max: 101,
        '90percentile': 81,
        '95percentile': 93,
        '99percentile': 99
    },
    'test.1': {
        count: 200,
        sum: 9482,
        mean: 47.41,
        median: 47,
        min: 1,
        max: 101,
        '90percentile': 93,
        '95percentile': 98,
        '99percentile': 99
    },
    'test.2': {
        count: 200,
        sum: 5113,
        mean: 25.565,
        median: 26,
        min: 1,
        max: 51,
        '90percentile': 45,
        '95percentile': 48,
        '99percentile': 50
    }
}

Notice the two timers test.1 and test.2 produce three timer outputs: test.1, test.2 and test (the latter being the aggregate of the other two timers).

Detailed example

The following example specifies multiple beforeAll, afterAll and test functions. In addition the first test passes an additional parameter to the next test.

var loaded = require('loaded');

var loadTest = loaded.newTest({
    title: 'Detailed load test example',
    iterations: 10,
    concurrency: 20
});
loadTest.beforeAll([
    function (next) {
        next(null, 'Before all');
    },
    function (var1, next) {
        console.log(var1);
        next();
    }
]);
loadTest.test([
    function (n, next) {
        var timer = loaded.newTimer('test.1');
        setTimeout(function () {
            timer.stop();
            next(null, 'Iteration ' + n);
        }, Math.round(Math.random() * 100));
    },
    function (var1, next) {
        var timer = loaded.newTimer('test.2');
        setTimeout(function () {
            console.log(var1);
            timer.stop();
            next();
        }, Math.round(Math.random() * 50));
    }
]);
loadTest.afterAll([
    function (next) {
        next(null, 'After all');
    },
    function (var1, next) {
        console.log(var1);
        next();
    }
]);
loadTest.run(function () {
    console.log(loaded.stats());
});

Example output:

Before all
Iteration 1
Iteration 3
Iteration 7
Iteration 5
Iteration 9
Iteration 4
Iteration 6
Iteration 2
Iteration 8
Iteration 10
After all
{
    test: {
        count: 20,
        sum: 781,
        mean: 39.05,
        median: 33,
        min: 11,
        max: 94,
        '90percentile': 75,
        '95percentile': 94,
        '99percentile': null
    },
    'test.1': {
        count: 10,
        sum: 517,
        mean: 51.7,
        median: 47,
        min: 21,
        max: 94,
        '90percentile': 94,
        '95percentile': null,
        '99percentile': null
    },
    'test.2': {
        count: 10,
        sum: 264,
        mean: 26.4,
        median: 29.5,
        min: 11,
        max: 41,
        '90percentile': 41,
        '95percentile': null,
        '99percentile': null
    }
}

Dependencies

This library relies heavily on Async.js.

Tests

To run tests and verify the code style, run the following command from the command line:

grunt

The test run will also run a code coverage tool that outputs a code coverage overview on the command line. More detailed output can be found in the generated /coverage directory.