this is my code:
void main() {
testWidgets("Localiza os widgets na home", (WidgetTester tester) async {
await tester.pumpWidget(const MaterialApp(home: HomeView()));
final Finder drawer = find.byType(IconButton);
await tester.tap(drawer);
expect(drawer, findsOneWidget);
await tester.pumpAndSettle();
final Finder listTileDrawer = find.byType(ListTile);
expect(listTileDrawer, findsNWidgets(5));
final Finder listViewDrawer = find.byType(ListView);
expect(listViewDrawer, findsOneWidget);
});
testWidgets("Valida se snackBar está sendo exibida corretamente", (WidgetTester tester) async {
await tester.pumpWidget(const MaterialApp(
home: Scaffold(
body: BotaoRedirecionamentoExterno(
url: 'url invalida',
texto: 'teste',
))));
final botao = find.byType(BotaoRedirecionamentoExterno);
await tester.tap(botao);
await tester.pumpAndSettle();
final Finder snackBar = find.byType(SnackBar);
expect(snackBar, findsOneWidget);
});
}
When I run: test/view/home/home_widget_test.dart --no-sound-null-safety it works as expected:
I/flutter (11181): 00:01 +1: Valida se snackBar está sendo exibida corretamente
I/flutter (11181): 00:02 +2: All tests passed!
But when I try: flutter test --no-sound-null-safety:
══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following TestFailure object was thrown running a test:
Expected: exactly one matching node in the widget tree
Actual: _WidgetTypeFinder:<zero widgets with type "SnackBar" (ignoring offstage widgets)>
Which: means none were found but one was expected
When the exception was thrown, this was the stack:
#4 main.<anonymous closure> (file:///Users/macos/Desktop/portal-agro-sp-master/test/view/home/home_widget_test.dart:33:5)
<asynchronous suspension>
<asynchronous suspension>
(elided one frame from package:stack_trace)
This was caught by the test expectation on the following line:
file:///Users/macos/Desktop/portal-agro-sp-master/test/view/home/home_widget_test.dart line 33
The test description was:
Valida se snackBar está sendo exibida corretamente
════════════════════════════════════════════════════════════════════════════════════════════════════
00:26 +25 -1: /Users/macos/Desktop/portal-agro-sp-master/test/view/home/home_widget_test.dart: Valida se snackBar está sendo exibida corretamente [E]
Test failed. See exception logs above.
The test description was: Valida se snackBar está sendo exibida corretamente
I need to be able to run all my tests together due to a customer requirement. I already have more than 23 tests ready and this is the first time this has happened.
Does anyone know why this is happening and a way to solve it ?
Related
Before, my integration test works. After I pull an update of another developer my integration test fails with the following error:
══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following NoSuchMethodError was thrown running a test:
The method 'containsKey' was called on null.
Receiver: null
Tried calling: containsKey("serverStatus")
When the exception was thrown, this was the stack:
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:38:5)
#1 _IndexState._referAFriendEnabled (package:limitless/pages/index.dart:1390:15)
Transition { currentState: HomeInitial(), event: FetchHomeCarousels(), nextState: HomeInitial() }
Transition { currentState: InitialInboxState(), event: InboxFetch(), nextState: InboxFetchingData() }
══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following assertion was thrown running a test (but after the test had completed):
'package:flutter_test/src/binding.dart': Failed assertion: line 1558 pos 12: 'inTest': is not true.
When the exception was thrown, this was the stack:
#2 LiveTestWidgetsFlutterBinding.pump (package:flutter_test/src/binding.dart:1558:12)
#3 WidgetTester.pumpAndSettle.<anonymous closure> (package:flutter_test/src/widget_tester.dart:668:23)
<asynchronous suspension>
<asynchronous suspension>
(elided 3 frames from class _AssertionError and package:stack_trace)
════════════════════════════════════════════════════════════════════════════════════════════════════
03:29 +0 -1: end-to-end test limitless non-transactional test
CustomerStart { }
Transition { currentState: CustomerInitial(), event: CustomerStart { }, nextState: CustomerLoading() }
03:31 +0 -1: Some tests failed.
Running the app works fine. It only fails when running integration test.
This is code snippet about containsKey.
void _referAFriendEnabled() async {
bool referralEnabled = false;
PackageInfo packageInfo = await PackageInfo.fromPlatform();
if (prefs.containsKey('serverStatus')) {
Map appSettings = await AppSharedPref.getServerStatus();
limitlessRepo.appVersion = appSettings["app_version"];
limitlessRepo.storeVersion = appSettings["latest_store_app_version"];
referralEnabled = appSettings["referral_code"];
limitlessRepo.version = packageInfo.version;
} else {
await limitlessRepo.isReferralCodeEnabled();
}
newVersionAvailable();
setState(() {
_isReferralEnabled = referralEnabled;
});
Does anyone has an idea about this? Thank you.
I'm trying to run an integration test which is highly dependent on the user clicking a magic link he got in his email. So far I failed to find a way of doing that. I came across Process.run but it seems like it should be run before the integration test starts and I need to do it during the test.
Any help with either iOS or Android will be highly appreciated. 🙏
This is the code I tried so far to work on iOS but Process.run ends with ProcessException: No such file or directory:
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
testWidgets('login test', (WidgetTester tester) async {
app_sandbox.main();
await tester.pumpAndSettle(Duration(seconds: 5));
expect(find.text('foo'), findsOneWidget);
await Process.run('xcrun', [
'simctl',
'openurl',
'7D6DEC47-C1E2-4F18-A38B-7B4C17558172',
'https://myDeepLink/sign-in',
]);
await tester.pumpAndSettle();
});
}
this might only work with flutter_driver
await Process.run('xcrun', [
'simctl',
'openurl',
'booted',
'https://myDeepLink/sign-in'
]).then((result) {
stdout.write(result.stdout);
stderr.write(result.stderr);
});
not with testWidgets of integration_test
there I got this error:
> Error occured: DriverError: Failed to fulfill RequestData due to
> remote error Original error: ext.flutter.driver: (112) Service has
> disappeared Original stack trace:
> #0 new _OutstandingRequest (package:vm_service/src/vm_service.dart:1746:45)
> #1 VmService._call (package:vm_service/src/vm_service.dart:2262:21)
> #2 VmService.callServiceExtension (package:vm_service/src/vm_service.dart:2233:14)
> #3 VMServiceFlutterDriver.sendCommand (package:flutter_driver/src/driver/vmservice_driver.dart:306:66)
> #4 FlutterDriver.requestData (package:flutter_driver/src/driver/driver.dart:522:45)
> #5 integrationDriver (package:integration_test/integration_test_driver_extended.dart:51:38)
> <asynchronous suspension>
I'm using socket_io_client v0.9.12 in my flutter app (still not using null safety). I am creating a socket connection with my back-end server when the app starts and allow child widgets to access it using a provider.
I am trying to start creating the connection in the constructor so that when I need to use the socket client, it would probably be initialized already.
This is my provider class which has the creation of the socket connection:
class SocketClient {
SocketClient() {
_initializer = initialize();
}
Future _initializer;
/// Socket client
Socket client;
/// Wait until the client is properly connected with the server
Future finishInitializing() => _initializer;
/// Initialize the socket connection with the server
Future initialize() async {
final completer = Completer<Socket>();
final socket = io(
'http://localhost:3000/gateway',
OptionBuilder() //
.setTransports(['websocket'])
.disableAutoConnect()
.setQuery({'token': 'TOKEN'})
.build(),
)..connect();
socket
..onConnect((_) {
completer.complete(socket);
});
client = await completer.future;
}
}
The main app widget I have:
#override
Widget build(BuildContext context) {
return Provider<SocketClient>(
create: (_) => SocketClient(),
builder: (context, _) {
return Scaffold(
...
);
},
);
}
This is how I am trying to use the socket client:
Future<void> foo(SocketClient socketClient) async {
await socketClient.finishInitializing();
final socket = socketClient.client;
socket.on(eventName, (dynamic uploadDrawingEvent) {
...
});
}
Everything works fine up to now. 🎉
However, when I try to run my tests that depend on this socket client, I see the below error:
Pending timers:
Timer (duration: 0:00:20.000000, periodic: false), created:
#0 new FakeTimer._ (package:fake_async/fake_async.dart:284:41)
#1 FakeAsync._createTimer (package:fake_async/fake_async.dart:248:27)
#2 FakeAsync.run.<anonymous closure> (package:fake_async/fake_async.dart:181:19)
#5 Manager.connect (package:socket_io_client/src/manager.dart:232:19)
#6 Manager.open (package:socket_io_client/src/manager.dart:194:41)
#7 Socket.connect (package:socket_io_client/src/socket.dart:104:8)
#8 SocketClient.initialize (package:flutter_app/web/services/socket_provider.dart:48:8)
<asynchronous suspension>
(elided 2 frames from dart:async)
══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following assertion was thrown running a test:
A Timer is still pending even after the widget tree was disposed.
'package:flutter_test/src/binding.dart':
Failed assertion: line 1241 pos 12: '!timersPending'
When the exception was thrown, this was the stack:
#2 AutomatedTestWidgetsFlutterBinding._verifyInvariants (package:flutter_test/src/binding.dart:1241:12)
#3 TestWidgetsFlutterBinding._runTestBody (package:flutter_test/src/binding.dart:803:7)
<asynchronous suspension>
(elided 2 frames from class _AssertionError)
...
initialize function keeps hanging after client = await completer.future; line. That future is not resolved even after the test is finished (see the error).
I would like to get ideas on how I can mock this socket client properly to avoid this error.
I'm looking more towards an answer which mocks the functionality of the socket client because I have some more tests to write to cover the event handlers.
Thank you in advance! 🙏
You can use await IOOverrides for override standard Socket method like socketConnect
Exemple:
await IOOverrides.runZoned(() async {
your code
}, socketConnect: (host, port, {sourceAddress, int sourcePort = 0, timeout}) => Future.value(mockSocket));
I am getting the following error Unhandled Exception: Null check operator and I am not sure if it is something wrong in my code or the library I am using. I am trying to test the livequery of the parse_server_sdk used by back4app because I require sending and receiving images in Realtime. Here is the relevant code:
import 'dart:io';
import 'package:filepicker_windows/filepicker_windows.dart';
import 'package:flutter/material.dart';
import 'package:parse_server_sdk_flutter/parse_server_sdk.dart';
void main() async {
final keyApplicationId = 'EPARW6nRAAyp5uehoDE7rBEby4wtehcZf9EayykS';
final keyClientKey = 'fDaL2DjyC9YdwCwZ4RB5c5vhACROaMOO1EjjL4Zn';
final keyParseServerUrl = 'https://parseapi.back4app.com';
final LIVE_QUERY_URL = 'wss://samuraichat.b4a.io';
await Parse().initialize(keyApplicationId, keyParseServerUrl,
clientKey: keyClientKey,
autoSendSessionId: true,
liveQueryUrl: LIVE_QUERY_URL,
coreStore: CoreStoreMemoryImp());
final LiveQuery liveQuery = LiveQuery();
QueryBuilder<ParseObject> query =
QueryBuilder<ParseObject>(ParseObject('FirstClass'))
..whereEqualTo('chatId', 1);
Subscription subscription = await liveQuery.client.subscribe(query);
subscription.on(LiveQueryEvent.create, (value) {
print('*** CREATE ***: ${DateTime.now().toString()}\n $value ');
print((value as ParseObject).objectId);
print((value as ParseObject).get('message'));
});
runApp(MyApp());
}
Here is the error stack:
[ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: Null check operator used on a null value
#0 MethodChannel.binaryMessenger (package:flutter/src/services/platform_channel.dart:142:86)
#1 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:148:36)
#2 MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:331:12)
#3 MethodChannelConnectivity.checkConnectivity (package:connectivity_platform_interface/src/method_channel_connectivity.dart:41:29)
#4 Connectivity.checkConnectivity (package:connectivity/connectivity.dart:46:22)
#5 Parse.checkConnectivity (package:parse_server_sdk_flutter/parse_server_sdk.dart:106:34)
#6 new LiveQueryReconnectingController (package:parse_server_sdk/src/network/parse_live_query.dart:45:28)
#7 new LiveQueryClient._internal (package:parse_server_sdk/src/network/parse_live_query.dart:146:30)
#8 LiveQueryClient._getInstance (package:parse_server_sdk/src/network/parse_live_query.dart:153:35)
#9 new LiveQuery (package:parse_server_sdk/src/network/parse_live_query.dart:416:30)
#10 main (package:chat_app/main.dart:18:37)
<asynchronous suspension>
Thanks.
Try to clean your app cache:
flutter clean
This bug should be fixed with this PR.
You use the current nullsafety branch by overriding the dependency in your pubspec.yaml:
dependency_overrides:
parse_server_sdk_flutter:
git:
url: https://github.com/parse-community/Parse-SDK-Flutter.git
ref: nullsafety
path: packages/flutter
parse_server_sdk:
git:
url: https://github.com/parse-community/Parse-SDK-Flutter.git
ref: nullsafety
path: packages/dart
I have a basic flutter project running on android where when the application starts, I write an executable bundled in my assets.
static String appInternalPath = '/data/data/com.maksimdan.face_merger';
void writeExecutable() async {
var executablePath = join(appInternalPath, 'main');
if (await File(executablePath).exists()) {
File(executablePath).delete();
print('deleted old executable');
} else {
print('not executable exists');
}
ByteData data = await rootBundle.load('lib/py/dist/main');
List<int> bytes =
data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
await File(executablePath).writeAsBytes(bytes);
print('wrote new executable');
}
Sometime later in my code I try to run it.
void invokeExecutable() async {
String executablePath = join(appInternalPath, 'main');
Process.run('chmod', ['u+x', executablePath]).then((ProcessResult results) {
Process.run(executablePath, []).then((ProcessResult results) {
print(results.stdout);
});
});
}
But obtain a permission denied error.
E/flutter (31825): [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: ProcessException: Permission denied
E/flutter (31825): Command: /data/data/com.maksimdan.flutter_general/main
E/flutter (31825): #0 _ProcessImpl._start (dart:io-patch/process_patch.dart:390:33)
E/flutter (31825): #1 Process.start (dart:io-patch/process_patch.dart:36:20)
E/flutter (31825): #2 _runNonInteractiveProcess (dart:io-patch/process_patch.dart:565:18)
E/flutter (31825): #3 Process.run (dart:io-patch/process_patch.dart:47:12)
E/flutter (31825): #4 _MyHomePageState.invokeExecutable.<anonymous closure> (package:flutter_general/main.dart:51:15)
E/flutter (31825): #5 _rootRunUnary (dart:async/zone.dart:1362:47)
E/flutter (31825): #6 _CustomZone.runUnary (dart:async/zone.dart:1265:19)
E/flutter (31825): <asynchronous suspension>
I've also tried:
Process.run('/system/bin/chmod', ['744', path]).then((ProcessResult results) {
print('shell1 complete');
Process.run(path, []).then((ProcessResult results) {
print('shell2 complete');
print(results.stdout);
});
});
My executable:
// 'Hello World!' program
#include <iostream>
int main()
{
std::cout << "Hello World!" << std::endl;
return 0;
}
>> g++ main.cc -o main
Is there a way to run your own executables in flutter with the proper permissions? On native android, there is an option to file.setExecutable(true); using this strategy. (Hosting an executable within Android application)
Or will I have to experiment with method channels?
pubspec.yml
name: face_merger
description: A new Flutter project.
version: 1.0.0+1
environment:
sdk: ">=2.1.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
sqflite: ^1.3.0+2
process_run: ^0.10.10+1
cupertino_icons: ^0.1.3
dev_dependencies:
flutter_test:
sdk: flutter
flutter:
uses-material-design: true
assets:
- lib/py/dist/main
I also verified that the file was written to the internal memory of on the device that I expected it to be written to using android studio's device explore.
Besides the writable permission you need to have readable permission in your app.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.xxx.yyy">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
...
You need to put the .db file extension at the end of the database name (Assuming DB_DIR is for a database). var path = join(DB_DIR, 'main.db');
Then I think you may want to use path_provider package and use
Directory documentsDirectory = await getApplicationDocumentsDirectory();
for the directory where you are accessing the database.