Flutter插件arch_test的使用详解

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

Flutter插件arch_test的使用详解

arch_test 是一个用于创建 Dart 应用程序架构测试的包。本文将详细介绍如何使用该插件,并提供一些示例代码。

开始使用

首先,你需要在 test 文件夹下的根目录创建一个测试文件,通常命名为 arch_test.dart

在这个文件中,你需要导入你的主库。如果不这样做,该包将无法找到任何来自你包的元素。

// 在 test/arch_test.dart 中
import 'package:my_package/main.dart';

void main() {
  // 你将在这里编写测试
}

接下来,你需要导入 arch_test 的主文件,它提供了创建测试所需的所有方法和类。你可以通过传递一个 ArchRule 参数来运行测试。你可以以流式方式或普通对象的方式创建 ArchRule

// 在 test/arch_test.dart 中
import 'package:my_package/main.dart';
import 'package:arch_test/arch_test.dart';

void main() {
  // 流式测试
  archTest(classes.that
    .areInsideFolder('entity')
    .should
    .extendClass<BaseEntity>(),
  );
  // 使用预定义帮助器作为普通对象创建 ArchRule
  archTest(ArchRule(
    selector: Selectors.classes,
    filter: Filters.insideFolder('entity'),
    validation: Validations.extendClass<BaseEntity>(),
  ));
}

当使用 archTest 时,它会自动加载你的包的结构,并根据你提供的 ArchRule 创建一个具有描述性名称的测试。例如,上述两个测试都将被命名为 classes THAT are inside folder "entity" SHOULD extend BaseEntity

包层

该包分为三个抽象层:

  • 核心:负责将 Dart 镜像系统转换为内部且更友好的类层次结构。你可以使用这一层获得最大的测试灵活性,但你也将需要写更多的代码;
  • 测试:提供标准化测试的基础类。这是一种更为结构化但仍然不是最简单和流畅的测试方法;
  • 流式:提供一种简单且可读性高的方式来创建测试。这应该是你的首选测试方法。

你可以查看以下部分了解如何使用这些层。

核心

核心层提供包的基本模型和组件,将你的包源代码转换为这些模型。

你可以看到有哪些模型,以及它们的字段和层次结构:

组件包括 DartPackageLoader,它负责加载包的代码结构,以及 DartElementFinder,它用于查找包内代码结构中的元素。

// 导入你的包的主文件,
// 否则 DartPackageLoader 将无法找到你的代码
import 'package:my_package/main.dart'; 
import 'package:test/test.dart';
// 如果你想只导入核心层可以这样做
import 'package:arch_test/core.dart'; 

void main() {
  late DartPackage package;
  setUp(() async {
    package = await DartPackageLoader.instance.loadCurrentPackage();
  });
  test('所有实体应继承 BaseEntity', () {
    final entities = findEntities();
    for (final entity in entities) {
      expect(entity.superClass, isNotNull, reason: '实体应该继承 BaseEntity');
      expect(entity.superClass!.name, 'BaseEntity', reason: '实体应该继承 BaseEntity');
    }
  });
  List<DartClass> findEntities() {
    // 简单的方法
    return DartElementFinder.instance.findByMatcher(
      matcher: (el) => el is DartClass && !el.isEnum,
      source: package,
    ).where((cls) => cls.library.split('/').contains('entities'));
    /* 复杂的方法
    final entities = [];
    final entityLibraries = package.libraries
      .where((lib) => lib.name.split('/').contains('entities')
      .toList();
    for (final entityLibrary in entityLibraries) {
      for (final cls in entityLibrary.classes) {
        if (!cls.isEnum) {
          entities.add(cls);
        }
      }
    }
    return entities;
    */
  }
}

如果你想要更多关于如何使用核心进行测试的例子,请参阅 testing_with_core 示例。

测试

测试层提供了一些类来标准化你创建和描述测试的方式,以及你的架构违规。这些类包括 ArchRuleSelectorFilterValidation

ArchRule 定义了基本的测试结构,使用 Selector 查询要测试的元素(例如类、方法、库等),使用 Filter 过滤查询的元素,并使用 Validation 验证这些元素是否遵循你定义的架构。你还可以使用 andor 方法组合多个过滤器或验证。

此层还提供了一些预定义的 SelectorFilterValidation,以帮助你编写更简洁的代码,并提供了一个 archTest 方法来帮助你减少样板代码并标准化测试名称。

// 导入你的包的主文件,
// 否则 DartPackageLoader 将无法找到你的代码
import 'package:my_package/main.dart'; 
import 'package:test/test.dart';
// 如果你不使用 archTest 方法,则需要导入 core
import 'package:arch_test/core.dart'; 
import 'package:arch_test/testing.dart'; 

void main() {
  // 使用预定义的
  archTest(ArchRule<DartClass>(
    selector: Selectors.classes,
    filter: Filters.insideFolder('entities'),
    validation: Validations.extendClass<BaseEntity>(),
  ));
  // 编写所有内容
  test('位于 "entities" 文件夹内的类应继承 BaseEntity', () async {
    final package = await DartPackageLoader.instance.loadCurrentPackage();
    ArchRule(
      selector: Selector(
        (package) => DartElementFinder.instance.findByMatcher(
          matcher: (el) => el is DartClass && !el.isEnum,
          source: package,
        ),
        description: 'classes',
      ),
      filter: Filter(
        (el) => el.library.split('/').contains('entities'),
        description: 'are inside folder "entities"',
      ),
      validation: Validation(
        (el, addViolation) {
          if (el.superClass == null) {
            addViolation('Does not have super class');
          }
          if (el.superClass.name != 'BaseEntity') {
            addViolation('Should extend BaseEntity');
          }
        },
        description: 'should extend BaseEntity',
      ),
    ).validate(package);
  });
}

这是一个使用 ArchRule 的失败测试示例输出:

在包 my_package 中发现了以下违规:

SomeEntity(位于 package:my_package/path/to/some_entity.dart:1:1)的违规:
- Does not have super class
- Should extend BaseEntity

如果你想要更多关于如何使用测试进行测试的例子,请参阅 testing_with_testing 示例。

流式

流式层提供了一种流式 API 来创建 ArchRule

你可以使用以下顶级常量开始你的规则:classesenumsmethodslibraries。从那里你可以使用 thatshould 添加过滤器和验证到你的测试,以及使用 andor 组合它们。注意 thatshould 是可调用类,所以你可以在流式 API 中使用自定义类。

// 导入你的包的主文件,
// 否则 DartPackageLoader 将无法找到你的代码
import 'package:my_package/main.dart';
// 如果你不使用 archTest 方法,则需要导入 testing
import 'package:arch_test/testing.dart'; 
import 'package:arch_test/fluent.dart'; 

void main() {
  // 使用预定义的
  archTest(classes.that.areInsideFolder('entities').should.extendClass<BaseEntity>());
  
  // 编写并组合自定义过滤器/验证
  archTest(classes
    .that(Filter((el) => el.name.endsWith('Entity'), description: 'have name ending with Entity'))
    .and(Filter((el) => el.name != 'BaseEntity'), description: 'are not BaseEntity'))
    .should(Validation((el, addViolation) {
      if (el.superClass == null || el.superClass.name != 'BaseEntity') {
        addViolation('Should extend BaseEntity');
      }
    }, description: 'should extend BaseEntity'))
    .or(Validation((el, addViolation) {
      if (el.library.split('/').contains('entities')) {
        addViolation('Should be outside of "entities" folder');
      }
    }, description: 'should be outside of "entities" folder')),
  );
}

更多关于Flutter插件arch_test的使用详解的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter插件arch_test的使用详解的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


针对您提到的Flutter未知功能插件arch_test的潜在使用,由于arch_test并非一个广为人知的官方或广泛使用的Flutter插件,我无法提供确切的文档或广泛认可的用例。不过,我可以基于插件名称和可能的用途,给出一个假设性的代码示例,展示如何在Flutter项目中集成并使用一个假设的架构测试插件。

请注意,以下代码是基于假设的,因为arch_test的具体实现和功能未知。这个示例旨在展示如何集成和使用一个假想的架构测试插件。

假设的arch_test插件功能

假设arch_test插件用于验证Flutter应用的架构是否符合某些最佳实践,比如依赖注入、MVVM模式等。

集成步骤

  1. pubspec.yaml中添加依赖

    dependencies:
      flutter:
        sdk: flutter
      arch_test: ^1.0.0  # 假设版本号
    
  2. 运行flutter pub get

    flutter pub get
    
  3. 使用插件进行架构测试

    假设arch_test提供了一个名为verifyArchitecture的方法,用于验证应用的架构。以下是一个简单的使用示例:

    import 'package:flutter_test/flutter_test.dart';
    import 'package:arch_test/arch_test.dart';  // 假设的导入路径
    
    void main() {
      testWidgets('verify app architecture', (WidgetTester tester) async {
        // 假设有一个用于测试的Widget
        await tester.pumpWidget(MyApp());
    
        // 使用arch_test插件进行架构验证
        await verifyArchitecture(tester.widget(find.byType(MyApp)));
      });
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        // 假设的应用架构
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(
              title: Text('Flutter Demo'),
            ),
            body: Center(
              child: Text('Hello, World!'),
            ),
          ),
        );
      }
    }
    

    在上面的代码中,verifyArchitecture是一个假设的方法,用于检查MyApp组件的架构是否符合arch_test插件定义的标准。

注意事项

  • 由于arch_test是一个假设的插件,上述代码中的verifyArchitecture方法和其他细节都是虚构的。
  • 在实际使用中,您需要参考arch_test插件的官方文档来了解其真实的功能和使用方法。
  • 如果arch_test是一个私有或内部使用的插件,您可能需要联系插件的开发者或维护者以获取更多信息和支持。

希望这个假设性的示例能够帮助您理解如何在Flutter项目中集成和使用一个假设的架构测试插件。如果您有关于具体插件的更多信息或需求,请提供详细信息以便给出更准确的指导。

回到顶部