随着时间的推移,更多的开发人员在流行的JavaScript库(如React和Vue)建立的框架上构建应用。 其中一个是next.js:一个web框架,它可以让你使用React构架一个灵活的可伸缩的应用

在使用每个框架时,两个有效的概念值得探索是测试和错误处理。 它们没有什么不同。 本文旨在揭示Next.js在运行测试和处理错误的不同方式。

Cypress测试元素

在Next.js应用程序上运行测试的一种方法是通过Cypress,这是一个基于JavaScript的测试框架。 首先,您需要使用Next.js创建一个基本应用程序,然后安装Cypress并运行测试。 首先导航到终端并创建应用程序:

npx create-next-app nextjs-starter-app

# then navigate to the application and begin the development server

cd nextjs-starter-app

# then start a development server on http://localhost:3000

npm run dev

接下来,在http://localhost:3000上打开应用程序。 这会展示通用的欢迎页面:

现在你将安装Cypress来演示如何运行基本测试。 导航回终端并运行命令在应用程序中设置Cypress:

npm install cypress --save-dev

一旦完成,您需要从终端启动Cypress。 为此,在应用程序package.json文件的scripts对象中创建一个test键,并将cypress open分配为值:

// package.json

  "scripts": {
    "test": "cypress open"
  }

现在,在终端中输入以下命令启动Cypress:

npm run test

这将打开Cypress的测试套件,您可以在其中查看和运行项目的测试。 您将注意到已经有少数示例测试来展示Cypress如何工作。 您可以通过运行下面的示例集成规范来了解更多信息:

Cypress Test Suite Example Tests

要构建和运行第一个测试,请导航到应用程序中的新创建的Cypress文件夹。 为测试编写脚本并将其保存在integrations文件夹中。 建议您首先删除文件夹中的示例测试。 创建文件并命名为deploy.spec.js

# integration/examples/deploy.spec.js

context('Deploy', () => {
    beforeEach(() => {
      cy.visit('http://localhost:3000');
    });

    it('should click on the Deploy section in the homepage', () => {
      cy.get('h3')
        .contains('Deploy')
        .click()
    });
  });

在上面的代码示例中,测试应执行以下功能:

  • 在每个测试之前访问主页
  • 浏览主页,并选择具有文本“Deploy”的任何h3
  • 单击此标题并打开链接

第三个函数将您的测试抛出CORS错误。 要防止此操作,请在cypress.json文件中禁用Web安全性:

{
    "chromeWebSecurity": false
}

#  Do note that this isn't advisable as a practice in production

在执行测试之前,您需要自动启动开发服务器。 为此实现这一目标,导航到终端并安装一个名为start-server-and-test

npm install start-server-and-test --save-dev

接下来,在您的package.json文件中,您将在scripts对象中设置指令。 这将使您能够先启动开发服务器,然后打开Cypress:

"scripts": {
    "test": "cypress open",
    "server": "start-server-and-test dev 3000 test"
  }

现在已经完成基本设置! 导航到终端并使用命令启动您的服务器并测试npm run server

在Next.js中测试API路由

在处理更大的应用程序时,您可能会发现您需要测试路由和api。 您可以通过Cypress实现这一目标。 在您的应用程序中,导航到pages文件夹并创建一个名为api的新文件夹。 在此文件夹中,创建一个名为books.js的文件,这将存储您API所需的数据和功能:

// pages/api/books.js

export default function books(req, res) {
  res.statusCode = 200;
  res.setHeader("Content-Type", "application/json");
  return res.json([
    {
      id: 1,
      book: "The Firm",
      author: "John Grisham",
    },
    {
      id: 2,
      book: "Cracking the PM interview",
      author: "Jackie Bavaro",
    },
    {
      id: 3,
      book: "Fools Die",
      author: "Mario Puzo",
    },
  ]);
}

接下来,您将创建一个用于测试的脚本。 导航到cypress中的integrations/examples文件夹,在其中您将为API路由定义测试:

// integration/examples/books.spec.js

describe("Book test", () => {
  it("Confirms the number of books in your local library", () => {
    cy.visit("http://localhost:3000");
    cy.request("GET", "api/books").as("books");
    cy.get("@books").should((response) => {
      expect(response.status).to.eq(200);
      expect(response).to.have.property("headers");
      expect(response).to.have.property("duration");
      expect(response.body).to.have.length(3);
    });
  });
});

基本上,测试期望从books api的响应中包含以下内容:

  • 响应状态等于200
  • API响应包括标题
  • API响应主体包含三个对象
  • 包括响应时间

在Next.js渲染错误页面

Next.js提供内置的错误页面,可用于显示服务器和客户端错误。 默认情况下,此文件包含在pages目录中:

// pages/_error.js

function Error({ statusCode }) {
  return (
    <p>
      {statusCode
        ? `An error ${statusCode} occurred on server`
        : 'An error occurred on client'}
    </p>
  )
}

Error.getInitialProps = ({ res, err }) => {
  const statusCode = res ? res.statusCode : err ? err.statusCode : 404
  return { statusCode }
}

export default Error

在应用程序的中重用Error组件,导入它,然后使用getServerSideProps()函数在每个请求上预呈现错误:

import Error from 'next/_error'

export async function getServerSideProps({ res }) {
  const data = await fetch("http://localhost:3000/api/books");
  const errorCode = data.ok ? false : data.statusCode;
  if (errorCode) {
    res.statusCode = errorCode;
  }
  const json = await data.json();

  return {
    props: { errorCode, books: json.books_count },
  };
}

export default function Page({ errorCode, books }) {
  if (errorCode) {
    return <Error statusCode={errorCode} />;
  }
}

结论

Next.js提供了一种令人敬畏的体验,这些体验是在使用此框架时为开发人员提供大量选择。 使用Cypress的方法和功能,可让您自由定义和根据需要更改测试。 下面的错误可以根据需要自定义并导入多个组件。