How can I read a file using a relative path when running flutter test?
When running flutter test the File('path/to/file') needs an absolute path but a relative path works when debugging.
I feel like I'm missing something obvious. Using VS Code, I can run a test by starting debug while in one of the test files. By doing so, the test will pass when using a relative path to read a file. However, when I run flutter test from the terminal, the same test fails because it is unable to find the file unless I change it to use an absolute path in which case the test will pass.
This is the line of code in the test that tries to create a model from the json file:
final tUserModel = UserModel.fromJson(json.decode(fixture('user_cached.json')));
The fixture function is imported from a different file and implemented as follows:
import 'dart:io';
String fixture(String name) => File('test/fixtures/$name').readAsStringSync();
When using that relative path I get the following output from terminal:
flutter test
00:03 +3 ~1 -1: loading /home/user/MyApp/test/features/user/data/datasources/user_local_data_source_test.dart [E]
Failed to load "/home/user/MyApp/test/features/user/data/datasources/user_local_data_source_test.dart": Cannot open file, path = 'test/fixtures/user_cached.json' (OS Error: No such file or directory, errno = 2)
dart:io _File.readAsStringSync
fixtures/fixture_reader.dart 3:60 fixture
features/user/data/datasources/user_local_data_source_test.dart 27:40 main.<fn>
package:test_api Declarer.group
package:flutter_test/src/test_compat.dart 226:13 group
features/user/data/datasources/user_local_data_source_test.dart 25:3 main
===== asynchronous gap ===========================
package:test_api RemoteListener.start
/tmp/flutter_tools.DRSZQD/flutter_test_listener.IPDUJJ/listener.dart 16:25 serializeSuite
/tmp/flutter_tools.DRSZQD/flutter_test_listener.IPDUJJ/listener.dart 43:36 main
flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel beta, 1.19.0-4.1.pre, on Linux, locale en_US.UTF-8)
[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
[✓] Chrome - develop for the web
[✓] Android Studio (version 4.0)
[✓] VS Code (version 1.46.0)
[✓] Connected device (3 available)
• No issues found!
How can I get flutter test to work with a relative file path?
Is there another way to run all tests from VS Code?
Try this.
String fixture(String name) {
var dir = Directory.current.path;
if (dir.endsWith('/test')) {
dir = dir.replaceAll('/test', '');
}
return File('$dir/test/fixtures/$name').readAsStringSync();
}
The issue has been raised a few times here: https://github.com/flutter/flutter/issues/20907
This worked for me:
import 'dart:io';
import 'package:path/path.dart';
String fixture(String name) {
final testDirectory = join(
Directory.current.path,
Directory.current.path.endsWith('test') ? '' : 'test',
);
return File('$testDirectory/fixtures/$name').readAsStringSync();
}
Thanks to: https://github.com/flutter/flutter/issues/20907#issuecomment-466185328
Related
My microfrontend react application is created using Nx Tool. It has been created using Nrwl react executor and the present configuration is untouched & is the default configuration provided by Nx.
When I build the application in production mode, the bundle generated is not minimized & not performance optimized. In project.json, flags were set for optimized code, but they were not being honoured.
In project.json, if I replace the value of *targets > build > options > "webpackConfig"* from **custom webpack path** to **"#nrwl/react/plugins/webpack"**, it honors the optimization flags and works as expected, but it doesnt generate remoteEntry.js file which is required by the host app to render the micro frontend app.
I also tried customizing the webpack based on this [official documentation](https://nx.dev/recipes/other/customize-webpack#module-federation), but the code returns error
Changes in webpack i tried with:
const withModuleFederation = require('#nrwl/react/module-federation');
const moduleFederationConfig = require('./module-federation.config');
const { ModuleFederationPlugin } = require("webpack").container;
/* ========1 Orginal Code snippet================= */
//Creates remoteEntry.js file, but not uglified code
module.exports = withModuleFederation({
...moduleFederationConfig,
});
/* =======2 ================== */
//Returns error: NX customWebpack is not a function
/* module.exports = {
plugins: [
new ModuleFederationPlugin({
...moduleFederationConfig,
}),
],
}; */
Steps to replicate:
Code exists here: https://stackblitz.com/edit/react-ts-azwv9t or get from GIT: https://github.com/kalingaCoder/react_MF
Do npm install
Do npm run build-cart
check bundle output here: dist\apps\cart ( files should be minimized, but that is not happening)
Files to check:
apps\cart\project.json : *targets > build > configurations > production*
apps\cart\webpack.config.js
apps\host\module-federation.config.js
Issue is fixed now, Earlier I was using #nrwl version 14, after migrating to latest, the issue is resolved.
Ran the below command to upgrade
nx migrate latest # same as nx migrate #nrwl/workspace#latest
I have a multi-module android project. I have a bunch of unit tests in each module and I have always been able to run them all at once using a run configuration like this one:
Many of my tests use a base class that runs with RobolectricTestRunner. This base class looks like this:
#RunWith(RobolectricTestRunner::class)
#Config(application = AndroidTest.ApplicationStub::class,
manifest = Config.NONE,
sdk = [21])
abstract class AndroidTest {
#Suppress("LeakingThis")
#Rule #JvmField val injectMocks = InjectMocksRule.create(this#AndroidTest)
fun application(): Application = ApplicationProvider.getApplicationContext()
internal class ApplicationStub : Application()
}
**When running these tests using the above config, I get the error **
[Robolectric] NOTICE: legacy resources mode is deprecated; see http://robolectric.org/migrating/#migrating-to-40
This makes many of my tests fail with ResourceNotFoundException
However, when I run tests only in a specific module, everything passes. This is because Robolectric now uses Binary resources:
[Robolectric] sdk=21; resources=BINARY
I have followed the migration instructions in build.gradle files for each module, having added the following in each android block:
testOptions {
unitTests {
includeAndroidResources = true
returnDefaultValues = true
}
}
One clue I have found but have been unable to fix is this when I run the ALL UNIT TEST task:
WARNING: No manifest file found at build/intermediates/merged_manifests/debug/../../library_manifest/debug/AndroidManifest.xml.
Falling back to the Android OS resources only.
No such manifest file: build/intermediates/merged_manifests/debug/../../library_manifest/debug/AndroidManifest.xml
To remove this warning, annotate your test class with #Config(manifest=Config.NONE).
I have tried, as you have seen, to add the manifest=Config.NONE, which had no effect (and is now deprecated anyway).
Edit: Also tried android.enableUnitTestBinaryResources = true in settings.gradle, but this prevents the app from building due to it being a deprecated flag in the current gradle tools.
Thanks for any help provided!
So with the default unit test run platform being changed to Gradle in Android Studio, I managed to figure out a way to run unit tests in multiple modules all at once, circumventing the Robolectric bug.
First, go into run configurations and create a new Gradle Config.
Then, as the gradle project, select the top level project.
For arguments, use --tests "*"
And now for the gradle tasks, this is a little bit more error-prone. Here is an example of how I have it setup for my project:
:androidrma:cleanTestGoogleDebugUnitTest :androidrma:testGoogleDebugUnitTest
:calendar:cleanTestDebugUnitTest :calendar:testDebugUnitTest
:gamification:cleanTest :gamification:test
:player:cleanTest :player:test
:playlists:cleanTest :playlists:test
:sleepjournal:cleanTest :sleepjournal:test
:sound-content-filters:cleanTest :sound-content-filters:test
Please note that I inserted new lines between each module for more clarity here, in the tasks, just separate each entry with a space.
For your app module, in my case named androidrma, you must use your build variants name in the cleanTestUnitTest and testUnitTest , in my case being GoogleDebug.
If we look at the calendar module, it is an android module, , so it still operates with the same logic as the appModule.
However, if you look at player, playlists, sleepjournal, etc. those are pure kotlin modules. The tasks thus differ in their syntax.
Once you have entered all this information and everything is functioning, I recommend checking "store as project file" checkbox at the top right of the run config setup screen.
This works in Android Studio 4.2 as well as Arctic Fox, haven't tested on other versions.
Is there a way for a C++ or Objective-C program to tell whether is it being run as a command-line application (e.g. with ./myprog in a shell) or as an app bundle (e.g. by double-clicking on a .app in Finder or running open myprog.app/ in Terminal)?
Currently I'm using the following.
CFBundleRef bundle = CFBundleGetMainBundle();
CFURLRef bundleUrl = CFBundleCopyBundleURL(bundle);
char bundleBuf[PATH_MAX];
CFURLGetFileSystemRepresentation(bundleUrl, TRUE, (UInt8*) bundleBuf, sizeof(bundleBuf));
At this point, bundleBuf now holds the path to the .app bundle or the directory containing the command-line executable. I can check whether the string ends with ".app", but this is hacky. Is there a better way to do this?
You can query the Uniform Type Identifier (UTI) of the URL (using CFURLCopyResourcePropertyForKey() with kCFURLTypeIdentifierKey) and see if it conforms to kUTTypeApplicationBundle (using UTTypeConformsTo()).
CFStringRef uti;
if (CFURLCopyResourcePropertyForKey(bundleUrl, kCFURLTypeIdentifierKey, &uti, NULL) &&
uti &&
UTTypeConformsTo(uti, kUTTypeApplicationBundle))
{
// Is bundled application
}
Using Objective-C, you can use the NSWorkspace methods -typeOfFile:error: and -type:conformsToType: for the same purpose.
I'm trying to develop a Dart package for my Flutter project.
It only consists of Dart (so no Flutter) code.
When trying to run my unit tests with Android Studio or IntelliJ I get the following error:
Test framework quit unexpectedly
In the output window I get the following messages:
Testing started at 21:38 ...
/Users/<user>/development/flutter/bin/cache/dart-sdk/bin/pub run test -r json /Users/<user>/Projects/personal/<project dir>/<project>
Observatory listening on http://127.0.0.1:57505/
Could not find a file named "pubspec.yaml" in "/Users/<user>/.pub-cache/hosted/pub.dartlang.org/test-1.5.3".
Process finished with exit code 66
The whole .pub-cache directory doesn't even exists...
How do I get the testing to work?
I had the error messages:
"Test framework quit unexpectedly" "The flutter SDK is not available"
The problem was that I configure the unit tests as Dart tests.
Solution in InteliJ:
Run > Edit Configurations... > + symbol on the top left > Flutter Test (to use the Flutter template instead of the Dart template)
Test scope: All in Directory and choose your_project/lib folder. This will search for all files named as *_test.dart
This thread helped figuring this out: dart:ui:1: Error: Not found: dart:ui. flutter/dart:
I've downloaded the separate Dart SDK en configured Android Studio and IntelliJ to use it instead of the one that ships with Flutter.
Now the tests are working again.
Just installed Android Studio to give it a try. I'm trying to create a test module for my application and, whatever the method I use, I always get the following error: "Error: No AndroidManifest.xml file found in the main project directory...".
Methods I use:
1) from Android Studio: New > Module > Test Module
2) from command line: android create test-project -m "main_path" -n "project_name" -p "test_path"
Any ideas on how to solve this?
Edit: As of 0.1.8 this is now supported in the IDE.
According to the documentation for the new build system a separate project is no longer needed, which implies that a separate module may not be either. That said, getting test working within the IDE is still problematic. I've posted an answer here that at least works for running tests from the command line.