注册

从现在开始,对你的Flutter代码进行单元测试和微件测试

必要性


作为一个开发,对自己开发的功能进行单元测试是非常有必要的。单元测试是软件开发中一种必要的测试方法。它旨在测试一个单独的模块或组件的功能。单元测试通常是自动化的,并且可以在开发过程中进行频繁的测试。在本文中,我们将探讨单元测试的必要性以及为什么它是软件开发中不可或缺的一部分。



  1. 验证代码的正确性

在编写代码时,开发人员往往会犯错误。这些错误可能是语法错误,逻辑错误或其他类型的错误。单元测试可以帮助开发人员及时发现这些错误。通过编写单元测试,开发人员可以验证代码是否按照预期执行,并且可以及早发现和解决错误。



  1. 提高代码质量

单元测试可以帮助开发人员编写更高质量的代码。编写单元测试需要开发人员仔细考虑每个功能点,并确保代码的每个方面都被测试到。通过这个过程,开发人员可以发现并解决潜在的问题,并确保代码的质量得到提高。



  1. 支持重构和改进

在软件开发的生命周期中,代码经常需要进行重构和改进。单元测试可以帮助开发人员在进行这些更改时保证代码的正确性。如果重构或改进代码后,单元测试仍然能够通过,那么开发人员就可以确信代码的行为没有发生变化。这种自信可以让开发人员更加轻松地进行代码更改,并减少由于更改而引入错误的风险。



  1. 提高代码的可维护性

单元测试可以提高代码的可维护性。通过编写单元测试,开发人员可以快速定位代码中的问题并进行修复。这可以使代码更容易维护,并减少开发人员需要花费的时间和精力。在团队合作的情况下,单元测试还可以帮助新成员更快地理解代码,并快速定位和解决问题。


总之,单元测试是软件开发中必不可少的一部分。它可以帮助开发人员验证代码的正确性,提高代码质量,支持重构和改进,并提高代码的可维护性。通过编写单元测试,开发人员可以确保代码的正确性和稳定性,并减少由于更改而引入错误的风险。


单元测试



  1. 安装测试框架

Flutter提供了自己的测试框架,称为flutter_test。在项目中使用flutter_test,需要在pubspec.yaml文件中添加依赖项:


dev_dependencies:
flutter_test:
sdk: flutter

然后,运行以下命令安装依赖项:


flutter packages get

当然在新创建的Flutter工程里,都会默认引用flutter_test并且创建好了test文件夹


image.png



  1. 编写测试用例

测试用例是用来测试应用程序的各个部分的代码。在Flutter中,测试用例通常包含在一个单独的文件中。在这个文件中,你需要导入flutter_test库,并编写测试代码。以下是一个示例:


void main() {
String time = testDate();
print('time=' + time);
}
///检查到期时间
String testDate() {
String expiryDate = '-长期';
List<String> list = (expiryDate).split('-');
if (list.length == 2) {
var start = list[0];
var end = list[1];
if (start.isEmpty || end.isEmpty) {
return '';
}
if (start.length == 8) {
start = DateTime.parse(start).format('yyyy.MM.dd');
}
if (end.length == 8) {
end = DateTime.parse(end).format('yyyy.MM.dd');
}
return '$start-$end';
}
return (expiryDate);
}

在单元测试中,我们可以给对应文件创建对应的测试文件。当我们把数据计算解耦出来,就可以达到不需要UI的情况测试返回结果的情况。配合Mock数据能极大的提高效率。



  1. 进行微件测试
    flutter_test还可以进行微件测试。
    比如我写了一个Widget,这个Widget需要一个json来构建,而json中的一个字段会影响我Widget的创建.我们需要检查这个Widget是否兼容这个json的所有情况.

void questionTitleWidgetTest() {
testWidgets('questionTitle', (widgetTester) async {
String path = '/Users/kfzs_002/Desktop/122.json';
File file = File(path);
String str = file.readAsStringSync();
Map<String, dynamic> json = jsonDecode(str);
Temp temp = Temp.fromJson(json);
for (int i = 0; i < (temp.data?.list?.length ?? 0); i++) {
var data = temp.data!.list![i];
if ((data.questionTitleArr ?? []).isEmpty) {
print('没有标题');
continue;
}
await widgetTester.pumpWidget(
MaterialApp(
home: Material(
child: QuestionTitleWidget(data: data.questionTitleArr ?? []),
),
),
);
print('index=$i');
await widgetTester.pump();
}
});
}

执行测试方法,我们就能在run窗口看到对应的数据结果。


有时我们会写一个动画组件,它有复杂的动画我想检查动画相关参数是否正确。


void examCircleProgressTest() {
testWidgets('examCircleProgressTest', (widgetTester) async {
await widgetTester.pumpWidget(ScreenUtilInit(
designSize: const Size(375, 812),
minTextAdapt: true,
useInheritedMediaQuery: true,
builder: (context, child) => GetMaterialApp(
home: Material(
child: Row(
children: [
ExamCircleProgress(
mTitle: 'title',
subjectType: 2,
progress: 30,
subTitle: 'subtitle',
score: '30',
)
],
),
),
),
));
// await widgetTester.pump();
for (var i = 0; i < 2000; i += 33) {
await widgetTester.pump(Duration(milliseconds: i));
}
});
}

这里我用到了widgetTester.pump.在Widget测试中,widgetTester.pump()方法是一个非常重要的方法,它的作用是将应用程序的状态推进到下一个时间片段。我以33毫秒为间隔,把这个Widget推进到了2秒后的状态。这样就能看到对应的数据情况了。


作者:无敌何尝不可
链接:https://juejin.cn/post/7225116802732425275
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

0 个评论

要回复文章请先登录注册