Sass をごりごり書いていると、本当に正しい値を返しているのかテストしたくなることがあります。探してみると Sass 用のユニットテストのライブラリ(True)もあるようでしたが、色々インストールするのもめんどうだし、僕の場合そこまでの規模でも無いなという感じだったので、Sass(+ Node)のみで完結するお手軽なテストを作ってみました。
ディレクトリ構成
概要としては/tests/api/api.scssにテストに必要な諸々を定義、/tests/tests.scssにテストを書きpackage.jsonから実行できるようにする、という流れです。
注意点として、関数(@function)のテストしかできないということです。なのでセレクタ内やミックスインに直書きするのではなく、なるべく関数を定義してそれをセレクタ内やミックスイン内で使うのがテスタブルではと思います。
ディレクトリ構成としては下記のような感じになります。
/Project
├ ...
├ package.json
├ /functions/_functions.scss // テストしたい関数群
└ /tests
├ /api/_api.scss // テスト用ライブラリ
└ tests.scss // ここにテストを書く
package.json
Sass のインストールとかそもそもの package.json の書き方まで説明すると大変なのでユニットテストの部分だけ書きます。要は Sass のコンパイルが実行できさえすれば良いので下記のような script を追加すれば良いです。
...
"scripts": {
"sass-test": "scss tests/tests.scss"
}
...
で、コンソールからnpm run sass-testと実行すれば OK です。package.json に書くのがめんどうであればコンソールで直接scss tests.scssとしても大丈夫です。
/api/_api.scss
一致するかどうかをチェックする関数しかありませんw 他にも必要なら流用して追加してみてください。
//
// @param string $message テストの名前
//
@mixin test($message) {
@debug $message;
@content;
}
//
// @param mixed $expected こうなるはずの値
// @param mixed $actual 実際の値
//
@mixin assert-equals($expected, $actual) {
@if ($expected == $actual) {
@debug 'OK!';
} @else {
@warn 'FAILURES! Expected: #{$expected} Actual: #{$actual}';
}
}
/tests/tests.scss
/api/_api.scssとテストしたい関数群を読み込んでテストを書きます。
@import '../functions/functions';
@import 'api/api';
//
// px を rem に変換するオリジナル関数のテスト
//
@include test('[function] px2rem()') {
$rem: px2rem(15px, 16px);
@include assert-equals(1rem, $rem);
$rem: px2rem(16px, 10px);
@include assert-equals(1.6rem, $rem);
}
で、コンソールから実行すると下記のように出力されます。
$ npm run sass-test
> sass-basis@4.3.2 sass-test /path/to/Project
> scss tests/tests.scss
tests/api/_api.scss:2 DEBUG: [function] px2rem()
WARNING: FAILURES! Expected: 1rem Actual: 0.875rem
on line xx of tests/api/_api.scss, in `assert-equals'
from line xx of tests/tests.scss, in `@content'
from line xx of tests/api/_api.scss, in `test'
from line xx of tests/tests.scss
tests/api/_api.scss:xx DEBUG: OK!
こけたときは WARNING が、パスしたときは OK! となります。