Flutter插件的golden_delicious的使用_Tolerance比较器用于Flutter测试

发布于 1周前 作者 eggper 最后一次编辑是 5天前 来自 Flutter

Flutter插件的golden_delicious的使用_Tolerance比较器用于Flutter测试

golden_delicious

构建状态 许可证

Tolerance比较器用于Flutter黄金测试。

Flutter插件的golden_delicious的安装

pubspec.yaml文件中添加以下依赖:

dependencies:
  golden_delicious: ^1.0.0

然后运行flutter pub get来安装该插件。

Flutter插件的golden_delicious的设置

1. 单个测试文件设置

要使用它,可以在测试文件中覆盖goldenFileComparator属性:

import 'package:flutter_test/flutter_test.dart';
import 'package:golden_delicious/golden_delicious.dart';

void main() {
  // 设置golden_file_comparator为golden_delicious_comparator
  goldenFileComparator = goldenDeliciousComparator;

  testWidgets('MyWidget', (tester) async {
    await tester.pumpWidget(MyWidget());
    await expectLater(find.byType(MyWidget), matchesGoldenFile('my_widget.png'));
  });
}
2. 使用flutter_test_config

你也可以通过flutter_test_config.dart文件配置容忍百分比。此文件由flutter_test包自动加载。

// flutter_test_config.dart
import 'dart:async';

import 'package:flutter_test/flutter_test.dart';
import 'package:golden_delicious/golden_delicious.dart';

Future<void> testExecutable(FutureOr<void> Function() testMain) async {
  setUpAll(() {
    goldenFileComparator = goldenDeliciousComparator;
  });

  await testMain();
}
3. 使用Golden Toolkit

Golden Toolkit是一个提供一组工具的包,使处理黄金文件变得更加容易。它还提供了GoldenToolkitConfiguration类,可以用来配置容忍百分比。

// flutter_test_config.dart
import 'dart:async';

import 'package:flutter_test/flutter_test.dart';
import 'package:golden_toolkit/golden_toolkit.dart';
import 'package:golden_delicious/golden_delicious.dart';

Future<void> testExecutable(FutureOr<void> Function() testMain) async {
  return GoldenToolkit.runWithConfiguration(
    () async {
      goldenFileComparator = goldenDeliciousComparator;
      await loadAppFonts();
      await testMain();
    },
    config: GoldenToolkitConfiguration(
      defaultDevices: const [
        Device.phone,
        Device.iphone11,
        Device.tabletPortrait,
        Device.tabletLandscape,
      ],
      enableRealShadows: true,
    ),
  );
}

// test/golden_toolkit_test.dart
import 'package:golden_toolkit/golden_toolkit.dart';

void main() {
  testGoldens('tolerance comparator example', (tester) async {
    const widget = MyHomePage(
      title: 'hello golden toolkit',
    );
    final builder = DeviceBuilder()
      ..addScenario(name: 'default page', widget: widget);

    await tester.pumpDeviceBuilder(builder);
    await screenMatchesGolden(tester, 'main');
  });
}

使用方法

在测试命令行中添加--dart-define=golden_tolerance=0.1来指定容忍度。默认值为0.0

# 0.1%容忍度
flutter test --dart-define=golden_tolerance=0.1

# 5%容忍度
flutter test --dart-define=golden_tolerance=5

Visual Studio Code提示

你可以在Visual Studio Code中定义自定义运行配置,以使用特定的容忍度百分比来运行测试。

// .vscode/launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Tolerance",
      "request": "launch",
      "type": "dart",
      "codeLens": {
        "for": ["run-test", "run-test-file"]
      },
      "args": [
        "--dart-define=golden_tolerance=0.1"
      ]
    }
  ]
}

示例代码

以下是完整的示例代码:

import 'package:flutter/material.dart';

///
/// 这是默认的Flutter计数器应用
///
/// 对于具体的golden_delicious使用,请参阅:
///   - [example/test/golden_test.dart]
///   - [example/test/golden_toolkit_test.dart]
///   - [example/test/flutter_test_config.dart]
///

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              '你已经按下了按钮多少次:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: '增加',
        child: const Icon(Icons.add),
      ),
    );
  }
}

更多关于Flutter插件的golden_delicious的使用_Tolerance比较器用于Flutter测试的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter插件的golden_delicious的使用_Tolerance比较器用于Flutter测试的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在探索Flutter中假想的golden_delicious插件时,我们可以基于插件名称进行创意性假设,并编写一些示例代码来展示其可能的用法。假设golden_delicious插件是一个用于数据可视化和界面美化的库,提供了丰富的图表和美化UI的组件。

以下是一个示例Flutter项目,展示了如何使用golden_delicious插件(假设它已正确集成到项目中)来创建一个包含图表和美化UI的页面。

import 'package:flutter/material.dart';
import 'package:golden_delicious/golden_delicious.dart'; // 假设的插件导入

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Golden Delicious Demo',
      theme: ThemeData(
        primarySwatch: Colors.amber,
      ),
      home: GoldenDeliciousDemoPage(),
    );
  }
}

class GoldenDeliciousDemoPage extends StatefulWidget {
  @override
  _GoldenDeliciousDemoPageState createState() => _GoldenDeliciousDemoPageState();
}

class _GoldenDeliciousDemoPageState extends State<GoldenDeliciousDemoPage> {
  // 假设的数据
  final List<Map<String, dynamic>> data = [
    {'label': 'A', 'value': 30},
    {'label': 'B', 'value': 45},
    {'label': 'C', 'value': 20},
    {'label': 'D', 'value': 15},
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Golden Delicious Plugin Demo'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              'Golden Delicious Pie Chart',
              style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
            ),
            SizedBox(height: 16),
            // 假设的GoldenDeliciousPieChart组件
            GoldenDeliciousPieChart(
              data: data,
              labelStyle: TextStyle(fontSize: 14, color: Colors.white),
              chartColor: Colors.amber,
            ),
            SizedBox(height: 32),
            Text(
              'Golden Delicious Bar Chart',
              style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
            ),
            SizedBox(height: 16),
            // 假设的GoldenDeliciousBarChart组件
            GoldenDeliciousBarChart(
              data: data,
              labelStyle: TextStyle(fontSize: 14, color: Colors.black),
              barColor: Colors.deepOrange,
            ),
            SizedBox(height: 32),
            Text(
              'Golden Delicious Custom Button',
              style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
            ),
            SizedBox(height: 16),
            // 假设的GoldenDeliciousButton组件
            GoldenDeliciousButton(
              onPressed: () {
                ScaffoldMessenger.of(context).showSnackBar(
                  SnackBar(content: Text('Button Pressed!')),
                );
              },
              buttonText: 'Click Me',
              buttonColor: Colors.amberAccent,
              textColor: Colors.black,
            ),
          ],
        ),
      ),
    );
  }
}

// 假设的GoldenDeliciousPieChart组件(实际插件中应已提供)
class GoldenDeliciousPieChart extends StatelessWidget {
  final List<Map<String, dynamic>> data;
  final TextStyle labelStyle;
  final Color chartColor;

  GoldenDeliciousPieChart({
    required this.data,
    required this.labelStyle,
    required this.chartColor,
  });

  @override
  Widget build(BuildContext context) {
    // 这里应调用插件提供的绘图API,以下仅为示意
    return CustomPaint(
      size: Size(300, 300),
      painter: GoldenDeliciousPiePainter(data, labelStyle, chartColor),
    );
  }
}

// 假设的GoldenDeliciousPiePainter类(实际插件中应已提供)
class GoldenDeliciousPiePainter extends CustomPainter {
  final List<Map<String, dynamic>> data;
  final TextStyle labelStyle;
  final Color chartColor;

  GoldenDeliciousPiePainter(this.data, this.labelStyle, this.chartColor);

  @override
  void paint(Canvas canvas, Size size) {
    // 绘制饼图的逻辑(实际插件中应已提供)
    final Paint paint = Paint()
      ..color = chartColor
      ..style = PaintingStyle.fill;

    double startAngle = 0.0;
    double sweepAngle;
    for (final item in data) {
      final value = item['value'] as double;
      sweepAngle = (value / data.sumBy((e) => e['value'] as double)) * 2.0 * 3.141592653589793;
      canvas.drawArc(Rect.fromCircle(center: Offset(size.width / 2, size.height / 2), radius: size.width / 2), startAngle, sweepAngle, true, paint);
      startAngle += sweepAngle;
    }

    // 绘制标签(仅为示意)
    for (int i = 0; i < data.length; i++) {
      final radians = (i / data.length) * 2.0 * 3.141592653589793 + 3.141592653589793 / 4; // 将角度转换为弧度并调整位置
      final x = size.width / 2 + (size.width / 2 - 20) * cos(radians); // 计算标签的x位置
      final y = size.height / 2 + (size.width / 2 - 20) * sin(radians); // 计算标签的y位置
      canvas.drawText(
        TextPainter(
          text: TextSpan(
            text: data[i]['label'] as String,
            style: labelStyle,
          ),
          textDirection: TextDirection.ltr,
        ),
        Offset(x, y),
      );
    }
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return false;
  }
}

// 假设的GoldenDeliciousBarChart组件(实际插件中应已提供)
class GoldenDeliciousBarChart extends StatelessWidget {
  final List<Map<String, dynamic>> data;
  final TextStyle labelStyle;
  final Color barColor;

  GoldenDeliciousBarChart({
    required this.data,
    required this.labelStyle,
    required this.barColor,
  });

  @override
  Widget build(BuildContext context) {
    // 这里应调用插件提供的绘图API,以下仅为示意
    return Column(
      children: List.generate(data.length, (index) {
        final value = data[index]['value'] as double;
        return Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            Text(
              data[index]['label'] as String,
              style: labelStyle,
            ),
            Container(
              width: 50,
              height: value * 10, // 假设高度与值成正比
              color: barColor,
            ),
          ],
        );
      }),
    );
  }
}

// 假设的GoldenDeliciousButton组件(实际插件中应已提供)
class GoldenDeliciousButton extends StatelessWidget {
  final VoidCallback onPressed;
  final String buttonText;
  final Color buttonColor;
  final Color textColor;

  GoldenDeliciousButton({
    required this.onPressed,
    required this.buttonText,
    required this.buttonColor,
    required this.textColor,
  });

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: onPressed,
      style: ButtonStyle(
        backgroundColor: MaterialStateProperty.all(buttonColor),
        foregroundColor: MaterialStateProperty.all(textColor),
      ),
      child: Text(buttonText),
    );
  }
}

请注意,上述代码中的GoldenDeliciousPieChart、`GoldenDelicious

回到顶部