Flutter

flutter pub add dev:tracera_flutter

需要 Dart ≥ 3.8 和 Flutter ≥ 3.24(见 自动化测试适配器)。tracera_flutter 在 pub.dev 上的页面。

环境变量与运行模式:自动化测试适配器。

在 main 函数开头或 flutter_test_config.dart 中调用一次 installTracera()。保留标准的 flutter_test 和 integration_test 导入;只需添加 installTracera、截图函数和 tracera 调用:

import 'package:flutter_test/flutter_test.dart';
import 'package:tracera/tracera.dart' as tracera;
import 'package:tracera_flutter/tracera_flutter.dart';

void main() {
  installTracera();

  testWidgets('user can sign in', (tester) async {
    await tracera.step('pump login', () async {
      await tester.pumpWidget(/* ... */);
    });
  }, tags: ['tracera-id-42']);
}

绑定 testCaseId 与 autotestName

为 testWidgets、test 或 group 添加标签 tracera-id-‹id›。添加 tracera-name-‹name› 可设置 autotestName。名称标签不能包含空格;若名称需要空格,请在测试内部用 tracera.testCase 绑定。若未指定名称标签,则 autotestName 取 Flutter 的测试名称。

testWidgets('user can sign in', (tester) async {
  // ...
}, tags: ['tracera-id-42', 'tracera-name-e2e_sign_in']);

testWidgets('user can sign out', (tester) async {
  tracera.testCase(43, 'e2e/sign out');
});

若要消除对未定义标签的警告,请把 Tracera 标签列在 dart_test.yaml 的 tags: 下。

Skip

在测试内部调用 markTestSkipped('reason')。结果会作为 Skipped 上报,原因会作为 comment 写入结果。

testWidgets('checkout', (tester) async {
  markTestSkipped('needs a seeded account');
}, tags: ['tracera-id-42']);

testWidgets 或 group 上的 skip: 不会写入报告。

步骤

使用 tracera.step('…', () { … })。setUp 回调进入结果的 准备,测试体进入 测试,tearDown 回调进入 清理。setUpAll / tearDownAll 内的步骤不会写入报告。

setUp(() {
  tracera.step('open shop', () {});
});

testWidgets('checkout', (tester) async {
  tracera.testCase(10);

  await tracera.step('add item', () async {
    await tester.pumpWidget(/* ... */);
    tracera.step('nested leaf', () {});
  });
});

tearDown(() {
  tracera.step('close shop', () {});
});

注释、错误与附件

限制与允许的 MIME 类型:自动化测试适配器。

tracera.comment、tracera.error 和附件会添加到当前打开的步骤;若没有打开的步骤,则添加到结果。tracera.attachmentFile 接收文件路径;tracera.attachmentBytes 接收名称和字节,并可选传入 mimeType。附件在结果上报时上传。

tracera.comment('result-level note');
tracera.error('result-level error');
tracera.attachmentFile('test/fixtures/screenshot.png');
tracera.step('open login', () {
  tracera.comment('step note');
  tracera.attachmentBytes(
    'body.json',
    utf8.encode('{"ok":true}'),
    mimeType: 'application/json',
  );
});

截图

截图以 PNG 附件添加,来自截屏或你传入的字节。

  • attachScreenshot(tester) 在 widget 测试中截取第一个 RepaintBoundary。
  • attachScreenshotBytes(bytes) 附加你已有的 PNG 字节。
  • attachIntegrationScreenshot(name: 'checkout') 在 integration_test 中截取设备屏幕。
testWidgets('checkout', (tester) async {
  await tester.pumpWidget(const RepaintBoundary(child: CheckoutPage()));
  await attachScreenshot(tester, fileName: 'checkout.png');
});

参数化测试

在循环中为每一行创建一个 testWidgets。若未指定名称,则 autotestName 取测试名称,因此请为每一行设置不同的标题。若要为每一行指定名称,请把名称传给 tracera.testCase:

for (final login in ['alice', 'bob']) {
  testWidgets('sign in as $login', (tester) async {
    tracera.testCase(7, 'login as $login');
  });
}

测试被重试时,只上报最后一次尝试。结果的 Env 标签页随后会包含 FLUTTER_RETRY(见 自动化测试适配器)。