在开发react应用或者其余web应用时,咱们常常要进行单元测试。jest是facebook开发的单元测试框架,可是他的测试结果一般是在终端或者cmd里面显示,其形式不够美观,并且没法一目了然的看到测试结果。javascript
通过一番调查,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
var server = new http.Server();
server.on('request',(req,res)=>{})
server.listen(4000, ()=>{})
此时一个简易的服务器就建好啦!只须要对req的url稍加判断就能够完成咱们的想要的功能:node
'/'
,就是打http://localhost:4000
时,咱们返回一个html文件;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>
复制代码
页面展现:
本例只是简单的探索与实现,相信社区确定有相关的架子,可是实现的过程,是最有趣的。
优势:能够在页面看到更直观的测试结果,
缺点:
但愿能给你们一些启发和新想法。仓库地址:github