如何將jest的測試結果轉移到頁面上

在開發react應用或者其餘web應用時,咱們常常要進行單元測試。jest是facebook開發的單元測試框架,可是他的測試結果一般是在終端或者cmd裏面顯示,其形式不夠美觀,並且沒法一目瞭然的看到測試結果。javascript

jest如何存儲測試結果

通過一番調查,jest.config中有這麼一項,根據官網的說法:css

testResultsProcessor [string]
默認值:undefined
This option allows the use of a custom results processor. This processor must be a node module that  
exports a function expecting an object with the following structure as the first argument and return it: 複製代碼

意思就是,這個屬性能夠容許結果處理程序使用。這個處理器必須是一個輸出函數的node模塊,這個函數的第一個參數會接收測試結果,且必須在最終返回測試結果。
jest配置:html

//jest.config.js
module.exports={
    testResultsProcessor:'./testResult'
}
複製代碼
//testResult/index.js
function test(result) {
    console.log(result)
    return result
}
module.exports = test
複製代碼

你會在命令行上看到打印出一個龐大的對象,這個對象就是處理結果。
注:要想看到,你首先要安裝jest,而且須要運行test測試,該函數纔會調用前端

如何把該對象發送到瀏覽器

如今,該對象所在的位置其實是在node環境中,也就是說,在後臺。那麼瀏覽器如何獲得呢?答案固然是:發請求!
咱們對test()結果處理器進行擴充,讓它在本地啓動一個node服務器(練習node的好機會!):vue

//testResult/index.js
var http = require("http");
var url = require("url");
var path = require("path");
var fs = require('fs')
var {exec}=require('child_process')
var server = new http.Server();
function test(result) {
    console.log(result.testResults[0].testResults);
    server.on('request', function (req, res) {
        console.log(req.method);
        var urlObj = url.parse(req.url);
        var urlPathname = urlObj.pathname;
        if (urlPathname === "/") {
            console.log(urlPathname);
            var urlPathname = urlObj.pathname;
            var filePathname = path.join(__dirname, './result.html', urlPathname)
            fs.readFile(filePathname, (err, data) => { //讀取文件響應
                if (err) {
                    res.writeHead(404, {
                        "Context-type": "text/plain"
                    });
                    res.write('404');
                    res.end();
                } else {
                    res.writeHead(200, {
                        "Context-type": "text/plain"
                    });
                    res.write(data); //返回數據
                    res.end();
                }
            })
        } else {
            res.writeHead(200, { 'Content-Type': 'aplication/json' })
            res.end(JSON.stringify(result))//發送數據給瀏覽器
        }
    })
    server.listen(4000, function () {
        console.log("運行在:http://localhost:4000");
    })
    return result
}
module.exports = test
複製代碼

你只須要一點node知識就能夠搭建一個簡易的服務器!java

  1. 第一步:實例化servervar server = new http.Server();
  2. 第二步:給server添加request請求事件server.on('request',(req,res)=>{})
  3. 第三步:綁定端口,server.listen(4000, ()=>{})

此時一個簡易的服務器就建好啦!只須要對req的url稍加判斷就能夠完成咱們的想要的功能:node

  1. 請求路徑爲'/',就是打http://localhost:4000時,咱們返回一個html文件;
  2. 請求路徑爲其餘時,好比fetch(http://localhost:4000/index.js),咱們就要返回jset測試結果。

返回的html文件能夠隨便寫:react

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Page Title</title>
</head>

<body>
    <script> fetch("http://localhost:4000/index.js", { headers: { 'content-type': 'application/json' }, }).then(res => { console.log(res); return res.json() }).then((data) => { console.log(data); }) </script>
</body>

</html>
複製代碼

初次嘗試

大膽的嘗試一次npm test,打開http://localhost:4000,打開控制檯,哇偶,咱們已經拿到了! git

同時,命令行中也打印出了咱們想要的結果(太長就不全拿出來了):

{
     failureMessage:
        '\u001b[1m\u001b[31m \u001b[1m● \u001b[1madds 1 + 2 \u001b[39m\u001b[22m\n\n......'
}
複製代碼

字符串的魔法藝術

兩個結果中有一個字段必定吸引了你的注意,沒錯就是failureMessage,先後端的打印,都呈現出使人困惑的形式,熟悉的人,一眼就能看出來這是ansi碼(做者查了很久,淚奔)。這樣的信息,在命令行裏打印出的字符串會有特效奧!不只會呈現出多種色彩,還能出現各類人性化的特效,好比,npm install時的進度條效果。 回到主題上來,前端的html是沒法識別的(至少在做者眼中),何況在傳遞數據的是,完整的ansi字符還出現了缺失,這就很難受了啊!
谷歌搜索,github搜索快進中······
控制檯字符樣式:chalk,能夠給控制檯添加多彩的樣式。它的依賴中有這一模塊:strip-ansi,用以將字符串中ansi字符去掉。 咱們在發送數據以前,對該字段的數據處理一下便可:github

//testResult/result.js
const stripAnsi = require('strip-ansi');
const typeOf = (obj) => {
    return Object.prototype.toString.call(obj)
}
const deal = (obj) => {
    let copy;
    if (typeOf(obj) === '[object Object]') {
        copy = {}
        for (let key in obj) {
            copy[key] = deal(obj[key]);
        }
    } else if (typeOf(obj) === '[object Function]') {
        copy = obj.bind();
    } else if (typeOf(obj) === '[object Array]') {
        copy = obj.map((item) => {
            return deal(item);
        })
    } else if (typeof obj === "string") {
        copy = stripAnsi(obj);
    } else {
        copy = obj
    }
    return copy
}
module.exports = deal
複製代碼
//testResult/index.js
var deal=require('./result')
···
 res.end(JSON.stringify(deal(result)))
···
複製代碼

最終展現

咱們最後再處理一下html,讓結果呈現出來,簡單使用了vue:

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <title>Page Title</title>
    <script src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>
</head>

<body>
    <style> .code {display: block;padding: 0.5em;font-size: 12px; margin-top: 0.5em;margin-bottom: 0.5em; overflow-x: auto; white-space: pre-wrap; border-radius: 0.25rem; background-color: rgba(206, 17, 38, 0.05);} </style>
    <div id="app">
        <div v-for="(item,index) in testResults">
            <h3>{{item.testFilePath}}</h3>
            <pre class="code">
            <code style=" font-family: Consolas, Menlo, monospace;" v-for="(minitem,minindex) in item.testResults">
               {{item.failureMessage?item.failureMessage:minitem.status}}
            </code>
        </pre>
        </div>
    </div>
    <script> fetch("http://localhost:4000/index.js", { headers: { 'content-type': 'application/json' }, }).then(res => { console.log(res); return res.json() }).then((data) => { console.log(data); render(data) }) function render(data) { var vm = new Vue({ el: "#app", data: data, mounted() { this.testResults.forEach(item => { item.testResults.forEach((item)=>{ item.failureMessages.forEach((err)=>{ throw err }) }) }); }, }) } </script>
</body>

</html>
複製代碼

頁面展現:

優缺點

本例只是簡單的探索與實現,相信社區確定有相關的架子,可是實現的過程,是最有趣的。
優勢:能夠在頁面看到更直觀的測試結果,
缺點:

  1. 每次從新測試要手動刷新頁面,
  2. 錯誤顯示還不夠美觀,

但願能給你們一些啓發和新想法。倉庫地址:github

相關文章
相關標籤/搜索