[每周一译]如何以及为什么要对Sass进行单元测试

当设计系统是真实的来源,并且订户可以轻松自行修改代码时,代码经过充分测试就变得非常重要了。 Lindsey分享了我们如何对Sass进行单元测试以及如何进行单元测试。

在Sparkbox社区,我们非常熟悉和喜爱设计系统,特别是当这些系统出色完成了任务,而且不断地得到改进。优秀的设计系统都是被接受和期待的,且具有巨大的潜在价值的。

作为团队的一员,我最近正为一个企业客户构想,设计,建立以及持续优化一个设计系统。这个特殊的设计系统分布在多个产品当中,是我们这两年半来一直在迭代的产品。它已经被少数几个我们称作“订阅者”的用户所接受。由于我们的设计系统是所有公司众多品牌和在线渠道中风格的“真实来源”,因此我们投入系统的样式的准确性非常重要。例如,如果我们要进行更新,但是这个更新破坏了订阅者的风格,则可能会影响生产代码。 这将导致我们的设计系统不信任,并可能影响我们为订户提供良好服务的能力受到质疑。

我们知道我们的企业客户的设计系统需要始终可靠,我们会非常认真地对其进行任何更新。最近,订阅者要求我们提供Sassmixinsfunctions两个函数,用于测试颜色,排版和间距等功能。其实这些东西已经存在的了,但是由于订阅者是无法进入我们的代码库,所以他们是用不了这些功能的。因此我们需要把我们的代码做得更加通用,但是如果这些更改操作不正当的话,将会对我们的底层代码有具大的影响。我们从不希望订阅者担心我们所做的更改会破坏他们的代码,因此我们开始研究如何对Sass进行单元测试。

一、什么是单元测试?

“你应该对你的sass代码进行单元测试吗?”这是一个很好的问题。然而,”你为什么想要这样做?”无疑是一个更好的问题。

确保你的代码都正确编译
用到sass的mixinsfunction的项目在单元测试中获益很大,因为其的确保证了你的代码的编译正确性。如果你的项目总体上都不怎么用到sassmixinsfunction,那么单元测试对你来说没啥用。mixinsfunction是sass的两个非常强大的特性,但是对于检查这些输出的准确性,sass就不那么好处理了。你的css可能依然可以正常编译,但是输出却不一定是我们所预期的。就我们的设计系统而言,以我们改变某些sass文件为例,这些例子当中,可能会改变级联并影响有关颜色或字体的编译样式。

快速捕获输出错误
对Sass进行单元测试的另一个原因是因为Sass是可以可变的库。这就会影响我们的css输出,这些我们都不可能立即发现的。进行单元测试将有助于在我们的代码发送到生产之前捕获输出错误,并允许我们在库更改时更快地调试这些错误。

对于我们当前的项目,我们使用一个名为True、由Miriam Suzanne开发,用于进行单元测试的开源工具。该工具目前维护良好,有多种方法可将其集成到您的项目中。

二、如何使用True工具?

有不少方法可以实现True,但下面的这些设置说明均来自True文档网站上的“使用Mocha(或其他JS Test Runners)”。这些说明假设您在项目中设置了npmnode-sass

首先,用npm安装True:

npm install sass-true

设置测试文件结构的方式完全取决于你自己。但是,如果您已经使用Sass partials来组织项目的样式,我建议您以类似的方式设置测试。您的单元测试是用Sass编写的,因此您可以使用partials来组织文件。下面是我们如何将我们的单元测试与Jasmine测试和设置文件一起组织的示例:
这里写图片描述

然后,将True导入项目(您的文件路径可能不同)并指定要测试的Sass文件:sass-tests.scss

// sass-tests.scss
@import "node_modules/sass-true/sass/true";
@import "../../../my-styles.scss";

接下来,您将编写用于设置Sass测试的JavaScript文件。我将依据Describe / It测试模式进行测试。Describe / It测试模式提供了测试结构,使测试的输出易于理解。

新建一个js测试文件:true-sass-spec.js

//true-sass-spec.js
var path = require('path');
var sassTrue = require('sass-true');

var sassFile = path.join(__dirname, 'true-sass-tests/sass_tests.scss');
sassTrue.runSass({file: sassFile}, describe, it);

现在你进行到了最有趣的一步——为我们的sass代码编写单元测试条件。

编写测试条件有两种主要方法,具体取决于您是在测试function还是mixin。我将从一个测试mixin的例子开始。

这是mixin在你的Sass中的样子:

@mixin primary-header {
 font-family: "Helvetica", Arial, sans-serif;
 font-size: 2rem;
 line-height: 2.5rem;
 color: #333;
 text-decoration: underline;
}

以下是对它的测试:

// Describe what you're testing
@include describe('The primary-header mixin') {
  // Explain what it should do
  @include it('outputs the properties of our primary header.') {
    // Assert the output of the mixin matches the expected result
    @include assert {
      @include output {
        @include primary-header();
      }
      @include expect {
        font-family: "Helvetica", Arial, sans-serif;
        font-size: 2rem;
        line-height: 2.5rem;
        color: #333;
        text-decoration: underline;
      }
    }
  }
}

当此测试通过时,以下是它在控制台console中的大概样子:
这里写图片描述

请注意,这些输出读起来就像正是发生了什么的句子。这是故意的,是通过使用Describe / It模式来完成的。

您还可以在上面的代码中使用contains而不是expect来测试子集是否存在某个属性。如果输出中有很多属性,但是并不需要测试所有属性,这样做则会减少大量代码,非常有用。更多的方法在True website上有说明。

这是我们想测试的Sass的function的一个例子:

@function divide-height ($height) {
  $startingHeight: 100%;
  @return $startingHeight / $height;
}

以下是对它的测试:

// Describe the function
@include describe('The `divide-height` function') {
  // Describe what it should do
  @include it('returns a valid height when given valid input.') {
    // Test your function with an input
    $test: divide-height('2');
    // What the expected value should be
    $expect: 50%;
    // Assert they are equal, otherwise show the error message
    @include assert-equal($test, $expect, "The height is either incorrect or does not exist.");
  }
}

控制台将输出失败,因为我们传递给我们的function(2)的输入是一个字符串,而不是一个数字,因此导致失败。
这里写图片描述

如果传递了正确输入的测试:

// Describe the function
@include describe('The `divide-height` function') {
  // Describe what it should do
  @include it('returns a valid height when given valid input.') {
    // Test your function with an input
    $test: divide-height(2);
    // What the expected value should be
    $expect: 50%;
    // Assert they are equal, otherwise show the error message
    @include assert-equal($test, $expect, "The height is either incorrect or does not exist.");
  }
}

则会通过测试:
这里写图片描述

三、先写一个不能通过的测试

感谢Sparkboxer Catherine的提醒,我最近在编写单元测试时学到的一个技巧是,你想先将测试编写为失败,然后调整它们以使它们通过。如果您的测试在您编写后立即通过,那么它们实际上可能无法正常工作。我们最近在测试一个无法正常工作的mixin时遇到了这种情况。结果是mixintest都没有返回任何输出,但测试没有失败,因为它们相等了(都没有输出)。如果我们先把测试写成失败,我们会更早地发现这个问题。

四、测试更多,担心更少

设计系统,web apps或任何在Sass中使用mixinfunction的项目都可以从单元测试中获益,以确保代码按预期进行编译。您可以及时发现可能会被忽视的意外输出。如果你确信你的测试会发现潜在的错误,那么在重构时你也会少担心。Sass单元测试是您可以添加到您的武器库中以确保正确构建Web的一件事。

原文:How and Why We Unit Test Our Sass ——LINDSEY WILD(06-25-18)

猜你喜欢

转载自blog.csdn.net/qq_41882147/article/details/81367639