随着时间的推移,更多的开发人员在流行的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
文件夹。 为测试编写脚本并将其保存在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的方法和功能,可让您自由定义和根据需要更改测试。 下面的错误可以根据需要自定义并导入多个组件。