10. a) Write unit tests for UI components.
Unit tests are handy for verifying the behaviour of a single function, method, or
class. The test package provides the core framework for writing unit tests, and the
flutter_test package provides additional utilities for testing widgets.
This recipe demonstrates the core features provided by the test package using the
following steps:
Add the test or flutter_test dependency.
Create a test file.
Create a class to test.
Write a test for our class.
Combine multiple tests in a group.
Run the tests.
For more information about the test package, see the test package documentation.
1. Add the test dependency
The test package provides the core functionality for writing tests in Dart. This is the
best approach when writing packages consumed by web, server, and Flutter apps.
To add the test package as a dev dependency, run flutter pub add:
content_copy
flutter pub add dev:test
2. Add the test package (if not already present)
In your pubspec. yaml:
dev_dependencies:
flutter_test:
sdk: flutter
test: ^1.24.0 # (Check for latest version)
and run
flutter pub get
3. Create a test file
In this example, create two files: counter. dart and counter_test.dart.
The [Link] file contains a class that you want to test and resides in the lib folder.
The counter_test.dart file contains the tests themselves and lives inside the test folder.
In general, test files should reside inside a test folder located at the root of your Flutter
application or package. Test files should always end with _test.dart, this is the
convention used by the test runner when searching for tests.
When you’re finished, the folder structure should look like this:
content_copy
counter_app/
lib/
[Link]
test/
counter_test.dart
4. Create a class to test
Next, you need a “unit” to test. Remember: “unit” is another name for a function,
method, or class. For this example, create a Counter class inside the lib/[Link]
file. It is responsible for incrementing and decrementing a value starting at 0.
content_copy
class Counter {
int value = 0;
void increment() => value++;
void decrement() => value--;
Note: For simplicity, this tutorial does not follow the “Test Driven Development”
approach. If you’re more comfortable with that style of development, you can always
go that route.
5. Write a test for our class
Inside the counter_test.dart file, write the first unit test. Tests are defined using the
top-level test function, and you can check if the results are correct by using the top-
level expect function. Both of these functions come from the test package.
content_copy
// Import the test package and Counter class
import 'package:counter_app/[Link]';
import 'package:test/[Link]';
void main() {
test('Counter value should be incremented', () {
final counter = Counter();
[Link]();
expect([Link], 1);
});
6. Combine multiple tests in a group
If you want to run a series of related tests, use the flutter_test package group function
to categorize the tests. Once put into a group, you can call flutter test on all tests in
that group with one command.
content_copy
import 'package:counter_app/[Link]';
import 'package:test/[Link]';
void main() {
group('Test start, increment, decrement', () {
test('value should start at 0', () {
expect(Counter().value, 0);
});
test('value should be incremented', () {
final counter = Counter();
[Link]();
expect([Link], 1);
});
test('value should be decremented', () {
final counter = Counter();
[Link]();
expect([Link], -1);
});
});
7. Run the tests
Now that you have a Counter class with tests in place, you can run the tests.
Run tests using IntelliJ or VSCode
The Flutter plugins for IntelliJ and VSCode support running tests. This is often the
best option while writing tests because it provides the fastest feedback loop as well as
the ability to set breakpoints.
IntelliJ
Open the counter_test.dart file
Go to Run > Run ‘tests in counter_test.dart’. You can also press the appropriate
keyboard shortcut for your platform.
VSCode
Open the counter_test.dart file
Go to Run > Start Debugging. You can also press the appropriate keyboard shortcut
for your platform.
Run tests in a terminal
To run the all tests from the terminal, run the following command from the root of the
project:
content_copy
flutter test test/counter_test.dart
To run all tests you put into one group, run the following command from the root of
the project:
content_copy
flutter test --plain-name "Test start, increment, decrement"
This example uses the group created in section 5.
To learn more about unit tests, you can execute this command
Output: -
10.b) Use Flutter's debugging tools to identify and fix issues.
Flutter provides a set of debugging tools that can help you identify and fix issues
in your app. Here's a step-by-step guide on how to use these tools:
1. Flutter DevTools:
Run your app with the flutter run command.
Open DevTools by running the following command in your terminal:
bash
flutter pub global activate devtools
flutter pub global run devtools
Open your app in a Chrome browser and connect it to DevTools by clicking on the
"Open DevTools" button in the terminal or by navigating to [Link]
DevTools provides tabs like Inspector, Timeline, Memory, and more.
2. Flutter Inspector:
Use the Flutter Inspector in your integrated development environment (IDE) like
Android Studio or Visual Studio Code.
Toggle the Inspector in Android Studio with the shortcut Alt + Shift + D
(Windows/Linux) or Option + Shift + D (Mac).
Inspect the widget tree, modify widget properties, and observe widget relationships.
3. Hot Reload:
Leverage Hot Reload to see the immediate effect of code changes without restarting
the entire app.
Press R in the terminal or use the "Hot Reload" button in your IDE.
4. Debugging with Breakpoints:
Set breakpoints in your code to pause execution and inspect variables.
Use the debugger in your IDE to step through code and identify issues.
5. Logging:
Utilize the print function to log messages to the console.
print('Debugging message');
View logs in the terminal or the "Logs" tab in DevTools.
6. Debug Paint:
Enable debug paint to visualize the layout and rendering of widgets.
Use the debugPaintSizeEnabled and debugPaintBaselinesEnabled flags.
void main() {
debugPaintSizeEnabled = true; // Shows bounding boxes of widgets
runApp(MyApp());
7. Memory Profiling:
Use the "Memory" tab in DevTools to analyze memory usage and identify potential
memory leaks.
Monitor object allocations and deallocations.
8. Performance Profiling (Timeline):
Analyze app performance using the "Timeline" tab in DevTools.
Identify UI jank, slow frames, and performance bottlenecks.
9. Flutter Driver Tests:
Write automated UI tests using Flutter Driver.
Simulate user interactions and validate the correctness of your UI.