大家好 我是 Yubin
身為一個開發者,寫測試是非常重要的。這篇文章介紹 Fastify 中要如何對 server 進行測試。
如果對 JavaScript Testing 不熟或沒經驗的朋友,可以先參考這篇正體中文的文章:
Javascript-Testing-Best-Practices。
撰寫 Fastify 測試的時候,可以自由的選用測試框架。如,jest、tap、vitest,等。
本文以 Jest 作為使用的測試框架。
先安裝相應的套件。
npm i -D jest ts-jest @types/jest
新增 jest.config.js
module.exports = {
preset: 'ts-jest',
transform: {
'^.+\\.(t|j)sx?$': 'ts-jest'
},
testEnvironment: 'node',
moduleFileExtensions: ['ts', 'js']
}
為了方便測試,我們先把程式進入點與設定 Server 的部分分離。
把設定 server 的地方,定義在 server.ts
,用來啟動伺服器、定義 route 或註冊 Plugin。
server.ts
import fastify, { FastifyInstance } from 'fastify'
const server: FastifyInstance = fastify()
const startServer: (port: number) => FastifyInstance = (port) => {
const listenAddress = '0.0.0.0'
const fastifyConfig = {
port: port,
host: listenAddress
}
server.listen(fastifyConfig)
server.get('/', (request, reply) => {
return reply.status(200).send({ message: 'Hello World' })
})
return server
}
export { startServer }
讓程式進入點 index.ts
以 import 的方式使用:
index.ts
import { startServer } from './server'
const port = 8888
startServer(port)
接著開一個測試檔案 server.test.ts
import { FastifyInstance } from 'fastify'
import { startServer } from '../server'
describe('Server test', () => {
let server: FastifyInstance
beforeAll(async () => {
server = startServer(8888)
await server.ready()
})
// test cases ...
})
以 Jest 為例,我們在 beforeAll 的地方,透過我們定義好的 startServer()
,把伺服器跑起來。
接著假設我要測的東西是,有一個 Request 進來,是一個 GET /
的 Request,則我要拿到 200 的狀態碼。
test('When GET /, then get 200 status code', async () => {
const response = await server.inject({
method: 'GET',
url: '/'
})
expect(response.statusCode).toBe(200)
})
透過 server.inject()
,我們可以製造一個假的 HTTP Request,並將該 Request 送到我們的 Server 中。對 Server 來說這個 Request 是真實存在的,會開始走過 Fastify 的生命週期。
.inject() 透過帶入參數可以設定期望中的 Request。
const response = await server.inject({
method: String,
url: String,
query: Object,
payload: Object,
headers: Object,
cookies: Object
}
要注意的是 .inject()
回應的型態是 Promise,記得要 await
來拿到 Response。
或是用 callback style 的方式:
server.inject({
method: String,
url: String,
query: Object,
payload: Object,
headers: Object,
cookies: Object
}, (error, response) => {
// your tests
})
自己覺得用 async/await
style 的方式會讓測試看起來比較容易閱讀。
上述程式建置好後,修改 package.json
中的 scripts
:
以 jest 為例。
"test": "jest --verbose --coverage --runInBand",
然後在 terminal 執行 npm run test
或 npm t
來啟動測試。
可以看到測試結果及覆蓋率報告。
備註:
Fastify 官網 使用的是 tap 作為測試框架,如果習慣使用 tap 的朋友也可以去參考參考。
寫測試對於開發者來說非常重要,不僅是為了程式品質,更可以提升開發人員的信心。
也可以搭配 TDD 與 CI Pipeline 等流程,不只讓程式品質與可靠度提升,也讓寫程式的人的心情與生活品質提升。