国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

使用 AVA 做自動化測試

Cruise_Chan / 2579人閱讀

摘要:單元測試,測試一個簡單的組件。接口測試,用戶信息接口測試。學習借鑒,一些使用做測試的開源項目。這里使用到的內置斷言斷言結果值等于我們想要的預期值,則測試通過。在里放入一個函數,函數自動執行,里面執行的結果必須拋出錯誤,則測試通過。

目錄

1、為什么選擇 AVA ?
2、API 概覽。
3、準備工作。
4、單元測試,測試一個簡單的工具函數。
5、使用 Promise、Async/await、Observable 。
6、使用 JSDOM 模擬瀏覽器環境。
7、單元測試,測試一個簡單的 React 組件。
8、Http 接口測試,GitHub 用戶信息接口測試。
9、串行測試。
10、快照斷言。
11、覆蓋率報告:nyc + Coveralls 。
12、持續集成:CircleCI 。
13、學習借鑒,一些使用 AVA 做測試的開源項目。
14、e2e測試框架推薦:TestCafe 。
15、參考。

為什么選擇 AVA

原子測試 - 名詞的鏈接屬于自己猜測,不知作者本人是否也是表達這個意思。
斷言 - 通俗的講,就是用來判斷 “ 函數的返回值 ” 與我們想要的值是否一致,一致則測試通過,不一致則不通過。

1、輕量,高效,簡單。
2、并發測試,強制編寫原子測試。
3、沒有隱藏的全局變量,每個測試文件獨立環境。
4、支持 ES2017,Promise,Generator,Async,Observable。
5、內置斷言,強化斷言信息。
6、可選的 TAP 輸出顯示。
7、為什么不用 Mocha,Tape,Tap?

官方文檔解釋:https://github.com/avajs/ava#faq

一些測試框架的對比:https://github.com/koajs/koa/...

API 概覽
test([title], implementation)                     基本測試
test.serial([title], implementation)              串行運行測試
test.cb([title], implementation)                  回調函數形式
test.only([title], implementation)                運行指定的測試
test.skip([title], implementation)                跳過測試
test.todo(title)                                  備忘測試
test.failing([title], implementation)             失敗的測試
test.before([title], implementation)              鉤子函數,這個會在所有測試前運行
test.after([title], implementation)               鉤子函數,這個會在所有測試之后運行
test.beforeEach([title], implementation)          鉤子函數,這個會在每個測試之前運行
test.afterEach([title], implementation)           鉤子函數,這個會在每個測試之后運行
test.after.always([title], implementation)        鉤子函數,這個會在所有測試之后運行,不管之前的測試是否失敗
test.afterEach.always([title], implementation)    鉤子函數,這個會在每個測試之后運行,不管之前的測試是否失敗
內置斷言

也可以用 chai, node assert 等其他斷言庫

.pass([message])                                  測試通過
.fail([message])                                  斷言失敗
.truthy(value, [message])                         斷言 value 是否是真值
.falsy(value, [message])                          斷言 value 是否是假值
.true(value, [message])                           斷言 value 是否是 true
.false(value, [message])                          斷言 value 是否是 false
.is(value, expected, [message])                   斷言 value 是否和 expected 相等
.not(value, expected, [message])                  斷言 value 是否和 expected 不等
.deepEqual(value, expected, [message])            斷言 value 是否和 expected 深度相等
.notDeepEqual(value, expected, [message])         斷言 value 是否和 expected 深度不等
.throws(function|promise, [error, [message]])     斷言 function 拋出一個異常,或者 promise reject 一個錯誤
.notThrows(function|promise, [message])           斷言 function 沒有拋出一個異常,或者 promise resolve
.regex(contents, regex, [message])                斷言 contents 匹配 regex
.notRegex(contents, regex, [message])             斷言 contents 不匹配 regex
.ifError(error, [message])                        斷言 error 是假值
.snapshot(expected, [message])                    將預期值與先前記錄的快照進行比較
.snapshot(expected, [options], [message])         將預期值與先前記錄的快照進行比較
準備工作

務虛已過,編寫測試用例之前我們需要先安裝 AVA
先全局安裝:npm i --global ava
再在項目根目錄安裝一次:npm i --save-dev ava
這是通俗的安裝方式,全局安裝方便 AVA 自身命令行調用,不用太糾結。

像我們剛剛說的,AVA 已經內置支持 ES2017 的語法,安裝 AVA 的時候已經幫我們安裝了一些關于 babel 的模塊,不過我們還再安裝幾個我們需要用到的 babel 模塊,如下。
npm i --save-dev babel-polyfill babel-preset-es2015 babel-preset-react babel-preset-stage-0

babel-polyfill                        // 包含 ES2015 及以后的功能函數,如:Object.assign
babel-preset-es2015                   // 支持 ES2015 語法
babel-preset-react                    // 支持 React 語法
babel-preset-stage-0                  // 支持 ECMA TC39 對 JS 語言定義的最早一個階段的想法的語法

關于 AVA 的一些基礎配置的意思,可以查看一下官方文檔。
實際用到的配置也不多,我們在 package.json 文件中配置一下 AVA :

"scripts": {
  "test": "ava --verbose"             // 添加測試命令,方便我們直接輸入一小段命令 npm test。--verbose 表示輸出的測試信息盡量詳細
},
"ava": {
  "babel": "inherit",                 // 繼承已有的 babel 配置,就是繼承我們下面 .babelrc 的文件配置
  "require": [                        // 每個測試前,先加載 require 里面的模塊
    "babel-register",                 // 默認引入的,安裝 AVA 時已經自帶安裝好
    "babel-polyfill"
  ]
}

在項目根目錄創建 .babelrc 文件, 并輸入以下內容:

這里的坑在于,如果不創建 .babelrc 文件,而是把 babel 的配置寫在 package.json 里,在使用 import 導入 React 組件時,會報語法錯誤。
可使用命令行創建文件:touch .babelrc

{
  "presets": ["es2015", "stage-0", "react"]
}

看看現在的目錄結構是怎么樣的:

單元測試,測試一個簡單的工具函數

test 目錄創建一個 simple_test.js 文件,內容如下

import test from "ava";

function trimAll(string) {
    return string.replace(/[s]/g, "");
}

test("trimAll testing", t => {
    // 字符串內含有空格符、制表符等空字符都應刪除
    t.is(trimAll(" 
 
 	 v  f B a r r  i  o  r  
  
  	  v    f  "), "Barrior");

    // 無空字符時,輸出值應為輸入值
    t.is(trimAll("Barrior"), "Barrior");

    // 輸入 new String 對象應與輸入基本類型字符串結果相同
    t.is(trimAll(new String(" T o m ")), "Tom");

    // 輸入其他非字符串數據類型時,應拋出錯誤
    [undefined, null, 0, true, [], {}, () => {}, Symbol()].forEach(type => {
        t.throws(() => {
            trimAll(type);
        });
    });
});

test():執行一個測試,第一個參數為標題,第二參數為測試用例函數,接收一個包含內置斷言 API 的參數 t,也是唯一一個參數;按照慣例這個參數名字叫做 t,沒必要重新取名字。

這里使用到的內置斷言:

t.is(resultValue, expected), 斷言結果值等于我們想要的預期值,則測試通過。全等判斷。

t.throws(function), 在 throws 里放入一個函數,函數自動執行,里面執行的結果必須拋出錯誤,則測試通過。

運行 npm test,可以看到如下結果,一個測試用例通過。

改動一下測試用例,看看測試不通過是怎么樣的。

t.is(trimAll("Barrior123"), "Barrior");

運行 npm test

紅色框框就是我們說的強化斷言信息,將結果值預期值進行了差異對比,幫助我們定位錯誤。

使用 Promise、Async/await、Observable

PromiseAsync/await 都是語法層面的東西,Observable 還沒深入了解過,
語法糖的代碼就不貼來占用空間了,可以下載示例代碼看看就會了。
Observable 這里的坑在于需要引入 RxJS: npm i --save rxjs,官方文檔并沒有說明。

import test from "ava";
import {Observable} from "rxjs";

test(t => {
    t.plan(3);
    return Observable
        .of(1, 2, 3, 4, 5, 6)
        .filter(n => {
            return n % 2 === 0;
        })
        .map(() => t.pass());
});
使用 JSDOM 模擬瀏覽器環境

安裝 JSDOM 模塊:npm i --save-dev jsdom

在目錄下創建一個 jsdom.js 文件,內容如下:

import test from "ava";
import {JSDOM} from "jsdom";

const html = `




    
發布
    `; const {window} = new JSDOM(html, {runScripts: "dangerously"}); const document = window.document; test("emulate DOM environment with JSDOM", t => { const textarea = document.querySelector(".comment-box textarea"); const btn = document.querySelector(".btn"); const list = document.querySelector(".list"); const text = "hello world"; btn.click(); // 觸發按鈕的點擊事件,此時文本框中沒有輸入內容 t.is(list.children.length, 0); // 列表應該保持為空 textarea.value = text; // 文本框中輸入內容 btn.click(); // 觸發按鈕的點擊事件 t.is(list.children.length, 1); // 此時列表的長度應該為 1 t.is(list.children[0].innerHTML, text); // 此時,第一個評論的內容應該等于剛剛我們輸入的內容 t.falsy(textarea.value); // 評論完后,文本框應該清空 });

    簡單介紹 JSDOM API。

    new JSDOM(html, {runScripts: "dangerously"}); :創建一個 DOM 環境,可以傳入完整的 HTML 文檔,也可以值傳入一行 HTML 文檔聲明,如:。

    參數 runScripts: "dangerously" 表示讓文檔里的 JavaScript 可以運行,默認禁止運行。

    創建后返回一個對象,里面包含一個 window 對象,我們便是需要用到這個 window 對象,及其屬性 document 對象,用在我們的測試。

    更多使用方法和配置可以查看一下官方文檔。

    測試里面的代碼就是原生的 JavaScript DOM 操作代碼。

    單元測試,測試一個簡單的 React 組件

    測試 React 組件需要依賴 JSDOM, 所以我們放在這里講。
    安裝需要依賴的一些模塊:npm i --save react react-dom, npm i --save-dev enzyme react-test-renderer。這里也不用糾結為什么一會用 --save, 一會用 --save-dev, 因為 --save 表示這些模塊在線上項目也需要用到,而 --save-dev 表示這些模塊只用作開發或者測試等,線上項目不需要用到這些模塊。
    Enzyme 是一個 React 測試工具,可以說是把 React 組件渲染在我們測試的環境里,不需要依賴真實的瀏覽器。
    Enzyme 依賴 react-test-rendererReact >=15.5 安裝 react-test-renderer,其它版本安裝 react-addons-test-utils

    src 目錄下創建 todo.js 文件,內容如下,一個簡單的備忘錄組件:

    import React from "react";
    import ReactDOM from "react-dom";
    
    export default class Todo extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                names: props.names || []
            };
        }
    
        add() {
            const elem = this.refs.textarea;
            const name = elem.value;
            if (name) {
                elem.value = "";
                this.state.names.push(name);
                this.setState({});
            } else {
                elem.focus();
            }
        }
    
        del(i) {
            this.state.names.splice(i, 1);
            this.setState({});
        }
    
        render() {
            return (
                
      { this.state.names.map((name, i) => { return (
    • Member name: {name}
    • ) }) }
    ) } }

    test 目錄下創建一個 helpers 文件夾,并在文件夾里面創建 setup_dom_env.js 文件, 內容如下。

    AVA 的規則會忽略 helpers 文件夾,不會將里面的文件當做測試文件執行。

    import {JSDOM} from "jsdom";
    const dom = new JSDOM("");
    global.window = dom.window;
    global.document = dom.window.document;
    global.navigator = dom.window.navigator;

    這就是 React 組件需要依賴的 JSDOM 模擬的 DOM 環境的代碼。
    需要將 window、document、navigator 等對象掛載到 global 對象上,組件才能運行。

    test 目錄下創建 react_component.js, 內容如下,先引入模擬 DOM 環境的文件。

    import "./helpers/setup_dom_env";
    import test from "ava";
    import React from "react";
    import {mount} from "enzyme";
    
    import Todo from "../src/todo";
    
    test("actual testing for react component", t => {
        const wrapper = mount();  // 讓組件運行,返回一個對象
    
        const list = wrapper.find("ul");                             // 從對象里找到 render 里的 DOM 元素 ul
        t.is(list.find("li").length, 2);                             // 斷言備忘錄有 2 條記錄
    
        wrapper.find("textarea").node.value = "Lily";                // 文本框寫入值
        wrapper.find("textarea + button").simulate("click");         // 觸發按鈕的點擊事件
        t.is(list.find("li").length, 3);                             // 斷言備忘錄有 3 條記錄
    });

    簡單介紹 Enzyme API

    mount: 表示渲染組件的時候支持生命周期,個人覺得測試時一般都會用這個,因為真實組件生命周期的調用是極為平常的事。

    Enzyme APIjQuery API 很相似,會 jQuery 應該很容易理解。

    Http 接口測試,GitHub 用戶信息接口測試

    打開接口:https://api.github.com/users/...,返回用戶的一些基本信息,有些字段值是動態改變的,用戶修改即變,這樣的動態字段我們可以查詢數據庫來對比。這里我們以一個假設不變的 login 字段來演示。

    先安裝 Request 模塊: npm i --save-dev request,方便發送 http 請求。

    test 目錄下創建 http.js, 內容如下。

    import test from "ava";
    import request from "request";
    
    // test.cb() 回調函數形式測試異步代碼,異步結束調用 t.end()
    test.cb("http api testing", t => {
    
        // 基于 Request API 創建 http 請求的配置
        const options = {
            baseUrl: "https://api.github.com",
            url: "/users/Barrior",
            // 請求超時時間
            timeout: 5 * 1000,
            // http 請求頭部,模擬得跟瀏覽器越像越好,不然被服務器處理成爬蟲或者其他就可能得不到我們想要的響應
            headers: {
                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36"
            }
        };
    
        // Request API 發送 GET 請求
        request.get(options, (err, res, body) => {
            if (err) t.fail("服務器響應超時!");
    
            if (res && res.statusCode === 200) {
                body = JSON.parse(body);
                t.is(body.login, "Barrior");
            } else {
                t.fail("無響應內容或狀態碼錯誤!");
            }
            
            // 異步結束
            t.end();
        });
    });

    運行 npm test,可以看到測試通過。

    串行測試

    很多情況并行測試就好,但某些場景我們需要測試按順序一個接一個的執行,即使是異步,并且后面的測試可能依賴前面測試的結果,這時就需要用到串行測試,test.serial()。

    test 目錄下創建 serial.js, 內容如下,一個簡單的串行測試演示。

    import test from "ava";
    
    const globalData = {};
    
    test.serial("serial testing: step one", t => {
        return new Promise(resolve => {
            setTimeout(() => {
                globalData.name = "Barrior";
                t.pass();
                resolve();
            }, 500);
        });
    });
    
    test("serial testing: step two", t => {
        t.is(globalData.name, "Barrior");
    });

    這里只是 serial.js 文件串行執行,如果想所有文件都串行執行,需要在命令行傳遞 --serial 標志。

    快照斷言

    t.snapshot(expected, [options]), 將預期值與先前記錄的快照進行比較。
    第一次運行測試,快照斷言會將預期值存儲起來,待第二次及以后運行測試,則拿已經存儲好的快照與新的預期值進行比較,吻合則測試通過,否則測試失敗。

    一般用于預期值比較龐大的情況,如:Html 模板,React 渲染出來的模板,或許還可以用于 Http 接口返回的一堆數據。

    如下,做個簡單演示。

    import test from "ava";
    
    function getUserInfo(uid) {
        return [{
            id: 0,
            name: "Barrior",
            sex: "male"
        }, {
            id: 1,
            name: "Tom",
            sex: "male"
        }][uid]
    }
    
    function renderUserDom(uid) {
        const userInfo = getUserInfo(uid);
        return `
            
        `;
    }
    
    test("snapshot", t => {
        const user1 = renderUserDom(0);
        const user2 = renderUserDom(1);
    
        // 自定義 id 必須是一個字符串或者 buffer
        // 不定義,AVA 會默認生成一個 id
        t.snapshot(user1, {id: "1"});
        t.snapshot(user2, {id: "2"});
    });
    覆蓋率報告:nyc + Coveralls

    安裝模塊 nyccoverallsnpm i --save-dev nyc coveralls
    擴展測試命令,前面加個 nyc 即可:"test": "nyc ava --verbose"
    測試覆蓋率是基于文件被測試的情況來反饋出指標,所以我們把 simple_test.js 里的 trimAll 函數多帶帶提出來作為一個文件,放到 src 目錄,命名為 trim_all.js

    運行 npm test,簡潔的覆蓋率報告如下。

    Stmts: Statement 的縮寫,語句覆蓋,通常指某一行代碼是否被測試覆蓋了,不包括注釋,條件等。
    Branch: 分支覆蓋或條件覆蓋,指某一個條件語句是否被測試覆蓋了,如:if、while;分支數是條件語句的兩倍。
    Funcs: Function 的縮寫,函數覆蓋,指這個函數是否被測試代碼調用了。
    Lines: 行覆蓋,通常情況等于語句覆蓋。一行未必只有一條語句(官方給的差異解釋):https://github.com/gotwarlost...

    這里有一篇關于這幾個指標的具體解釋和演示說明,和對做覆蓋率報告的思考:http://www.infoq.com/cn/artic...

    如果想看具體報告的信息,可以輸出成 html 文檔來瞧瞧,如下添加輸出報告命令。

    "scripts": {
       ...
      "report": "nyc report --reporter=html"
    }

    運行 npm run reportcoverage 目錄就會生成一些相關文件,瀏覽器打開 index.html,就可以看到如下內容。

    點擊文件進去,可以查看該文件測試覆蓋的詳情。

    Coveralls

    一個將項目覆蓋率展示到網頁上,適合開源項目。
    網址:https://coveralls.io

    先注冊登錄,然后在項目根目錄添加 .coveralls.yml,內容如下。

    service_name: travis-ci
    repo_token: 你自己的項目 token, Coveralls 網站提供的私有令牌

    添加上傳命令。

    "scripts": {
       ...
      "coverage": "nyc report --reporter=text-lcov | coveralls"
    }

    運行 npm run coverage,等待報告上傳完畢,就可以在網站上看到報告。

    持續集成:CircleCI

    通俗的講,持續集成就是每次提交代碼,自動化程序就自動構建(包括編譯,發布,自動化測試等)來驗證代碼,從而盡早地發現代碼中的錯誤。
    網址:https://circleci.com/,適合開源項目。

    在項目根目錄添加 circle.yml 文件,內容如下,配置項都可以在文檔中找到。

    # 配置 NodeJS 的版本為 7
    machine:
      node:
        version: 7
    
    # 安裝依賴的命令
    dependencies:
      override:
        - npm i -g ava
        - npm i
    
    # 運行的測試命令
    test:
      override:
        - npm test

    使用 GitHub 賬號登錄 CircleCI 網站,選擇持續集成這個項目,這里我們用的是 1.0 平臺,不要選 2.0,因為配置的寫法不一樣。
    至此,每次提交代碼到這個項目,CircleCI 就會自動幫我們集成。

    完成了覆蓋率和持續集成,這兩個網站都提供了小徽章給我們,類似如下,可以貼到項目中以顯某種態度。

    學習借鑒,一些使用 AVA 做測試的開源項目

    pageres

    postcss-discard-comments

    postcss-selector-parser

    download

    jparticles

    e2e測試框架推薦:TestCafe

    官網地址:https://devexpress.github.io/...

    推薦理由(缺點須躬行):

    無需配置繁瑣的環境。

    基于 NodeJS 生態。

    參考

    http://i5ting.github.io/ava-p...
    https://github.com/avajs/ava

    最后

    文中的代碼托放于 GitHub,可供參考。

    文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

    轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/84508.html

    相關文章

    • 使用 ava 和 jsdom 前端測試

      摘要:前同事留下的測試,是基于瀏覽器的,主要還是功能測試。這里不詳細說怎么在瀏覽器端使用測試了。而且作者也是建議和支持這樣做的,簡單明了的測試腳本,重要性有時候可能和測試本身一樣重要。經測試,在瀏覽器也有這種問題。 2016-09-03 更新 隨著在工作學習中更多地接觸、使用測試工具,發現自己在本文中的一些記錄是不準確、不正確的。 今天(九月三日)在家看了 NingJs 的直播,其中有一個分...

      GHOST_349178 評論0 收藏0
    • 基于 Babel 的 npm 包最小化設置

      摘要:翻譯瘋狂的技術宅原文本文首發微信公眾號歡迎關注,每天都給你推送新鮮的前端技術文章本文描述了通過生成包的最小設置。是用于轉換的預設。有關這兩個屬性的更多信息設置多平臺包。表示使用上一節中的配置。結論以上是通過創建包最小庫的方法。 翻譯:瘋狂的技術宅原文:http://2ality.com/2017/07/npm... 本文首發微信公眾號:jingchengyideng歡迎關注,每天都...

      ?。?。 評論0 收藏0
    • 提高代碼質量——使用Jest和Sinon給已有的代碼添加單元測試

      摘要:現在,我們可以使用單元測試來提高自己的代碼質量。它在單元測試的編寫中通常用來模擬等相關請求。通過這篇文章,你應該學會了如何針對已有代碼從零開始編寫一套完整的單元測試用例。 概述 在日常的功能開發中,我們的代碼測試都依賴于自己或者QA進行測試。這些操作不僅費時費力,而且還依賴開發者自身的驅動。在開發一些第三方依賴的庫時,我們也沒有辦法給第三方提供完整的代碼質量報告。 現在,我們可以使用單...

      voyagelab 評論0 收藏0
    • 即將到來 Javascript 三個改變, 你會很喜歡它們的,因為確實是方便了很多!

      摘要:你將看到它們的語法時時關注它們的進展與更新。標準有個版本,個發布第個版本被放棄了。此建議的目的只是避免在起草建議被放棄或發生重大帶來的麻煩。如果使用過度,將導致性能下降。在這個場景中,數字和空字符串都被認為是假的。 showImg(https://segmentfault.com/img/bVbj2Az?w=2000&h=1333); 想閱讀更多優質文章請猛戳GitHub博客,一年百來...

      tinysun1234 評論0 收藏0
    • 2016-JavaScript之星

      摘要:在,是當之無愧的王者,贏得了與之間的戰爭,攻陷了的城池。于月發布了版本,這一版本為了更好的表現加入了渲染方式。前端框架這個前端框架清單可能是年疲勞的元兇之一。的創建者,目前在工作為尋找構建簡單性和自主配置性之間的平衡做了很大的貢獻。 春節后的第一篇就從這個開始吧~本文已在前端早讀課公眾號上首發 原文鏈接 JavasScript社區在創新的道路上開足了馬力,曾經流行過的也許一個月之后就過...

      Binguner 評論0 收藏0

    發表評論

    0條評論

    Cruise_Chan

    |高級講師

    TA的文章

    閱讀更多
    最新活動
    閱讀需要支付1元查看
    <