如何将jest的测试结果转移到页面上

在开发react应用或者其他web应用时,我们经常要进行单元测试。jest是facebook开发的单元测试框架,但是他的测试结果通常是在终端或者cmd里面显示,其形式不够美观,而且无法一目了然的看到测试结果。

jest如何存储测试结果

经过一番调查,jest.config中有这么一项,根据官网的说法:

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配置:

//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的好机会!):

//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知识就可以搭建一个简易的服务器!

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

此时一个简易的服务器就建好啦!只需要对req的url稍加判断就可以完成我们的想要的功能:

  1. 请求路径为'/',就是打http://localhost:4000时,我们返回一个html文件;
  2. 请求路径为其他时,比如fetch(http://localhost:4000/index.js),我们就要返回jset测试结果。

返回的html文件可以随便写:

<!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,打开控制台,哇偶,我们已经拿到了!

同时,命令行中也打印出了我们想要的结果(太长就不全拿出来了):

{
     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字符去掉。 我们在发送数据之前,对该字段的数据处理一下即可:

//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

转载于:https://juejin.im/post/5c2c57ba5188257ed57eb471

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值