ERROR in flutter: widget_test.dart cannot detect MyApp() pls helpme - flutter

Being a total beginner I am trying out various flutter feature and I am stuck at running the main.dart due to errors in the widget_test.dart file. Please point out if the error is due to some other reason.
main.dart
import 'package:flutter/material.dart';
import 'package:food_app/pages/HomePage.dart';
import 'package:food_app/pages/StarterPage.dart';
void main() => runApp(
MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(fontFamily: 'Roboto'),
home: StarterPage(),
)
);
widget_test.dart
// This is a basic Flutter widget test.
//
// To perform an interaction with a widget in your test, use the WidgetTester
// utility that Flutter provides. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:food_app/main.dart';
void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(MyApp());
// Verify that our counter starts at 0.
expect(find.text('0'), findsOneWidget);
expect(find.text('1'), findsNothing);
// Tap the '+' icon and trigger a frame.
await tester.tap(find.byIcon(Icons.add));
await tester.pump();
// Verify that our counter has incremented.
expect(find.text('0'), findsNothing);
expect(find.text('1'), findsOneWidget);
});
}

This widget_test.dart file is a file for your tests (obviously). It is separate of your main code and its purpose is only for writing unit, widget, integration and probably some other tests.
I believe that your question came up because your IDE shows you a problem in that code. You don't have to worry about it. As long as you run flutter run or flutter build tests aren't touched.
You can delete the whole tests/ directory if you don't plan on maintaining them.
I deeply suggest you learn about Flutter unit and widget tests as you and your skills will benefit from it, it is also an industry standard to write tests. You can learn more about them in Testing Flutter apps. If you're only getting started with Flutter, you can leave it for later though.
However, if you plan to fix those test, firstly, you should put your MaterialApp in some custom widget, for example FoodApp (guessing from the package name) and pump it in tests. You will need to tweak those tests a little bit more than that. Please refer to the resource I linked above.

Related

Flutter, how to take full screenshot

i am trying to find a way to take a screenshot of entire screen. Flutter library is only allowing me to make a screenshot of a widget, but i want a screenshot of entire android.
I did find this link:
How to programmatically take a screenshot on Android?
and this is resolwing my problem, but i tried to use that java code as it is in documentation:
https://flutter.dev/docs/development/platform-integration/platform-channels?tab=android-channel-java-tab
sadly i am not able to run that code, maybie im making some kind of mistakes? i find a error, while i whas following docs instruction, after that program whas working (not exacly, java whas not able to find my battery, but code whas compiling), and then i copy first answer from that stack link and i tried to pase it in "MainActivity" folder, sadly program whas not working, my "old" java code whas comipilng, from the docs, not the new one.
If you know the solution how to make a photo of entire android screen using some kind of buttor in flutter, or how to implement code from that link into my MainActivity.java folder, please help
Try this package native_screenshot
https://pub.dev/packages/native_screenshot
You can simply run this function to take the screenshot of your phone:
Future<void> _capturePng() async {
String path = await NativeScreenshot.takeScreenshot();
print(path);
}
You can learn more about this package here
It work fine with Android and IOS
Hope it will be useful
You can use screenshot plugin:https://pub.dev/packages/screenshot to take a widget screenshot.
A screenshot is a simple plugin to capture widgets as Images. This plugin wraps your widgets inside RenderRepaintBoundary
Use this package as a library
Add this to your package's pubspec.yaml file:
dependencies:
screenshot: ^0.2.0
Now in your Dart code, Import it:
import 'package:screenshot/screenshot.dart';
This handy plugin can be used to capture any Widget including full-screen screenshots & individual widgets like Text().
Create Instance of Screenshot Controller
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
File _imageFile;
//Create an instance of ScreenshotController
ScreenshotController screenshotController = ScreenshotController();
#override
void initState() {
// TODO: implement initState
super.initState();
}
...
}
Wrap the widget that you want to capture inside Screenshot Widget. Assign the controller to screenshotController that you have created earlier
Screenshot(
controller: screenshotController,
child: Text("This text will be captured as image"),
),
Take the screenshot by calling the capture method. This will return a File
screenshotController.capture().then((File image) {
//Capture Done
setState(() {
_imageFile = image;
});
}).catchError((onError) {
print(onError);
});
Duplicate: How to take a screenshot of the current widget - Flutter

How to test canvas with testWidgets in a flutter mobile app project

I was reading about how to build tests for flutter app widgets with the testWidgets function, like this test which comes by default when creating a new flutter project:
// <project>/test/widget_test.dart
void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
await tester.pumpWidget(CounterApp());
// validate counter starts at zero
expect(find.text('0'), findsOneWidget);
await tester.tap(find.byIcon(Icons.add));
await tester.pump();
expect(find.text('0'), findsNothing);
expect(find.text('1'), findsOneWidget);
}
}
But how would one test a canvas to see if the drawings/patterns and paragraphs are being displayed correctly? Does the finder object finds a Text widget if I draw a paragraph with canvas.drawParagraph(...)? I couldn't find info about this in the docs.
Testing Canvas in general (no matter the technology) should be performed using visual testing (or visual regression testing).
flutter_test package provides matchesGoldenFile function that makes it possible. There's a nice tutorial on Flutter's Github that will guide you through.

Flutter widget vs Flutter driver

I'm writing tests for a mobile App written in Flutter.
I followed this Flutter Cookbook on testing Flutter apps, to learn how to write widget and integration tests.
This tutorial works perfectly, but I'm still stuck with my own Integration tests.
To simplify, let's assume I have an app, containing only a TextField:
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'MyAppp',
home: Scaffold(
body: Center(child: TextField()),
),
);
}
}
I want to write a test for this app. For instance, I want to test the following scenario:
Open the app
Check that the TextField is empty
Select the TextField
Enter "hello, world!"
Check that TextField contains "hello, world!"
I wrote the following Widget test, which works fine:
void main() {
testWidgets('TextField behavior', (WidgetTester tester) async {
// Create app
await tester.pumpWidget(MyApp());
// Find TextField, check there is 1
final textFieldFinder = find.byType(TextField);
expect(textFieldFinder, findsOneWidget);
// Retrieve TextField Widget from Finder
TextField textField = tester.widget(textFieldFinder);
// Check TextField is empty
expect(textField.controller.text, equals(""));
// Enter text
await tester.enterText(textFieldFinder, "hello, world!");
// Check TextField contains text
expect(textField.controller.text, equals("hello, world!"));
});
}
This test passes, but I wanted to write an Integration test, doing more or less the same, to be able to test it on a real device.
Indeed if this Widget test passes, it will probably pass on all device. But in my app I have more complex widgets and interactions between them, I want to be able to launch tests on both Android and iOS.
I tried to write integration tests using Flutter driver, but I did not find what I wanted in the documentation and examples.
How can I check Widget properties, to verify that my App behaves as expected?
I wrote the following sample:
import 'package:flutter_driver/flutter_driver.dart';
import 'package:test/test.dart';
void main() {
group('TextField', () {
final textFieldFinder = find.byType('TextField');
FlutterDriver driver;
setUpAll(() async {
driver = await FlutterDriver.connect();
});
tearDownAll(() async {
if (driver != null) {
driver.close();
}
});
test('TextField behavior', () async {
// ??? how to check that the TextField is empty
await driver.tap(textFieldFinder);
await driver.enterText("hello, world!");
// ??? how to check that the TextField contains hello, world!
});
});
}
The Flutter Cookbook tutorial explains how to retrieve an object by its Text, this would help to check if the Text is present, but for instance is it possible to check that a Container color is red?
Where is the limit between Widget and Integration tests?
Writing Widget tests is pretty straighforward, but I didn't find many examples or documentation about how to write more complexe integration tests using Flutter driver.
If anyone is interested:
To be able to test what I want (not only the presence of widgets, but also theirs states, their properties,...) test driver was not enough for me.
What I did in my project, is to use the flutter_test to write widget tests and check the properties I want.
To test it on a real device (Android or iOS), I used the integration_test package (previously e2e package) available here, which adapts flutter_test results to a format compatible with flutter drive.
To use integration_test, add this line in the main of your widget tests:
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
Then create a file (e.g. integration_test.dart) in your test_driver folder with this content:
import 'package:integration_test/integration_test_driver.dart';
Future<void> main() => integrationDriver();
Then you can launch these driver test by running:
flutter drive \
--driver=test_driver/integration_test.dart \
--target=test/widget_test/widget_test.dart
With your widgets tests wrote in the file test/widget_test/widget_test.dart.
It really helped me, since some widgets did not have the same behavior on Android and iOS.
Today I use both flutter_test (launched on real device with integration_test) and real flutter_driver tests:
I write widget tests to check a single widget, or a single page,
I use flutter driver to write more sophisticated scenarios to test the whole application.
I think there's a difference between flutter widget and flutter driver. In that, flutter widgets is for widget tests and flutter driver is for integration tests. I'm not exactly sure what that means on a practical standpoint but I think integration test are easier to run tests on application interactions that would be made by a user since integration tests run on an actual device as compared to widget tests. Will update if I find more information on this.

Load Data during Splash Screen in Flutter

I need to know is there any way to perform a task during splash screen is visible in flutter. I know how to add splash screen in flutter but I don't know how to perform background operations during splash screen is visible. I can't find anything on the internet, please help.
Yes, yes you can. The main() function can actually be tagged as async, so you can do whatever you need to do before running runApp(...) in the main() method body, even asynchronously. This way, the splash screen will be shown until your asynchronous result is retrieved, before calling runApp(...). For example:
Future<void> main() async {
// Do whatever you need to do here
final home = await setHomeWidgetDependingOnLoginStatus();
return runApp(MyApp(home: home));
}
The animated_splash_screen package does this worderfully. add it to your pubspec.yml
animated_splash_screen: ^1.1.0
AnimatedSplashScreen.withScreenFunction(
splash: 'images/splash.png',
screenFunction: () async{
// Your code here
return MainScreen();
},
splashTransition: SplashTransition.rotationTransition,
pageTransitionType: PageTransitionType.scale,
)
This will load and hold you splash screen until your function is complete.
Your function has to return a widget, in this case is your home screen. This also allows for dynamic routing depending on your data eg, is user logged in.

In Flutter widget testing, how to pause app to find suggested Finder?

I am following flutter widget testing as https://flutter.io/testing/#widget-testing.
It says that
simply flutter run test/widget_test.dart to see your test run in your preferred runtime environment such as a simulator or a device. During a flutter run session on a widget test, you can also interactively tap parts of the screen for the Flutter tool to print the suggested Finder.
I am using flutter run test/widget_test.dart so that i can tap and get suggested finders. But I am not able to pause the test so that i can actually tap. The test runs and automatically ends. So that there are no widgets on the screen except Text('Test Finished').
Thank you very much!
I know it's been almost 2 years since the question was asked, but anyway. tester.idle() helped me to pause an app.
testWidgets('idle', (WidgetTester tester) async {
await tester.pumpWidget(
//
);
await tester.tap(find.byIcon(Icons.bluetooth));
await tester.pump();
tester.idle();
});