摘要:我在單元測試中主要用的庫有和,框架為。如果運(yùn)行單元測試不想生成文檔,直接用就可以了,相應(yīng)的配置如下如果不想為某個生成文檔,就不要調(diào)用的,直接按原生的寫法就可以了。生成的文檔內(nèi)容形式如下原文地址通過單元測試為自動生成文檔
在開發(fā)中,為項(xiàng)目生成文檔是很常見的需求,很多第三方庫(如jsdoc、swagger等)的做法是為需要生成文檔的函數(shù)編寫相應(yīng)的符合規(guī)范的注釋,然后運(yùn)行相應(yīng)的命令,生成一個靜態(tài)網(wǎng)頁形式的文檔。
用注釋生成文檔的好處是可以為無論是普通函數(shù)還是 API,只要編寫了相應(yīng)的注釋都能生成相應(yīng)的文檔,然而這種做法總覺得有點(diǎn)繁瑣,尤其是只需要為 API 生成文檔的時候,需要手動編寫大量的輸入和輸出作為使用示例。而且我只想需要 markdown 形式的文檔,丟在內(nèi)部 Gitlab 的 wiki 上供前端人員査閱,然后可以根據(jù) commit 的 history 查閱不同的版本。
不想手動為 API 文檔編寫大量的輸入輸出,那哪里會有輸入輸出呢,就很容易的想到了單元測試會產(chǎn)生輸入和輸出。好,那就用單元測試來為 API 生成文檔。
我在單元測試中主要用的庫有 mocha、supertest和power-assert,Web 框架為 express。
完整代碼示例:
// app.js const express = require("express"); const bodyParser = require("body-parser"); const app = express(); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); app.post("/user/create", function (req, res) { const name = req.body.name; res.json({ status: 200, error_code: 0, message: "success", data: { id: "123abc", name: "node", gender: "male", age: 23, }, }); }); app.get("/user/search", function (req, res) { const name = req.query.name; res.json({ status: 200, error_code: 0, message: "success", data: { id: "123abc", name: "node", gender: "male", age: 23, }, }); }); app.get("/user/:id", function (req, res) { const userId = req.params.id; res.json({ status: 200, error_code: 0, message: "success", data: { id: "123abc", name: "node", gender: "male", age: 23, }, }); }); app.listen(3000, function () { console.log(`Server is listening on 3000`); }); module.exports = app;
下面是測試文件。
// test/uset.test.js const assert = require("power-assert"); const supertest = require("supertest"); const U = require("../utils"); const app = require("../app"); const agent = supertest.agent(app); describe("Test", function () { it("should create user success", function (done) { U.test({ agent, file: "user", group: "用戶相關(guān)API", title: "創(chuàng)建用戶", method: "post", url: "/user/create" params: { name: { value: "node", type: "String", required: true, desc: "名稱" }, gender: { value: "male", type: "String", required: false, desc: "性別" }, age: { value: 23, type: "Int", required: false, desc: "" }, }, headers: { entrance: "client" }, expect: 200, callback (err, res) { if (err) return done(err); assert(res.body.data.name === "node"); assert(res.body.data.age === 23); done(); }, }); }); it("should search user success", function (done) { U.test({ agent, file: "user", group: "用戶相關(guān)API", title: "搜索用戶", method: "get", url: "/user/search" params: { name: { value: "node", type: "String", required: true, desc: "名稱" }, }, expect: 200, callback (err, res) { if (err) return done(err); assert(res.body.data.name === "node"); assert(res.body.data.age === 23); done(); }, }); }); it("should search user success", function (done) { U.test({ agent, file: "user", group: "用戶相關(guān)API", title: "獲取用戶信息", method: "get", url: "/user/:id" params: { id: { value: "123abc", type: "String", required: true, desc: "" }, }, expect: 200, callback (err, res) { if (err) return done(err); assert(res.body.data.name === "node"); assert(res.body.data.age === 23); done(); }, }); }); });
在測試文件中,測試用例的代碼調(diào)用到了 utils.js 中的 test 方法,該方法的主要作用是接收單元測試的輸入和輸出并生成相應(yīng)的文檔,其中需要向 test 方法傳入一個對象作為參數(shù),對象中的字段解讀如下:
agent:調(diào)用 API 的代理。
file:生成的文檔的文件名稱。
group:某一組文檔的名稱。
title:接口的名稱。
method:接口的方法。
params:接口的參數(shù),即輸入。
headers: 添加到請求頭中的信息。
expect:supertest 的expect。
callback:supertest 方法的 end 的回調(diào)函數(shù)。
utils.js代碼如下:
// utils.js const path = require("path"); const fs = require("fs"); const mdStr = {}; exports.test = function (obj) { if (!mdStr[obj.group]) { mdStr[obj.group] = ""; mdStr[obj.group] += "## " + obj.group + " "; } const fields = {}; mdStr[obj.group] += `### ${ obj.title } `${ obj.method }` ${ obj.url } #### 參數(shù) `; mdStr[obj.group] += " 參數(shù)名 | 類型 | 是否必填 | 說明 -----|-----|-----|----- "; Object.keys(obj.params).forEach(function (param) { const paramVal = obj.params[param]; fields[param] = paramVal["value"]; mdStr[obj.group] += `${ param } | ${ paramVal["type"] } | ${ paramVal["required"] ? "是" : "否" } | ${ paramVal["desc"] } `; }); mdStr[obj.group] += " #### 使用示例 請求參數(shù): "; mdStr[obj.group] += "```json " + JSON.stringify(fields, null, 2) + " ``` "; mdStr[obj.group] += " 返回結(jié)果: "; if (obj.url.indexOf(":") > -1) { obj.url = obj.url.replace(/:w*/g, function (word) { return fields[word.substr(1)]; }); } obj.agent[obj.method](obj.url) .set(obj.header || {}) .query(fields) .send(fields) .expect(obj.expect) .end(function (err, res) { mdStr[obj.group] += "```json " + JSON.stringify(res.body, null, 2) + " ``` "; mdStr[obj.group] += " "; if (process.env["GEN_DOC"] > 0) { fs.writeFileSync(path.resolve(__dirname, "./docs/", obj.file + ".md"), mdStr[obj.group]); } obj.callback(err, res); }); }
這樣,在根目錄創(chuàng)建一個 docs 目錄,運(yùn)行 npm run test:doc 命令,就會在 docs 目錄下生成文檔。如果運(yùn)行單元測試不想生成文檔,直接用npm test就可以了,相應(yīng)的package.json配置如下:
"scripts": { "test": "export NODE_ENV="test" && mocha", "test:doc": "export NODE_ENV="test" && export GEN_DOC=1 && mocha" }
如果不想為某個 API 生成文檔,就不要調(diào)用 utils 的 test,直接按原生的寫法就可以了。
若需要對參數(shù)進(jìn)行簽名,可在調(diào)用 test 方法時,增加形如sign: true的配置,然后在 test 方法中做相應(yīng)的判斷和實(shí)現(xiàn)相應(yīng)的簽名。
生成的文檔內(nèi)容形式如下:
原文地址:通過單元測試為API自動生成文檔
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/88071.html
摘要:對模塊進(jìn)行了打包,監(jiān)聽文件更改刷新等功能,創(chuàng)建了個服務(wù),分別為靜態(tài)資源服務(wù)用于代理本地資源,與自刷新瀏覽器請求服務(wù)用于接受,請求,返回?cái)?shù)據(jù)服務(wù)用于收發(fā)消息。除了項(xiàng)目,還可以換成項(xiàng)目。項(xiàng)目地址如果覺得對你有所幫助,多謝支持 prince-cli 快速指南 這是一個為快速創(chuàng)建SPA所設(shè)計(jì)的腳手架,旨在為開發(fā)人員提供簡單規(guī)范的開發(fā)方式、服務(wù)端環(huán)境、與接近native應(yīng)用的體驗(yàn)。使用它你能夠獲...
摘要:首先安裝單元測試環(huán)境使用模塊來模擬定義的模型。根據(jù)刪除這是單元測試的最后一小節(jié)。需要根據(jù)需求和單元測試用例來編寫應(yīng)用邏輯,使我們的程序更加穩(wěn)定。我們會運(yùn)行自動測試用例,一直重構(gòu),直到所有單元測試都通過。 本文轉(zhuǎn)載自:眾成翻譯譯者:文藺鏈接:http://www.zcfy.cc/article/746原文:https://semaphoreci.com/community/tutoria...
摘要:首先安裝單元測試環(huán)境使用模塊來模擬定義的模型。根據(jù)刪除這是單元測試的最后一小節(jié)。需要根據(jù)需求和單元測試用例來編寫應(yīng)用邏輯,使我們的程序更加穩(wěn)定。我們會運(yùn)行自動測試用例,一直重構(gòu),直到所有單元測試都通過。 本文轉(zhuǎn)載自:眾成翻譯譯者:文藺鏈接:http://www.zcfy.cc/article/746原文:https://semaphoreci.com/community/tutoria...
摘要:塊就是測試用例,表示一個單獨(dú)的測試,塊可以包含多個斷言塊塊就是斷言,判斷預(yù)期結(jié)果和執(zhí)行結(jié)果是否一致失敗的話會打印錯誤提示注意因?yàn)榧^函數(shù)不能夠訪問的上下文,所以在需要用到上下文的時候不能使用,否則報(bào)錯。 前言 我的英文水平有點(diǎn)渣,所以就貼上原文給你們自己翻譯了,還有g(shù)ithub地址,如果發(fā)現(xiàn)有些中文文檔的話也會順便贈送飛機(jī)票 mocha Mocha is a feature-rich ...
摘要:原文鏈接在中貫徹單元測試在團(tuán)隊(duì)合作中,你寫好了一個函數(shù),供隊(duì)友使用,跑去跟你的隊(duì)友說,你傳個值進(jìn)去,他就會返回結(jié)果了。如果你也為社區(qū)貢獻(xiàn)過,想更多人使用的話,加上單元測試吧,讓你的值得別人信賴。 原文鏈接:BlueSun | 在Nodejs中貫徹單元測試 在團(tuán)隊(duì)合作中,你寫好了一個函數(shù),供隊(duì)友使用,跑去跟你的隊(duì)友說,你傳個A值進(jìn)去,他就會返回B結(jié)果了。過了一會,你隊(duì)友跑過來說,我傳個A...
閱讀 2484·2023-04-26 02:18
閱讀 1271·2021-10-14 09:43
閱讀 3841·2021-09-26 10:00
閱讀 6985·2021-09-22 15:28
閱讀 2550·2019-08-30 15:54
閱讀 2611·2019-08-30 15:52
閱讀 486·2019-08-29 11:30
閱讀 3475·2019-08-29 11:05