聊聊前端測試

長期以來,前端測試並非開發者必需要編寫的,但隨着前端工程化的發展,前端測試已經成爲持續集成中重要的組成部分,編寫前端測試能夠達到如下目的:前端

  • 正確性:能夠驗證代碼的正確性,在上線前內心有底
  • 自動化:經過編寫測試用例,能夠作到一次編寫,屢次運行
  • 解釋性:測試用例中會設計如何使用這些 API,良好的測試用例比開發文檔更直觀
  • 驅動開發:要保證代碼的可測試性,就須要在開發中注意 API 的設計。TDD 測試驅動開發的思想就是在開發階段編寫可測試性代碼,以保證代碼的可測試性。
  • 保證重構:互聯網行業產品迭代速度很快,迭代後必然存在代碼重構的過程,那怎麼才能保證重構後代碼的質量呢?有測試用例作後盾,就能夠大膽的進行重構

單元測試

單元測試包括:斷言,測試框架,測試用例,測試覆蓋率,mock 等幾個方面。目的是讓開發者明確知道代碼結果git

斷言

斷言:保證最小單元是否正常運行檢測方法。github

測試框架

測試框架用於爲測試服務,它自己並不參與測試,主要用於管理測試用例和生成測試報告,提高測試用例的開發速度、可讀性和可維護性。常見的測試框架有:mocha,jest,jasmine 等。web

測試風格

一般有如下兩種測試風格,開發者能夠根據狀況選擇。編程

  • 測試驅動開發(TDD):關注全部的功能是否被實現,每個功能都具有對應的測試用例。
  • 行爲驅動開發(BDD):關注總體行爲是否符合預期,編寫的每一行代碼都有目的提供一個全面的測試用例集。
TDD 運行流程

TDD(Test Drived Develop)。TDD 的原理是在開發功能代碼以前,先編寫單元測試用例代碼,經過測試來推進整個開發的進行前端工程化

  • setup(單個測試用例開始以前)
  • suiteSetup(每個測試用例開始以前)
  • test(定義測試用例,並用斷言庫進行設置)
  • teardown(單個測試用例開始以後)
  • suiteTeardown(每個測試用例開始以後)
suite('Array', function() {
  setup(function() {
    // 測試用例開始以前
  });
  suite('#indexOf', function() {
    test('should return -1 when not present', function() {
      assert.equal(-1, [1, 2, 3].indexOf(4));
    });
  });
  teardown(function() {
    // 測試用例以後
  });
});
複製代碼
BDD 運行流程

BDD(Behavior Driven Development)。行爲驅動的開發,描述了軟件的行爲過程,能夠直接做爲軟件的需求文檔瀏覽器

  • before(單個測試用例開始以前)
  • beforeEach(每個測試用例開始以前)
  • it(定義測試用例,並用斷言庫進行設置)
  • after(單個測試用例開始以後)
  • afterEach(每個測試用例開始以後)
describe('Array', function() {
  before(function() {
    // 測試用例開始以前
  });
  describe('#indexOf', function() {
    it('should return -1 when not present', function() {
      [1, 2, 3].indexOf(4).should.equal(-1);
    });
  });
});
複製代碼

測試用例

測試用例(Test Case)是爲某個特殊目標而編制的一組測試輸入、執行條件以及預期結果,用來判斷一個代碼功能是否知足特定需求。測試用例最小須要經過正向測試和反向測試來保證對功能的覆蓋。安全

使用 it 來定義一個測試用例:服務器

it('should return -1 when not present', function(done) {
  // xxx
});
複製代碼

異步測試

在執行異步測試用例時,會將 done 函數注入實參。網絡

it('should return -1 when not present', function(done) {
  setTimeout(() => {
    done();
  }, 1000);
});
複製代碼

測試覆蓋率

測試覆蓋率用來判斷單元測試對代碼的覆蓋狀況。原理是經過向源代碼中注入統計代碼,用於監聽每一行代碼的執行狀況。能夠統計到該行代碼是否執行和執行次數。測試覆蓋率包括如下幾個方面:

  • 行覆蓋率(line coverage):是否每一行都執行了?
  • 函數覆蓋率(function coverage):是否每一個函數都調用了?
  • 分支覆蓋率(branch coverage):是否每一個 if 代碼塊都執行了?
  • 語句覆蓋率(statement coverage):是否每一個語句都執行了?

E2E 測試

E2E(End To End)測試是模擬用戶進行頁面操做,經過來判斷頁面狀態的變化,從而檢查功能是否運行正常的測試方法。

在使用 E2E 測試時,測試程序經常會自動打開瀏覽器,執行配置的操做,所以須要驅動瀏覽器,常見的庫有:

  • selenium/webdriver
  • nightwatch
  • puppeteer

性能測試

性能測試的範疇比較普遍,包括基準測試、壓力測試等。

基準測試

基準測試統計的是在多少時間內執行了多少次某個方法。經常使用 Benchmark 庫來編寫。

  • 面向切面編程(AOP)無侵入式統計。
  • Benchmark 基準測試方法,他並非簡單地統計執行多少次測試代碼後對比時間,它對測試有着嚴密的抽樣過程,執行多少次取決於採樣到的數據可否完成統計。根據統計次數計算方差。
var suite = new Benchmark.Suite();

// add tests
suite
  .add('RegExp#test', function() {
    /o/.test('Hello World!');
  })
  .add('String#indexOf', function() {
    'Hello World!'.indexOf('o') > -1;
  })
  // add listeners
  .on('cycle', function(event) {
    console.log(String(event.target));
  })
  .on('complete', function() {
    console.log('Fastest is ' + this.filter('fastest').map('name'));
  })
  // run async
  .run({ async: true });

// logs:
// => RegExp#test x 4,161,532 +-0.99% (59 cycles)
// => String#indexOf x 6,139,623 +-1.00% (131 cycles)
// => Fastest is String#indexOf
複製代碼

壓力測試

壓力測試主要是針對於服務器端,它能夠幫助咱們發現系統中的瓶頸問題,減小發布到生產環境後出問題的概率。還能預估系統的承載能力,使咱們能根據其作出一些應對措施。

對網絡接口作壓力測試須要檢查的幾個經常使用指標有吞吐率,響應時間和併發數,這些指標反映了服務器併發處理能力。

  • pv 網站當日訪問人數。
  • uv 獨立訪問人數。
  • qps 服務器每秒處理請求數。qps=pv/t。

經常使用的壓力測試工具:ab、JMeter。

安全測試

安全測試是比較專業的測試,測試人員須要瞭解常見的 web 攻擊方式,而後模擬攻擊測試的程序,以防上線後其餘不法人員使用一樣的方式對程序進行攻擊。前端常見的攻擊方式有:

  • XSS
  • SQL 注入
  • CSRF

功能測試

功能測試是對產品的各功能進行驗證,根據功能測試用例,逐項測試,檢查產品是否達到用戶要求的功能。常見的功能測試方法有冒煙測試、迴歸測試等。

冒煙測試

自由測試的一種,找到一個 bug 而後修復,而後專門針對此 bug。優缺點以下:

  • 節省時間。
  • 缺點覆蓋率極低。

迴歸測試

修改一處對總體功能所有測試,通常配合自動化測試。優缺點以下:

  • 大幅度下降出錯機率。
  • 時間耗費重。

測試相關庫

  • karma:使用真實的瀏覽器環境,而且可測試兼容性。
  • mocha:測試框架。
  • chai:斷言庫。
  • istanbuljs/nyc:覆蓋率庫。
  • backstopjs:測試 UI。
  • benchmark:基準測試。
  • phantomjs:無頭瀏覽器。
  • nightwatch:e2e 測試。
  • jest:大而全。

更多文章,歡迎 Star 和 訂閱個人博客

相關文章
相關標籤/搜索