Software QA FYI - SQAFYI

Testing a Sass Function in 5 Minutes

By: Hugo Giraudel

The other day, I was playing with the include-media library from Eduardo Bouças and I wanted to quickly test a function I built so I started writing a little mixin to help me test a lot of different scenarios. After a couple of minutes, I came up with the most minimalistic Sass testing engine you could possibly get.

While this article might be slightly technical, I believe it can be helpful to many people as testing it should be the responsibility of every developer. Also, when going through things one after the other, you’ll see that it actually is not that difficult to understand.

Creating a dummy function to test
Everything starts with a function to test. For our purpose, I suggest we go with a very simple function. Let’s say, a function to double a number.

@function double($value) {
@return $value * 2;
}


Sounds simple enough. Although, and only for our demo concerns, we are going to voluntarily introduce a bug inside our function so that we can actually see that one of our tests fails.

@function double($value) {
// Voluntarily introduced bug for demonstration purpose
@if $value == 3 {
@return 5;
}

@return $value * 2;
}
Writing tests

You might find it surprising, but writing tests in our system is as simple as writing a Sass map where keys are function inputs, and values are expected results.

$tests-double: (
1: 2,
2: 4,
3: 6,
4: 8
);


That’s it! We’ve written our tests. Again: on the left side are the inputs, and on the right side the expected outputs.

The test runner
So far, so good. We have built our function and we have written our tests. We now only need to create the test runner.

If you are familiar with Sass, you might already understand where this is going. Our test runner is going to iterate on the test map, calling the function for each input and making sure that it matches the expected output. Then, it will print the result of our tests.

Here is what our test runner looks like:
/// Run a function ($function) on a test suite ($tests)
/// @param {Map} $tests - Test suite
/// @param {String} $function - Name of function to test
@mixin run-tests($tests, $function) { .. }


Alright. Let’s dig into the belly of the beast. The idea is to build a string with the result of each test, and once everything has been done, print the string with the @error directive. We could also pass it to the content property of a pseudo-element for instance, but it’s slightly more complex so we’ll stick to @error.

First thing to do is to iterate on the test suite. For each test, we dynamically call the function from its name (with the call(..) function) and we check if the result is as expected.


@mixin run-tests($tests, $function) {
$output: ';

@each $test, $expected-result in $tests {
$result: call($function, $test...);

@if $result == $expected-result {
// Test passed
$output: $output + 'Test passed; ';
} @else {
// Test failed
$output: $output + 'Test failed; ';
}
}


// Print output
@error $output;
}

Full article...


Other Resource

... to read more articles, visit http://sqa.fyicenter.com/art/

Testing a Sass Function in 5 Minutes