一、插件介绍

automated_testing_demo 是一款专为开源鸿蒙(OpenHarmony)平台适配的 Flutter 自动化测试框架,提供了完整的集成测试解决方案。该框架基于 Flutter 官方 integration_test 扩展,针对鸿蒙平台的特性进行了深度优化,支持文件系统操作、数据库操作和键盘输入等关键功能的自动化测试。

在这里插入图片描述

核心功能特性:

  1. 多维度测试支持

    • 文件系统测试(基于 path_provider_ohos
    • 数据库操作测试(基于 sqflite
    • 键盘输入测试
  2. 鸿蒙平台适配

    • 支持鸿蒙 Stage 模型项目结构
    • 与鸿蒙资源系统无缝集成
    • 提供鸿蒙专属的文件系统访问能力
  3. 易用性设计

    • 遵循 Flutter 测试框架的标准 API
    • 提供清晰的测试结果输出
    • 支持批量测试和单例测试

二、使用步骤

1. 包的引入

由于该框架是针对鸿蒙平台的自定义修改版本,需要通过 Git 方式引入。在项目的 pubspec.yaml 文件中添加以下依赖配置:

dependencies:
  path: any
  collection: any
  flutter:
    sdk: flutter
  path_provider_android: ^2.1.0
  path_provider_foundation: ^2.3.0
  path_provider_linux: ^2.2.0
  path_provider_platform_interface: ^2.1.0
  path_provider_ohos:
    git:
      url: "https://gitcode.com/openharmony-tpc/flutter_packages.git"
      path: "packages/path_provider/path_provider_ohos"
  sqflite:
  sqflite_common:
  synchronized:
  matcher:
  meta:
  vm_service_lib:
  sqflite_helper:
    git:
      url: https://gitee.com/simplelove520/sqflite_helper.git
      path:
  cupertino_icons: ^1.0.2

dev_dependencies:
  integration_test:
    sdk: flutter
  flutter_test:
    sdk: flutter
  flutter_lints: ^2.0.0
  test:

2. 项目配置

鸿蒙项目结构配置

确保你的鸿蒙项目遵循标准的 Stage 模型结构,并且已经正确配置了 Flutter 集成环境。重点检查以下文件:

  • ohos/entry/src/main/ets/plugins/GeneratedPluginRegistrant.ets:确保已正确注册所有插件
  • ohos/entry/src/main/module.json5:配置正确的模块信息
测试目录结构

在项目根目录下创建 integration_test 目录,用于存放自动化测试用例:

project_root/
├── integration_test/
│   ├── path_provider_test.dart   # 文件系统测试
│   ├── sqflite_test.dart         # 数据库测试
│   └── key_input_test.dart       # 键盘输入测试
└── pubspec.yaml

3. API 调用和测试示例

文件系统测试示例

创建 integration_test/path_provider_test.dart 文件,用于测试文件系统操作:

import 'dart:io';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:path_provider_platform_interface/path_provider_platform_interface.dart';

void main() {
  IntegrationTestWidgetsFlutterBinding.ensureInitialized();

  testWidgets('获取临时目录', (WidgetTester tester) async {
    final PathProviderPlatform provider = PathProviderPlatform.instance;
    final String? result = await provider.getTemporaryPath();
    expect(result, isNotNull);
    print('临时目录:$result');

    // 创建测试文件验证目录可访问性
    final Directory directory = Directory(result!);
    final File testFile = File('${directory.path}${Platform.pathSeparator}test_temp.txt');
    await testFile.writeAsString('临时文件测试内容');
    expect(await testFile.exists(), isTrue);
    await testFile.delete();
  });

  testWidgets('获取应用文档目录', (WidgetTester tester) async {
    final PathProviderPlatform provider = PathProviderPlatform.instance;
    final String? result = await provider.getApplicationDocumentsPath();
    expect(result, isNotNull);
    print('应用文档目录:$result');
  });

  testWidgets('获取外部存储目录', (WidgetTester tester) async {
    final PathProviderPlatform provider = PathProviderPlatform.instance;
    final String? result = await provider.getExternalStoragePath();
    expect(result, isNotNull);
    print('外部存储目录:$result');
  });
}
数据库测试示例

创建 integration_test/sqflite_test.dart 文件,用于测试数据库操作:

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart' hide test;
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'package:test/test.dart' show test;
import 'dart:math';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  Database? _database;
  final String _tableName = "users";

  // 打开数据库测试
  test('打开数据库', () async {
    var _dbName = "test_${Random().nextInt(36000)}.db";
    try {
      _database = await openDatabase(_dbName);
      final path = await getDatabasesPath();
      print("数据库打开成功,路径:$path");
      expect(_database, isNotNull);
    } catch (error) {
      print('数据库打开失败:' + error.toString());
      fail('数据库打开测试失败');
    }
  });

  // 创建表测试
  test('创建表', () async {
    if (_database != null) {
      try {
        await _database!.execute(
            "CREATE TABLE $_tableName(id INTEGER PRIMARY KEY, name TEXT, age INTEGER)");
        print('表创建成功');
      } catch (error) {
        print('表创建失败:' + error.toString());
        fail('表创建测试失败');
      }
    }
  });

  // 插入数据测试
  test('插入数据', () async {
    if (_database != null) {
      try {
        final id = await _database!.insert(_tableName, {'name': '张三', 'age': 25});
        print("数据插入成功,ID:$id");
        expect(id, greaterThan(0));
      } catch (error) {
        print("数据插入失败:" + error.toString());
        fail('数据插入测试失败');
      }
    }
  });

  // 查询数据测试
  test('查询数据', () async {
    if (_database != null) {
      final maps = await _database!.query(_tableName);
      print('数据查询成功:');
      maps.forEach((map) {
        print(map.toString());
      });
      expect(maps.length, greaterThan(0));
    }
  });

  // 更新数据测试
  test('更新数据', () async {
    if (_database != null) {
      try {
        final changeRows = await _database!.update(
            _tableName, {'name': '李四', 'age': 30},
            where: 'id = ?', whereArgs: [1]);
        print("数据更新成功,影响行数:$changeRows");
        expect(changeRows, greaterThan(0));
      } catch (error) {
        print("数据更新失败:" + error.toString());
        fail('数据更新测试失败');
      }
    }
  });

  // 删除数据测试
  test('删除数据', () async {
    if (_database != null) {
      try {
        int count = await _database!
            .rawDelete("DELETE FROM $_tableName WHERE id = ?", [1]);
        print("数据删除成功,影响行数:$count");
        expect(count, greaterThan(0));

        // 关闭数据库
        await _database!.close();
      } catch (e) {
        print("数据删除失败:" + e.toString());
        fail('数据删除测试失败');
      }
    }
  });
}
键盘输入测试示例

创建 integration_test/key_input_test.dart 文件,用于测试键盘输入功能:

import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:flutter/material.dart';

void main() {
  IntegrationTestWidgetsFlutterBinding.ensureInitialized();

  testWidgets('键盘输入测试', (WidgetTester tester) async {
    // 构建一个包含文本输入框的测试界面
    await tester.pumpWidget(MaterialApp(
      home: Scaffold(
        body: Center(
          child: TextField(
            autofocus: true,
            decoration: const InputDecoration(
              labelText: '请输入文本',
            ),
          ),
        ),
      ),
    ));

    // 等待界面渲染完成
    await tester.pumpAndSettle();

    // 模拟键盘输入
    await tester.enterText(find.byType(TextField), 'Hello OpenHarmony!');
    await tester.pumpAndSettle();

    // 验证输入内容
    expect(find.text('Hello OpenHarmony!'), findsOneWidget);
    print('键盘输入测试成功');
  });

  testWidgets('特殊字符输入测试', (WidgetTester tester) async {
    await tester.pumpWidget(MaterialApp(
      home: Scaffold(
        body: Center(
          child: TextField(
            autofocus: true,
            decoration: const InputDecoration(
              labelText: '请输入特殊字符',
            ),
          ),
        ),
      ),
    ));

    await tester.pumpAndSettle();

    // 输入特殊字符
    await tester.enterText(find.byType(TextField), '!@#$%^&*()_+-=[]{}|;:,.<>?');
    await tester.pumpAndSettle();

    expect(find.text('!@#$%^&*()_+-=[]{}|;:,.<>?'), findsOneWidget);
    print('特殊字符输入测试成功');
  });
}

4. 运行测试

在鸿蒙设备或模拟器上运行测试:

# 运行所有集成测试
flutter test integration_test/

# 运行指定测试文件
flutter test integration_test/path_provider_test.dart
flutter test integration_test/sqflite_test.dart
flutter test integration_test/key_input_test.dart

三、总结

automated_testing_demo 为 Flutter 开发者提供了一套完整的鸿蒙平台自动化测试解决方案,具有以下核心优势:

  1. 平台兼容性:专门针对鸿蒙平台优化,解决了 Flutter 测试框架在鸿蒙平台上的兼容性问题

  2. 全面的测试覆盖:支持文件系统、数据库和用户输入等关键功能的测试,满足大部分应用的测试需求

  3. 易用性:遵循 Flutter 测试框架的标准 API,开发者无需学习新的测试语法

  4. 可靠性:基于成熟的 integration_testsqflite 等库,测试结果准确可靠

该框架的应用价值在于帮助开发者在鸿蒙平台上快速构建和执行自动化测试,提高应用质量,减少手动测试成本,加速应用的开发和发布周期。

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐