Flutter功能生成测试插件generator_test的使用

Flutter功能生成测试插件generator_test的使用

介绍

generator_test 是一个用于帮助测试生成器和 build_runner 包的库,它允许使用 Dart 文件而不是字符串来编写测试。这使得测试生成器和 build_runner 包变得更加简单和直观。

目的

测试生成器和 build_runner 包可能比较困难,generator_test 的目的是让这个过程变得更简单。

使用方法

1. 添加依赖

首先,在你的 pubspec.yaml 文件中添加 generator_test 作为开发依赖:

dev_dependencies:
  generator_test: ^最新版本
2. 创建fixture文件

fixture 是一个已知的状态,测试将基于此状态运行。你可以创建一个“输出”文件来与生成的代码进行比较,基于特定的输入。

例如,假设你有一个输入文件 input.dart

@ClassName()
class Example {}

对应的 fixture 文件 input.g.dart 可能如下所示:

// **************************************************************************
// ClassNameGenerator
// **************************************************************************

// The class name is `Example`

generator_test 会自动处理 part 文件的包含与否,并根据被测试的生成器选择合适的扩展名。你可以在 fixture 文件的顶部使用 * 包裹生成器名称,或者让 generator_test 自动处理:

// @generator=ClassNameGenerator
3. 创建测试
测试生成器

以下是一个测试生成器的示例:

import 'package:generator_test/generator_test.dart';
import './fake_generator.dart';

void main() async {
  final generator = SuccessGenerator(
    ['input.dart'],          // 输入文件路径
    ['input.g.dart'],        // 生成的文件路径
    fakeGenerator,           // 生成器实例
    compareWithFixture: true, // 是否与 fixture 文件比较
  );

  await generator.test();    // 运行测试
}
测试构建器

如果你使用的是 build_runner,可以这样测试:

import 'package:generator_test/generator_test.dart';
import './fake_builder.dart';

void main() async {
  final generator = SuccessGenerator.fromBuilder(
    ['input.dart'],          // 输入文件路径
    ['input.g.dart'],        // 生成的文件路径
    classNameBuilder,        // 构建器入口点
    compareWithFixture: true, // 是否与 fixture 文件比较
    options: {'add_comment': true}, // 构建器配置
  );

  await generator.test();    // 运行测试
}
4. 调试技巧

调试 build_runner 可能比较复杂,尤其是当你需要从大量的数据中筛选出你需要的值时。generator_test 提供了一个简单的调试方式:你可以在测试中添加 async/await 并在调试模式下运行测试。

例如:

void main() {
  test('generates successfully', () async {
    final generator = SuccessGenerator.fromBuilder(
      ['input.dart'],
      classNameBuilder,
      compareWithFixture: false, // 仅验证输入
    );

    // 在这里设置断点并调试
    await generator.test();
  });
}

通过这种方式,你可以更轻松地找到你需要的值,并确保生成器按预期工作。

完整示例 Demo

下面是一个完整的示例项目,展示了如何使用 generator_test 来测试一个简单的生成器。

项目结构:

.
├── lib
│   └── fake_generator.dart
├── test
│   ├── input.dart
│   ├── input.g.dart
│   └── generator_test.dart
└── pubspec.yaml

lib/fake_generator.dart (简单的生成器实现)

import 'package:build/src/builder/build_step.dart';
import 'package:source_gen/source_gen.dart';

class ClassNameGenerator extends Generator {
  @override
  FutureOr<String> generate(LibraryReader library, BuildStep buildStep) {
    final classes = library.classes.where((c) => c.hasAnnotation(const TypeChecker.fromRuntime(ClassName)));
    return classes.map((c) => '// The class name is ${c.name}').join('\n');
  }
}

class ClassName {
  const ClassName();
}

test/input.dart (输入文件)

@ClassName()
class Example {}

test/input.g.dart (预期生成的文件)

// **************************************************************************
// ClassNameGenerator
// **************************************************************************

// The class name is Example

test/generator_test.dart (测试文件)

import 'package:generator_test/generator_test.dart';
import '../lib/fake_generator.dart';

void main() async {
  final generator = SuccessGenerator(
    ['input.dart'],          // 输入文件路径
    ['input.g.dart'],        // 生成的文件路径
    ClassNameGenerator(),    // 生成器实例
    compareWithFixture: true, // 是否与 fixture 文件比较
  );

  await generator.test();    // 运行测试
}

更多关于Flutter功能生成测试插件generator_test的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter功能生成测试插件generator_test的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter项目中生成测试插件generator_test的示例。假设你已经有了一个基本的Flutter项目结构,以下步骤将指导你如何创建和使用一个简单的代码生成器插件来生成测试代码。

1. 创建Flutter项目(如果还没有)

首先,确保你已经安装了Flutter SDK,然后在终端中运行以下命令来创建一个新的Flutter项目:

flutter create my_flutter_app
cd my_flutter_app

2. 添加依赖

pubspec.yaml文件中,添加必要的依赖。虽然generator_test不是一个实际的Flutter包名,但我们可以模拟一个代码生成器插件。这里我们使用build_runnerjson_serializable作为示例,因为它们是常见的代码生成工具。

dependencies:
  flutter:
    sdk: flutter
  json_annotation: ^4.3.0

dev_dependencies:
  build_runner: ^2.1.4
  json_serializable: ^6.1.4

3. 创建数据模型

创建一个数据模型类,比如user.dart,并应用json_serializable注解:

// lib/models/user.dart
import 'package:json_annotation/json_annotation.dart';

part 'user.g.dart';

@JsonSerializable()
class User {
  final String name;
  final int age;

  User({required this.name, required this.age});

  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
  Map<String, dynamic> toJson() => _$UserToJson(this);
}

4. 生成代码

在项目根目录下运行以下命令来生成user.g.dart文件:

flutter pub run build_runner build

这将会在你的lib/models/目录下生成一个user.g.dart文件,包含User类的fromJsontoJson方法的实现。

5. 使用生成的代码

现在你可以在你的Flutter应用中使用这个数据模型了。例如,在main.dart中:

// lib/main.dart
import 'package:flutter/material.dart';
import 'models/user.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    User user = User.fromJson({'name': 'John Doe', 'age': 30});
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('User Info'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text('Name: ${user.name}'),
              Text('Age: ${user.age}'),
            ],
          ),
        ),
      ),
    );
  }
}

6. 测试代码生成(模拟generator_test)

虽然generator_test不是一个真实存在的包,但你可以使用Flutter的测试框架来验证生成的代码。例如,你可以编写一个简单的单元测试来验证User类的序列化和反序列化功能:

// test/user_test.dart
import 'package:test/test.dart';
import 'package:my_flutter_app/models/user.dart';

void main() {
  group('User', () {
    test('supports value comparison', () {
      expect(
        User(name: 'John Doe', age: 30),
        equals(User(name: 'John Doe', age: 30)),
      );
    });

    test('toJson and fromJson works correctly', () {
      User user = User(name: 'John Doe', age: 30);
      Map<String, dynamic> userJson = user.toJson();
      User newUser = User.fromJson(userJson);

      expect(newUser.name, equals('John Doe'));
      expect(newUser.age, equals(30));
    });
  });
}

然后运行测试:

flutter test

总结

以上示例展示了如何在Flutter项目中添加代码生成依赖(如json_serializable),生成代码,并在应用中使用这些生成的代码。同时,还展示了如何编写单元测试来验证生成的代码的正确性。虽然generator_test不是一个实际存在的包,但你可以使用Flutter的测试框架来模拟和验证代码生成的功能。

回到顶部