编写综合测试

编辑

设置项目后,您可以开始编写综合测试,检查最终用户可能在您的站点上执行的关键操作和请求。

语法概述
编辑

要为您的应用程序编写综合测试,您需要了解基本的 JavaScript 和 Playwright 语法。

Playwright 是 Microsoft 开发的浏览器测试库。它快速、可靠,并具有现代 API,可以自动等待页面元素准备就绪。

综合代理公开用于创建和运行测试的 API,包括

journey

测试一个离散的功能单元。接受两个参数:一个 name(字符串)和一个 callback(函数)。请参阅创建旅程了解更多信息。

step

旅程中应按特定顺序完成的操作。接受两个参数:一个 name(字符串)和一个 callback(函数)。请参阅添加步骤了解更多信息。

expect

检查值是否满足特定条件。支持多种检查。请参阅进行断言了解更多信息。

beforeAll

在任何 journey 运行之前,运行一次提供的函数。如果提供的函数是 Promise,则运行器将等待 Promise 解析后再调用 journey。接受一个参数:一个 callback(函数)。请参阅设置和删除全局状态了解更多信息。

before

在单个 journey 运行之前,运行提供的函数。接受一个参数:一个 callback(函数)。请参阅设置和删除全局状态了解更多信息。

afterAll

在所有 journey 运行完成后,运行一次提供的函数。接受一个参数:一个 callback(函数)。请参阅设置和删除全局状态了解更多信息。

after

在单个 journey 完成后,运行提供的函数。接受一个参数:一个 callback(函数)。请参阅设置和删除全局状态了解更多信息。

monitor

monitor.use 方法允许您在逐个旅程的基础上确定监视器的配置。例如,如果您希望两个旅程创建具有不同间隔的监视器,则应在每个旅程中调用 monitor.use,并在每个旅程中将 schedule 属性设置为不同的值。请注意,这仅在使用 push 命令在 Kibana 中创建监视器时才相关。请参阅配置单个监视器了解更多信息。

创建旅程
编辑

使用 .journey.ts.journey.js 文件扩展名创建一个新文件,或编辑一个示例旅程文件。

旅程测试一个离散的功能单元。例如,登录网站、将内容添加到购物车或加入邮件列表。

旅程函数接受两个参数:一个 name 和一个 callbackname 可帮助您识别单个旅程。callback 参数是一个封装旅程执行操作的函数。回调提供对新的 Playwright pageparamsbrowsercontext 实例的访问权限。

journey('Journey name', ({ page, browser, context, params, request }) => {
  // Add steps here
});
参数
编辑

name (字符串)

用于描述旅程的用户定义字符串。

callback (函数)

您将在其中添加步骤的函数。

实例:

page
Playwright 的 page 对象,使您可以控制浏览器的当前页面。
browser
Playwright 创建的 browser 对象。
context
一个 浏览器上下文,它不与其他浏览器上下文共享 Cookie 或缓存。
params
用户定义的变量,允许您使用自定义参数调用综合套件。例如,如果您想根据 env 使用不同的主页(devlocalhostprod 为 URL)。有关更多信息,请参阅使用参数和机密
request
一个请求对象,可用于独立于浏览器交互发出 API 请求。例如,为了支持基于浏览器的测试,获取身份验证凭据或令牌。有关更多信息,请参阅发出 API 请求
添加步骤
编辑

一个旅程由一个或多个步骤组成。步骤是应按特定顺序完成的操作。步骤在综合应用程序中单独显示,并带有屏幕截图,方便调试和错误跟踪。

一个基本的两步旅程如下所示

journey('Journey name', ({ page, browser, client, params, request }) => {
    step('Step 1 name', () => {
      // Do something here
    });
    step('Step 2 name', () => {
      // Do something else here
    });
});

步骤可以根据您的需要简单或复杂。例如,基本的第一步可能会加载网页

step('Load the demo page', () => {
  await page.goto('https://elastic.github.io/synthetics-demo/'); 
});

有关更多信息,请转到 page.goto 参考

参数
编辑

name (字符串)

用于描述旅程的用户定义字符串。

callback (函数)

您可以在其中使用综合和Playwright 语法模拟用户工作流程的函数。

如果您想通过直接与网页交互来生成代码,可以使用综合记录器

记录器启动一个 Chromium 浏览器,它将侦听您与网页的每次交互,并使用 Playwright 在内部记录它们。当您完成与浏览器的交互后,记录器会将记录的操作转换为 JavaScript 代码,您可以在 Elastic Synthetics 或 Heartbeat 中使用这些代码。

有关开始使用综合记录器的更多详细信息,请参阅使用综合记录器

Playwright 语法
编辑

在每个步骤的回调中,您可能会使用大量的 Playwright 语法。使用 Playwright 来模拟和验证用户工作流程,包括

请访问Playwright 文档以获取信息。

通过 Elastic 的全局托管测试基础设施或私有位置运行时,请勿尝试以 headful 模式运行(使用 headless:false),因为这不受支持。

但是,并非所有 Playwright 功能都应与 Elastic Synthetics 一起使用。在某些情况下,Elastic Synthetics 库中内置了 Playwright 功能的替代方案。这些替代方案旨在更好地用于综合监控。请勿使用 Playwright 语法来

  • 发出 API 请求。请改用 Elastic Synthetic 的 request 参数。请参阅发出 API 请求了解更多信息。

此外,Elastic Synthetics 中未开箱即用地支持某些 Playwright 功能,包括

通过 screenshotvideo 以编程方式进行的捕获不会被存储,也不会在 Synthetics 应用程序中显示。提供 path 很可能会导致监控器因缺少写入本地文件的权限而失败。

进行断言
编辑

更复杂的 step 可能会等待页面元素被选中,然后确保它与预期值匹配。

Elastic Synthetics 使用 @playwright/testexpect 函数进行断言,并支持大多数 Playwright 断言。Elastic Synthetics 支持 toHaveScreenshot 或任何 快照断言

例如,在以下 HTML 的页面上

<header class="header">
  <h1>todos</h1>
  <input class="new-todo"
    autofocus autocomplete="off"
    placeholder="What needs to be done?">
</header>

您可以使用以下测试来验证类为 new-todoinput 元素是否具有预期的 placeholder 值(input 元素的提示文本)

step('Assert placeholder text', async () => {
  const input = await page.locator('input.new-todo'); 
  expect(await input.getAttribute('placeholder')).toBe(
    'What needs to be done?'
  ); 
});

找到类为 new-todoinput 元素。

使用 Synthetics 代理提供的断言库来检查 placeholder 属性的值是否与特定字符串匹配。

发起 API 请求
编辑

您可以使用 request 参数来独立于浏览器交互发起 API 请求。例如,您可以从 HTTP 端点检索令牌,并在后续的网页请求中使用它。

step('make an API request', async () => {
  const response = await request.get(params.url);
  // Do something with the response
})

Elastic Synthetics 的 request 参数类似于 Playwright 公开的其他请求对象,但有一些关键差异

  • Elastic Synthetics 的 request 参数内置于库中,因此无需单独导入,这减少了所需的代码量,并允许您在 内联 Journey 中发起 API 请求。
  • 与 Playwright 的 context.requestpage.request 不同,Elastic Synthetics 公开的顶级 request 对象具有其自己独立的 Cookie 存储,后者与相应的 BrowserContext 共享 Cookie 存储。
  • 如果要控制 request 对象的创建,可以通过 --playwright-options 或在 synthetics.config.ts 文件中传递选项来实现。

有关显示如何使用 request 对象的完整示例,请参阅 Elastic Synthetics 演示存储库

request 参数并非旨在用于编写纯 API 测试。相反,它是一种在基于浏览器的测试中支持编写纯 HTTP 请求的方法。

设置和删除全局状态
编辑

如果在 Journey 之前或之后有任何操作应执行,您可以使用 beforebeforeAllafterafterAll

要设置全局状态或将用于单个 journey 的服务器(例如),请使用 before 钩子。要在所有 Journey 之前执行此设置一次,请使用 beforeAll 钩子。

before(({ params }) => {
  // Actions to take
});

beforeAll(({ params }) => {
  // Actions to take
});

您可以使用 after 钩子清理全局状态或关闭用于单个 journey 的服务器。要在所有 Journey 之后执行此清理一次,请使用 afterAll 钩子。

after(({ params }) => {
  // Actions to take
});

afterAll(({ params }) => {
  // Actions to take
});
导入 NPM 包
编辑

您可以在 Journey 代码中导入和使用其他 NPM 包。请参考以下使用外部 NPM 包 is-positive 的示例

import { journey, step, monitor, expect } from '@elastic/synthetics';
import isPositive from 'is-positive';

journey('bundle test', ({ page, params }) => {
  step('check if positive', () => {
    expect(isPositive(4)).toBe(true);
  });
});

当您从使用外部 NPM 包的 Journey 创建监控器时,这些包将在调用 push 命令时与 Journey 代码一起捆绑。

但是,使用外部包时存在一些限制

  • 压缩后的捆绑 Journey 不应超过 800 KB。
  • 由于平台不一致,原生 Node 模块将无法按预期工作。
示例合成测试
编辑

基本合成测试的完整示例可能如下所示

import { journey, step, expect } from '@elastic/synthetics';

journey('Ensure placeholder is correct', ({ page }) => {
  step('Load the demo page', async () => {
    await page.goto('https://elastic.github.io/synthetics-demo/');
  });
  step('Assert placeholder text', async () => {
    const placeholderValue = await page.getAttribute(
      'input.new-todo',
      'placeholder'
    );
    expect(placeholderValue).toBe('What needs to be done?');
  });
});

您可以在 Elastic Synthetics 演示存储库中找到更复杂的示例。

在本地测试
编辑

在您编写 Journey 时,您可以在本地运行它们以验证它们是否按预期工作。然后,您可以创建监控器以定期运行您的 Journey。

要测试项目中的所有 Journey,请导航到包含 Synthetics 项目的目录并在其中运行 Journey。默认情况下,@elastic/synthetics 运行器将仅运行文件名与 *.journey.(ts|js)* 匹配的文件。

# Run tests on the current directory. The dot `.` indicates
# that it should run all tests in the current directory.
npx @elastic/synthetics .
测试内联监控器
编辑

要在本地测试内联监控器的 Journey,请将内联 Journey 管道传输到 npx @elastic/synthetics 命令。

例如,假设您的内联监控器包含以下代码

step('load homepage', async () => {
    await page.goto('https://elastic.ac.cn');
});
step('hover over products menu', async () => {
    await page.hover('css=[data-nav-item=products]');
});

要在本地运行该 Journey,您可以将该代码保存到文件中,并将该文件的内容管道传输到 @elastic-synthetics

cat path/to/sample.js | npx @elastic/synthetics --inline

您将获得如下响应

Journey: inline
   ✓  Step: 'load homepage' succeeded (1831 ms)
   ✓  Step: 'hover over products menu' succeeded (97 ms)

 2 passed (2511 ms)