如何测试快速应用程序
#node #测验 #fastify

Manuel Spigolon

在本文中,我将向您展示如何测试快速效果和MongoDB应用程序!

请注意,这篇文章是"How to use Fastify and MongoDb"article的随访,您学会了如何创建CRUD应用程序。

什么样的测试?

我们必须说它存在世界上很多测试:

  • 单元测试:编写的测试以测试一个单元的代码。
  • 集成测试:编写以测试整个应用程序的测试。
  • 最终测试:编写的测试以测试从客户端到服务器端的整个应用程序。
  • UI测试:编写用于测试应用程序用户界面的测试。
  • 性能测试:编写以测试应用程序性能的测试。
  • 安全测试:编写以测试应用程序安全性的测试。
  • 烟雾测试:编写以简单方式测试应用程序的测试。
  • 压力测试:以压力性的方式编写以测试应用程序的测试。

我认为我可以继续列出几个小时的所有测试。

如果您想深入研究,可以阅读Martin Fowler's网站。它包含许多有关测试的文章。

现在,我们将专注于集成测试

我选择编写集成测试,因为我认为:

  • 您可以专注于应用程序的业务逻辑。
  • 在码头环境中,旋转容器便宜且容易。
  • 测试代码较少:您也不需要模拟和修复模拟。
  • 将您在生产中的一些错误结晶很有帮助。

可以肯定的是,添加单元测试是一种很好的方法,但我通常会为特定组件做。我们将在本文末尾看到一个示例。

选择正确的测试框架

fastify具有a koude0 methodthat允许您在不启动HTTP服务器的情况下向应用程序注入请求。

koude1测试框架中的此功能使您可以更快地测试应用程序。

组合是node-tap并行运行测试(每个测试,文件一个过程)。因此,您将创建的文件越多,并且测试将更快。 Fastify的inject功能将避免无聊的Address already in use错误。

npm install tap -D安装后,让我们一起使用简短的tap示例。

// test/index.test.js
const t = require('tap')

t.test('my first test', async t => {
  t.ok(true, 'my first assertion')
})

您可以看到,此框架非常容易且清晰使用:您在必须运行断言的函数中定义了一些.test().node-tap是一个功能完整的测试框架,您会喜欢它的功能。

>

现在您可以简单地使用:
运行文件

node test/index.test.js

或在package.json中添加脚本:

{
  "scripts": {
    "test": "tap test/**.test.js"
  }
}

创建可测试的应用程序

在我们的previous article中,我们创建了一个CRUD应用程序。我们将优化它,并使其可测试。

为了使其可测试,我们需要改进app.js文件并将配置加载分解。现在,fastify-env默认情况下从.env文件加载配置。

运行测试时,我们想从.env.test加载配置或直接注入。

module.exports = fp(async function application (app, opts) {
  await app.register(require('fastify-env'), {
    data: opts.envData,
    schema: {
    // ... old code

我们添加了data参数。现在,fastify-env将将schema检查应用于data对象。当data是虚假的时,将使用process.env对象。通过这种方式,我们可以通过直接注入所需的配置来测试它。

如果存在fastify-env插件也将加载.env文件,但不会覆盖data对象。

仅此而已!现在我们可以写我们的测试用例!

编写测试

测试案例我们的应用程序需求如下:

  • 创建一个todo
  • 阅读todo
  • 更新todo
  • 阅读已更新的todo
  • 删除todo
  • 更新一个不存在的待办事项
  • 删除不存在的todo

让我们在test/legacy.test.js文件中创建第一个测试用例:

const t = require('tap')
const fastify = require('fastify')
const appModule = require('../app')

t.test('create', async t => {
  const app = fastify()
  app.register(appModule, {
    envData: {
      NODE_ENV: 'testing',
      MONGO_URL: 'mongodb://localhost:27017/my-todo-app'
    }
  })
  t.teardown(() => app.close()) // let's close the server after the test

  const response = await app.inject({
    method: 'POST',
    url: '/todos',
    payload: {
      text: 'test todo'
    }
  })

  t.equal(response.statusCode, 201)

  const todo = response.json()
  t.ok(todo.id, 'the id has been returned')
})

现在运行node test/legacy.test.js将显示此输出:

TAP version 13
# Subtest: create
    ok 1 - should be equal
    ok 2 - the id has been returned
    1..2
ok 1 - create # time=206.184ms

1..1

太好了!我们创建了一个创建todo并返回ID的测试用例。

备忘录:记住在运行测试之前运行npm run mongo:start以旋转数据库。

如您所见,inject方法接受一个输入对象:

  • method:http方法
  • url:url
  • payload:发送载荷
  • headers:发送的标题
  • query:查询字符串

much more

让我们继续其他测试用例:

  // ...previous code..
  const todo = response.json()
  t.ok(todo.id, 'the id has been returned')

  t.test('read', async t => {
    const response = await app.inject({
      method: 'GET',
      url: '/todos'
    })

    t.equal(response.statusCode, 200)
    t.equal(response.json().length, 1)
    t.notOk(response.json()[0].done)
  })
})

现在,我们正在为create测试用例创建一个子测验:read。如您所见,我们正在检查状态代码和响应的长度:我们已经插入了todo,然后我们正在阅读待办事项列表并检查只有一个元素。

如果我们再次运行,我们会遇到错误!

...
 diff: |
  --- expected
  +++ actual
  @@ -1,1 +1,1 @@
  -1
  +2
...

这是由于我们正在使用相同的数据库,并且先前的测试用例已插入了todo,在第二次运行中,我们添加了另一个。

实施集成测试时,这是一个常见的问题。创建集成测试需要一个阶段开始之前:

  • 旋转:当我们准备数据库运行测试时。

如前所述,这对于复制生产中发现的问题很有用。在一个旋转阶段,我们可以创建需要复制错误的数据,然后验证在实现之后修复了该错误。

这很有用,因为测试运行后,您也可以在数据库上检查数据!因此,您将立即准备修复错误并在应用程序中本地播放。

让我们更新我们的测试文件:

const mongoClean = require('mongo-clean')
const { MongoClient } = require('mongodb')

t.test('spin up phase - prepare data', async t => {
  const c = await MongoClient.connect('mongodb://localhost:27017/my-todo-app')
  await mongoClean(c.db())
  c.close()
})

t.test('create', async t => {
  // ...

现在,运行我们的测试将成功:

# Subtest: create
    ok 1 - should be equal
    ok 2 - the id has been returned
    # Subtest: read
        ok 1 - should be equal
        ok 2 - should be equal
        ok 3 - expect falsey value
        1..3
    ok 3 - read # time=5.999ms

    1..3
ok 1 - create # time=211.436ms

1..1
# time=216.488ms

做得好!我们现在有工作集成测试!

现在,您拥有所有可以构建可测试应用程序的部分,并完成我们之前列出的缺失测试用例。

Insights:如果您创建多个文件来测试您的应用程序,请记住使用不同的数据库名称。您只需要自定义envData.MONGO_URL参数。这将避免测试之间的冲突。

如果您想全部看到它们,请给koude35存储库进行检查。

概括

我们在本教程中看到了很多东西。

  • 如何将node-tap用于我们的测试。
  • 如何使用fastify-env插件进行可测试的应用程序。
  • fastify.inject调用应用程序端点的方法。
  • 如何处理集成测试。

现在您需要在Fastify中练习并构建自己的应用程序!

评论并分享您是否喜欢这篇文章!