简体   繁体   中英

Flutter: how to load file for testing

File can be read from the directory relative to the dart script file, simply as var file = new File('./fixture/contacts.json') .

However the file cannot be read flutter test running inside IDE.

Loading as resource (it is not, since I do not want to bundle the test data file in the app) also does not work in test.

What is a good way to read file in flutter (for both command line test and IDE test)?

Running flutter test is very fast. However testing inside Intellij IDE is ver slow, but it can set debug breakpoint and step into and view variables. So both testing is very useful.

Just had a go at this and it's easier than you might expect.

First, create a folder that lives in the same directory than your tests are. For example, I created a folder called test_resources .

测试资源文件夹结构。

Then, let's say we have the following JSON file for testing purposes.

test_resources/contacts.json

{
  "contacts": [
    {
      "id": 1,
      "name": "Seth Ladd"
    },
    {
      "id": 2,
      "name": "Eric Seidel"
    }
  ]
}

test/load_file_test.dart

We could use it for our test like so:

import 'dart:convert';
import 'dart:io';
import 'package:flutter_test/flutter_test.dart';

void main() {
  test('Load a file', () async {
    final file = new File('test_resources/contacts.json');
    final json = jsonDecode(await file.readAsString());
    final contacts = json['contacts'];

    final seth = contacts.first;
    expect(seth['id'], 1);
    expect(seth['name'], 'Seth Ladd');

    final eric = contacts.last;
    expect(eric['id'], 2);
    expect(eric['name'], 'Eric Seidel');
  });
}

I encountered this same issue today. My tests passed in my IDE (Android Studio) but failed on CI. I found that the IDE wanted a non-relative path but flutter test wants a relative path. I think this is a bug and I'll be looking for the right place to report it. However, I found a crude work around for the meantime. Basically, I have a function which tries both ways to specify the file path..

import 'dart:convert';
import 'dart:io';

Future<Map<String, dynamic>> parseRawSample(String filePath,
    [bool relative = true]) async {
  filePath = relative ? "test_data/src/samples/raw/$filePath" : filePath;

  String jsonString;
  try {
    jsonString = await File(filePath).readAsString();
  } catch (e) {
    jsonString = await File("../" + filePath).readAsString();
  }
  return json.decode(jsonString);
}

much of that code is specific to my situation, but I think others could probably adapt this work around for their purposes.

i created an util because vscode and command line test base path is different

https://github.com/terryx/flutter-muscle/blob/master/github_provider/test/utils/test_path.dart

this is how i use it

https://github.com/terryx/flutter-muscle/blob/master/github_provider/test/services/github_test.dart#L13


Another way is to specify exact test path in command line

$ flutter test test

You can just put your test files in two places (I know it is not a good practice to have the same data in two places). Let's say I want to have data.json file to be opened in code under tests with final file = File(dataFilename) , then dataFilename will be 'test_resources/data.json'. If test is executed from Android Studio, test_resources is a folder in project root. If tests are executed from command line test_resources is a folder in test folder. So placing the file in both places will solve the problem.

Just copying the solution from Flocbit : https://github.com/flutter/flutter/issues/20907#issuecomment-557634184

String fixture(String name) {
   var dir = Directory.current.path;
   if (dir.endsWith('/test')) {
     dir = dir.replaceAll('/test', '');
   }
   return File('$dir/test/fixtures/$name').readAsStringSync();
}

Works great!

The current directory is always the project root in Flutter 2.0 🎉 So you can now read files with the same code on the command line and in the IDE.

https://github.com/flutter/flutter/pull/74622

You can use DefaultAssetBundle ,

final response = DefaultAssetBundle.of(context).loadString('assets/file_name.json');

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM