3.0.3 • Public • Published


    An incredibly tiny javascript testing library. Heavily inspired by the wonderful ava and tape.


    • Supports sync and async tests
    • Provides arming/disarming and timeouts for async tests
    • Test cases structured as simple objects and functions
    • Easily flag a test or group to skip, or only run
    • Can be used as a CLI tool or a library
    • Comes with a file watcher to automatically re-run tests on file changes
    • No dependacies!
    • Under 100 lines!

    Test Syntax

    // Tests are just functions or objects of functions. If the test passes,
    // the function returns nothing, if the test fails the function should throw an error.
    const check = require('pico-check');
    //Test Cases are just nested objects of test functions
    const testCases = {
      'testing addition' : (t)=>{
        t.is(3 + 4, 7);
      'async tests' : {
        'promise check' : (t)=>{
          return request(api_url)
              t.is(result, {code : 200, body : { ok : true }});
        'async/await' :  async (t)=>{
          const bar = Promise.resolve('bar');
          t.is(await bar, 'bar');
      '_skipped test' : (t)=>t.fail()
    const {results, skipped, passed, failed} = await check(testCases);
    /* Returns the exact same object structure but true if pass, error if fail, and false if skipped
      'testing addition': true,
      'async tests': {
        'promise check': AssertionError [ERR_ASSERTION]: Expected values to be loosely deep-equal:
          { code: 404 } should loosely deep-equal { code: 200, body : { ok : true }},
        'async/await': true
      '_skipped test': false



    $ npm install --save-dev pico-check

    CLI usage

      "name": "smashing-project",
      "scripts": {
        "test": "pico-check ./tests",
        "test:dev": "pico-check --watch ./tests"
      "devDependencies": {
        "pico-check": "^2.0.0"

    Library Usage

    const check = require('pico-check');
    const testCases = {
      init$ : (t)=>{
        //This test always runs, even with the only flag
      this_is_a_group : {
        addition_test : (t)=>t.is(3+4, 7),
        $only_test : (t)=>{
          //this test is flagged with a $, so pico-check will skip every other test not marked with '$'
        _skipped_group : {
          sad_test : (t)=>{}
      _skipped_test : (t)=>{
        // this test is flagged with '_' so it will always be skipped
    check(testCases, {logs: false})
      .then(({failed, skipped, results})=>{
        process.exit(failed === 0 ? 0 : 1);


    You can flag tests and groups with _ and $ in the test name to change the test runner behaviour.

    Skip Flag - _test_name

    If a test or group name starts with a _ the test/group will be skipped

    Only Flag - $test_name

    If a test or group name starts with a $ the test runner will be set into "only mode", and will only run tests/groups with the Only Flag or the Always Flag.

    Always Flag - test_name$

    If a test or group ends with a $ then this test will always run regardless of other flags and modes. This is useful for test cases that set up or clean up needed processes for other test cases (such as database connections or setting environment variables).


    Each test function will be provided an assertion object as it's first parameter. pico-checks assertion object is an extension of node's built-in assert, so you can use any of the default assertions. Here are pico-checks additional assertions:

    t.pass([msg]) / t.fail([msg])

    Passes/fails a test case with an optional message

      (complexCondition ? t.pass() : t.fail('The complex condition failed'))

    t.is(actual, expected, [msg]) / t.not(actual, expected, [msg])

    Will do a deep comparison between the actual and the expected.

      t.not(3 + 4, 8);
      t.is({a : 6, b : [1,2,3]}, {a:6, b:[1,2,3]});

    t.ok(value, [msg])

    Checks if value is truthy

      t.ok(3 + 4 == 8, 'Math is broken');

    t.type(value, type, [msg])

    A shorthand for t.is(typeof value, type, msg). Handles arrays as type 'array' and errors as type 'error';

      t.type(3, 'number');
      t.type({a:true}, 'object');
      t.type([1,2,3], 'array');
      t.type(new Error('oops'), 'error');

    t.armed = false

    Sometimes you need a test to implictly fail unless a certain code path is ran. For this use case you can 'prime' your test case to error using t.armed = true, and stop it from failing by calling t.armed = false.

    async (t)=>{
      t.armed = true;
      emitter.on('update', ()=>t.armed = false);

    t.timeout = 2000

    pico-check only allows tests 2 seconds of run time before a timeout. You can modify this on a test by test basis by changing the t.timeout value in the test code.

    async (t)=>{
      t.timeout = 8000; //8 seconds
      await a_longer_process();


    pico-check gives each test a promise mapping it's resolve and reject functions as t.pass() and t.fail() respectively. To use this the test function just needs to return the t.wait

    async (t)=>{
      return t.wait;



    npm i pico-check

    DownloadsWeekly Downloads






    Unpacked Size

    19.9 kB

    Total Files


    Last publish


    • stolksdorf