使用 jsdom 和 AVA 为 Nuxt 应用编写测试

你已经独立学习了 jsdomAVA,并进行了一些简单的测试。现在,我们可以将这两个包一起引入到我们的 Nuxt 应用程序中。让我们在上一章创建的 Nuxt 应用程序中安装它们,该应用程序位于 /chapter-12/nuxt-universal/cross-domain/jwt/axios-module/frontend/,使用以下步骤:

  1. 通过 npm 安装这两个工具,并将它们保存到 package.json 文件中的 devDependencies 选项:

    $ npm i ava --save-dev
    $ npm i jsdom --save-dev
  2. 安装 Babel 核心和其他 Babel 包,以便我们在应用程序的测试中编写 ES6 代码:

    $ npm i @babel/polyfill
    $ npm i @babel/core --save-dev
    $ npm i @babel/preset-env --save-dev
    $ npm i @babel/register --save-dev
  3. AVA 配置添加到 package.json 文件,如下所示:

    // package.json
    {
      "scripts": {
        "test": "ava --verbose",
        "test:watch": "ava --watch"
      },
      "ava": {
        "require": [
          "./setup.js",
          "@babel/polyfill"
        ],
        "files": [
          "test/**/*"
        ]
      }
    }
  4. 在根目录下创建一个 setup.js 文件,就像你在上一节中所做的那样,但使用以下代码:

    // setup.js
    require('@babel/register')({
      babelrc: false,
      presets: ['@babel/preset-env']
    })
  5. 准备以下测试模板,用于在 /test/ 目录中编写测试:

    // test/tests.js
    import test from 'ava'
    import { Nuxt, Builder } from 'nuxt'
    import { resolve } from 'path'
    let nuxt = null
    test.before('Init Nuxt.js', async t => {
      const rootDir = resolve(__dirname, '..')
      let config = {}
      try { config = require(resolve(rootDir, 'nuxt.config.js')) }
      catch (e) {}
      config.rootDir = rootDir
      config.dev = false
      config.mode = 'universal'
      nuxt = new Nuxt(config)
      await new Builder(nuxt).build()
      nuxt.listen(5000, 'localhost')
    })
    // 在这里编写你的测试...
    test.after('Closing server', t => {
      nuxt.close()
    })

    测试将在 localhost:5000(或你喜欢的任何端口)上运行。你应该在生产构建上进行测试,因此在 config.dev 键中关闭开发模式,如果你的应用程序是为服务器端和客户端开发的,则在 config.mode 键中使用 universal。然后,确保在测试过程结束后关闭 Nuxt 服务器。

  6. 编写第一个测试来测试我们的主页,以确保在此页面上渲染了正确的 HTML

    // test/tests.js
    test('路由 / 存在并渲染正确的 HTML', async (t) => {
      let context = {}
      const { html } = await nuxt.renderRoute('/', context)
      t.true(html.includes('<p class="blue">My marvelous Nuxt.js project</p>'))
    })
  7. /about 路由编写第二个测试,以确保在此页面上渲染了正确的 HTML

    // test/tests.js
    test('路由 /about 存在并渲染正确的 HTML', async (t) => {
      let context = {}
      const { html } = await nuxt.renderRoute('/about', context)
      t.true(html.includes('<h1>About page</h1>'))
      t.true(html.includes('<p class="blue">Something awesome!</p>'))
    })
  8. /about 页面编写第三个测试,以确保通过使用 jsdom 在服务器端进行 DOM 操作,文本内容、类名和样式符合预期:

    // test/tests.js
    test('路由 /about 存在并渲染正确的 HTML 和样式',
    async (t) => {
      function hexify (number) {
        const hexChars =
          ['0','1','2','3','4','5','6','7','8','9','a','b',
           'c','d','e','f']
        if (isNaN(number)) {
          return '00'
        }
        return hexChars[(number - number % 16) / 16] +
               hexChars[number % 16]
      }
      const window = await nuxt.renderAndGetWindow(
        'http://localhost:5000/about')
      const element = window.document.querySelector('.blue')
      const rgb = window.getComputedStyle(element).color.match(/\d+/g)
      const hex = '' + hexify(rgb[0]) + hexify(rgb[1]) + hexify(rgb[2])
      t.not(element, null)
      t.is(element.textContent, 'Something awesome!')
      t.is(element.className, 'blue')
      t.is(hex, '0000ff')
    })

    如果使用 npm run test 运行测试并通过,你将得到以下结果:

    ✓ Route / exits and renders correct HTML (369ms)
    ✓ Route /about exits and renders correct HTML (369ms)
    ✓ Route /about exists and renders correct HTML and style (543ms)
    3 tests passed

你可以看到,在我们的第三个测试中,我们创建了一个 hexify 函数,用于将 Window.getComputedStyle 方法计算出的十进制代码 (R, G, B) 转换为十六进制代码。例如,对于你在 CSS 样式中设置为 color: white 的颜色,你将得到 rgb(255, 255, 255)。因此,对于 0000ff,你将得到 rgb(0, 0, 255),应用程序必须将其转换为通过测试。

你可以在我们的 GitHub 仓库中的 /chapter-13/nuxt-universal/ava/ 找到这些测试。

做得好。你已经成功地为 Nuxt 应用程序编写了简单的测试。我们希望你发现在 Nuxt 中编写测试既简单又有趣。测试的复杂性取决于你想要测试的内容。因此,首先了解你想要测试的内容非常重要。然后,你可以开始编写有意义且相关的测试。

然而,使用 jsdomAVA 测试 Nuxt 应用程序有一些限制,因为它不涉及浏览器。请记住,jsdom 旨在将原始 HTML 转换为服务器端的 DOM,因此我们在前面的练习中使用 async/await 语句异步请求页面以进行测试。如果你想使用浏览器测试你的 Nuxt 应用程序,Nightwatch 可能是一个不错的解决方案,所以我们将在下一节中对其进行介绍。让我们继续。