前端进阶-编写测试代码

版权声明:如有转载请注明出处 http://blog.csdn.net/modurookie ,谢谢 https://blog.csdn.net/MoDuRooKie/article/details/84792452

Sublime Text 快捷键

Gulp

Gulp 是基于 node.js 的一个前端自动化构建工具,开发这可以使用它构建自动化工作流程(前端集成开发环境)。 使用 gulp 你可以简化工作量,让你把重点放在功能的开发上,从而提高你的开发效率和工作质量。

安装 Gulp

在安装 gulp 之前,需要先安装 Node.jsNPM。我们可以通过访问 Nodes官网 并下载最新版的 NodeJS,来下载和安装 NodeJS 和 NPM。然后安装 Gulp

在这里插入图片描述

每个 Gulp 项目都以一个 Gulp 文件开始,此文件位于项目的根目录中 gulpfile.js,并规定你在运行 Gulp 时应执行的所有任务。由于 Gulp 文件本质上是一个 node.js 的脚本, 因此我们首先需要将 Gulp 作为依赖项,然后设置一个默认的任务。

var gulp = require('gulp');
gulp.task('default', function() {
	console.log("Hello, Gulp!");
});

在这里插入图片描述

Grunt 任务和 Gulp 流

在这里插入图片描述

Sass

Sass 是一款强化 CSS 的辅助工具,它在 CSS 语法的基础上增加了变量 (variables)、嵌套 (nested rules)、混合 (mixins)、导入 (inline imports) 等高级功能,这些拓展令 CSS 更加强大与优雅。

当我们在 Sass 中编写样式表时,可以摆脱很多 CSS 的烦恼,并将其编译为纯 CSS。不要手动为每个浏览器设置 CSS 属性,使用自动前缀完成自动设置。

Jasmine

测试各类同步及异步功能,JavaScript 没有内置测试模块,我们需要使用库来获取此类功能。Jasmine 2.2

<!--引入 jasmine 库-->
<script src="lib/jasmine-2.2.0/jasmine.js"></script>
<script src="lib/jasmine-2.2.0/jasmine-html.js"></script>
<script src="lib/jasmine-2.2.0/boot.js"></script>
<!--引入源文件(应用代码)-->
<script src="src/Player.js"></script>
<script src="src/Song.js"></script>
<!--规格说明(测试文件)-->
<script src="spec/SpecHelper.js"></script>
<script src="spec/PlayerSpec.js"></script>

describe 是用于内容组织的工具,与缩进的作用类似。 describeit 函数的使用创造了用于组织信息的提纲。it 用于指明程序规格(spec),它是封装测试代码的容器,帮助明确程序具体特性。如果所有 spec 内容返回 true 则该 spec 通过,其中任何一项出现问题都会造成测试失败。it 定义了这一测试的边界,describe 确定了一套测试内容,由一组相关 spec 组成。这套测例定名为 Player 表示其内容都与播放器相关。

// describe 函数-调用标记为黑色
describe("Player", function() {
  var player;
  var song;
  beforeEach(function() {
    palyer = new Player();
    song = new Song();		
  });
  it("should be able to play a Song", function() {
    player.paly(song);
    // expect 函数,后面跟一个匹配器-调用标记为绿色
    expect(player.currentlyPlayingSong).toEqual(song);

   // ...
    expect(player).toBePlaying(song);
  });
  // ...
})

不同的组织测试的方法并没有对错之分,它取决于个人喜好。

编写测试

expect(add(0.1, 0.2)).toBe(0.3);
// 其运行效果如下
add(0.1, 0.2) === 0.3 // 表达式返回 true 测试通过
// 如果想对结果取反,在匹配器前加 not
expect(add(0.1, 0.2).not.tobe(0.1));

每个测试都是从 expect 调用开始,可以把它视为测试的出发点,开启了测试流程。expect 函数接收一个通常称为 actual 的单变量实例,add(0.1, 0.2) 是我们的测试对象。接下来告诉测试框架要对结果进行怎样的比较,比较函数又称为匹配器(matcher),是跟在 expect 之后的方法。Jasmine 有大量匹配器可用,也可以自定义它们。toBe 在语义上表示严格等于,最后我们把期望值传到匹配器。

红绿重构(refactor)周期

先写出测试,开始时候没有进行实现,所有测试点均失败。之后开始写代码以通过测试,测试保证你能安全地进行代码重构,为系统添加新特性。地址本示例如下:

先创建两个文件 AddressBookSpec.jsAddressBook.js。然后更新 html 来运行它们:

<!--引入 jasmine 库-->
<script src="lib/jasmine-2.2.0/jasmine.js"></script>
<script src="lib/jasmine-2.2.0/jasmine-html.js"></script>
<script src="lib/jasmine-2.2.0/boot.js"></script>
<!--引入源文件(应用代码)-->
<script src="src/AddressBook.js"></script>
<!--规格说明(测试文件)-->
<script src="spec/AddressBookSpec.js"></script>

describe 建立 AddressBook 测试组,在其中用 it 添加内容要求应用能够添加联系人,采用面向对象方法处理这个问题,新建一个 AddressBook对象,向其中加入联系人,需要应用中有 addContact 方法,向方法中传入对象作为参数,下一步是确定合适的方法,检测联系人信息是否成功加入。如果获得地址本的第一个联系人应该与刚加入的联系人相同。

describe("Address Book", function() {
  it("should be able to add a contact", function() {
    var addressBook = new AddressBook(),
        thisContact = new Contact();

    addressBook.addContact(thisContact);
    expect(addressBook.getContact(0)).tobe(thisContact);
  });
});
function AddressBook() {
  this.contacts = [];
}

AddressBook.prototype.addContact = function(contact) {
  this.contacts.push(contact);
}

AddressBook.prototype.getContact = function(index) {
  return this.contacts[index];
}

移除冗余代码

describe("Address Book", function() {
  it("should be able to add a contact", function() {
    var addressBook = new AddressBook(),
        thisContact = new Contact();

    addressBook.addContact(thisContact);
    expect(addressBook.getContact(0)).tobe(thisContact);
  });

  it("should be able to delete a contact", function() {
    var addressBook = new AddressBook(),
        thisContact = new Contact();

    addressBook.addContact(thisContact);
    addressBook.deleteContact(0);
    expect(addressBook.getContact(0)).not.toBeDefined();
  });
});

上述代码中,我们发现一份冗余代码,在每份规格说明中都要重设 Contact 和 AddressBook。一方面这让我们的代码耦合度很低,另一方面我们在低效手动操作。Jasmine 提供了一个函数帮助我们在每个测例前运行特定代码,函数名为 beforeEach

var addressBook,
    thisContact;
    
beforeEach(function() {
  addressBook = new AddressBook(),
  thisContact = new Contact();
});

测试异步代码

我们需要在函数结束时传递必要信息。

AddressBook.prototype.getInitialContacts = function(cb) {
  var self = this;
  setTimeOut(function() {
    self.initialComplete = true;
    if (cb) {
      return cb();
    }
  }, 3);
}

在函数运行结束后,可以看到构造函数中将初值设置为 false。

describe("Async Address Book", function() {
  it("should grab initial contacts", function() {
    var addressBook = new AddressBook();
    address.getInitialContacts();
    expect(addressBook.initialComplete).toBe(true);
  });
});

对异步函数的正确测试

describe("Async Address Book", function() {
  var addressBook = new AddressBook();

  beforeEach(function(done) {
    addressBook.getInitialContacts(function() {
      done();
    });
  });

  if("should grab initial contacts", function(done) {
    expect(addressBook.initialComplete).toBe(true);
    done();
  });
});

加上 beforeEach 函数,在异步函数回调内容中加入 done(),它会通知测试框架。把 done 作为参数传入规格说明,测试结束再调用 done,包括异步测试全部通过。

猜你喜欢

转载自blog.csdn.net/MoDuRooKie/article/details/84792452