跳到主要内容

测试数据查询

介绍

查询编辑器是数据源插件的核心部分,用户在此构建用于获取数据的查询。您的数据源插件可以提供功能丰富的查询编辑器,支持针对不同 API 的各种查询类型。您的查询编辑器甚至可以提供可视化查询构建器、智能提示和自动完成等功能。

测试查询编辑器是否加载

以下示例是一个简单的冒烟测试,用于验证数据源查询编辑器是否加载成功。

queryEditor.spec.ts
import { test, expect } from '@grafana/plugin-e2e';

test('should render query editor', async ({ panelEditPage, readProvisionedDataSource }) => {
const ds = await readProvisionedDataSource({ fileName: 'datasources.yml' });
await panelEditPage.datasource.set(ds.name);
await expect(panelEditPage.getQueryEditorRow('A').getByRole('textbox', { name: 'Query Text' })).toBeVisible();
});

独立测试查询编辑器部分

在以下示例中,查询编辑器通过向 /regions 发送请求加载区域,并在将其填充到下拉菜单之前过滤掉包含 gov 的区域。

通过 <page>.mockResourceResponse 方法,您可以模拟对数据源 resource API 请求的响应。为了测试过滤是否按预期工作,我们使用此方法模拟 /regions 响应,并断言当单击区域下拉列表时,仅显示名称中不包含 -gov- 的区域。

queryEditor.spec.ts
test('should filter out govcloud regions', async ({ panelEditPage, selectors, readProvisionedDataSource }) => {
const regionsMock = ['us-gov-west-1', 'us-east-1', 'us-west-1', 'us-gov-east-1'];
const expectedRegions = ['us-east-1', 'us-west-1'];
const ds = await readProvisionedDataSource({ fileName: 'datasources.yaml' });
await panelEditPage.datasource.set(ds.name);
await panelEditPage.mockResourceResponse('regions', regionsMock);
await panelEditPage.getQueryEditorRow('A').getByText('Regions').click();
await expect(panelEditPage.getByGrafanaSelector(selectors.components.Select.option)).toHaveText(expectedRegions);
});

测试整个数据流

以下示例展示了一个集成测试,它测试了插件的整个查询数据流。

警告

在端到端测试中调用第三方 API 可能会有用,但也存在安全隐患,并可能导致 CI 流水线不稳定。您应始终仔细考虑,并考虑使用模拟数据。

queryEditor.spec.ts
test('data query should be successful when the query is valid', async ({
panelEditPage,
readProvisionedDataSource,
}) => {
const ds = await readProvisionedDataSource({ fileName: 'datasources.yaml' });
await panelEditPage.datasource.set(ds.name);
await panelEditPage.getQueryEditorRow('A').getByText('Query Text').fill('SELECT * FROM dataset');
await expect(panelEditPage.refreshPanel()).toBeOK();
});

进行面板数据断言

在许多情况下,断言数据查询响应正常不足以说明您的数据源插件工作正常。您还必须对面板中显示的数据进行断言。

Grafana 包含一组内置面板,并且在 Grafana 插件目录 中提供了各种社区面板。每个面板渲染数据的方式可能不同,因此无法提供一种一致的方式来断言所有面板上显示的数据。因此,我们建议您使用 Table 面板来完成此操作。

<page>.panel.data 属性返回一个 Playwright 定位器,该定位器解析 `Table` 面板中当前显示一个或多个包含值的元素。这意味着您可以使用任何接受定位器作为接收类型的自动重试 匹配器

queryEditor.spec.ts
test('data query should return values 10 and 20', async ({ panelEditPage, readProvisionedDataSource }) => {
const ds = await readProvisionedDataSource({ fileName: 'datasources.yml' });
await panelEditPage.datasource.set(ds.name);
await panelEditPage.setVisualization('Table');
await expect(panelEditPage.refreshPanel()).toBeOK();
await expect(panelEditPage.panel.data).toContainText(['10', '20']);
});

如果您想断言 `Table` 面板中显示的列头,可以使用 <page>.panel.fieldNames 属性。

queryEditor.spec.ts
test('data query should return headers  and 3', async ({ panelEditPage, readProvisionedDataSource }) => {
const ds = await readProvisionedDataSource({ fileName: 'datasources.yml' });
await panelEditPage.datasource.set(ds.name);
await panelEditPage.setVisualization('Table');
await expect(panelEditPage.refreshPanel()).toBeOK();
await expect(panelEditPage.panel.fieldNames).toHaveText(['Stockholm', 'Vienna']);
});

在预置仪表盘中测试查询

有时,您可能希望打开现有面板的编辑页面并运行查询,以确保一切按预期工作。

test('query in provisioned dashboard should return temp and humidity data', async ({
readProvisionedDashboard,
gotoPanelEditPage,
}) => {
const dashboard = await readProvisionedDashboard({ fileName: 'dashboard.json' });
const panelEditPage = await gotoPanelEditPage({ dashboard, id: '3' });
await expect(panelEditPage.refreshPanel()).toBeOK();
await expect(panel.fieldNames).toContainText(['temperature', 'humidity']);
await expect(panel.data).toContainText(['25', '10']);
});

您也可以打开现有仪表盘,并验证表格面板是否已按预期渲染数据。

test('getting panel by id', async ({ gotoDashboardPage, readProvisionedDashboard }) => {
const dashboard = await readProvisionedDashboard({ fileName: 'dashboard.json' });
const dashboardPage = await gotoDashboardPage(dashboard);
const panel1 = await dashboardPage.getPanelById('3');
await expect(panel1.data).toContainText(['25', '32', 'staging']);
const panel2 = await dashboardPage.getPanelByTitle('Basic table example');
await expect(dashboardPage.panel2.fieldNames).toContainText(['Tokyo', 'Berlin']);
});