āļāļēāļĢāļāļāļŠāļāļ Flutter āļāļĒāđāļēāļāļāļĢāļāļāđāļ§āļ: Widget Test, Integration Test āđāļĨāļ°āļāļĨāļĒāļļāļāļāđāļŠāļąāļĄāļ āļēāļĐāļāđāļāļēāļāļŠāļēāļĒāđāļāļāļāļīāļ 2026
āļāļđāđāļĄāļ·āļāļāļēāļĢāļāļāļŠāļāļ Flutter āļāļāļąāļāļŠāļĄāļāļđāļĢāļāđ: widget test, integration test, golden test āđāļĨāļ° mocking āļāđāļ§āļĒ Mocktail āļāļĢāđāļāļĄāļāļąāļ§āļāļĒāđāļēāļāđāļāđāļāļāļĢāļīāļāđāļĨāļ°āđāļāļ§āļāļēāļāļāļĩāđāļāļāļāđāļāļĒāđāļāļāļēāļĢāļŠāļąāļĄāļ āļēāļĐāļāđāļāļēāļāļŠāļēāļĒāđāļāļāļāļīāļ 2026

āļāļēāļĢāļāļāļŠāļāļ Flutter āđāļāđāļāļāļąāļāļāļąāļĒāļŠāļģāļāļąāļāļāļĩāđāđāļĒāļāđāļāļāļāļĨāļīāđāļāļāļąāļāļĢāļ°āļāļąāļ production āļāļāļāļāļēāļ prototype āļāļąāđāļ§āđāļ Flutter āļĄāļĩāļĢāļ°āļāļāļāļēāļĢāļāļāļŠāļāļāđāļāļāļąāļ§āļŠāļēāļĄāļāļĢāļ°āđāļ āļ āđāļāđāđāļāđ unit, widget āđāļĨāļ° integration āđāļāļĒāđāļāđāļĨāļ°āļāļĢāļ°āđāļ āļāļĄāļļāđāļāđāļāđāļēāđāļāļāļĩāđāļāļąāđāļāļāļĩāđāđāļāļāļāđāļēāļāļāļąāļāļāļāļāđāļāļāļāļĨāļīāđāļāļāļąāļ āļāļāļāļ§āļēāļĄāļāļĩāđāļāļģāđāļŠāļāļ pattern āļāļēāļĢāļāļāļŠāļāļāļāļĩāđāđāļāđāđāļāđāļāļĢāļīāļāļŠāļģāļŦāļĢāļąāļ widget test, integration test, golden test āđāļĨāļ°āļāļĨāļĒāļļāļāļāđ mocking āļāļĩāđāļŠāļēāļĄāļēāļĢāļāļāļģāđāļāđāļāđāđāļāđāđāļāļĒāļāļĢāļāļāļąāđāļāđāļāļāļēāļāļāļąāļāļāļēāļāļĢāļ°āļāļģāļ§āļąāļāđāļĨāļ°āļāļēāļĢāļŠāļąāļĄāļ āļēāļĐāļāđāļāļēāļāļŠāļēāļĒāđāļāļāļāļīāļāđāļāļāļĩ 2026
āļāļļāļāļāļāļŠāļāļ Flutter āļāļĩāđāļĄāļĩāđāļāļĢāļāļŠāļĢāđāļēāļāļāļĩāļāļ°āđāļāđāļāđāļāļāļēāļĄāļāļīāļĢāļēāļĄāļīāļāļāļēāļĢāļāļāļŠāļāļ: unit test āļāļģāļāļ§āļāļĄāļēāļāļāļĩāđāļāļģāļāļēāļāđāļĢāđāļ§āļāļĒāļđāđāļāļēāļāļĨāđāļēāļ, widget test āļāļĩāđāđāļāđāļāđāļāļĢāđāļāļāļĒāļđāđāļāļąāđāļāļāļĨāļēāļ āđāļĨāļ° integration test āļāļģāļāļ§āļāļāđāļāļĒāļāļĩāđāđāļāļēāļ°āļāļāļāļĒāļđāđāļŠāđāļ§āļāļāļ Widget test āļāļģāļāļēāļāđāļāđāđāļāđāļ§āļĨāļēāđāļĄāđāļāļķāļāļŦāļāļķāđāļāļ§āļīāļāļēāļāļĩāđāļāļĒāđāļĄāđāļāđāļāļāđāļāđāļāļļāļāļāļĢāļāđ āļāļģāđāļŦāđāđāļāđāļāļāļąāđāļāļāļĩāđāđāļŦāđāļāļĨāļāļāļāđāļāļāļāļēāļāļāļēāļĢāļĨāļāļāļļāļāļāļĩāļāļĩāđāļŠāļļāļāļŠāļģāļŦāļĢāļąāļāđāļāļāļāļĨāļīāđāļāļāļąāļ Flutter āļŠāđāļ§āļāđāļŦāļāđ
āļāļ·āđāļāļāļēāļ Widget Testing āđāļ Flutter
Widget test āļāļĢāļ§āļāļŠāļāļāļŠāđāļ§āļāļāļĢāļ°āļāļāļ UI āđāļāļāđāļĒāļāļŠāđāļ§āļ āđāļāļĒāđāļĄāđāļāđāļāļāđāļāđ emulator āļŦāļĢāļ·āļāļāļļāļāļāļĢāļāđāļāļĢāļīāļ Flutter āļŠāļĢāđāļēāļ widget tree āđāļāļŠāļ āļēāļāđāļ§āļāļĨāđāļāļĄāļāļāļŠāļāļāđāļāļ headless āļāđāļ§āļĒāđāļŦāđāđāļāđ feedback loop āļāļĩāđāļĢāļ§āļāđāļĢāđāļ§āđāļāļ·āđāļāļāļĢāļ§āļāļāļąāļāļāļąāļāļŦāļēāļāđāļēāļ layout, event handler āđāļĨāļ°āļāļēāļĢāđāļāļĨāļĩāđāļĒāļāđāļāļĨāļ state āļāđāļāļāļāļĩāđāļāļ°āļāļđāļāļāļģāļāļķāđāļ production
Package flutter_test āļĄāļĩ testWidgets(), WidgetTester āļŠāļģāļŦāļĢāļąāļāļāļģāļĨāļāļāļāļēāļĢāđāļāđāļāļāļ āđāļĨāļ°āļāļĨāļēāļŠ Finder āļŠāļģāļŦāļĢāļąāļāļāđāļāļŦāļē widget āđāļ tree
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:my_app/counter_widget.dart';
void main() {
testWidgets('Counter increments on tap', (WidgetTester tester) async {
// Inflate the widget tree
await tester.pumpWidget(
const MaterialApp(home: CounterWidget()),
);
// Verify initial state
expect(find.text('0'), findsOneWidget);
expect(find.text('1'), findsNothing);
// Simulate user tap on the increment button
await tester.tap(find.byIcon(Icons.add));
await tester.pump(); // Rebuild after state change
// Assert updated state
expect(find.text('0'), findsNothing);
expect(find.text('1'), findsOneWidget);
});
}āļāļēāļĢāđāļĢāļĩāļĒāļ pump() āļāļ°āļāļĢāļīāļāđāļāļāļĢāđāļāļēāļĢ rebuild āļŦāļāļķāđāļ frame āļŠāļģāļŦāļĢāļąāļ animation āļŦāļĢāļ·āļāļāļēāļĢāļāļģāļāļēāļāļāļĩāđāļĄāļĩāļāļēāļĢāļŦāļāđāļ§āļāđāļ§āļĨāļē pumpAndSettle() āļāļ°āļĢāļāļāļāļāļ§āđāļē frame āļāļąāđāļāļŦāļĄāļāļāļ°āđāļŠāļĢāđāļāļŠāļĄāļāļđāļĢāļāđ āļāļēāļĢāļĢāļđāđāļ§āđāļēāļāļ§āļĢāđāļāđāđāļāđāļĨāļ°āļ§āļīāļāļĩāđāļĄāļ·āđāļāđāļāđāļāđāļāļāļģāļāļēāļĄāļŠāļąāļĄāļ āļēāļĐāļāđāļāļĩāđāļāļāļāđāļāļĒ āđāļāļĒ pump() āđāļŦāđāļāļēāļĢāļāļ§āļāļāļļāļĄāļāļĩāđāđāļĄāđāļāļĒāļģ āļāļāļ°āļāļĩāđ pumpAndSettle() āļŠāļ°āļāļ§āļāļāļ§āđāļēāđāļāđāļāļēāļāļāđāļēāļāļāļąāļ animation āđāļāļāđāļĄāđāļĄāļĩāļāļĩāđāļŠāļīāđāļāļŠāļļāļ
āļāļēāļĢāļāļāļŠāļāļ Async Operations āđāļĨāļ° Widget āļāļĩāđāļāļąāļāđāļāļĨāļ·āđāļāļāļāđāļ§āļĒ Stream
Widget āđāļāđāļĨāļāļāļĢāļīāļāļāļķāđāļāļāļēāļāļēāļĢāđāļĢāļĩāļĒāļ network, āļāļēāļāļāđāļāļĄāļđāļĨ āļŦāļĢāļ·āļ stream āļāļēāļĢāļāļāļŠāļāļāļŠāđāļ§āļāļāļĢāļ°āļāļāļāđāļŦāļĨāđāļēāļāļĩāđāļāđāļāļāļāļ§āļāļāļļāļĄāļāļĪāļāļīāļāļĢāļĢāļĄ async āļāļĒāđāļēāļāļāļąāļāđāļāļ WidgetTester āļāļģāļāļēāļāļĢāđāļ§āļĄāļāļąāļ event loop āļāļāļ Dart āđāļāđ āđāļāđ dependency āļ āļēāļĒāļāļāļāļāļģāđāļāđāļāļāđāļāļ mock āđāļāļ·āđāļāļŦāļĨāļĩāļāđāļĨāļĩāđāļĒāļ test āļāļĩāđāđāļĄāđāđāļŠāļāļĩāļĒāļĢ
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
import 'package:my_app/user_profile_widget.dart';
import 'package:my_app/user_repository.dart';
class MockUserRepository extends Mock implements UserRepository {}
void main() {
late MockUserRepository mockRepo;
setUp(() {
mockRepo = MockUserRepository();
});
testWidgets('displays user name after loading', (tester) async {
// Arrange: mock returns a user after a delay
when(() => mockRepo.fetchUser(1)).thenAnswer(
(_) async => User(id: 1, name: 'Alice'),
);
await tester.pumpWidget(
MaterialApp(
home: UserProfileWidget(repository: mockRepo),
),
);
// Assert: loading indicator visible initially
expect(find.byType(CircularProgressIndicator), findsOneWidget);
// Wait for the Future to complete and rebuild
await tester.pumpAndSettle();
// Assert: user name displayed, loader gone
expect(find.text('Alice'), findsOneWidget);
expect(find.byType(CircularProgressIndicator), findsNothing);
// Verify the repository was called exactly once
verify(() => mockRepo.fetchUser(1)).called(1);
});
}Mocktail āđāļāđāļāđāļĨāļāļĢāļēāļĢāļĩ mocking āļāļĩāđāđāļāļ°āļāļģāđāļāļĢāļ°āļāļāļāļīāđāļ§āļĻ Flutter āļŠāļģāļŦāļĢāļąāļāļāļĩ 2026 āļāđāļēāļāļāļēāļ Mockito āļāļĢāļāļāļĩāđ Mocktail āđāļĄāđāļāđāļāļāļāļēāļĢāļāļąāđāļāļāļāļ code generation āļāļģāđāļŦāđāļāļēāļĢāļāļąāđāļāļāđāļē test āđāļĢāđāļ§āļāļķāđāļ API when() / verify() āļāđāļēāļāļāđāļēāļĒāđāļĨāļ°āļāļĢāļāļāļāļĨāļļāļĄāļŠāļāļēāļāļāļēāļĢāļāđ dependency injection āļŠāđāļ§āļāđāļŦāļāđ
āļāļĨāļĒāļļāļāļāđ Mocking āļāđāļ§āļĒ Mocktail āļŠāļģāļŦāļĢāļąāļāđāļāđāļāļāļĢāđāļāļĄāļŠāļąāļĄāļ āļēāļĐāļāđ
āļāļđāđāļŠāļąāļĄāļ āļēāļĐāļāđāļĄāļąāļāļāļēāļĄāđāļāļĩāđāļĒāļ§āļāļąāļ dependency injection āđāļĨāļ°āļāļ§āļēāļĄāļŠāļēāļĄāļēāļĢāļāđāļāļāļēāļĢāļāļāļŠāļāļāđāļ Flutter Pattern āļāļĩāđāđāļāđāļāļ°āđāļāļāļāļĩāļāļĒāđāļēāļāļŠāļĄāđāļģāđāļŠāļĄāļāļāļ·āļ: constructor injection āļĢāđāļ§āļĄāļāļąāļ abstract class (āļŦāļĢāļ·āļ interface āļāđāļēāļāļĢāļ°āļāļ implicit interface āļāļāļ Dart)
abstract class WeatherService {
Future<Weather> getWeather(String city);
}
// real implementation
class OpenMeteoWeatherService implements WeatherService {
final http.Client _client;
OpenMeteoWeatherService(this._client);
Future<Weather> getWeather(String city) async {
final response = await _client.get(
Uri.parse('https://api.open-meteo.com/v1/forecast?city=$city'),
);
return Weather.fromJson(jsonDecode(response.body));
}
}class MockHttpClient extends Mock implements http.Client {}
void main() {
late MockHttpClient mockClient;
late OpenMeteoWeatherService service;
setUp(() {
mockClient = MockHttpClient();
service = OpenMeteoWeatherService(mockClient);
});
test('parses weather JSON correctly', () async {
// Arrange: return a known JSON payload
when(() => mockClient.get(any())).thenAnswer(
(_) async => http.Response(
'{"temperature": 22.5, "condition": "sunny"}',
200,
),
);
// Act
final weather = await service.getWeather('Paris');
// Assert
expect(weather.temperature, 22.5);
expect(weather.condition, 'sunny');
});
}Pattern āļāļĩāđ āļāļ·āļāļāļēāļĢāđāļĒāļ dependency āļ āļēāļĒāļāļāļāđāļ§āđāđāļāļ·āđāļāļāļŦāļĨāļąāļ interface āđāļĨāļ° inject mock āđāļāđāļēāđāļ āļŠāļēāļĄāļēāļĢāļāļāļģāđāļāđāļāđāđāļāđāđāļŦāļĄāļ·āļāļāļāļąāļāļāļąāļ repository, āļāļĢāļīāļāļēāļĢ analytics āđāļĨāļ° platform channel āļāļđāđāļŠāļąāļĄāļ āļēāļĐāļāđāđāļŦāđāļāļļāļāļāđāļēāļāļąāļāļāļēāļĢāđāļĒāļāļŠāđāļ§āļāļāļĩāđāđāļāļĢāļēāļ°āđāļŠāļāļāļāļķāļāļāļ§āļēāļĄāđāļāđāļēāđāļāļŦāļĨāļąāļāļāļēāļĢ SOLID āđāļĨāļ°āļŠāļāļēāļāļąāļāļĒāļāļĢāļĢāļĄāļāļĩāđāļāļĢāđāļāļĄāļŠāļģāļŦāļĢāļąāļ production
Integration Testing āļāđāļ§āļĒ Package integration_test
Integration test āļāļĢāļ§āļāļŠāļāļāļ§āđāļēāļŦāļĨāļēāļĒāļŠāđāļ§āļāļāļĢāļ°āļāļāļāļāļģāļāļēāļāļĢāđāļ§āļĄāļāļąāļāļāļāļāļļāļāļāļĢāļāđāļāļĢāļīāļāļŦāļĢāļ·āļ emulator Package integration_test āđāļāļāļąāļ§āđāļāđāļāļŠāļ°āļāļēāļāđāļāļ·āđāļāļĄāļĢāļ°āļŦāļ§āđāļēāļ API āļāļāļ flutter_test āļāļąāļāļāļēāļĢāļāļģāļāļēāļāļĢāļ°āļāļąāļāļāļļāļāļāļĢāļāđ
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:my_app/main.dart' as app;
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
testWidgets('complete login flow', (tester) async {
// Launch the full app
app.main();
await tester.pumpAndSettle();
// Navigate to login screen
await tester.tap(find.text('Sign In'));
await tester.pumpAndSettle();
// Fill in credentials
await tester.enterText(
find.byKey(const Key('email_field')),
'test@example.com',
);
await tester.enterText(
find.byKey(const Key('password_field')),
'securePassword123',
);
// Submit the form
await tester.tap(find.byKey(const Key('login_button')));
await tester.pumpAndSettle();
// Verify navigation to dashboard
expect(find.text('Dashboard'), findsOneWidget);
});
}Integration test āļĢāļąāļāļāđāļ§āļĒāļāļģāļŠāļąāđāļ flutter test integration_test/ āļāļēāļĢāļāļāļŠāļāļāđāļŦāļĨāđāļēāļāļĩāđāļāļģāļāļēāļāļāļāļāļļāļāļāļĢāļāđāļāļķāļāđāļāđāđāļ§āļĨāļēāļāļēāļāļāļ§āđāļē widget test āđāļāļ§āļāļēāļāļāļĩāđāđāļāļ°āļāļģāļāļ·āļ: āđāļāđāļ integration test āđāļāļāļĩāđ user flow āļāļĩāđāļŠāļģāļāļąāļ (login, checkout, onboarding) āđāļĨāļ°āļāļķāđāļāļāļē widget test āļŠāļģāļŦāļĢāļąāļāļāļĪāļāļīāļāļĢāļĢāļĄāļāļāļāđāļāđāļĨāļ°āļŦāļāđāļēāļāļ
āļŠāļģāļŦāļĢāļąāļāđāļāļāļāļĩāđāđāļāđāļāļāļāļāļąāļ UI āļāļāļ platform native āđāļāđāļ dialog āļāļāļŠāļīāļāļāļīāđ, push notification, prompt āļĒāļ·āļāļĒāļąāļāļāļąāļ§āļāļāļāđāļ§āļĒāđāļāđāļāđāļĄāļāļĢāļīāļ package Patrol āļāļĒāļēāļĒāļāļ§āļēāļĄāļŠāļēāļĄāļēāļĢāļāļāļēāļĢāļāļāļŠāļāļ Flutter āļāđāļ§āļĒāļāļēāļĢāļĢāļāļāļĢāļąāļ native automation
āļāļĢāđāļāļĄāļāļĩāđāļāļ°āļāļīāļāļīāļāļāļēāļĢāļŠāļąāļĄāļ āļēāļĐāļāđ Flutter āđāļĨāđāļ§āļŦāļĢāļ·āļāļĒāļąāļāļāļĢāļąāļ?
āļāļķāļāļāļāļāđāļ§āļĒāļāļąāļ§āļāļģāļĨāļāļāđāļāļāđāļāđāļāļāļ, flashcards āđāļĨāļ°āđāļāļāļāļāļŠāļāļāđāļāļāļāļīāļāļāļĢāļąāļ
Golden Test āļŠāļģāļŦāļĢāļąāļāļāļĢāļ§āļāļāļąāļ Visual Regression
Golden test āļāļąāļāļ āļēāļāļŦāļāđāļēāļāļāļāļāļ widget āļāļĩāđ render āđāļĨāđāļ§āđāļĨāļ°āđāļāļĢāļĩāļĒāļāđāļāļĩāļĒāļāļāļąāļāļ āļēāļ baseline āļāļ§āļēāļĄāđāļāļāļāđāļēāļāļĢāļ°āļāļąāļ pixel āđāļāļāđāļāļēāļĄāļāļ°āļāļģāđāļŦāđ test āļĨāđāļĄāđāļŦāļĨāļ§ āļāđāļ§āļĒāļāļĢāļ§āļāļāļąāļ visual regression āļāļĩāđāđāļĄāđāđāļāđāļāļąāđāļāđāļāļāđāļāļ deploy
Flutter 3.29+ āļĢāļāļāļĢāļąāļ golden test āđāļāļāļąāļ§ āļŠāļģāļŦāļĢāļąāļāļŠāļāļēāļāļāļēāļĢāļāđāļāļąāđāļāļŠāļđāļ āđāļāđāļ āļŦāļĨāļēāļĒāļāļāļēāļāļŦāļāđāļēāļāļ, theme, locale āļāđāļēāļāļāļąāļ Alchemist āļĄāļĩ API āļāļĩāđāļĄāļĩāđāļāļĢāļāļŠāļĢāđāļēāļāļāļąāļāđāļāļāđāļāļāļāļĩāđ golden_toolkit āļāļĩāđāļĒāļļāļāļīāļāļēāļĢāļāļąāļāļāļēāđāļĨāđāļ§
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:my_app/primary_button.dart';
void main() {
testWidgets('PrimaryButton matches golden file', (tester) async {
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: Center(
child: PrimaryButton(
label: 'Submit',
onPressed: () {},
),
),
),
),
);
// Compare against baseline image
await expectLater(
find.byType(PrimaryButton),
matchesGoldenFile('goldens/primary_button.png'),
);
});
}āļŠāļĢāđāļēāļāļ āļēāļ baseline āļāđāļ§āļĒāļāļģāļŠāļąāđāļ flutter test --update-goldens āđāļāđāļ golden file āđāļ§āđāđāļ version control Pipeline CI āļāļ§āļĢāļĢāļąāļ golden test āļāļ platform āļāļĩāđāļŠāļĄāđāļģāđāļŠāļĄāļ (container Linux āđāļāđāļāļĄāļēāļāļĢāļāļēāļ) āđāļāļ·āđāļāļŦāļĨāļĩāļāđāļĨāļĩāđāļĒāļāļāļ§āļēāļĄāđāļāļāļāđāļēāļāļāļāļ pixel āļĢāļ°āļŦāļ§āđāļēāļ platform
āļāļēāļĢāļāļąāļāđāļāļĢāļāļŠāļĢāđāļēāļāļāļļāļāļāļāļŠāļāļ Flutter āđāļŦāđāļāļĒāļēāļĒāđāļāđ
āļāļēāļĢāļāļąāļāļĢāļ°āđāļāļĩāļĒāļ test āļĄāļĩāļāļ§āļēāļĄāļŠāļģāļāļąāļāđāļĄāļ·āđāļ codebase āđāļāļīāļāđāļ Pattern āļāļĩāđāļāļĒāļēāļĒāđāļāđāļāļĩāļāļ·āļ: āļŠāļ°āļāđāļāļāđāļāļĢāļāļŠāļĢāđāļēāļāđāļāđāļĢāļāļāļāļĢāļĩ lib/ āļ āļēāļĒāđāļ test/ āđāļāļĒāđāļĒāļāļāļąāļāđāļāļāļĢāļ°āļŦāļ§āđāļēāļāļāļąāđāļ unit, widget āđāļĨāļ° integration
test/
unit/
services/
weather_service_test.dart
models/
user_test.dart
widget/
screens/
login_screen_test.dart
dashboard_test.dart
components/
primary_button_test.dart
goldens/
primary_button.png
integration_test/
login_flow_test.dart
checkout_flow_test.dartāđāļāđāļāļāļēāļĢāļāļąāđāļāļāđāļēāļāļĩāđāđāļāđāļĢāđāļ§āļĄāļāļąāļ āđāļāđāļ mock instance, factory āļāđāļāļĄāļđāļĨāļāļāļŠāļāļ, custom matcher āļāļ§āļĢāļāļĒāļđāđāđāļāđāļāđāļĢāļāļāļāļĢāļĩ test/helpers/ āļāļēāļĢāđāļāļĢāđāļŠāđāļ§āļāļāļĢāļ°āļāļāļāđāļŦāļĨāđāļēāļāļĩāđāļĢāļ°āļŦāļ§āđāļēāļāđāļāļĨāđ test āļāđāļ§āļĒāļĨāļāļāļ§āļēāļĄāļāđāļģāļāđāļāļāđāļāļĒāđāļĄāđāļŠāļĢāđāļēāļ coupling āļāļĩāđāđāļāđāļāđāļāļīāļāđāļ
āļāļąāļ§āļāļĩāđāļ§āļąāļāļŠāļģāļāļąāļāļāļĩāđāļāļ§āļĢāļāļīāļāļāļēāļĄāļāđāļ§āļĒāđāļāļĢāļ·āđāļāļāļĄāļ·āļ coverage āļāļāļ Flutter:
- Line coverage: āđāļāđāļēāļŦāļĄāļēāļĒ 80%+ āļŠāļģāļŦāļĢāļąāļ business logic, 60%+ āļŠāļģāļŦāļĢāļąāļāđāļāđāļ UI
- Branch coverage: āļāļĢāļ§āļāļŠāļāļāļ§āđāļē conditional path āļāļđāļāļāļāļŠāļāļāđāļĨāđāļ§
- āđāļ§āļĨāļēāļāļģāļāļēāļāļāļāļ test: unit + widget test āļāđāļģāļāļ§āđāļē 5 āļāļēāļāļĩ, integration test āļāđāļģāļāļ§āđāļē 30 āļāļēāļāļĩ
āļāļēāļĢāļĢāļąāļ flutter test --coverage āļāļ°āļŠāļĢāđāļēāļāđāļāļĨāđ lcov.info Pipeline CI āļŠāļēāļĄāļēāļĢāļāđāļāđ lcov āļŦāļĢāļ·āļ Codecov āđāļāļ·āđāļāđāļŠāļāļāļ āļēāļāđāļāļ§āđāļāđāļĄ coverage āđāļĨāļ°āļāļąāļāļāļąāļāđāļāđāđāļāļāļāđāļāļąāđāļāļāđāļģ
āļāļģāļāļēāļĄāļŠāļąāļĄāļ āļēāļĐāļāđāđāļāļĩāđāļĒāļ§āļāļąāļ Flutter Testing āļāļĩāđāļāļāļāđāļāļĒ
āļāļēāļĢāļŠāļąāļĄāļ āļēāļĐāļāđāļāļēāļāļŠāļēāļĒāđāļāļāļāļīāļāđāļāļāļĩ 2026 āļĄāļąāļāļĢāļ§āļĄāļŠāļāļēāļāļāļēāļĢāļāđāđāļāļĩāđāļĒāļ§āļāļąāļ Flutter testing āđāļāđāļāļāļĢāļ°āļāļģ āļāđāļāđāļāļāļĩāđāđāļāđāļ pattern āļāļĩāđāļāļāļāđāļāļĒāļāļĩāđāļŠāļļāļ āļāļēāļāļāđāļāļĄāļđāļĨāļāļĢāļīāļāļāļāļāļāļąāļāļāļąāļāļāļē Flutter
"āļāļ§āļēāļĄāđāļāļāļāđāļēāļāļĢāļ°āļŦāļ§āđāļēāļ pump() āļāļąāļ pumpAndSettle() āļāļ·āļāļāļ°āđāļĢ?"
pump() āļāļĢāļīāļāđāļāļāļĢāđāļāļēāļĢ rebuild āļŦāļāļķāđāļ frame āđāļāđāļēāļāļąāđāļ pumpAndSettle() āđāļĢāļĩāļĒāļ pump() āļāđāļģāļāļāļāļ§āđāļēāļāļ°āđāļĄāđāļĄāļĩ frame āļāļĩāđāļāļđāļāļāļąāļāļāļīāļ§āļāļĩāļ āđāļŦāļĄāļēāļ°āļŠāļģāļŦāļĢāļąāļ animation āđāļĨāļ°āļāļēāļĢāđāļāļĨāļĩāđāļĒāļ route āļāļļāļāļāļĩāđāļāđāļāļāļĢāļ°āļ§āļąāļ: pumpAndSettle() āļāļ° timeout āļāļąāļ widget āļāļĩāđāļĄāļĩ animation āđāļĄāđāļŠāļīāđāļāļŠāļļāļ (loading spinner, shimmer effect) āđāļŦāđāđāļāđ pump(Duration) āļŠāļģāļŦāļĢāļąāļāļāļĢāļāļĩāđāļŦāļĨāđāļēāļāļąāđāļ
"Widget test āļāđāļēāļāļāļēāļ integration test āļāļĒāđāļēāļāđāļĢ?"
Widget test āļāļģāļāļēāļāđāļāļŠāļ āļēāļāđāļ§āļāļĨāđāļāļĄ headless āđāļāļĒāđāļĄāđāļāđāļāļāđāļāđāļāļļāļāļāļĢāļāđ āļāļāļŠāļāļāļŠāđāļ§āļāļāļĢāļ°āļāļāļāđāļāļāđāļĒāļāļŠāđāļ§āļ Integration test āļāļģāļāļēāļāļāļāļāļļāļāļāļĢāļāđāļāļĢāļīāļāļŦāļĢāļ·āļ emulator āļāļāļŠāļāļāđāļāļāļāļąāđāļāļŦāļĄāļāļŦāļĢāļ·āļāļŠāđāļ§āļāđāļŦāļāđ Widget test āļāļģāļāļēāļāđāļĢāđāļ§ (āļĄāļīāļĨāļĨāļīāļ§āļīāļāļēāļāļĩ) āđāļĨāļ°āļāļ§āļĢāļĢāļąāļāđāļ CI āļāļļāļāļāļĢāļąāđāļāļāļĩāđ commit Integration test āļāđāļēāļāļ§āđāļē (āļāļēāļāļĩ) āđāļĨāļ°āļĄāļąāļāļĢāļąāļāđāļĄāļ·āđāļ merge āļŦāļĢāļ·āļ build āļāļĨāļēāļāļāļ·āļ
"āļāļ°āļāļāļŠāļāļ widget āļāļĩāđāļāļķāđāļāļāļē Provider āļŦāļĢāļ·āļ Riverpod āđāļāđāļāļĒāđāļēāļāđāļĢ?"
āļāļĢāļāļ widget āļāļĩāđāļāđāļāļāļāļēāļĢāļāļāļŠāļāļāļāđāļ§āļĒ provider scope āļāļĩāđāđāļŦāļĄāļēāļ°āļŠāļĄ āđāļĨāļ° inject override āđāļāļāļēāļ°āļŠāļģāļŦāļĢāļąāļāļāļēāļĢāļāļāļŠāļāļ:
// testing a Riverpod-dependent widget
import 'package:flutter_riverpod/flutter_riverpod.dart';
testWidgets('CartWidget shows item count', (tester) async {
await tester.pumpWidget(
ProviderScope(
overrides: [
// Override the cart provider with test data
cartProvider.overrideWith(
(ref) => CartNotifier(initialItems: [
CartItem(name: 'Widget Book', price: 29.99),
]),
),
],
child: const MaterialApp(home: CartWidget()),
),
);
expect(find.text('1 item'), findsOneWidget);
expect(find.text('\$29.99'), findsOneWidget);
});āđāļāļ§āļāļēāļāļāļĩāđāļŦāļĨāļĩāļāđāļĨāļĩāđāļĒāļāļāļēāļĢāļāļķāđāļāļāļē global state āđāļĨāļ°āļāļģāđāļŦāđāđāļāđāļĨāļ° test āļĄāļĩāļāļ§āļēāļĄ deterministic āļāļēāļĢāđāļāļĢāļĩāļĒāļĄāļāļģāļāļāļāļāļĢāđāļāļĄāļāļąāļ§āļāļĒāđāļēāļāđāļāđāļāļāļĩāđāđāļāđāļāļĢāļđāļāļāļĢāļĢāļĄ āđāļāļāļāļĩāđāļāļ°āđāļāđāļāļāļģāļāļāļīāļāļēāļĒāđāļāļīāļāļāļēāļĄāļāļĢāļĢāļĄ āđāļŦāđāļāļĨāļĨāļąāļāļāđāļāļĩāđāļāļĩāļāļ§āđāļēāđāļāļāļēāļĢāļŠāļąāļĄāļ āļēāļĐāļāđ Flutter āļāļĒāđāļēāļāļŠāļĄāđāļģāđāļŠāļĄāļ āļŠāļģāļŦāļĢāļąāļāļāļēāļĢāđāļāļĢāļĩāļĒāļĄāļāļąāļ§āļŠāļąāļĄāļ āļēāļĐāļāđ Flutter āđāļāļīāđāļĄāđāļāļīāļĄ āļŠāļēāļĄāļēāļĢāļāļĻāļķāļāļĐāļēāđāļĄāļāļđāļĨ widget testing āđāļĨāļ°āđāļĄāļāļđāļĨ unit testing āļāļ SharpSkill
āđāļĢāļīāđāļĄāļāļķāļāļāđāļāļĄāđāļĨāļĒ!
āļāļāļŠāļāļāļāļ§āļēāļĄāļĢāļđāđāļāļāļāļāļļāļāļāđāļ§āļĒāļāļąāļ§āļāļģāļĨāļāļāļŠāļąāļĄāļ āļēāļĐāļāđāđāļĨāļ°āđāļāļāļāļāļŠāļāļāđāļāļāļāļīāļāļāļĢāļąāļ
āļŠāļĢāļļāļ
- Widget test āđāļŦāđ ROI āļŠāļđāļāļŠāļļāļāđāļāđāļāļ Flutter āļāđāļ§āļĒāļāļēāļĢāļāļģāļāļēāļāļāļĩāđāđāļĢāđāļ§ āđāļĄāđāļāđāļāļāļāļķāđāļāļāļļāļāļāļĢāļāđ āđāļĨāļ°āļāļĢāļ§āļāļŠāļāļ UI āđāļāļĒāļāļĢāļāļāđāļēāļ
testWidgets()āđāļĨāļ°WidgetTester - āđāļāđ Mocktail āļŠāļģāļŦāļĢāļąāļ mock dependency: āđāļĄāđāļāđāļāļ codegen, API
when()/verify()āļāļĩāđāļŠāļ°āļāļēāļ āđāļĨāļ°āđāļāđāļēāļāļąāļāđāļāđāđāļāđāļĄāļĢāļđāļāđāļāļāļāļąāļāļĢāļ°āļāļ implicit interface āļāļāļ Dart - Integration test āļāļ§āļĢāđāļāđāļāđāļāļāļēāļ° user flow āļāļĩāđāļŠāļģāļāļąāļ (login, checkout, āļāļģāļĢāļ°āđāļāļīāļ) āđāļāđāļēāļāļąāđāļ āļāļģāđāļŦāđāđāļāļēāļ°āļāļāđāļĨāļ°āļĢāļąāļāđāļĄāļ·āđāļ merge āļŦāļĢāļ·āļāđāļ pipeline CI āļāļĨāļēāļāļāļ·āļ
- Golden test āļāļĢāļ§āļāļāļąāļ visual regression āđāļāļĒāļāļąāļāđāļāļĄāļąāļāļī āđāļāđāļ baseline āđāļ version control āđāļĨāļ°āļĢāļąāļāļāļ platform CI āļāļĩāđāļŠāļĄāđāļģāđāļŠāļĄāļāđāļāļ·āđāļāļŦāļĨāļĩāļāđāļĨāļĩāđāļĒāļāļāļ§āļēāļĄāđāļāļāļāđāļēāļāļāļāļ pixel āļĢāļ°āļŦāļ§āđāļēāļ OS
- āļŠāļ°āļāđāļāļāđāļāļĢāļāļŠāļĢāđāļēāļ
lib/āđāļāđāļāđāļĢāļāļāļāļĢāļĩtest/āļāļīāļāļāļēāļĄ coverage āļāđāļ§āļĒflutter test --coverageāđāļĨāļ°āļāļąāļāļāļąāļāđāļāđāđāļāļāļāđ 80%+ āļŠāļģāļŦāļĢāļąāļ business logic - āļāļēāļĢāđāļāļĢāļĩāļĒāļĄāļŠāļąāļĄāļ āļēāļĐāļāđ: āļāļķāļāļāļāļāļ§āļēāļĄāđāļāļāļāđāļēāļāļĢāļ°āļŦāļ§āđāļēāļ
pump()āļāļąāļpumpAndSettle(), override test Provider/Riverpod āđāļĨāļ° pattern constructor injection āļāļĢāđāļāļĄāļāļąāļ§āļāļĒāđāļēāļāđāļāđāļāļāļĩāđāđāļāđāļāļĢāļđāļāļāļĢāļĢāļĄ
āđāļĢāļīāđāļĄāļāļķāļāļāđāļāļĄāđāļĨāļĒ!
āļāļāļŠāļāļāļāļ§āļēāļĄāļĢāļđāđāļāļāļāļāļļāļāļāđāļ§āļĒāļāļąāļ§āļāļģāļĨāļāļāļŠāļąāļĄāļ āļēāļĐāļāđāđāļĨāļ°āđāļāļāļāļāļŠāļāļāđāļāļāļāļīāļāļāļĢāļąāļ

āđāļāļĩāļĒāļāđāļāļĒ
Anthony Fillion-MailletāļāļąāļāļāļąāļāļāļēāļāļđāļĨāļŠāđāļāļ āļāļđāđāļāđāļāļāļąāđāļ SharpSkill
āđāļāđāļāļāļąāļāļāļąāļāļāļēāļāļđāļĨāļŠāđāļāļāļĄāļēāļāļ§āđāļē 10 āļāļĩ āļāļđāđāļĨ SharpSkill āđāļĨāļ°āļĢāļąāļāļāļīāļāļāļāļāļāļļāļāļŠāļīāđāļāļāļĩāđāđāļāļĒāđāļāļĢāđāļāļĩāđāļāļĩāđ
āļāļąāļāđāļāļāđāļĄāļ·āđāļ 14 āļāļĪāļĐāļ āļēāļāļĄ 2569
āđāļāđāļ
āđāļāļĢāđ
āļāļāļāļ§āļēāļĄāļāļĩāđāđāļāļĩāđāļĒāļ§āļāđāļāļ

20 āļāļģāļāļēāļĄāļŠāļąāļĄāļ āļēāļĐāļāđāļāļēāļ Flutter āļāļĩāđāļāļāļāđāļāļĒāļāļĩāđāļŠāļļāļāļŠāļģāļŦāļĢāļąāļāļāļąāļāļāļąāļāļāļēāđāļāļāļĄāļ·āļāļāļ·āļ
āđāļāļĢāļĩāļĒāļĄāļāļąāļ§āļŠāļąāļĄāļ āļēāļĐāļāđāļāļēāļ Flutter āļāđāļ§āļĒāļāļģāļāļēāļĄ 20 āļāđāļāļāļĩāđāļāļđāļāļāļēāļĄāļāđāļāļĒāļāļĩāđāļŠāļļāļ āļāļĢāļāļāļāļĨāļļāļĄ Widget, State Management, Dart, āļŠāļāļēāļāļąāļāļĒāļāļĢāļĢāļĄ āđāļĨāļ°āđāļāļ§āļāļēāļāļāļāļīāļāļąāļāļīāļāļĩāđāļāļĩāļāļĩāđāļŠāļļāļ āļāļĢāđāļāļĄāļāļģāļāļāļīāļāļēāļĒāļāļĒāđāļēāļāļĨāļ°āđāļāļĩāļĒāļāđāļĨāļ°āļāļąāļ§āļāļĒāđāļēāļāđāļāđāļ

Flutter āđāļĨāļ° Dart 3: Records, Patterns āđāļĨāļ° Sealed Classes āļŠāļģāļŦāļĢāļąāļāļāļģāļāļēāļĄāļŠāļąāļĄāļ āļēāļĐāļāđāļāļąāđāļāļŠāļđāļ āļāļĩ 2026
āļāļđāđāļĄāļ·āļāđāļāļīāļāļĨāļķāļāđāļāļĩāđāļĒāļ§āļāļąāļ Dart 3 Records, Pattern Matching āđāļĨāļ° Sealed Classes āļāļĢāđāļāļĄāļāļąāļ§āļāļĒāđāļēāļāđāļāđāļāļāļĢāļīāļ āđāļŦāļĄāļēāļ°āļŠāļģāļŦāļĢāļąāļāđāļāļĢāļĩāļĒāļĄāļŠāļąāļĄāļ āļēāļĐāļāđāļāļēāļ Flutter Developer āđāļāļĢāļ°āļāļąāļ Senior āđāļĨāļ° Lead

Dart Isolates āđāļĨāļ° Concurrency 2026: compute, Async āđāļĨāļ°āļāļģāļāļēāļĄāļŠāļąāļĄāļ āļēāļĐāļāđ
āļāļđāđāļĄāļ·āļāļāļāļąāļāļŠāļĄāļāļđāļĢāļāđāđāļāļĩāđāļĒāļ§āļāļąāļ Dart isolates, āļāļąāļāļāđāļāļąāļ compute āđāļ Flutter āđāļĨāļ° pattern āļāļāļ concurrency āļŠāļģāļŦāļĢāļąāļāļāļēāļĢāļāļąāļāļāļēāđāļāļāļāļĩāđāļāļāļāļŠāļāļāļāļĢāļ§āļāđāļĢāđāļ§āđāļāļāļĩ 2026