devkind/laravel-cypress

Laravel Cypress 模板

1.2.5 2023-07-22 21:40 UTC

This package is auto-updated.

Last update: 2024-09-23 00:36:24 UTC


README

此包提供必要的模板,以便快速开始使用 Cypress 测试您的 Laravel 应用程序。

视频教程

如果您想对这个包进行更直观的审查,请观看 Laracasts 上的此视频

目录

安装

如果您还没有安装 Cypress,这是您的第一步。

npm install cypress --save-dev

现在您可以通过 Composer 安装此包。将其作为开发依赖项拉入。

composer require laracasts/cypress --dev

最后,运行 cypress:boilerplate 命令,将 Cypress 测试的初始模板文件复制过来。

php artisan cypress:boilerplate

就是这样!您已经准备好了。我们为您提供了一个 example.cy.js 规范,您可以尝试使用它。让我们现在运行它

npx cypress open

在打开的 Cypress 窗口中,选择 "端到端测试",然后选择 "在 Chrome 中启动端到端测试"。这将在您的应用程序中列出所有规范。当然,在这个阶段,我们只有一个示例规范。点击 example.cy.js 来运行它。哇!全部绿色。

Cypress 配置

我们在项目的 cypress.config.js 文件中声明了一些初始设置。现在快速查看以确保一切正常。特别是,请确保 baseUrl 属性已正确设置(我们默认为您的应用程序的 APP_URL 环境设置)。

环境处理

运行 php artisan cypress:boilerplate 命令后,您现在将在项目根目录中有一个 .env.cypress 文件。为了让您开始,此文件是 .env 的副本。您可以随时根据需要更新它,以准备您的应用程序进行 Cypress 测试。

很可能是您想使用一个特殊的数据库,以确保您的 Cypress 接受测试与您的开发数据库隔离。

DB_CONNECTION=mysql
DB_DATABASE=cypress

在运行 Cypress 测试时,此包默认会自动备份您的 primary .env 文件,并将其与 env.cypress 交换。完成后,当然环境文件将重置到原始状态。

所有 Cypress 测试都根据 .env.cypress 中指定的环境运行。

然而,当您的 Cypress 测试失败时,手动 以触发测试失败的确切状态浏览您的应用程序 往往很有用。如果环境在每次测试运行后自动还原,则无法这样做。

为了解决这个问题,您有两个选择

选项 1

暂时禁用重置环境的 Cypress 任务。访问 cypress/support/index.js 并取消注释这部分。

after(() => {
  // cy.task("activateLocalEnvFile", {}, { log: false });
});

这就完成了!只是记住,在您完成 Cypress 测试后,手动将本地 .env 文件恢复到正常。

选项 2

当使用 php artisan serve 启动服务器时,您可以选择传递一个 --env 标志来指定应用程序所需的配置。

php artisan serve --env="cypress"

^ 此命令指示 Laravel 启动服务器并使用 .env.cypress 中声明的配置。

现在访问 cypress.json 并将 baseUrl 修改为指向您的本地服务器。

{
  "baseUrl": "http://127.0.0.1:8000"
}

现在您已经设置好了!我建议创建一个 npm 脚本来简化此过程。打开 package.json 并添加以下内容

{
  "scripts": {
    "test:cypress": "php artisan serve --env=cypress & cypress open"
  }
}

现在,您可以从命令行运行 npm run test:cypress 以启动本地服务器并打开 Cypress。

如果您选择第二个选项,请访问 cypress/support/index.js 并删除 activateCypressEnvFileactivateLocalEnvFile 任务,如图所示。它们不再需要,因为您将自行处理环境。

API

此包将为您的 Cypress 工作流程添加各种命令,以使 Laravel 测试环境更加熟悉。

我们通过在您的应用程序中公开一些 Cypress 特定的端点来实现这一点。请放心:这些端点 永远 不会在生产环境中可访问。

cy.login()

查找匹配提供的可选属性的现有用户,并将其设置为测试的认证用户。如果未找到,它将创建一个新用户并登录。

test('authenticated users can see the dashboard', () => {
  cy.login({ username: 'JohnDoe' });

  cy.visit('/dashboard').contains('Welcome Back, JohnDoe!');
});

如果您还需要在用户模型上预加载关系或指定服务器返回之前模型工厂的状态,请将一个对象传递给 cy.login(),如下所示

test('authenticated users can see the dashboard', () => {
    cy.login({
        attributes: { username: 'JohnDoe' },
        state: ['guest'],
        load: ['profile']
    });

    cy.visit('/dashboard').contains('Welcome Back, JohnDoe!');
});

如果用 PHP 编写,此对象将有效转换为

$user = User::factory()->guest()->create([ 'username' => 'JohnDoe' ])->load('profile');

auth()->login($user);

cy.currentUser()

从服务器获取当前认证用户(如果有的话)。相当于 Laravel 的 auth()->user()

test('assert the current user has email', () => {
    cy.login({ email: 'joe@example.com' });

    cy.currentUser().its('email').should('eq', 'joe@example.com');
    
    // or...
    
    cy.currentUser().then(user => {
        expect(user.email).to.eql('joe@example.com');
    });
});

cy.logout()

注销当前认证用户。相当于 Laravel 的 auth()->logout()

test('once a user logs out they cannot see the dashboard', () => {
  cy.login({ username: 'JohnDoe' });

  cy.logout();

  cy.visit('/dashboard').assertRedirect('/login');
});

cy.create()

使用 Laravel 工厂创建并持久化新的 Eloquent 记录。

test('it shows blog posts', () => {
  cy.create('App\\Post', { title: 'My First Post' });

  cy.visit('/posts').contains('My First Post');
});

注意,上面的 cy.create() 调用相当于

App\Post::factory()->create(['title' => 'My First Post']);

您可以选择性地指定所需的记录数作为第二个参数。这将返回一个帖子集合。

test('it shows blog posts', () => {
  cy.create('App\\Post', 3, { title: 'My First Post' });
});

最后,您还可以将对象传递给 cy.create()。如果您需要预加载关系或在给定的模型工厂状态下创建模型记录,则应首选此选项。

test('it shows blog posts', () => {
    cy.create({
        model: 'App\\Post',
        attributes: { title: 'My First Post' },
        state: ['archived'],
        load: ['author'],
        count: 10
    })
});

如果用 PHP 编写,此对象将有效转换为

$user = \App\Post::factory(10)->archived()->create([ 'title' => 'My First Post' ])->load('author');

auth()->login($user);

cy.refreshRoutes()

在您的 Cypress 测试套件运行之前,此包将自动获取 Laravel 应用程序的所有命名路由集合并将其存储在内存中。您不需要手动调用此方法,但如果您的路由会因特定测试而更改,则此方法可用。

test('it refreshes the list of Laravel named routes in memory', () => {
    cy.refreshRoutes();
});

cy.refreshDatabase()

在测试数据库上触发 migrate:refresh。通常,您会在 beforeEach 调用中使用此操作,以确保在每次新测试之前,您的数据库都是新鲜迁移和清理过的。

beforeEach(() => {
  cy.refreshDatabase();
});

test('it does something', () => {
  // php artisan migrate:fresh has been
  // called at this point.
});

cy.seed()

在当前 Cypress 环境中运行所有数据库种子器或单个类。

test('it seeds the db', () => {
  cy.seed('PlansTableSeeder');
});

假设在 .env.cypress 文件中将 APP_ENV 设置为 "acceptance",则上面的调用相当于

php artisan db:seed --class=PlansTableSeeder --env=acceptance

cy.artisan()

触发当前环境下的任何 Artisan 命令。请记住,像往常一样,在选项之前加两个短横线。

test('it can create posts through the command line', () => {
  cy.artisan('post:make', {
    '--title': 'My First Post',
  });

  cy.visit('/posts').contains('My First Post');
});

此调用相当于

php artisan post:make --title="My First Post"

cy.php()

虽然这与验收测试的精神不完全相符,但此命令将允许您触发和评估任意 PHP。

test('it can evaluate PHP', () => {
    cy.php(`
        App\\Plan::first();
    `).then(plan => {
        expect(plan.name).to.equal('Monthly'); 
    });
});

在您使用此命令时要谨慎,但它可能在您需要验证应用程序或数据库对某些动作的响应状态时非常有用。它也可以用于设置测试的“世界”。话虽如此,通常使用 cy.seed() 的有针对性的数据库种子器将是更好的方法。

路由

每次您的测试套件运行时,此包都将获取 Laravel 应用程序的所有命名路由,并将它们存储在内存中。您还会在 ./cypress/support/routes.json 文件中找到包含此 JSON 的转储。

此包重写了基础 cy.visit() 方法,允许您以可选的方式传递一个 route 名称而不是 URL。

test('it loads the about page using a named route', () => {
    cy.visit({
        route: 'about'
    });
});

如果命名路由需要通配符,您可以使用 parameters 属性包括它。

test('it loads the team dashboard page using a named route', () => {
    cy.visit({
        route: 'team.dashboard',
        parameters: { team: 1 }
    });
});

如果您需要访问应用程序的完整路由列表,请使用 Cypress.Laravel.routes 属性。

// Get an array of all routes for your app.

Cypress.Laravel.routes; // ['home' => []]

此外,如果您需要将命名路由转换为相关联的 URL,请使用 Cypress.Laravel.route() 方法,如下所示

Cypress.Laravel.route('about'); // /about-page

Cypress.Laravel.route('team.dashboard', { team: 1 }); // /teams/1/dashboard

安全

如果您发现任何与安全相关的问题,请通过电子邮件 jeffrey@laracasts.com 反馈,而不是使用问题跟踪器。

鸣谢

许可协议

MIT 许可协议(MIT)。更多信息请参阅 许可文件