JavaScripting

The definitive source of the best
JavaScript libraries, frameworks, and plugins.


  • ×

    Fast Check

    Property based testing framework for JavaScript (like QuickCheck) written in TypeScript
    Filed under 

    • 🔾30%Overall
    • 244
    • 22 hours
    • 🕩12
    • 👥6

    fast-check logo

    Property based testing framework for JavaScript/TypeScript

    Build Status npm version total downloads

    Coverage Status dependencies Status devDependencies Status Known Vulnerabilities

    Getting started

    Hands-on tutorial and definition of Property Based Testing: :checkered_flag: see tutorial.

    Property based testing frameworks check the truthfulness of properties. A property is a statement like: for all (x, y, ...) such as precondition(x, y, ...) holds property(x, y, ...) is true.

    Install the module with: npm install fast-check --save-dev

    Example of integration in mocha:

    const fc = require('fast-check');
    
    // Code under test
    const contains = (text, pattern) => text.indexOf(pattern) >= 0;
    
    // Properties
    describe('properties', () => {
      // string text always contains itself
      it('should always contain itself', () => {
        fc.assert(fc.property(fc.string(), text => contains(text, text)));
      });
      // string a + b + c always contains b, whatever the values of a, b and c
      it('should always contain its substrings', () => {
        fc.assert(fc.property(fc.string(), fc.string(), fc.string(), (a,b,c) => contains(a+b+c, b)));
      });
    });
    

    In case of failure, the test raises a red flag. Its output should help you to diagnose what went wrong in your implementation. Example with a failing implementation of contain:

    1) should always contain its substrings
        Error: Property failed after 1 tests (seed: 1527422598337, path: 0:0): ["","",""]
        Shrunk 1 time(s)
        Got error: Property failed by returning false
    
        Hint: Enable verbose mode in order to have the list of all failing values encountered during the run
    

    Integration with other test frameworks: ava, jasmine, jest, mocha and tape.

    More examples: simple examples, fuzzing and against various algorithms.

    Useful documentations:

    Why should I migrate to fast-check?

    fast-check has initially been designed in an attempt to cope with limitations I encountered while using other property based testing frameworks designed for JavaScript:

    • strong and up-to-date types - thanks to TypeScript
    • ability to shrink on fc.oneof - surprisingly some frameworks don't
    • easy map method to derive existing arbitraries while keeping shrink - some frameworks ask the user to provide both a->b and b->a mappings in order to keep a shrinker
    • kind of flatMap-operation called chain - able to bind the output of an arbitrary as input of another one while keeping the shrink working
    • biased by default - by default it generates both small and large values, making it easier to dig into counterexamples without having to tweak a size parameter manually
    • precondition checks with fc.pre(...) - filtering invalid entries can be done directly inside the check function if needed
    • verbose mode - easier troubleshooting with verbose mode enabled
    • replay directly on the minimal counterexample - no need to replay the whole sequence, you get directly the counterexample
    • custom examples in addition of generated ones - no need to duplicate the code to play the property on custom examples
    • model based approach - use the power of property based testing to test UI, APIs or state machines
    • logger per predicate run - simplify your troubleshoot with fc.context and its logging feature

    For more details, refer to the documentation in the links above.

    Issues found by fast-check in famous packages

    fast-check has been able to find some unexpected behaviour among famous npm packages. Here are some of the errors detected using fast-check:

    js-yaml

    Issue detected: enabling !!int: binary style when dumping negative integers produces invalid content [more]

    Code example: yaml.dump({toto: -10}, {styles:{'!!int':'binary'}}) produces toto: 0b-1010 not toto: -0b1010

    left-pad

    Issue detected: unicode characters outside of the BMP plan are not handled consistently [more]

    Code example:

    leftPad('a\u{1f431}b', 4, 'x') //=> 'a\u{1f431}b'  -- in: 3 code points, out: 3 code points
    leftPad('abc', 4, '\u{1f431}') //=> '\u{1f431}abc' -- in: 3 code points, out: 4 code points
    

    query-string

    Issue detected: enabling the bracket setting when exporting arrays containing null values produces an invalid output for the parser [more]

    Code example:

    m.stringify({bar: ['a', null, 'b']}, {arrayFormat: 'bracket'}) //=> "bar[]=a&bar&bar[]=b"
    m.parse('bar[]=a&bar&bar[]=b', {arrayFormat: 'bracket'})       //=> {bar: [null, 'b']}
    
    Show All