Article : Testing a Sass Function in 5 Minutes

Extract from Sitepoint article “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 is 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;

At this point, we have our system working. Let’s run it on our test suite to see what it looks like.

@include run-tests($tests-double);

Test passed; Test passed; Test failed; Test passed;

Hey! That’s a start right? Now we only need to make the output a bit more helpful (and friendly).

Pimping the output

This is the moment where you can customize the output to make it look like you want. There is no single way to do this, you can output whatever you prefer. Note that as per the CSS specification, you can have a line break in your string using \a.

In my case, here is what I went with:

Continue reading this article on SitePoint …

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.