Détail du package

jssmartcheck

mukeshsoni126MIT0.2.3

Property based generative testing for JavaScript

test, property based testing, testing, javascript

readme

jssmartcheck

jssmartcheck is a JavaScript property-based testing tool inspired by Haskell's QuickCheck and Clojure's test.check.

Property based testing is also known as generator based testing or generative testing. The principle behind property based testing is that it's really hard to create random testing data which covers all edge cases. But if we let the machine do the generation of test data for us, we could catch many more errors than otherwise. The generation of data by machine also lets us run our test on much more data than using manual methods.

Another difference from traditional unit testing is that instead of giving the tests an 'expected output', we need to specify a property of the function which holds true for a given 'set' of input. This makes us think harder about the way we write functions, a welcome side effect.

How to Use

$ npm install jssmartcheck

In your test file -

var jsc = require('jssmartcheck');
var gen = jsc.gen;

// sort is idempotent
var property = function(x) {
    return x.sort() === x.sort().sort();
}

// for all array of integers 'l', sorting l once is equal to sorting l twice
jsc.forAll(gen.arrayOf(gen.int)).check(property);
// { result: true, numTests: 100, seed: 14.77343332953751 }

Example of a failing test case -

// the first element of a sorted array of integers is less than the last element
var propFn = (x) => {
    x.sort();
    return x[0] < x[x.length - 1];
}

var nonEmptyGen = gen.suchThat((n) => n.length > 0, gen.arrayOf(gen.int));
jsc.forAll(nonEmptyGen).check(propFn)
// {"result":false,"numTests":0,"fail":[[0,0]]}

jssmartcheck will throw an AssertionError if the property function fails for any of the generated input. The printed output will show result key as false for a failing test case.

Also as seen in the failing test case, one can easily compose new generators out of the existing ones. jssmartcheck even provides a few helper functions to make the process of writing custom generators easy.

Integration with testing frameworks

jssmartcheck works out of the box for mochajs. Should also work with jasmine and qunit but have not been tested yet.

Documentation

Generators

Generators help you generate random values of a specific type against which the property function is run. jssmartcheck provides a number of generators to get you started. You can also compose your own generators using the existing ones. Or roll up your own. They are just functions.

You can use the gen.sample function to quickly check what a generator might produce.

Simple Generators

var gen = require('jssmartcheck').gen;

// generate 10 random integers
gen.sample(gen.int, 10); // [ 0, 0, -1, 1, -2, 4, 1, 0, -6, 0 ]

// generate 10 random positive integers
gen.sample(gen.int.positive); // [ 0, 0, -1, 1, -2, 4, 1, 0, -6, 0 ]

// generate 5 random strings
gen.sample(gen.string, 5); // [ '', '', '\u0012', 'tû¨', '›è'

Slightly complex Generators

// generate 10 random ascii strings
gen.sample(gen.string.ascii, 10); // [ '', '', '9', '', 'rNq', '6b#Ph', 'J', 'r', '.K', '\'qwq DcZ' ]

// generate 10 random alpha numeric strings
gen.sample(gen.string.alphaNum, 10); // [ '', '', '', 'Ti', 'A', 'vInl', 'Wi', 'puniD', 'q3z', 'RuZZ3Rsh' ]

// generate 5 strings matching the given pattern
gen.sample(gen.string.matches(/boo{1,3}m/)); // [ 'boom', 'boom', 'boooom', 'booom', 'boom' ]

// generate numeric strings of length 3-6 characters and numeric only
gen.sample(gen.string.matches(/\d{3,6}/), 5); // [ '3404', '3685', '4451', '137513', '75258' ]

// generate an object of given shape
gen.sample(gen.object.ofShape({
    name: gen.string.matches(/\w{3,5}(\s\w{5,8})?/),
    age: gen.suchThat((age) => age > 4, gen.int.positive),
    sex: gen.elements(['M', 'F', 'Neither'])
}), 10)

/*
    [ 
        { name: 'vWo4 _7ivwS', age: 10, sex: 'M' },
        { name: 'T9uZe', age: 9, sex: 'F' },
        { name: '53f O_JBi1u', age: 6, sex: 'M' },
        { name: '0n1', age: 6, sex: 'Neither' },
        { name: '49yW
MQzJyHBR', age: 5, sex: 'F' },
        { name: 'm24 XbC68G', age: 6, sex: 'M' },
        { name: 'iON i_7u5_V', age: 7, sex: 'F' },
        { name: '_3yc', age: 7, sex: 'Neither' },
        { name: 'StH_\fJE3_fJX', age: 10, sex: 'M' },
        { name: '7bo8\fwt73_H', age: 7, sex: 'F' } 
    ]
*/

Detailed Documentation of all Generators

Number generators

integers - gen.int

var gen = require('jssmartcheck').gen;

// generate 10 random integers
gen.sample(gen.int, 10); // [ 0, 0, -1, 1, -2, 4, 1, 0, -6, 0 ]

positive integers - gen.int.positive

var gen = require('jssmartcheck').gen;

// generate 10 random positive integers
gen.sample(gen.int.positive, 10); // [ 0, 0, -1, 1, -2, 4, 1, 0, -6, 0 ]

integer in a range - gen.int.between


var gen = require('jssmartcheck').gen;

// generate 10 integer in the range [min, max] (both inclusive)
gen.sample(gen.int.between(10, 100), 10); // [ 55, 31, 10, 75, 84, 19, 59, 34, 86, 12]

floating point number - gen.float


var gen = require('jssmartcheck').gen;

// generate 10 floating point numbers
gen.sample(gen.float, 10); 

/* 
    [ 
        0,
        -9263.793444260955,
        1457.7880781143904,
        -23325.45812241733,
        -27032.062970101833,
        -22139.405994676054,
        53050.33131502569,
        30739.869456738234,
        25103.324092924595,
        65394.96577810496 
    ]
*/

large integer - gen.int.large


var gen = require('jssmartcheck').gen;

// generate 10 large integers
gen.sample(gen.int.large, 10); 

/*
    [ 
        1.7942217500110602e+308,
        2.9093457718352433e+306,
        3.6593154190409177e+307,
        8.085731107763065e+306,
        9.616694531726025e+307,
        1.1036431189239296e+308,
        1.7337810355081831e+308,
        1.7816857602101413e+308,
        6.798105794239869e+307,
        4.032906283193464e+307 
    ]
*/

unsigned integer - gen.uint


var gen = require('jssmartcheck').gen;

// generate 10 unsigned integers
gen.sample(gen.uint, 10);  //[ 0, 0, 3, 6, 14, 18, 23, 10, 21, 11 ]

String generators

strings - gen.string

var gen = require('jssmartcheck').gen;

// generate 10 strings
gen.sample(gen.string, 10); 

/*
    [ 
        '',
        '',
        '„',
        'šðœ',
        'K',
        '[²Wg',
        '\u0001çä',
        '"qt',
        'jK\u001c]ô',
        '²Ý»¼¶\tG' 
    ]
*/

Array generators

array - gen.arrayOf

var gen = require('jssmartcheck').gen;

// generate an array of integers
gen.sample(gen.arrayOf(gen.int), 1); // [ [0, 4, 2, 6] ]

WIP

Still working of the detailed documentation of rest of the generators. In the mean time, you can look at the tests to get a feel of how they work.

changelog

0.1.1 / 2015-02-28

  • Updated readme to install package from npm
  • fixed most of the linter issues. static analysis rules!
  • removed throwaway folder
  • Got a single distribution file finally. Had to use browserify --standalone (-s) option
  • random object generator
  • moved all other functions (except sample) from generators/index.js to generators/misc.js
  • default value for size parameter in string generators.
  • moved frequency generator to misc generators. Also wrote a test for any generator. Actually just a console.log
  • bugfix for frequency generator. Also wrote a somewhat proper test for frequency generator
  • added a default value for size for arrayOf
  • added a default max and min value for random number generator
  • Added dist directory to git ignore
  • Added dist files for the last time. Need to remove it from repo
  • Added a changelog
  • updated todo
  • Readme update
  • Updated readme
  • Have released the readme page since the library can be installed from github
  • Can now do npm install <github_location> and start using the lib
  • Added more examples and updated the readme
  • A discontinuity use-case
  • Added an example test
  • More useful messages for both passing and failing test cases
  • Wrote a shrinker for ints using generatorsga . Looks like a good idea for now :)
  • example test fix
  • Updated todo
  • bug fix for check function
    • Added an example test for string concat operation
    • End of lodash dependency
  • extend api in utils
    • Further addition of util methods - Resolved merge conflicts
  • Merge branch 'master' of github.com:mukeshsoni/jssmartcheck
  • refactoring of generators
  • Merge branch 'master' of https://github.com/mukeshsoni/jssmartcheck
  • Added isObject api to utils
  • Added max iterations to suchthat
  • Utils implementation of _.range
  • Util implementation of _.random
  • number generator int.between fix
  • Updated todo list
  • Added suchThat generator manipulator
  • Updated todo list
  • Updated todo list
  • Updated todo
  • Added function generator
  • Reverted numbers generators to be bounded by size
  • Generating object of any shape
  • Forgot to remove .only from a test
  • added a frequency generator to select generator based on weighted average
  • Added some more basic generators which can be composed to get the more complex ones
  • Proper use of size; use a combination of random and size.
  • accept size param
  • Added falsy generator
  • Added some util functions
  • Added ascii and ascii string generators
  • wrongly interpreted peerdependencies
  • Added some more tests for string.matches
  • Patterns with pipes now supported
  • generator for string.matches. Not handling special cases from now. Mostly copied from randexp.js
  • Merge
  • wrap the gens inside the generator namespace using the extend api
  • Initial naive implementation of forAll and check functions
  • Added extend method to generators
  • Removed generator_tests file
  • Directory restructuring
  • int.positive and int.between apis
  • Added an arrayOf generator
  • Added a couple of string generators
  • Added constant file Basic integer generator
  • Setup dependencies for testing, es6 to es5 conversion and generating distribution file on npm publish
  • Initial commit

0.1.0 / 2015-02-26

  • updated todo
  • Readme update
  • Updated readme
  • Have released the readme page since the library can be installed from github
  • Can now do npm install <github_location> and start using the lib
  • Added more examples and updated the readme
  • A discontinuity use-case
  • Added an example test
  • More useful messages for both passing and failing test cases
  • Wrote a shrinker for ints using generatorsga . Looks like a good idea for now :)
  • example test fix
  • Updated todo
  • bug fix for check function
    • Added an example test for string concat operation
    • End of lodash dependency
  • extend api in utils
    • Further addition of util methods - Resolved merge conflicts
  • Merge branch 'master' of github.com:mukeshsoni/jssmartcheck
  • refactoring of generators
  • Merge branch 'master' of https://github.com/mukeshsoni/jssmartcheck
  • Added isObject api to utils
  • Added max iterations to suchthat
  • Utils implementation of _.range
  • Util implementation of _.random
  • number generator int.between fix
  • Updated todo list
  • Added suchThat generator manipulator
  • Updated todo list
  • Updated todo list
  • Updated todo
  • Added function generator
  • Reverted numbers generators to be bounded by size
  • Generating object of any shape
  • Forgot to remove .only from a test
  • added a frequency generator to select generator based on weighted average
  • Added some more basic generators which can be composed to get the more complex ones
  • Proper use of size; use a combination of random and size.
  • accept size param
  • Added falsy generator
  • Added some util functions
  • Added ascii and ascii string generators
  • wrongly interpreted peerdependencies
  • Added some more tests for string.matches
  • Patterns with pipes now supported
  • generator for string.matches. Not handling special cases from now. Mostly copied from randexp.js
  • Merge
  • wrap the gens inside the generator namespace using the extend api
  • Initial naive implementation of forAll and check functions
  • Added extend method to generators
  • Removed generator_tests file
  • Directory restructuring
  • int.positive and int.between apis
  • Added an arrayOf generator
  • Added a couple of string generators
  • Added constant file Basic integer generator
  • Setup dependencies for testing, es6 to es5 conversion and generating distribution file on npm publish
  • Initial commit