使用 testcontainer nginx +jest 集成测试njs 模块
jest 是一个很不错的js 测试框架,我们可以此方便的进行js 测试,基于testcontainer 我们可以使用容器
方便的测试,以下是一个参考使用
项目准备
- 项目结构
├── README.md
├── conf
│ └── nginx.conf
├── dist
│ └── main.js
├── jest-testcontainers-config.js
├── jest.config.js
├── package.json
├── src
│ └── app.js
├── test
│ └── ad.test.js
└── yarn.lock
- 依赖的包
基于jest testcontainer 包装 Trendyol/jest-testcontainers,testcontainers/testcontainers-node
代码说明
- nginx 配置
conf/nginx.conf
user root;
load_module modules/ngx_http_js_module.so;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type text/html;
gzip on;
real_ip_header X-Forwarded-For;
js_import /opt/jsapp/main.js;
resolver 114.114.114.114;
server {
listen 80;
charset utf-8;
default_type text/html;
location = /token {
js_content main.token;
}
}
}
- package.json
{
"name": "myjest",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"devDependencies": {
"@trendyol/jest-testcontainers": "^2.1.1",
"jest": "^28.1.0"
},
"scripts": {
// 使用DEBUG 开启日志,方便查询错误
"test": "DEBUG=testcontainers* jest"
},
"dependencies": {
"cross-fetch": "^3.1.5"
}
}
- jest 配置
jest.config.js, jest-testcontainers-config.js
module.exports = {
preset: '@trendyol/jest-testcontainers'
}
jest-testcontainers-config.js
const PWD = __dirname
module.exports = {
nginx: {
image: 'nginx',
tag: '1.22.0-alpine',
ports: [80],
env: {
MYNAME: 'dalong',
},
bindMounts: [
{
source: `${PWD}/conf/nginx.conf`,
target: "/etc/nginx/nginx.conf",
mode: "ro"
},
{
source: `${PWD}/dist/main.js`,
target: "/opt/jsapp/main.js",
mode: "ro"
}
]
}
};
- test
ad.test.js
const fetch = require("cross-fetch")
describe("nginx test", () => {
var nginxServerURI;
beforeAll(() => {
// 使用testcontainer 提供的变量获取容器暴露的端口以及ip
nginxServerURI = `http://${global.__TESTCONTAINERS_NGINX_IP__}:${global.__TESTCONTAINERS_NGINX_PORT_80__}/token`;
});
it("token test", async () => {
console.log(nginxServerURI)
let result = await (
await fetch(nginxServerURI)
).text();
console.log(result)
})
})
运行测试
- 命令
yarn test
- 效果
TRACE 5ec7e82a08c080584ab34f15ec898772730414c1b9d5229dc7c438cb36f8c07b: a/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
testcontainers:containers J/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
testcontainers:containers V/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
testcontainers:containers ^10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
testcontainers:containers +0ms
testcontainers:containers TRACE 5ec7e82a08c080584ab34f15ec898772730414c1b9d5229dc7c438cb36f8c07b: `10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
testcontainers:containers +7ms
testcontainers:containers TRACE 5ec7e82a08c080584ab34f15ec898772730414c1b9d5229dc7c438cb36f8c07b: R/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
testcontainers:containers +0ms
testcontainers:containers TRACE 5ec7e82a08c080584ab34f15ec898772730414c1b9d5229dc7c438cb36f8c07b: R/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
testcontainers:containers +5ms
testcontainers:containers TRACE 5ec7e82a08c080584ab34f15ec898772730414c1b9d5229dc7c438cb36f8c07b: B/docker-entrypoint.sh: Configuration complete; ready for start up
testcontainers:containers +1ms
console.log
http://localhost:49515/token
at Object.log (test/ad.test.js:8:13)
console.log
<html>
<head><title>500 Internal Server Error</title></head>
<body>
<center><h1>500 Internal Server Error</h1></center>
<hr><center>nginx/1.22.0</center>
</body>
</html>
at Object.log (test/ad.test.js:12:13)
PASS test/ad.test.js
nginx test
✓ token test (25 ms)
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 0 | 0 | 0 | 0 |
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 0.291 s, estimated 1 s
Ran all test suites.
testcontainers:containers TRACE 5ec7e82a08c080584ab34f15ec898772730414c1b9d5229dc7c438cb36f8c07b: �172.17.0.1 - - [29/May/2022:14:24:30 +0000] "GET /token HTTP/1.1" 500 177 "-" "node-fetch/1.0 (+https://github.com/bitinn/node-fetch)"
testcontainers:containers a2022/05/29 14:24:30 [error] 32#32: *2 js exception: ReferenceError: "onlyUnique2" is not defined // 此处是估计调整异常的,可以看到异常信息
testcontainers:containers ' at Array.prototype.filter (native)
testcontainers:containers ) at Hashids (/opt/jsapp/main.js:2548)
testcontainers:containers ' at token (/opt/jsapp/main.js:2767)
testcontainers:containers X, client: 172.17.0.1, server: , request: "GET /token HTTP/1.1", host: "localhost:49515"
testcontainers:containers +546ms
说明
使用 jest-testcontainers 测试js 应用是一个很不错的选择,同时进行njs 测试也是可以的,以前说过一个njs 的cli 进行js 测试,但是集成上jest+testcontainer 这样我们的njs 模块开发就更加方便了,此方法也可以做为openresty 模块测试使用
参考资料
https://www.testcontainers.org/modules/nginx/
https://github.com/testcontainers/testcontainers-node
https://www.testcontainers.org/
https://jestjs.io/zh-Hans/docs/getting-started
https://github.com/Trendyol/jest-testcontainers
https://github.com/jirutka/njs-typescript-starter
https://github.com/rongfengliang/jest-testcontainers-njs-learning
·