Nest项目使用Docker配合测试
发布于 4 年前 作者 a1292717155 2316 次浏览 来自 分享

前言

Nestjs作为当下对TypeScript支持最好的后端框架之一(可能没有之一),被越来越多的人使用.

最近自己也在学习和使用中,这其中也踩了不少坑,尤其是在和数据库连接的测试中.

这篇文章主要介绍如何使用Docker配合单元测试

测试的三种方法

  • 使用mock,对返回值进行mock,不直接和数据库进行交互
  • 使用内存数据库/磁盘数据库.例如Sqlite.
  • 利用docker增加测试数据库,在测试是开启docker内的数据库服务

三种方式的优缺点

方法 优点 缺点
使用mock 更加灵活,和数据库进行了隔离 写法麻烦且难维护;没有和数据库真实产生交互
使用内存数据库/磁盘数据库 和数据库产生真实交互,容易维护 postgresql的很多特性,内存数据库其实并不支持
利用Docker 对你实际使用的数据库类型进行测试 复杂度和开销比较大

利用Docker增加测试数据库

以上三种方式,在项目中都使用过,根据实际情况,我最终选择了第三种方法:利用Docker增加测试数据库

思路

每次在跑测试之前,开启Docker启动相应的数据库服务,并初始化数据库;单元测试结束之后,移除数据库,关闭Docker服务.

安装Docker

大家可以参考这个去安装 https://www.runoob.com/docker/ubuntu-docker-install.html

配置docerk-compose

version: "3"
services:
  test-db:
    image: postgres
    restart: always
    ports:
    - "5433:5432"
    environment:
      POSTGRES_PASSWORD: xxx
    volumes:
      - ./test/init.sql:/docker-entrypoint-initdb.d/init.sql #初始化测试数据库

方法一: 通过npm 启动

    "posttest": "docker-compose stop test-db && docker-compose rm -f test-db", //测试结束后关闭docker并移除服务
    "pretest": "docker-compose up -d test-db" //测试开始前开启dcoker和服务

###方法二: 配置jest npm 启动的方式,无法在IDE内单独执行某个测试,所以我开始对jest进行配置

用setup和globalTeardown在测试开始前和结束后,启动/关闭 docker

//setup.ts
const { execSync } = require('child_process');
export default async function() {
  execSync('docker-compose up -d test-db');
}
//globalTeardown.ts
const { execSync } = require('child_process');
export default async function() {
  execSync('docker-compose stop test-db && docker-compose rm -f test-db');
}
//jest.json
 "globalSetup": "./test/setup.ts",
  "globalTeardown": "./test/globalTeardown.ts"

小结

以上就是最近对Nestjs测试的实践.这三种方式对其他Node项目应该也是一样的.如果项目需要集成Redis或者其他服务,都可以通过Docker进行配置

6 回复

SQLite创建的数据库有一种模式IN-MEMORY,但是它并不表示SQLite就成了一个内存数据库。IN-MEMORY模式可以简单地理解为,本来创建的数据库文件是基于磁盘的,现在整个文件使用内存空间来代替磁盘空间,其它操作保持一致。也就是数据库的设计没有根本改变。

无法在IDE内单独执行某个测试,是这样么?

@i5ting 嗯嗯,是的.这个地方描述的确实不太准确.我们项目中一直使用的是IN-MEMORY模式. 谢谢大佬指出.

@i5ting 如果我只配置了npm的话,是没办法在WebStrom中通过IDE点击来执行某个单独的测试的.因为IDE跑jest测试的时候走的是jest的配置,所以后面我又弄的jest启动的时候开启Docker. 还请大佬多多指教.是不是可以有继续优化的地方

vscode里是断点打到测试用例上的,jest跑的时候也是可以单个测试执行或watch的。可以玩的点还是非常多的。

@i5ting WeChat7e76d92538e31bd47916e5e0e9ccd3f2.png 如果我只加了npm的那个script我没办法点击某个测试用例执行的时候,运行docker. 所以我弄了jest的globalSetup和globalTeardown. 这个方案是我们第一次在一个项目中使用,也不知道对不对.

回到顶部