Skip to main content

One post tagged with "fast-check"

View All Tags

· 3 min read
Jesse Mitchell

Hi all!

This release is focused on introducing fuzzing / property based testing to the Pineapple framework, which should make it ridiculously easy to cover a variety of test cases with simple test expressions.

Utilizing the amazing fast-check npm package, Pineapple is now able to fuzz a handful of test-cases and shrink any counter-examples down to the smallest test-case it can find to trip an error.

For example:


/**
* Using fuzz testing, this will cover a handful of scenarios,
* positives, negatives, zeroes
* Without you needing to go over each example explicitly.
*
* @test #integer, #integer returns @ as number
* @test #integer, #integer returns args.0 + args.1
*
* The above test is a little silly since it's embedding the
* same logic in the test, but demonstrates that it's possible.
*/
function add (a, b) {
return a + b
}

/**
* @test #array(#integer) returns @ as number
* @test #array(#string, { minLength: 1 }) throws
* @test [1, 2, 3] returns 6
* @test [#integer, 2, 3] returns args.0.0 + 5
* @test [] returns 0
*/
export function sum (values) {
if (values.some(i => typeof i !== 'number')) throw new Error('An item in the array is not a number.')
return values.reduce((a, b) => a + b, 0)
}

/**
* @test { name: #string, age: #integer(1, 20) } throws
* @test { name: 'Jesse', age: #integer(21, 80) } returns cat(args.0.name, ' is drinking age.')
*/
export function drinkingAge ({ name, age }) {
if (age >= 21) return `${name} is drinking age.`
throw new Error(`${name} is not drinking age.`)
}

This works great for handling a variety of scenarios without having to write much code, and also works with the snapshot tech built into Pineapple (making it even easier to pin functionality for a handful of test-cases).

When your tests fail though, Pineapple & Fast-Check will work together to help identify the issue.

/**
* A simple template function.
* @test 'Hello $0' ~> #string returns cat('Hello ', args.0)
* @param {string} templateString
*/
export function template (templateString) {
/** @param {string} replace */
return replace => templateString.replace(/\$0/g, replace)
}
✖ Failed test (template): 'Hello $0' ~> #string returns cat('Hello ', args.0)
>> file:///Users/jesse/Documents/Projects/pineapple/test/fuzz.js:35
- Expected
+ Received

- Hello $$
+ Hello $
Failing Example: [
"$$"
]
Shrunk 4 times.
Seed: -2121637705

Fast-Check shrinks the test-case to help you as the developer realize: "Oh! The replace string needs escaped because the $ character is special in the replace function."

If you wish to read up more on the Fuzz Testing technology, you may do so here.