有可能只用一个工具来测试所有的东西吗?虽然这听起来像是开发者的白日梦,但有了Cypress,一个JavaScript前端测试框架,这几乎是可能的。Cypress是专门为JavaScript前端开发者建立的,他们可以用它来快速开始编写测试,而不需要添加第三方的依赖或包。这是Selenium等其他工具所没有的好处。在本教程中,我将指导你使用Cypress来测试一个API。
本教程包括以下内容:
- 设置Cypress框架
- 了解Cypress如何对API进行HTTP调用
- 了解如何使用Cypress的
cy.request()方法
先决条件
要学习本教程,你需要具备一些条件。
使用Cypress进行API测试
由于Cypress是一个独立的前端测试工具,它在执行过程中代表Web应用程序发出HTTP请求。虽然看起来Cypress是从浏览器发出这些请求的,但实际上它使用Node.js作为引擎,向API服务器发出HTTP请求。它使用Node.js来返回从服务器上收到的响应。

注意: Cypress公开了cy.request() 方法,以便从框架内进行HTTP请求。这就是我们在本教程中使用的方法,以测试我们使用Cypress的端点。
初始化目录和设置Cypress
首先,通过在终端上运行这些命令,创建一个空目录并初始化一个空的Node项目。
mkdir testing-apis-with-cypress && cd testing-apis-with-cypress
第一条命令创建了目录,而第二条命令则创建了一个具有默认配置的Node.js项目。我们将在本教程的后面更新默认配置。我们将在初始化的Node项目中编写我们的测试。
npm init -y
你需要知道,npm init -y 以默认配置创建一个Node项目,不会提示你定制项目的package.json 文件的内容。如果只运行npm init ,package.json 文件将产生不同的结果,因为它将提示你对Node项目属性的配置。
现在你有一个初始化的目录,你可以安装Cypress框架。Cypress的安装和其他npm包的安装一样,所以你可以用任何一种方式安装它。
npm install cypress
或者。
yarn add cypress
在安装完Cypress之后,下一步是初始化Cypress框架。这个过程将创建默认的Cypress目录,如果需要的话,你需要编写你的测试和包含包。
在终端中,运行命令cypress open 。该命令将首次初始化Cypress,并创建默认的Cypress目录和文件。
注意: 如果你遇到问题,你可能需要全局安装Cypress。

设置Git并推送到CircleCI
在开始编写测试之前,你需要设置CircleCI。首先,通过运行该命令在项目中初始化一个Git仓库。
git init
接下来,在根目录下创建一个.gitignore 文件。在该文件中,添加node_modules ,以防止npm生成的模块被添加到你的远程仓库。下一步将是添加一个提交,然后将你的项目推送到GitHub。
现在登录CircleCI,导航到项目。那里会有一个与你的GitHub用户名或你的组织相关的所有GitHub仓库的列表。找到你想在CircleCI中设置的仓库。在我们的例子中,它是api-testing-with-cypress 项目。在项目仪表板上,选择选项来设置所选项目。选择使用现有配置的选项。

现在,在提示中,选择选项,开始构建过程。你可以预期你的管道会失败,因为你仍然需要将定制的.circleci/config.yml 文件添加到 GitHub。

编写CI流水线
一旦你建立了CircleCI管道,现在是时候将CircleCI添加到本地项目中。首先,在根目录下创建一个名为.circleci 的文件夹。在这个文件夹中,创建一个config.yml 文件。将这些配置细节添加到config.yml中。
version: 2
jobs:
build:
docker:
- image: cypress/base:14.16.0
environment:
## this enables colors in the output
TERM: xterm
working_directory: ~/repo
steps:
- checkout
- restore_cache:
keys:
- v1-deps-{{ .Branch }}-{{ checksum "package.json" }}
- v1-deps-{{ .Branch }}
- v1-deps
- run:
name: Install Dependencies
command: npm ci
- save_cache:
key: v1-deps-{{ .Branch }}-{{ checksum "package.json" }}
# cache NPM modules and the folder with the Cypress binary
paths:
- ~/.npm
- ~/.cache
- run: $(npm bin)/cypress run
- store_artifacts:
path: ~/repo/api-testing-with-cypress
在这个配置中,CircleCI从环境中拉出一个Cypress Docker镜像,并检查任何存储的我们的依赖性的缓存。
下一阶段是恢复缓存(如果存在的话),并且只在用save-cache 检测到变化时才更新应用程序的依赖关系。它运行api-testing-with-cypress Cypress测试,并将缓存的项目存储在位于~/repo/api-testing-with-cypress 目录的工件中。
把你的改动推送到GitHub,CircleCI就会自动开始构建过程。这里,由于我们目前还没有任何测试,我们的管道将再次失败。我们将在以后添加测试后重新运行。在CircleCI仪表板上,你应该能够看到创建的管道和执行情况,即使没有在我们的存储库中运行测试。
开始使用Cypress
在本教程中,我们将使用我们在heroku上托管的一个已经建立的API来测试我们的应用程序。要做到这一点,我们首先需要Cypress了解我们将在测试中使用的API Url(Cypress将其称为baseUrl )。
设置baseUrl
Cypress框架有一个配置文件cypress.json ,由Cypress的初始化过程生成。cypress.json 文件存储了我们提供的所有配置变量,这也是我们将设置我们的baseUrl 的地方。这是为了确保我们在运行测试时不需要重复整个URL。baseUrl 将被设置为我们的Heroku API URL的配置变量,如下面cypress.json 文件中的代码片断所示。
{
"baseUrl": "http://todo-app-barkend.herokuapp.com/"
}
设置运行命令
现在我们已经准备好了我们的测试URL,我们需要创建一个简单的方法让我们使用终端来运行我们的测试。要做到这一点,我们将在package.json 文件中的脚本部分添加一个脚本。为了实现这一目标,我们需要在package.json 文件的脚本部分添加下面的test 命令。
"scripts": {
"test": "cypress open"
},
这个命令告诉Cypress在执行我们的测试时,以非无头模式运行,并打开一个浏览器。
package.json 文件中的脚本使你不得不在终端上运行的命令和脚本自动化。相反,你使用npm 来执行它们,同时以一种对正在运行的程序可以理解的方式来包装它们。
在Cypress中编写测试
Cypress是一个前端测试工具,它生成了很多文件和目录,是如何编写Cypress测试的例子。现在我们可以忽略它们。
现在,Cypress已被初始化,你的CircleCI管道已被配置好,是时候开始编写测试了。
编写你的第一个Cypress API测试
请记住,Cypress的工作方式是在引擎盖下使用Node来触发HTTP请求,并将其路由回Cypress,以进行断言并验证是否进行了预期的调用。在第一个测试中,我们将向我们的todo应用程序发出一个GET 请求,以确保它确实向API返回todo项目。在这样做之前,我们需要删除目录cypress/integration/ 中的所有内容。这个目录包含了由Cypress初始化生成的假脚手架。在cypress/integration/ ,创建另一个名为api-tests 的目录。为了确保Cypress能够理解测试文件夹的动作,用这个配置值更新cypress.json 文件。
{
d "integrationFolder": "cypress/integration/api-tests"
}
在api-tests 文件夹中,创建todo.spec.js 文件,这就是我们将编写测试的地方。这里是最棒的一点。Cypress是自我维持的,所以我们不需要任何其他外部依赖来测试我们的API。
打开todo.spec.js 文件,为todos的APIGET 请求设置测试。添加这段代码。
describe('TODO api testing', () => {
let todoItem;
it('fetches Todo items - GET', () => {
cy.request('/todos/').as('todoRequest');
cy.get('@todoRequest').then(todos => {
expect(todos.status).to.eq(200);
assert.isArray(todos.body, 'Todos Response is an array')
});
});
});
在这个例子中,Cypress将baseUrl 附在cy.request() 方法上。这个方法向托管的API端点发出GET请求,以获得我们的todo项目,并验证API是否被测试调用。
注意: 当cy.request() 没有被传递任何HTTP请求操作时,它默认为GET请求。这就是为什么你不需要告诉测试你正在进行一个APIGET 请求。
执行赛普拉斯API测试
要执行第一个测试,并检查一切运行是否正常,请在终端运行npm test 命令。我们在前面的package.json中定义了npm test 命令。Cypress仪表板将打开。

当我们运行命令执行测试时,任何添加的测试规格(文件)将显示在Cypress仪表板上。选择实际的测试,看着Cypress执行它。

仪表板显示,测试执行成功,我们能够得到所有的todo项目。Cypress默认在浏览器中运行,所以我们可以进一步验证从测试返回的所有元素。
从屏幕的左侧,点击显示返回数组的最后一个断言。这将输出打印到控制台。然后,你可以在同一窗口上右击检查元素,打开浏览器的开发工具。点击控制台标签,显示我们在测试中断言的数组项目。我们有理由庆祝,因为我们可以验证我们的API和我们的测试是正确工作的。
编写和添加更多的测试
现在,你已经熟悉了添加赛普拉斯,你可以添加更多的测试。例如,你可以测试添加一个新的todo项目和删除一个todo项目。
it('deletes Todo items - DELETE', () => {
cy.request('DELETE', `/todos/${todoItem}`).as('todoRequest');
// deletes Todo item with id = 9
cy.get('@todoRequest').then(todos => {
expect(todos.status).to.eq(200);
assert.isString(todos.body, 'todo deleted!')
});
});
it('Adds Todo item - POST', () => {
cy.request('POST', '/todos/', { task: "run tests" }).as('todoRequest');
// adds new Todo item by defining Todo name
cy.get('@todoRequest').then(todos => {
expect(todos.status).to.eq(200);
cy.wrap(todos.body).should('deep.include', {
task: 'run tests',
completed: false,
});
});
});
POST 在这个代码片段中,我们在cy.request() 中声明了HTTP请求的类型。这也是声明任何其他参数的地方,比如body ,用于创建一个新的todo项目的请求。使用这些测试,你可以验证你可以使用我们的API创建一个todo项目,获得所有创建的todo项目,并删除一个todo项目。成功了!我们的API没有被破坏。
现在,我们需要验证这些测试是否在已经创建的CircleCI管道上通过。你已经初始化了CircleCI,所以你只需要提交并推送你的修改到GitHub。CircleCI将自动运行我们的测试。

再一次,成功了!你所有的测试都通过了。
总结
在本教程中,你已经设置了Cypress并配置了它来运行API测试。你学会了如何为测试设置baseUrl ,并配置了测试框架中的目录。你学会了使用cy.request() 来进行不同的HTTP操作,以及如何使用Cypress测试运行器。