For CI, I need to write a program that runs flutter test integration_test
and captures the stdout result. In python the code would be:
import subprocess
process = subprocess.Popen(
f'flutter test integration_test',
shell=True,
universal_newlines=True,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE)
print('starting')
for line in process.stdout:
print(f'[from python]: {line}')
If you run the above code in the example directory of a plugin package(for example path_provider) with an emulator, every output line will be prefixed with [from python]
as expected:
...
[from python]: 00:17 0: getTemporaryDirectory
[from python]: 00:17 1: getTemporaryDirectory
[from python]: 00:17 1: getApplicationDocumentsDirectory
[from python]: 00:18 1: getApplicationDocumentsDirectory
[from python]: 00:18 2: getApplicationDocumentsDirectory
...
However I need to write the program in dart, the code I wrote is:
import 'dart:io';
Future<void> main() async {
print('starting');
final process = await Process.start(
'flutter', <String>['test', 'integration_test'],
runInShell: true);
await for (final line in process.stdout) {
print('[from dart]: ${String.fromCharCodes(line)}');
}
}
When I run the above code in the same example directory, some lines are not prefixed with [from dart]
, which means some stdout results were not captured by the dart program but are directly written to console.
[from dart]: â Built build/app/outputs/flutter-apk/app-debug.apk.
00:15 0: loading /home/hakkyu/mydir/project/flutter/flutter_plugins/packages/path_provider/path_provider/example/integration_test/path_provider_test.dart
[from dart]: Installing build/app/outputs/flutter-apk/app.apk...
00:16 0: loading /home/hakkyu/mydir/project/flutter/flutter_plugins/packages/path_provider/path_provider/example/integration_test/path_provider_test.dart
[from dart]: 492ms
00:17 0: loading /home/hakkyu/mydir/project/flutter/flutter_plugins/packages/path_provider/path_provider/example/integration_test/path_provider_test.dart
00:17 0: getTemporaryDirectory
00:17 1: getTemporaryDirectory
00:17 1: getApplicationDocumentsDirectory
00:17 2: getApplicationDocumentsDirectory
00:17 2: getApplicationSupportDirectory
00:17 3: getApplicationSupportDirectory
00:17 3: getLibraryDirectory
00:17 4: getLibraryDirectory
00:17 4: getExternalStorageDirectory
If I haven't made any mistakes in the code, I can only assume that there are implementation differences in "process" between python and dart. I have no clue what to look into at this point. What could be causing this issue?
CodePudding user response:
Give this a try:
import 'dart:convert';
import 'dart:io';
Future<void> main() async {
print('starting');
final process = await Process.start(
'flutter', <String>['test', 'integration_test'],
runInShell: true);
await for (final line
in process.stdout.transform(Utf8Decoder()).transform(LineSplitter())) {
print('[from dart]: $line');
}
}
.transform(Utf8Decoder())
will convert bytes into Strings. .transform(LineSplitter())
will split the strings up if there are newlines, I am not too familiar with python, but I am guessing this is what the universal_newlines=True
option does.