Fix: performance improvement on golden test comparison (#142913)

During golden test image comparison 2 lists of a different type are compared with the method "identical", so this will never be true. The test image is a _Uint8ArrayView while the master image is an Uint8List. So that results in always a heavy computation to get the difference between the test and the master image.

When you run this test snippet I go from 51 seconds to 14 seconds:
```dart
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  for (int i = 0; i < 100; i++) {
    testWidgets('Small test', (WidgetTester tester) async {
      await tester.pumpWidget(Directionality(textDirection: TextDirection.ltr, child: Text('jo')));
      await expectLater(find.byType(Text), matchesGoldenFile('main.png'));
    });
  }
}
```
This commit is contained in:
Kris Pypen 2024-02-09 23:05:00 +01:00 committed by GitHub
parent 1887bc410f
commit 2f117c545b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 17 additions and 8 deletions

View file

@ -175,13 +175,6 @@ mixin LocalComparisonOutput {
/// Returns a [ComparisonResult] to describe the pixel differential of the
/// [test] and [master] image bytes provided.
Future<ComparisonResult> compareLists(List<int>? test, List<int>? master) async {
if (identical(test, master)) {
return ComparisonResult(
passed: true,
diffPercent: 0.0,
);
}
if (test == null || master == null || test.isEmpty || master.isEmpty) {
return ComparisonResult(
passed: false,
@ -190,6 +183,13 @@ Future<ComparisonResult> compareLists(List<int>? test, List<int>? master) async
);
}
if (listEquals(test, master)) {
return ComparisonResult(
passed: true,
diffPercent: 0.0,
);
}
final Codec testImageCodec =
await instantiateImageCodec(Uint8List.fromList(test));
final Image testImage = (await testImageCodec.getNextFrame()).image;

View file

@ -9,8 +9,8 @@ import 'dart:ui' as ui;
import 'package:file/memory.dart';
import 'package:flutter/foundation.dart' show DiagnosticLevel, DiagnosticPropertiesBuilder, DiagnosticsNode, FlutterError;
import 'package:flutter_test/flutter_test.dart' hide test;
import 'package:flutter_test/flutter_test.dart' as test_package;
import 'package:flutter_test/flutter_test.dart' hide test;
// 1x1 transparent pixel
const List<int> _kExpectedPngBytes = <int>[
@ -85,6 +85,15 @@ void main() {
final LocalFileComparator comparator = goldenFileComparator as LocalFileComparator;
expect(comparator.basedir.path, contains('flutter_test'));
});
test('image comparison should not loop over all pixels when the data is the same', () async {
final List<int> invalidImageData1 = Uint8List.fromList(<int>[127]);
final List<int> invalidImageData2 = Uint8List.fromList(<int>[127]);
// This will fail if the comparison algorithm tries to generate the images
// to loop over every pixel which is not necessary when test and master
// is exactly the same (for performance reasons).
await GoldenFileComparator.compareLists(invalidImageData1, invalidImageData2);
});
});
group('LocalFileComparator', () {