前端進階-編寫測試程式碼
Gulp
Gulp 是基於 node.js
的一個前端自動化構建工具
,開發這可以使用它構建自動化工作流程(前端整合開發環境)。 使用 gulp 你可以簡化工作量,讓你把重點放在功能的開發上,從而提高你的開發效率和工作質量。
安裝 Gulp
在安裝 gulp 之前,需要先安裝 Node.js
和 NPM
。我們可以通過訪問 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
是用於內容組織的工具,與縮排的作用類似。 describe
和 it
函式的使用創造了用於組織資訊的提綱。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.js
和 AddressBook.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,包括非同步測試全部通過。
相關文章
- 使用 xunit 編寫測試程式碼
- 使用Pandaria編寫API自動化測試進階用法API
- 如何編寫優秀的測試程式碼|單元測試
- 前端進階課程之單元測試前端
- 前端面試之手寫程式碼前端面試
- 「中高階前端面試」JavaScript手寫程式碼無敵祕籍前端面試JavaScript
- 程式碼寫作測試
- 為程式碼編寫穩定的單元測試 [Go]Go
- 無需編寫程式碼,API業務流程測試,零程式碼實現API
- 前端筆試之手寫程式碼(一)前端筆試
- 程式碼規範之前端編寫碼規範前端
- 手寫現代前端框架diff演算法-前端面試進階前端框架演算法面試
- 如何用 JMeter 編寫效能測試指令碼?JMeter指令碼
- 效能測試——壓測工具locust——指令碼初步編寫指令碼
- 前端工程師進階之旅-手撕程式碼【前端常用方法以及面試常見題】前端工程師面試
- .NET Core TDD 前傳: 編寫易於測試的程式碼 -- 縫
- 前端面試必會手寫的程式碼前端面試
- Laravel 單元測試實戰(2)- 編寫實際功能並讓程式碼測試透過Laravel
- Golang 編寫測試教程Golang
- 前端頁面測試如何定位漏測程式碼前端
- 介面測試進階篇
- .NET Core TDD 前傳: 編寫易於測試的程式碼 -- 依賴項
- .NET Core TDD 前傳: 編寫易於測試的程式碼 -- 構建物件物件
- 開發測試用例:手動擼程式碼 VS 填鴨式編寫
- 編寫一個 Makefile 檔案,對階段專案一的程式碼進行自動化編譯編譯
- 如何編寫測試團隊通用的Jmeter指令碼JMeter指令碼
- 你寫的前端程式碼有做過單元測試嗎?使用什麼工具?怎麼測試的?前端
- 測試用例編寫方法
- 不用寫程式碼,也能做好介面測試
- 軟體測試員必須編寫程式碼嗎?掌握多少程式設計能力才夠?程式設計
- Redux 進階 -- 編寫和使用中介軟體Redux
- 在 VSCode 中編寫 Markdown 的進階指南VSCode
- .NET Core TDD 前傳: 編寫易於測試的程式碼 -- 全域性狀態
- .NET Core TDD 前傳: 編寫易於測試的程式碼 -- 單一職責
- Laravel 單元測試實戰(3)- 編寫整合測試確保介面和資料庫程式碼正確Laravel資料庫
- Sublime 編寫編譯 swift程式碼編譯Swift
- 【前端面試】同學,你會手寫程式碼嗎?前端面試
- 前端進階:二進位制資料的操控—-附專案程式碼前端