测试简介

未匹配的标注

AdonisJS 具有开箱即用的测试支持,无需安装任何第三方包。只需运行node ace test,奇迹就会发生。

注:AdonisJS 使用 Japa(一个自制的测试框架)来编写和执行测试。 因此,我们强烈建议你阅读 Japa 文档一次

每次全新安装的 AdonisJS 都会附带一个在tests/functional/hello-world.spec.ts文件中编写的示例功能测试。让我们打开这个文件并了解如何用 AdonisJS 编写测试。

import { test } from '@japa/runner'

test('display welcome page', async ({ client }) => {
  const response = await client.get('/')

  response.assertStatus(200)
  response.assertTextIncludes('<h1 class="title"> It Works! </h1>')
})
  • 使用@japa/runner包导出的test函数注册测试。
  • test函数接受标题作为第一个参数,实现回调作为第二个参数。
  • 实现回调接收测试上下文。测试上下文包含可用于获得更好测试体验的其他属性。

让我们通过执行以下命令来运行测试。

node ace test

# [ info ] 运行测试...

# tests/functional/hello-world.spec.ts
#  ✔ 显示欢迎页面 (24ms)

#  PASSED 

# total        : 1
# passed       : 1
# duration     : 28ms

现在让我们重新运行测试命令,但这次使用--watch标志。观察者将观察文件系统更改并在每次文件更改后执行测试。

node ace test --watch

查看视频演示

测试套件

AdonisJS 将测试组织成多个套件。每个套件的测试都位于其子目录中。例如:

  • 功能测试存储在tests/functional/目录中。
  • 单元测试存储在tests/unit/目录中。

套件在.adonisrc.json文件中注册,你可以根据需要删除/添加套件。套件结合了文件的唯一名称和 glob 模式。

注:你也可以使用make:suite命令创建一个新的测试套件并将其注册到.adonisrc.json文件中。

// title: .adonisrc.json
{
  "tests": {
    "suites": [
      {
        "name": "functional",
        "files": "tests/functional/**/*.spec(.ts|.js)"
      }
    ]
  }
}

你还可以为每个测试套件注册生命周期挂钩。这些钩子使用configureSuite方法在tests/bootstrap.ts文件中注册。

在下面的例子中,AdonisJS 为功能测试套件注册了一个设置钩子来启动 HTTP 服务。

export const configureSuite: Config['configureSuite'] = (suite) => {
  if (suite.name === 'functional') {
    suite.setup(() => TestUtils.httpServer().start())
  }
}

配置测试运行器

AdonisJS 在项目根目录中的test.ts文件中配置测试运行程序。该文件首先启动 AdonisJS 应用程序,然后使用 Japa 运行测试。

在大多数情况下,你永远不会触及test.ts文件。相反,我们建议你使用tests/bootstrap.ts文件来进一步配置测试运行程序或在测试之前/之后运行自定义逻辑。

引导文件导出以下属性,然后将其提供给 Japa。

// title: tests/bootstrap.ts
export const plugins: Config['plugins'] = []
export const reporters: Config['reporters'] = []
export const runnerHooks: Required<Pick<Config, 'setup' | 'teardown'>> = {
  setup: [],
  teardown: [],
}
export const configureSuite: Config['configureSuite'] = (suite) => {
}

插件

plugins属性接受一系列 Japa 插件。默认情况下,我们注册以下插件。

  • assert - 断言模块进行断言。
  • runFailedTests - 仅运行失败测试(如果有)的插件。
  • apiClient - 用于测试 HTTP 端点的 API 客户端。

reporters

reporters属性接受一组 Japa 记者。我们注册 spec-reporter 以在终端显示测试进度。


runnerHooks

你可以使用runnerHooks属性在测试之前或之后运行操作(跨所有套件)。

-setup钩子在所有测试之前执行。
-teardown钩子在所有测试后执行。


配置套件

configureSuite方法使用 Japa suite 类的实例执行。你可以使用套件实例对其进行配置。

环境变量

在测试期间,AdonisJS 会自动将NODE_ENV的值设置为test

我们还加载.env.test文件并将该文件中定义的值与现有环境变量合并。默认情况下定义了以下覆盖。

NODE_ENV=test
ASSETS_DRIVER=fake
SESSION_DRIVER=memory
  • ASSETS_DRIVER属性将用于提供 捆绑资产 的驱动程序切换为假实现。这样做允许你在不使用 Webpack 编译前端资源的情况下运行测试。
  • SESSION_DRIVER切换到在内存中持久化会话数据并在测试期间访问它。使用任何其他驱动程序都会破坏测试。

创建测试

你可以使用 node ace make:test 命令创建测试。该命令接受套件名称作为第一个参数,然后是测试文件名。

node ace make:test functional list_users

# CREATE: tests/functional/list_users.spec.ts

你可以按如下方式创建嵌套文件结构。

node ace make:test functional users/list

# CREATE: tests/functional/users/list.spec.ts

运行测试

你可以通过执行 node ace test 命令来运行测试。此外,你可以通过传递套件名称来运行特定套件的测试。

# 运行所有测试
node ace test

# 只执行功能测试
node ace test functional

# 单元和功能测试按顺序执行
node ace test unit functional

# 仅在“单元”和“功能”套件中使用“订单”或“上传”标签进行测试
node ace test --tags="orders,upload" unit functional

test命令接受以下标志。

  • --watch:在监视模式下运行测试。如果测试文件被更改,观察者将只运行修改后的文件中的测试。否则,将执行所有测试。
  • --tags:运行具有一个或多个上述标签的测试。
  • --ignore-tags--tags 标志的逆向。只运行没有所有提到的标签的测试。
  • --files:从提到的文件中挑选并运行测试。
  • --timeout:定义所有测试的全局超时。
  • --force-exit:如果测试过程没有正常结束,则强制退出。
  • --tests:按标题运行特定测试。

数据库管理

本节介绍数据库迁移、运行播种器以及使用全局事务在测试之间获得干净的数据库状态。

注意:确保你已安装 @adonisjs/lucid 以使以下示例正常工作。

迁移数据库

你可以在运行所有测试之前迁移数据库并在测试之后回滚它。这可以通过在 tests/bootstrap.ts 文件中注册 TestUtils.db().migrate() 挂钩来完成。

// 文件名: tests/bootstrap.ts
export const runnerHooks: Required<Pick<Config, 'setup' | 'teardown'>> = {
  setup: [
    () => TestUtils.ace().loadCommands(),
    () => TestUtils.db().migrate()
  ],
  teardown: [],
}

种子数据库

你还可以通过调用 TestUtils.db().seed() 方法来运行数据库播种器。

setup: [
  () => TestUtils.ace().loadCommands(),
  () => TestUtils.db().migrate()
  () => TestUtils.db().seed()
],

全局事务

我们建议你使用 数据库全局事务 在测试之间获得干净的数据库状态。

在下面的示例中,我们在所有测试之前启动一个全局事务并在测试之后回滚它。

提示:group.each.setup 方法在组内的每个测试之前运行。

import Database from '@ioc:Adonis/Lucid/Database'

test.group('Group name', (group) => {
  group.each.setup(async () => {
    await Database.beginGlobalTransaction()
    return () => Database.rollbackGlobalTransaction()
  })
})

如果你使用多个数据库连接,那么你可以为每个连接定义一个挂钩。例如:

group.each.setup(async () => {
  await Database.beginGlobalTransaction('pg')
  return () => Database.rollbackGlobalTransaction('pg')
})

group.each.setup(async () => {
  await Database.beginGlobalTransaction('mysql')
  return () => Database.rollbackGlobalTransaction('mysql')
})

本文章首发在 LearnKu.com 网站上。

本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://learnku.com/docs/adonisjs/5.x/te...

译文地址:https://learnku.com/docs/adonisjs/5.x/te...

上一篇 下一篇
贡献者:3
讨论数量: 0
发起讨论 只看当前版本


暂无话题~