Flutter应用测试与反馈插件testfairy_flutter的使用

发布于 1周前 作者 itying888 来自 Flutter

Flutter应用测试与反馈插件testfairy_flutter的使用

TestFairy Flutter集成

这是Flutter的TestFairy集成,包含原生SDK。

安装

阅读安装文档:pub.dartlang.org

快速开始

在您的项目中引入库并运行主应用程序如下:

确保您的项目是AndroidX兼容的。最低支持的iOS目标版本为11.0。

pubspec.yaml文件配置

dependencies:
  testfairy_flutter: any

main.dart文件示例

// [@dart](/user/dart) = 2.18 
import 'dart:async';
import 'dart:io';
import 'package:testfairy_flutter/testfairy_flutter.dart';

void main() {
  HttpOverrides.global = TestFairy.httpOverrides();

  runZonedGuarded(
    () async {
      try {
        FlutterError.onError = (details) => TestFairy.logError(details.exception);

        // 调用 `await TestFairy.begin()` 或其他设置代码
        await TestFairy.begin('YOUR_APP_TOKEN');

        runApp(TestFairyGestureDetector(child: TestfairyExampleApp()));
      } catch (error) {
        TestFairy.logError(error);
      }
    },
    (e, s) {
      TestFairy.logError(e);
    },
    zoneSpecification: new ZoneSpecification(
      print: (self, parent, zone, message) {
        TestFairy.log(message);
      },
    )
  );
}

如何使用最新版的Flutter和Null-safe Dart编译?

为了使用最新的稳定版Flutter通道中的TestFairy,您必须将插件的最低版本设置为2.1.0。

对于最新的不稳定版Flutter通道,请克隆此仓库,并将其作为离线依赖项使用,而不是在pub上发布的版本。

  1. 克隆repo
  2. 使用以下代码将克隆作为离线依赖项(假设两个项目位于同一目录下作为兄弟目录):
dependencies:
  testfairy_flutter:
    path: ../testfairy-flutter # 或 "./testfairy-flutter" 如果你在主项目内克隆它作为一个子目录
  1. testfairy-flutter添加到你的VCS,但不包括其.git目录。
  2. 当此仓库有更新时,删除testfairy-flutter并重试上述步骤。

故障排除

  • 我看到warning: None of the architectures in ARCHS (x86_64) are valid错误。

启动Runner工作区,并在Build Settings中将VALID_ARCHS添加x86_64

  • 我看到Specs satisfying the TestFairy dependency were found, but they required a higher minimum deployment target.错误。

您需要更新本地SDK以及CocoaPods仓库。

运行pod repo update并在pubspec.yaml中更新插件。然后运行cd ios; pod update TestFairy; cd ..

更多详细信息请参见完整文档和示例代码。

示例Demo

以下是完整的示例Demo,演示如何使用TestFairy Flutter插件进行各种测试和功能调用。

// [@dart](/user/dart) = 2.18
import 'dart:async';
import 'dart:core';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:testfairy_flutter/testfairy_flutter.dart';

const String APP_TOKEN = 'SDK-gLeZiE9i';

void main() {
  HttpOverrides.global = TestFairy.httpOverrides();

  runZonedGuarded(() async {
    try {
      FlutterError.onError = (FlutterErrorDetails? details) =>
          TestFairy.logError(details?.exception ?? 'Unknown error');
      await TestFairy.begin(APP_TOKEN);
      runApp(TestFairyGestureDetector(child: TestfairyExampleApp()));
    } catch (error) {
      TestFairy.logError(error);
    }
  }, (Object e, StackTrace s) {
    TestFairy.logError(e);
  }, zoneSpecification: ZoneSpecification(
    print: (Zone self, ZoneDelegate parent, Zone zone, String message) {
      TestFairy.log(message);
    },
  ));
}

class TestfairyExampleApp extends StatefulWidget {
  [@override](/user/override)
  _TestfairyExampleAppState createState() => _TestfairyExampleAppState();
}

class _TestfairyExampleAppState extends State<TestfairyExampleApp> {
  String errorMessage = 'No error yet.';
  String testName = '';
  bool testing = false;

  GlobalKey hiddenWidgetKey = GlobalKey();

  [@override](/user/override)
  void initState() {
    super.initState();
    TestFairy.hideWidget(hiddenWidgetKey);
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      showPerformanceOverlay: true,
      home: Scaffold(
        appBar: AppBar(title: const Text('Testfairy Plugin Example App')),
        body: Center(
          child: SingleChildScrollView(
            child: Column(
              children: [
                ElevatedButton(
                  onPressed: onCoolButton,
                  child: const Text('Cool Button'),
                ),
                ElevatedButton(
                  onPressed: onLifecycleTests,
                  child: const Text('Lifecycle Tests'),
                ),
                ElevatedButton(
                  onPressed: onServerEndpointTest,
                  child: const Text('Server Endpoint Test'),
                ),
                ElevatedButton(
                  onPressed: onFeedbackTests,
                  child: const Text('Feedback Tests'),
                ),
                Text('HIDE ME FROM SCREENSHOTS', key: hiddenWidgetKey),
              ],
            ),
          ),
        ),
      ),
    );
  }

  void beginTest(String name) {
    setState(() {
      testing = true;
      testName = name;
    });
  }

  void endTest() {
    setState(() {
      testing = false;
      testName = '';
    });
  }

  void setError(dynamic error) {
    setState(() {
      errorMessage = error != null ? error.toString() : 'Unknown error';
    });
  }

  void onCoolButton() async {
    if (testing) return;
    beginTest('Cool Button');
    try {
      await TestFairy.begin(APP_TOKEN);
      await Future<void>.delayed(const Duration(seconds: 20));
      await TestFairy.stop();
    } catch (e) {
      setError(e);
    }
    endTest();
  }

  void onLifecycleTests() async {
    if (testing) return;
    beginTest('Lifecycle');
    try {
      await TestFairy.begin(APP_TOKEN);
      await Future<void>.delayed(const Duration(seconds: 2));
      await TestFairy.pause();
      await Future<void>.delayed(const Duration(seconds: 2));
      await TestFairy.resume();
      await Future<void>.delayed(const Duration(seconds: 2));
      await TestFairy.stop();
    } catch (e) {
      setError(e);
    }
    endTest();
  }

  void onServerEndpointTest() async {
    if (testing) return;
    beginTest('Server Endpoint');
    try {
      await TestFairy.setServerEndpoint('http://example.com');
      await TestFairy.begin(APP_TOKEN);
      await Future<void>.delayed(const Duration(seconds: 1));
      await TestFairy.stop();
    } catch (e) {
      setError(e);
    }
    endTest();
  }

  void onFeedbackTests() async {
    if (testing) return;
    beginTest('Feedbacks');
    try {
      await TestFairy.begin(APP_TOKEN);
      await Future<void>.delayed(const Duration(seconds: 2));
      await TestFairy.sendUserFeedback('Dummy feedback from Flutter');
      await TestFairy.showFeedbackForm();
    } catch (e) {
      setError(e);
    }
    endTest();
  }
}

更多关于Flutter应用测试与反馈插件testfairy_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter应用测试与反馈插件testfairy_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,关于在Flutter应用中使用testfairy_flutter插件进行测试与收集反馈,以下是一个简要的代码示例和集成指南。testfairy_flutter插件允许你将Flutter应用集成到TestFairy平台,以便进行实时测试、崩溃报告和用户反馈收集。

前提条件

  1. 确保你已经安装了Flutter和Dart SDK。
  2. 在TestFairy网站上创建一个应用并获得API Key。

步骤 1: 添加依赖

首先,在你的pubspec.yaml文件中添加testfairy_flutter依赖:

dependencies:
  flutter:
    sdk: flutter
  testfairy_flutter: ^x.y.z  # 替换为最新版本号

然后运行flutter pub get来安装依赖。

步骤 2: 初始化TestFairy

在你的Flutter应用的主入口文件(通常是main.dart)中,初始化TestFairy。

import 'package:flutter/material.dart';
import 'package:testfairy_flutter/testfairy_flutter.dart';

void main() {
  // 替换为你的TestFairy API Key
  String apiKey = "your_testfairy_api_key_here";

  // 初始化TestFairy
  TestFairy.begin(apiKey: apiKey);

  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '0',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {},
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

步骤 3: 配置TestFairy(可选)

你可以根据需求配置更多TestFairy的选项,比如设置检查点、用户信息、日志等。

// 在应用中的适当位置,比如按钮点击事件
void _handleButtonClick() {
  // 设置检查点
  TestFairy.checkpoint("user_reached_main_screen");

  // 添加自定义用户信息
  TestFairy.setMetadata({
    "user_id": "12345",
    "user_email": "user@example.com",
  });

  // 记录日志
  TestFairy.log("User clicked the button");
}

步骤 4: 运行应用

完成上述步骤后,你可以运行你的Flutter应用。在TestFairy仪表板上,你应该能够看到实时会话、崩溃报告和用户反馈。

flutter run

注意

  • 确保你的API Key是正确的,并且应用已经在TestFairy上创建。
  • 根据你的具体需求调整TestFairy的配置和使用。
  • TestFairy提供了丰富的文档和API,建议查阅官方文档以获取更多信息和高级功能。

这样,你就成功地在Flutter应用中集成了testfairy_flutter插件,可以开始进行测试和收集反馈了。

回到顶部