Skip to content

Latest commit

 

History

History
330 lines (246 loc) · 17.4 KB

File metadata and controls

330 lines (246 loc) · 17.4 KB

Flutter Testing : Answers

  1. What is unit testing, and why is it important in Flutter? Unit testing verifies the functionality of individual components. It is important for identifying bugs early, ensuring code correctness, and facilitating refactoring.

  2. How do you write a simple unit test in Flutter? A simple unit test can be written using the test function:

    import 'package:test/test.dart';
    
    void main() {
      test('String should return length 3', () {
        var str = 'abc';
        expect(str.length, 3);
      });
    }
  3. What is widget testing, and how does it differ from unit testing? Widget testing checks the UI and interactions of a widget in isolation. Unlike unit tests, which focus on logic, widget tests ensure that the UI behaves as expected.

  4. How do you write a widget test in Flutter? You write a widget test using the testWidgets function:

    import 'package:flutter_test/flutter_test.dart';
    
    void main() {
      testWidgets('Counter increments smoke test', (WidgetTester tester) async {
        await tester.pumpWidget(MyApp());
        expect(find.text('0'), findsOneWidget);
        await tester.tap(find.byIcon(Icons.add));
        await tester.pump();
        expect(find.text('1'), findsOneWidget);
      });
    }
  5. What is integration testing in Flutter, and why is it important? Integration testing evaluates how multiple components work together. It is important for ensuring that the complete app behaves as expected and that interactions between modules function correctly.

  6. How do you write an integration test in Flutter? Integration tests are written in the integration_test package:

    import 'package:integration_test/integration_test.dart';
    import 'package:flutter_test/flutter_test.dart';
    
    void main() {
      IntegrationTestWidgetsFlutterBinding.ensureInitialized();
    
      testWidgets('Integration test example', (WidgetTester tester) async {
        // Your test code here
      });
    }
  7. What is the purpose of the testWidgets function in Flutter? The testWidgets function is used to create widget tests, allowing for testing of widgets and their interactions with the widget tree.

  8. How do you mock dependencies in Flutter tests? Dependencies can be mocked using packages like mockito or mocktail, allowing you to replace real implementations with controlled, test-specific behavior.

  9. What is the flutter_test package, and how is it used? The flutter_test package provides testing utilities and functions specifically for Flutter apps, including support for widget testing, matchers, and more.

  10. How do you use the expect function in Flutter tests? The expect function is used to assert that a certain condition is true in tests:

    expect(value, matcher);
  11. What is the Mocktail package, and how is it used for mocking in tests? Mocktail is a Dart package for creating mock objects without the need for code generation. It is used to create lightweight mock implementations of classes for testing.

  12. How do you run tests in Flutter? Tests can be run using the command:

    flutter test
  13. What is the test package in Dart, and how is it used in Flutter testing? The test package provides a framework for writing tests in Dart. In Flutter, it is often used for unit tests and integrates with the flutter_test package for widget tests.

  14. How do you test asynchronous code in Flutter? Asynchronous code can be tested using the async and await keywords in your test functions to wait for Future results.

  15. What is the Finder class in Flutter testing? The Finder class is used to locate widgets in the widget tree during tests. It provides methods like find.byType and find.byKey to locate specific widgets.

  16. How do you use the pump method in widget tests? The pump method is called to rebuild the widget tree in widget tests:

    await tester.pump();
  17. What is the Golden test in Flutter, and how is it used? Golden tests compare the UI of a widget against a "golden" image. They are used for visual regression testing to ensure UI changes don't alter the expected appearance.

  18. How do you write a test for a custom widget? A test for a custom widget can be written using the testWidgets function:

    testWidgets('Custom widget test', (WidgetTester tester) async {
      await tester.pumpWidget(CustomWidget());
      // Add assertions here
    });
  19. What is the BlocTest function in Flutter? BlocTest is a utility from the flutter_bloc package that simplifies testing BLoCs by providing built-in methods for asserting state changes and events.

  20. How do you test state management in Flutter? State management can be tested by creating tests for your state management solution (e.g., BLoC, Provider) to ensure correct state transitions and behaviors.

  21. What is the Mock class in Flutter testing? The Mock class is part of the mockito package, allowing you to create mock implementations of interfaces or classes for testing purposes.

  22. How do you verify interactions with mock objects in Flutter tests? Interactions can be verified using methods like verify from the mockito package:

    verify(mockObject.methodCall());
  23. What is the StreamMatcher class in Flutter testing? The StreamMatcher class is used to match expected values emitted from Streams in tests, allowing for validation of asynchronous data flows.

  24. How do you test error states in Flutter? Error states can be tested by simulating error conditions and asserting that the appropriate UI or state changes occur in response.

  25. What is the setUp function in Flutter tests? The setUp function is called before each test runs, allowing you to initialize variables or set up test conditions.

  26. How do you test animations in Flutter? Animations can be tested by using the pump method with a duration to simulate time passing:

    await tester.pumpAndSettle();
  27. What is the integration_test package in Flutter? The integration_test package provides a framework for writing integration tests, focusing on testing the complete app in a real environment.

  28. How do you test HTTP requests in Flutter? HTTP requests can be tested using mock HTTP clients or packages like http_mock_adapter to simulate server responses.

  29. What is the mockito package, and how is it used in Flutter testing? The mockito package is used for creating mock objects and verifying interactions in tests, making it easier to isolate and test components.

  30. How do you test navigation in Flutter? Navigation can be tested by simulating user interactions that trigger navigation and asserting that the expected pages are displayed.

  31. What is the tearDown function in Flutter tests? The tearDown function is called after each test runs, allowing for cleanup of resources or resetting state.

  32. How do you test user interactions in Flutter? User interactions can be tested using the tap, drag, and other interaction methods available in the WidgetTester class.

  33. What is the expectLater function in Flutter tests? The expectLater function is used for asynchronous expectations, allowing for assertions that complete after some asynchronous operation.

  34. How do you test forms in Flutter? Forms can be tested by filling out fields, simulating submissions, and asserting that validation and state changes occur correctly.

  35. What is a Fake class in Flutter testing? A Fake class provides a lightweight implementation of a dependency for testing purposes, often used to simulate behavior without complexity.

  36. How do you test JSON serialization in Flutter? JSON serialization can be tested by creating tests that check the conversion from and to JSON format for model classes.

  37. What is TestWidgetsFlutterBinding in Flutter? TestWidgetsFlutterBinding is a class that binds the Flutter framework to the test environment, allowing for widget testing to interact with the app's lifecycle.

  38. How do you test platform channels in Flutter? Platform channels can be tested using mock channels to simulate communication between Flutter and native code.

  39. What is the testbed package in Flutter? The testbed package provides a testing environment for Flutter applications, allowing for easier setup of tests involving dependencies and environment configuration.

  40. How do you test theme changes in Flutter? Theme changes can be tested by updating the theme in the widget tree and asserting that the UI reflects the expected theme.

  41. What is the widgetTester in Flutter testing? The widgetTester is an instance of WidgetTester used in widget tests to interact with the widget tree and perform actions like finding widgets and pumping frames.

  42. How do you test accessibility features in Flutter? Accessibility features can be tested by ensuring that widgets are correctly marked as accessible, and using tools like the accessibility inspector to verify compliance.

  43. What is the test_driver package in Flutter? The test_driver package is used for writing integration tests that run on a device or emulator

, allowing for end-to-end testing of Flutter applications.

  1. How do you test performance in Flutter? Performance can be tested using the flutter_driver package to measure frame rendering times and resource usage during tests.

  2. What is the testRecording function in Flutter? The testRecording function allows capturing interactions and state during tests, which can be useful for debugging and validation.

  3. How do you test scrollable widgets in Flutter? Scrollable widgets can be tested by simulating scrolling actions and asserting that the correct items are visible.

  4. What is the dart_test.yaml file in Flutter? The dart_test.yaml file is used to configure test runners in Dart, specifying test settings, dependencies, and any necessary configurations.

  5. How do you test native integrations in Flutter? Native integrations can be tested using mock channels and ensuring that the expected data flows between Flutter and the native platform.

  6. What is testFixtures in Flutter testing? testFixtures allows for reusable test data and setup configurations, enabling easier and cleaner test organization.

  7. How do you run tests on multiple devices in Flutter? Tests can be run on multiple devices using CI/CD tools or by specifying device targets in your test commands.

Modern testing practices (2026)

  1. What is the testing pyramid for a Flutter app, and what kind of tests live at each level?

    • Unit tests (test/ directory, flutter test) — pure Dart, no widgets, no I/O. Largest slice; should be hundreds or thousands. Test domain logic, formatters, repositories with mocked dependencies.
    • Widget tests — pump a widget tree, fire gestures, assert visible result. Medium slice; one per screen at minimum.
    • Golden tests — pixel-comparison for visual regressions; cover the canonical states (loading, empty, error, populated) × (light, dark) × (LTR, RTL).
    • Integration tests (integration_test/) — drive the real app on a real device or emulator; fewest in number, slowest, but indispensable for happy-path flows.
  2. How do you write a golden test for a widget that adapts to dark mode and RTL? Use testGoldens + screenMatchesGolden from golden_toolkit, or matchesGoldenFile from flutter_test. Pump variants of the widget under each theme/locale and snapshot each.

    testWidgets('PostCard renders in 4 modes', (tester) async {
      for (final brightness in [Brightness.light, Brightness.dark]) {
        for (final dir in [TextDirection.ltr, TextDirection.rtl]) {
          await tester.pumpWidget(MaterialApp(
            theme: ThemeData(brightness: brightness),
            home: Directionality(textDirection: dir, child: const PostCard()),
          ));
          await expectLater(
            find.byType(PostCard),
            matchesGoldenFile('goldens/post_card_${brightness}_$dir.png'),
          );
        }
      }
    });

    Run with flutter test --update-goldens to regenerate after intentional UI changes.

  3. What is the patrol package, and when does it beat integration_test? patrol extends integration_test with the ability to interact with native dialogs (permission prompts, biometric prompts, Wi-Fi pickers), grant runtime permissions, control Bluetooth/airplane mode, and dismiss notifications. Plain integration_test cannot touch native dialogs because the Dart side has no view of them. Use patrol when your test must approve a runtime permission or dismiss a system prompt.

    patrolTest('login flow with biometric prompt', ($) async {
      await $.pumpWidgetAndSettle(const MyApp());
      await $('Sign in with Face ID').tap();
      await $.native.tap(Selector(text: 'OK'));   // native dialog
      await $('Welcome back').waitUntilVisible();
    });
  4. How does mocktail replace mockito for modern Dart tests? mocktail does not require code generation — no @GenerateMocks, no build_runner step — and it works with sound null safety out of the box. mockito historically required nullable-aware fallbacks via provideDummy or generated mocks via mockito_codegen. For new Flutter projects, mocktail is friction-free; mockito remains common in legacy projects.

    class MockUserRepo extends Mock implements UserRepo {}
    
    test('shows error when load fails', () async {
      final repo = MockUserRepo();
      when(() => repo.fetch()).thenThrow(Exception('boom'));
      // ... pump and assert
    });
  5. How do you test a Notifier/AsyncNotifier (Riverpod 2.x) in isolation? Use ProviderContainer to construct a scope, override dependencies, and read the notifier directly. No widget tree required.

    test('cart adds item', () {
      final container = ProviderContainer(overrides: [
        productApiProvider.overrideWithValue(FakeProductApi()),
      ]);
      addTearDown(container.dispose);
    
      final cart = container.read(cartNotifierProvider.notifier);
      cart.add(const CartItem(id: 'a', qty: 1));
      expect(container.read(cartNotifierProvider), hasLength(1));
    });
  6. What is flutter_test's pumpAndSettle vs pump, and when does each loop forever?

    • pump(duration) — runs one frame after duration. Useful for animations driven by AnimationController where you know the duration.
    • pumpAndSettle() — pumps frames until no scheduled frames remain. Convenient for finishing animations or async builders. pumpAndSettle hangs forever when something keeps scheduling frames: a repeating animation, an unfinished Timer, a constantly-firing Stream. Replace it with a fixed pump(Duration(seconds: 1)) in such cases.
  7. How do you test a StreamProvider whose data source is an external API? Override the underlying repository with a fake StreamController so you can emit events on demand.

    test('feedProvider emits new posts', () async {
      final controller = StreamController<List<Post>>();
      final container = ProviderContainer(overrides: [
        feedRepoProvider.overrideWithValue(FakeFeedRepo(controller.stream)),
      ]);
      final sub = container.listen(feedProvider, (_, __) {});
    
      controller.add([Post(id: '1', title: 'Hello')]);
      await container.read(feedProvider.future);
      expect(container.read(feedProvider).value, hasLength(1));
    
      await controller.close();
      sub.close();
      container.dispose();
    });
  8. How do you measure test coverage for Flutter, and what is a realistic coverage target?

    flutter test --coverage
    genhtml coverage/lcov.info -o coverage/html

    Realistic targets: 70–80% for domain layer (pure Dart logic), 50–60% for presentation (widget tests are expensive to write), 30–40% overall for a real-world app. Don't chase 100% — many widget code paths exist only for very specific platform states and aren't worth the test cost.

  9. How do you make widget tests deterministic when they depend on time, network, or randomness?

    • Time — wrap DateTime.now() calls behind a Clock interface and inject a fake. Use tester.binding.delayed(...) to advance fake time.
    • Network — never hit real HTTP; mock the HTTP client or, better, mock the higher-level repository.
    • Randomness — inject a Random instance with a fixed seed. Determinism is a property of design, not of testing tools — if your code is hard to test deterministically, the dependencies aren't injected enough.
  10. What is mockito's nullable argument-matcher problem, and how does mocktail avoid it? Under sound null safety, Mockito-generated mocks can't return null for non-nullable return types without an explicit provideDummy<T>(...) registration or generated mocks. This is friction for ad-hoc tests. mocktail uses registerFallbackValue only for argument matchers (any()) on non-primitive types, and never requires return-type registration — when(() => repo.fetch()).thenAnswer((_) async => Result(...)) just works.