使用 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
·

posted on 2022-05-29 22:36  荣锋亮  阅读(162)  评论(0编辑  收藏  举报

导航