在開發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