测试

测试基于 Jest 测试框架。为了方便的编写测试,提供了 mockDatabase()mockServer() 用于数据库和服务端应用的测试。

mockDatabase()

默认提供一种完全隔离的 db 测试环境

1import { mockDatabase } from '@tachybase/test';
2
3describe('my db suite', () => {
4  let db;
5
6  beforeEach(async () => {
7    db = mockDatabase();
8    db.collection({
9      name: 'posts',
10      fields: [
11        {
12          type: 'string',
13          name: 'title',
14        },
15      ],
16    });
17    await db.sync();
18  });
19
20  afterEach(async () => {
21    await db.close();
22  });
23
24  test('my case', async () => {
25    const repository = db.getRepository('posts');
26    const post = await repository.create({
27      values: {
28        title: 'hello',
29      },
30    });
31
32    expect(post.get('title')).toEqual('hello');
33  });
34});

mockServer()

提供模拟的服务端应用实例,对应的 app.db 为 mockDatabase() 实例,同时还提供了便捷的 app.agent() 用于测试 HTTP API,针对 Tachybase 的 Resource Action 还封装了 app.agent().resource() 用于测试资源的 Action。

1import { MockServer, mockServer } from '@tachybase/test';
2
3// 每个插件的 app 最小化安装的插件都不一样,需要插件根据自己的情况添加必备插件
4async function createApp(options: any = {}) {
5  const app = mockServer({
6    ...options,
7    plugins: [
8      'acl',
9      'users',
10      'collection-manager',
11      'error-handler',
12      ...options.plugins,
13    ],
14    // 还会有些其他参数配置
15  });
16  // 这里可以补充一些需要特殊处理的逻辑,比如导入测试需要的数据表
17  return app;
18}
19
20// 大部分的测试都需要启动应用,所以也可以提供一个通用的启动方法
21async function startApp() {
22  const app = createApp();
23  await app.quickstart({
24    // 运行测试前,清空数据库
25    clean: true,
26  });
27  return app;
28}
29
30describe('test example', () => {
31  let app: MockServer;
32
33  beforeEach(async () => {
34    app = await startApp();
35  });
36
37  afterEach(async () => {
38    // 运行测试后,清空数据库
39    await app.destroy();
40    // 只停止不清空数据库
41    await app.stop();
42  });
43
44  test('case1', async () => {
45    // coding...
46  });
47});

常用的应用流程

如果需要测试不同流程的情况,可以根据以下示例执行相关命令。

先安装再启动

终端命令行

1pnpm tachybase install
2pnpm start

前置的测试流程

1const app = mockServer();
2await app.runCommand('install');
3await app.runCommand('start');

先启动再安装

终端命令行

1pnpm start # 常驻内存
2# 另一个终端里执行
3pnpm tachybase install

前置的测试流程

1const app = mockServer();
2await app.runCommand('start');
3await app.runCommand('install');

快速启动(自动安装或升级)

终端命令行

1yarn start --quickstart

前置的测试流程

1const app = mockServer();
2await app.runCommand('start', '--quickstart');

对已安装启动的应用进行重装

终端命令行

1pnpm start --quickstart
2# 另一个终端里执行
3pnpm tachybase install -f

前置的测试流程

1const app = mockServer();
2await app.runCommand('start', '--quickstart');
3await app.runCommand('install', '-f');

升级应用(启动前)

终端命令行

1pnpm tachybase upgrade
2pnpm start

前置的测试流程

1const app = mockServer();
2await app.runCommand('upgrade', '-f');
3await app.runCommand('start', '--quickstart');

升级应用(启动后)

1pnpm start # 常驻内存
2# 另一个终端里执行
3pnpm tachybase upgrade

前置的测试流程

1const app = mockServer();
2await app.runCommand('start', '--quickstart');
3await app.runCommand('upgrade', '-f');

激活插件

终端命令行

1yarn start --quickstart
2yarn pm enable @my-project/plugin-hello

前置的测试流程

1const app = mockServer();
2await app.runCommand('start', '--quickstart');
3await app.runCommand('pm', 'enable', '@my-project/plugin-hello');

禁用插件

终端命令行

1yarn start --quickstart
2yarn pm disable @my-project/plugin-hello

前置的测试流程

1const app = mockServer();
2await app.runCommand('start', '--quickstart');
3await app.runCommand('pm', 'disable', '@my-project/plugin-hello');