# Flutter Verification

> Use when verifying Flutter applications - covers widget tests, integration tests, golden tests, performance testing, and build validation

- Skill: `tomevault-io/flutter-verification` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add tomevault-io/flutter-verification`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tomevault-io/flutter-verification/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Integrations & APIs
- Author: tomevault-io (https://skillmd.com/u/tomevault-io)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tomevault-io/flutter-verification

---


# Flutter Verification and Testing

Comprehensive Flutter verification patterns covering widget tests, integration tests, golden tests, performance testing, platform verification, accessibility, build validation, asset verification, localization coverage, and code quality checks.

## Widget Testing Fundamentals

### Basic Widget Tests

```dart
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/material.dart';

void main() {
  group('CounterWidget', () {
    testWidgets('displays initial count', (WidgetTester tester) async {
      // Build the widget
      await tester.pumpWidget(
        const MaterialApp(
          home: CounterWidget(initialCount: 5),
        ),
      );

      // Verify initial state
      expect(find.text('5'), findsOneWidget);
      expect(find.text('6'), findsNothing);
    });

    testWidgets('increments counter on button tap', (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: CounterWidget(initialCount: 0),
        ),
      );

      // Find and tap the increment button
      final incrementButton = find.byIcon(Icons.add);
      await tester.tap(incrementButton);
      await tester.pump(); // Trigger rebuild

      // Verify updated state
      expect(find.text('1'), findsOneWidget);
    });

    testWidgets('enters text in input field', (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: FormWidget(),
        ),
      );

      // Find text field
      final textField = find.byType(TextField);

      // Enter text
      await tester.enterText(textField, 'Hello Flutter');
      await tester.pump();

      // Verify text was entered
      expect(find.text('Hello Flutter'), findsOneWidget);
    });
  });
}
```

### Advanced Widget Finders

```dart
void main() {
  testWidgets('finds widgets using various finders', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          appBar: AppBar(title: const Text('Test App')),
          body: Column(
            children: [
              const Text('Welcome', key: Key('welcome-text')),
              ElevatedButton(
                onPressed: () {},
                child: const Text('Submit'),
              ),
              const Icon(Icons.home),
            ],
          ),
        ),
      ),
    );

    // Find by text
    expect(find.text('Welcome'), findsOneWidget);
    expect(find.text('Submit'), findsOneWidget);

    // Find by key
    expect(find.byKey(const Key('welcome-text')), findsOneWidget);

    // Find by type
    expect(find.byType(ElevatedButton), findsOneWidget);
    expect(find.byType(Icon), findsOneWidget);

    // Find by icon
    expect(find.byIcon(Icons.home), findsOneWidget);

    // Find by widget
    expect(find.byWidget(const Text('Welcome', key: Key('welcome-text'))), findsOneWidget);

    // Find descendant
    expect(
      find.descendant(
        of: find.byType(AppBar),
        matching: find.text('Test App'),
      ),
      findsOneWidget,
    );

    // Find ancestor
    expect(
      find.ancestor(
        of: find.text('Welcome'),
        matching: find.byType(Column),
      ),
      findsOneWidget,
    );

    // Find with predicate
    expect(
      find.byWidgetPredicate(
        (widget) => widget is Text && widget.data == 'Welcome',
      ),
      findsOneWidget,
    );
  });
}
```

### Testing User Interactions

```dart
void main() {
  testWidgets('handles complex user interactions', (WidgetTester tester) async {
    await tester.pumpWidget(const MaterialApp(home: TodoApp()));

    // Enter text in todo input
    await tester.enterText(find.byType(TextField), 'Buy groceries');
    await tester.pump();

    // Tap add button
    await tester.tap(find.byIcon(Icons.add));
    await tester.pump();

    // Verify todo was added
    expect(find.text('Buy groceries'), findsOneWidget);

    // Long press on todo
    await tester.longPress(find.text('Buy groceries'));
    await tester.pumpAndSettle(); // Wait for animations

    // Verify context menu appeared
    expect(find.text('Delete'), findsOneWidget);

    // Tap delete
    await tester.tap(find.text('Delete'));
    await tester.pumpAndSettle();

    // Verify todo was deleted
    expect(find.text('Buy groceries'), findsNothing);
  });

  testWidgets('handles scrolling', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: ListView.builder(
            itemCount: 100,
            itemBuilder: (context, index) => ListTile(
              title: Text('Item $index'),
            ),
          ),
        ),
      ),
    );

    // Verify first item is visible
    expect(find.text('Item 0'), findsOneWidget);
    expect(find.text('Item 50'), findsNothing);

    // Scroll to item
    await tester.scrollUntilVisible(
      find.text('Item 50'),
      500.0, // Scroll delta
    );
    await tester.pumpAndSettle();

    // Verify item is now visible
    expect(find.text('Item 50'), findsOneWidget);

    // Drag to scroll
    await tester.drag(find.byType(ListView), const Offset(0, -300));
    await tester.pumpAndSettle();
  });

  testWidgets('handles gestures', (WidgetTester tester) async {
    await tester.pumpWidget(const MaterialApp(home: GestureTestWidget()));

    // Tap
    await tester.tap(find.byType(GestureDetector));
    await tester.pump();

    // Double tap
    await tester.tap(find.byType(GestureDetector));
    await tester.pump(const Duration(milliseconds: 50));
    await tester.tap(find.byType(GestureDetector));
    await tester.pumpAndSettle();

    // Drag
    await tester.drag(find.byType(GestureDetector), const Offset(100, 0));
    await tester.pumpAndSettle();

    // Fling
    await tester.fling(find.byType(GestureDetector), const Offset(0, -200), 1000);
    await tester.pumpAndSettle();
  });
}
```

### Testing Async Operations

```dart
void main() {
  testWidgets('handles async data loading', (WidgetTester tester) async {
    await tester.pumpWidget(const MaterialApp(home: AsyncDataWidget()));

    // Initially shows loading indicator
    expect(find.byType(CircularProgressIndicator), findsOneWidget);
    expect(find.text('Data loaded'), findsNothing);

    // Wait for async operation to complete
    await tester.pumpAndSettle();

    // Verify data is loaded
    expect(find.byType(CircularProgressIndicator), findsNothing);
    expect(find.text('Data loaded'), findsOneWidget);
  });

  testWidgets('handles delayed animations', (WidgetTester tester) async {
    await tester.pumpWidget(const MaterialApp(home: AnimatedWidget()));

    // Pump frames for specific duration
    await tester.pump(const Duration(milliseconds: 100));
    await tester.pump(const Duration(milliseconds: 200));

    // Or pump until all animations complete
    await tester.pumpAndSettle();
  });

  testWidgets('tests with fake async', (WidgetTester tester) async {
    await tester.runAsync(() async {
      // Code that uses real async operations
      final response = await http.get(Uri.parse('https://api.example.com/data'));
      expect(response.statusCode, 200);
    });
  });
}
```

### Mocking Dependencies

```dart
import 'package:mockito/mockito.dart';
import 'package:mockito/annotations.dart';

// Generate mocks
@GenerateMocks([UserRepository, AuthService])
void main() {
  late MockUserRepository mockUserRepository;
  late MockAuthService mockAuthService;

  setUp(() {
    mockUserRepository = MockUserRepository();
    mockAuthService = MockAuthService();
  });

  testWidgets('displays user data from repository', (WidgetTester tester) async {
    // Setup mock
    when(mockUserRepository.getUser('123'))
        .thenAnswer((_) async => User(id: '123', name: 'John Doe'));

    // Build widget with mock
    await tester.pumpWidget(
      MaterialApp(
        home: UserProfilePage(
          userId: '123',
          repository: mockUserRepository,
        ),
      ),
    );

    // Wait for async operation
    await tester.pumpAndSettle();

    // Verify user data is displayed
    expect(find.text('John Doe'), findsOneWidget);

    // Verify repository was called
    verify(mockUserRepository.getUser('123')).called(1);
  });

  testWidgets('handles authentication errors', (WidgetTester tester) async {
    // Setup mock to throw error
    when(mockAuthService.login(any, any))
        .thenThrow(AuthException('Invalid credentials'));

    await tester.pumpWidget(
      MaterialApp(
        home: LoginPage(authService: mockAuthService),
      ),
    );

    // Enter credentials
    await tester.enterText(find.byKey(const Key('email')), 'test@example.com');
    await tester.enterText(find.byKey(const Key('password')), 'wrong_password');

    // Tap login
    await tester.tap(find.text('Login'));
    await tester.pumpAndSettle();

    // Verify error message is shown
    expect(find.text('Invalid credentials'), findsOneWidget);

    // Verify login was attempted
    verify(mockAuthService.login('test@example.com', 'wrong_password')).called(1);
  });
}
```

## Integration Testing

### Full App Integration Tests

```dart
// integration_test/app_test.dart
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();

  group('end-to-end test', () {
    testWidgets('complete user flow', (WidgetTester tester) async {
      // Start the app
      app.main();
      await tester.pumpAndSettle();

      // Verify splash screen or initial page
      expect(find.text('Welcome'), findsOneWidget);

      // Navigate to login
      await tester.tap(find.text('Sign In'));
      await tester.pumpAndSettle();

      // Enter credentials
      await tester.enterText(find.byType(TextField).first, 'test@example.com');
      await tester.enterText(find.byType(TextField).at(1), 'password123');

      // Submit login
      await tester.tap(find.text('Login'));
      await tester.pumpAndSettle(const Duration(seconds: 3));

      // Verify home page
      expect(find.text('Home'), findsOneWidget);

      // Navigate through app
      await tester.tap(find.byIcon(Icons.settings));
      await tester.pumpAndSettle();

      expect(find.text('Settings'), findsOneWidget);

      // Logout
      await tester.tap(find.text('Logout'));
      await tester.pumpAndSettle();

      // Verify back at welcome screen
      expect(find.text('Welcome'), findsOneWidget);
    });

    testWidgets('data persistence across app restarts', (WidgetTester tester) async {
      app.main();
      await tester.pumpAndSettle();

      // Add data
      await tester.tap(find.byIcon(Icons.add));
      await tester.pumpAndSettle();
      await tester.enterText(find.byType(TextField), 'Test item');
      await tester.tap(find.text('Save'));
      await tester.pumpAndSettle();

      // Verify data exists
      expect(find.text('Test item'), findsOneWidget);

      // Restart app
      await tester.restartAndRestore();

      // Verify data persisted
      expect(find.text('Test item'), findsOneWidget);
    });
  });

  group('navigation flow', () {
    testWidgets('deep linking works correctly', (WidgetTester tester) async {
      app.main();
      await tester.pumpAndSettle();

      // Simulate deep link
      // This depends on your routing setup
      await tester.tap(find.text('Open Product'));
      await tester.pumpAndSettle();

      expect(find.text('Product Details'), findsOneWidget);
    });

    testWidgets('back button navigation', (WidgetTester tester) async {
      app.main();
      await tester.pumpAndSettle();

      // Navigate forward
      await tester.tap(find.text('Next Page'));
      await tester.pumpAndSettle();

      // Press back
      await tester.pageBack();
      await tester.pumpAndSettle();

      // Verify returned to previous page
      expect(find.text('Home'), findsOneWidget);
    });
  });
}
```

### Multi-Screen Integration Tests

```dart
void main() {
  IntegrationTestWidgetsFlutterBinding.ensureInitialized();

  testWidgets('e-commerce checkout flow', (WidgetTester tester) async {
    app.main();
    await tester.pumpAndSettle();

    // Browse products
    expect(find.text('Products'), findsOneWidget);

    // Add item to cart
    await tester.tap(find.text('Add to Cart').first);
    await tester.pumpAndSettle();

    // Verify cart badge
    expect(find.text('1'), findsOneWidget);

    // Go to cart
    await tester.tap(find.byIcon(Icons.shopping_cart));
    await tester.pumpAndSettle();

    // Verify item in cart
    expect(find.text('Cart'), findsOneWidget);
    expect(find.text('Product Name'), findsOneWidget);

    // Proceed to checkout
    await tester.tap(find.text('Checkout'));
    await tester.pumpAndSettle();

    // Fill shipping info
    await tester.enterText(find.byKey(const Key('address')), '123 Main St');
    await tester.enterText(find.byKey(const Key('city')), 'Springfield');
    await tester.enterText(find.byKey(const Key('zip')), '12345');

    // Continue to payment
    await tester.tap(find.text('Continue'));
    await tester.pumpAndSettle();

    // Enter payment details
    await tester.enterText(find.byKey(const Key('card_number')), '4242424242424242');
    await tester.enterText(find.byKey(const Key('expiry')), '12/25');
    await tester.enterText(find.byKey(const Key('cvv')), '123');

    // Complete purchase
    await tester.tap(find.text('Place Order'));
    await tester.pumpAndSettle(const Duration(seconds: 5));

    // Verify order confirmation
    expect(find.text('Order Confirmed'), findsOneWidget);
    expect(find.textContaining('Order #'), findsOneWidget);
  });
}
```

### Testing with Real APIs (Optional)

```dart
void main() {
  IntegrationTestWidgetsFlutterBinding.ensureInitialized();

  group('API integration tests', () {
    testWidgets('fetches and displays real data', (WidgetTester tester) async {
      app.main();
      await tester.pumpAndSettle();

      // Wait for API call to complete
      await tester.pumpAndSettle(const Duration(seconds: 5));

      // Verify data from API is displayed
      expect(find.byType(ListTile), findsWidgets);
    });

    testWidgets('handles network errors gracefully', (WidgetTester tester) async {
      // Configure app to use invalid API endpoint
      app.main(apiUrl: 'https://invalid-url-that-will-fail.com');
      await tester.pumpAndSettle();

      // Wait for error state
      await tester.pumpAndSettle(const Duration(seconds: 5));

      // Verify error message is shown
      expect(find.text('Unable to load data'), findsOneWidget);

      // Test retry functionality
      await tester.tap(find.text('Retry'));
      await tester.pumpAndSettle(const Duration(seconds: 5));
    });
  });
}
```

## Golden Tests (Visual Regression Testing)

### Basic Golden Tests

```dart
void main() {
  testWidgets('matches golden file', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(
        home: Scaffold(
          body: Center(
            child: Text('Hello World'),
          ),
        ),
      ),
    );

    // Compare against golden file
    await expectLater(
      find.byType(MaterialApp),
      matchesGoldenFile('golden/hello_world.png'),
    );
  });

  testWidgets('matches golden with custom size', (WidgetTester tester) async {
    // Set specific screen size
    await tester.binding.setSurfaceSize(const Size(400, 600));

    await tester.pumpWidget(
      MaterialApp(
        home: ProductCard(
          title: 'Test Product',
          price: '\$99.99',
          imageUrl: 'https://example.com/image.jpg',
        ),
      ),
    );

    await expectLater(
      find.byType(ProductCard),
      matchesGoldenFile('golden/product_card.png'),
    );

    // Reset size
    await tester.binding.setSurfaceSize(null);
  });
}
```

### Golden Tests for Different States

```dart
void main() {
  group('button states golden tests', () {
    testWidgets('default state', (WidgetTester tester) async {
      await tester.pumpWidget(
        MaterialApp(
          home: ElevatedButton(
            onPressed: () {},
            child: const Text('Click Me'),
          ),
        ),
      );

      await expectLater(
        find.byType(ElevatedButton),
        matchesGoldenFile('golden/button_default.png'),
      );
    });

    testWidgets('disabled state', (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: ElevatedButton(
            onPressed: null,
            child: Text('Click Me'),
          ),
        ),
      );

      await expectLater(
        find.byType(ElevatedButton),
        matchesGoldenFile('golden/button_disabled.png'),
      );
    });

    testWidgets('hover state', (WidgetTester tester) async {
      await tester.pumpWidget(
        MaterialApp(
          home: ElevatedButton(
            onPressed: () {},
            child: const Text('Click Me'),
          ),
        ),
      );

      // Simulate hover
      final gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
      await gesture.addPointer(location: Offset.zero);
      addTearDown(gesture.removePointer);
      await tester.pump();

      await gesture.moveTo(tester.getCenter(find.byType(ElevatedButton)));
      await tester.pumpAndSettle();

      await expectLater(
        find.byType(ElevatedButton),
        matchesGoldenFile('golden/button_hover.png'),
      );
    });
  });
}
```

### Golden Tests for Themes

```dart
void main() {
  group('theme golden tests', () {
    testWidgets('light theme', (WidgetTester tester) async {
      await tester.pumpWidget(
        MaterialApp(
          theme: ThemeData.light(),
          home: const HomePage(),
        ),
      );

      await expectLater(
        find.byType(MaterialApp),
        matchesGoldenFile('golden/home_page_light.png'),
      );
    });

    testWidgets('dark theme', (WidgetTester tester) async {
      await tester.pumpWidget(
        MaterialApp(
          theme: ThemeData.dark(),
          home: const HomePage(),
        ),
      );

      await expectLater(
        find.byType(MaterialApp),
        matchesGoldenFile('golden/home_page_dark.png'),
      );
    });
  });
}
```

### Golden Tests for Responsive Layouts

```dart
void main() {
  group('responsive layout golden tests', () {
    testWidgets('mobile layout', (WidgetTester tester) async {
      await tester.binding.setSurfaceSize(const Size(375, 667)); // iPhone SE

      await tester.pumpWidget(
        const MaterialApp(home: ResponsivePage()),
      );

      await expectLater(
        find.byType(ResponsivePage),
        matchesGoldenFile('golden/responsive_mobile.png'),
      );
    });

    testWidgets('tablet layout', (WidgetTester tester) async {
      await tester.binding.setSurfaceSize(const Size(768, 1024)); // iPad

      await tester.pumpWidget(
        const MaterialApp(home: ResponsivePage()),
      );

      await expectLater(
        find.byType(ResponsivePage),
        matchesGoldenFile('golden/responsive_tablet.png'),
      );
    });

    testWidgets('desktop layout', (WidgetTester tester) async {
      await tester.binding.setSurfaceSize(const Size(1920, 1080));

      await tester.pumpWidget(
        const MaterialApp(home: ResponsivePage()),
      );

      await expectLater(
        find.byType(ResponsivePage),
        matchesGoldenFile('golden/responsive_desktop.png'),
      );
    });

    tearDown(() async {
      await tester.binding.setSurfaceSize(null);
    });
  });
}
```

## Performance Testing

### Frame Rendering Performance

```dart
import 'package:flutter/scheduler.dart';

void main() {
  testWidgets('measures frame rendering performance', (WidgetTester tester) async {
    await tester.pumpWidget(const MaterialApp(home: PerformanceTestPage()));

    // Start performance tracking
    final timeline = await tester.binding.traceAction(() async {
      // Perform action that triggers animations
      await tester.tap(find.byIcon(Icons.play_arrow));

      // Let animation run for 2 seconds
      await tester.pumpAndSettle(const Duration(seconds: 2));
    });

    // Analyze timeline
    final summary = TimelineSummary.summarize(timeline);

    // Assert performance metrics
    expect(summary.countFrames(), greaterThan(0));

    // Check for frame drops (frames taking longer than 16ms)
    final frameTimes = summary.computeFrameTimes();
    final droppedFrames = frameTimes.where((time) => time > const Duration(milliseconds: 16));

    expect(droppedFrames.length, lessThan(frameTimes.length * 0.1)); // Less than 10% dropped frames
  });

  testWidgets('tests scrolling performance', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: ListView.builder(
            itemCount: 10000,
            itemBuilder: (context, index) => ListTile(
              title: Text('Item $index'),
              leading: const CircleAvatar(),
              subtitle: Text('Subtitle $index'),
            ),
          ),
        ),
      ),
    );

    final timeline = await tester.binding.traceAction(() async {
      // Perform fast scroll
      await tester.fling(
        find.byType(ListView),
        const Offset(0, -5000),
        5000,
      );
      await tester.pumpAndSettle();
    });

    final summary = TimelineSummary.summarize(timeline);

    // Verify smooth scrolling
    expect(summary.countFrames(), greaterThan(30)); // At least 30 frames

    final avgFrameTime = summary.computeAverageFrameTime();
    expect(avgFrameTime.inMilliseconds, lessThan(16)); // Under 60fps threshold
  });
}
```

### Memory Profiling

```dart
void main() {
  testWidgets('monitors memory usage', (WidgetTester tester) async {
    await tester.pumpWidget(const MaterialApp(home: MemoryTestPage()));

    // Get initial memory
    final initialMemory = tester.binding.window.physicalSize.width *
                          tester.binding.window.physicalSize.height * 4;

    // Perform memory-intensive operations
    for (int i = 0; i < 100; i++) {
      await tester.tap(find.text('Add Image'));
      await tester.pump();
    }

    await tester.pumpAndSettle();

    // Check for memory leaks by ensuring widgets are properly disposed
    // This is a simplified check - use DevTools for detailed memory profiling
    await tester.pumpWidget(Container());
    await tester.pump();

    // Verify no lingering state
  });

  testWidgets('checks for widget rebuild efficiency', (WidgetTester tester) async {
    int buildCount = 0;

    await tester.pumpWidget(
      MaterialApp(
        home: StatefulBuilder(
          builder: (context, setState) {
            buildCount++;
            return Column(
              children: [
                const Text('Static Widget'),
                ElevatedButton(
                  onPressed: () => setState(() {}),
                  child: const Text('Rebuild'),
                ),
              ],
            );
          },
        ),
      ),
    );

    final initialBuildCount = buildCount;

    // Trigger rebuild
    await tester.tap(find.text('Rebuild'));
    await tester.pump();

    // Should only rebuild once
    expect(buildCount, equals(initialBuildCount + 1));
  });
}
```

### Timeline Analysis

```dart
import 'dart:convert';
import 'dart:io';

void main() {
  testWidgets('generates performance report', (WidgetTester tester) async {
    await tester.pumpWidget(const MaterialApp(home: TestPage()));

    final timeline = await tester.binding.traceAction(() async {
      // Complex UI operations
      await tester.tap(find.text('Load Data'));
      await tester.pumpAndSettle();

      await tester.drag(find.byType(ListView), const Offset(0, -500));
      await tester.pumpAndSettle();
    });

    final summary = TimelineSummary.summarize(timeline);

    // Write summary to file
    await summary.writeSummaryToFile('performance_summary', pretty: true);
    await summary.writeTimelineToFile('timeline', pretty: true);

    // Analyze specific events
    final buildEvents = timeline.events!
        .where((event) => event.name == 'Frame')
        .toList();

    print('Total frames: ${buildEvents.length}');

    // Check for expensive operations
    final expensiveEvents = timeline.events!
        .where((event) => event.duration != null && event.duration!.inMilliseconds > 100)
        .toList();

    expect(expensiveEvents, isEmpty, reason: 'Found expensive operations');
  });
}
```

## Platform Testing

### iOS and Android Build Verification

```bash
# In your test script or CI/CD pipeline

# Android build verification
flutter build apk --debug
flutter build apk --release --no-shrink
flutter build appbundle --release

# iOS build verification (requires macOS)
flutter build ios --debug --no-codesign
flutter build ios --release --no-codesign

# Verify build outputs exist
test -f build/app/outputs/flutter-apk/app-release.apk
test -f build/app/outputs/bundle/release/app-release.aab
test -d build/ios/iphoneos/Runner.app
```

### Platform-Specific Tests

```dart
import 'dart:io';

void main() {
  group('platform-specific tests', () {
    testWidgets('iOS specific behavior', (WidgetTester tester) async {
      // Skip on non-iOS platforms
      if (!Platform.isIOS) {
        return;
      }

      await tester.pumpWidget(const MaterialApp(home: PlatformTestPage()));

      // Test iOS-specific features
      expect(find.byType(CupertinoNavigationBar), findsOneWidget);
    }, skip: !Platform.isIOS);

    testWidgets('Android specific behavior', (WidgetTester tester) async {
      if (!Platform.isAndroid) {
        return;
      }

      await tester.pumpWidget(const MaterialApp(home: PlatformTestPage()));

      // Test Android-specific features
      expect(find.byType(AppBar), findsOneWidget);
    }, skip: !Platform.isAndroid);
  });

  testWidgets('tests platform adaptive widgets', (WidgetTester tester) async {
    await tester.pumpWidget(const MaterialApp(home: AdaptiveWidget()));

    if (Platform.isIOS) {
      expect(find.byType(CupertinoButton), findsOneWidget);
    } else {
      expect(find.byType(ElevatedButton), findsOneWidget);
    }
  });
}
```

### Testing Platform Channels

```dart
import 'package:flutter/services.dart';

void main() {
  const channel = MethodChannel('com.example.app/native');

  setUp(() {
    // Mock method channel
    TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
        .setMockMethodCallHandler(channel, (MethodCall call) async {
      switch (call.method) {
        case 'getBatteryLevel':
          return 85;
        case 'getDeviceInfo':
          return {
            'model': 'Test Device',
            'os': 'Test OS',
            'version': '1.0.0',
          };
        default:
          throw MissingPluginException();
      }
    });
  });

  tearDown(() {
    TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
        .setMockMethodCallHandler(channel, null);
  });

  testWidgets('calls native platform method', (WidgetTester tester) async {
    await tester.pumpWidget(const MaterialApp(home: BatteryWidget()));

    // Trigger platform method call
    await tester.tap(find.text('Get Battery Level'));
    await tester.pumpAndSettle();

    // Verify result
    expect(find.text('Battery: 85%'), findsOneWidget);
  });

  test('handles platform exceptions', () async {
    expect(
      () async => await channel.invokeMethod('invalidMethod'),
      throwsA(isA<MissingPluginException>()),
    );
  });
}
```

## Accessibility Verification

### Semantic Labels

```dart
void main() {
  testWidgets('verifies semantic labels', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          appBar: AppBar(title: const Text('Test')),
          body: Column(
            children: [
              IconButton(
                icon: const Icon(Icons.home),
                onPressed: () {},
                tooltip: 'Go to home',
              ),
              const Text('Welcome'),
              Image.asset(
                'assets/logo.png',
                semanticLabel: 'Company logo',
              ),
            ],
          ),
        ),
      ),
    );

    // Verify semantic labels exist
    expect(
      tester.getSemantics(find.byType(IconButton)),
      matchesSemantics(
        label: 'Go to home',
        isButton: true,
      ),
    );

    expect(
      tester.getSemantics(find.byType(Image)),
      matchesSemantics(label: 'Company logo'),
    );
  });

  testWidgets('ensures all interactive elements are accessible', (WidgetTester tester) async {
    await tester.pumpWidget(const MaterialApp(home: AccessibilityTestPage()));

    // Find all interactive widgets
    final buttons = find.byType(ElevatedButton);
    final iconButtons = find.byType(IconButton);
    final textFields = find.byType(TextField);

    // Verify each has semantic label or tooltip
    for (final finder in [buttons, iconButtons, textFields]) {
      final count = tester.widgetList(finder).length;
      for (int i = 0; i < count; i++) {
        final semantics = tester.getSemantics(finder.at(i));
        expect(
          semantics.label,
          isNotEmpty,
          reason: 'Interactive element at index $i missing semantic label',
        );
      }
    }
  });
}
```

### Screen Reader Testing

```dart
void main() {
  testWidgets('tests screen reader navigation order', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Semantics(
          sortKey: const OrdinalSortKey(0),
          child: Column(
            children: [
              Semantics(
                sortKey: const OrdinalSortKey(1),
                child: const Text('First'),
              ),
              Semantics(
                sortKey: const OrdinalSortKey(2),
                child: const Text('Second'),
              ),
              Semantics(
                sortKey: const OrdinalSortKey(3),
                child: const Text('Third'),
              ),
            ],
          ),
        ),
      ),
    );

    // Verify semantic order
    final semantics = tester.getSemantics(find.byType(Column));
    // Verify reading order matches intended order
  });

  testWidgets('verifies live regions for dynamic content', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Semantics(
          liveRegion: true,
          child: const DynamicContentWidget(),
        ),
      ),
    );

    // Trigger content update
    await tester.tap(find.text('Update'));
    await tester.pumpAndSettle();

    // Verify screen reader is notified
    final semantics = tester.getSemantics(find.byType(DynamicContentWidget));
    expect(semantics.hasFlag(SemanticsFlag.isLiveRegion), isTrue);
  });
}
```

### Contrast and Text Scaling

```dart
void main() {
  testWidgets('verifies text scales correctly', (WidgetTester tester) async {
    await tester.pumpWidget(
      MediaQuery(
        data: const MediaQueryData(textScaleFactor: 1.0),
        child: MaterialApp(
          home: const Text('Normal Text'),
        ),
      ),
    );

    final normalSize = tester.getSize(find.text('Normal Text'));

    // Test with large text
    await tester.pumpWidget(
      MediaQuery(
        data: const MediaQueryData(textScaleFactor: 2.0),
        child: MaterialApp(
          home: const Text('Normal Text'),
        ),
      ),
    );

    final largeSize = tester.getSize(find.text('Normal Text'));

    // Verify text scales
    expect(largeSize.height, greaterThan(normalSize.height));
  });

  testWidgets('verifies sufficient color contrast', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Container(
          color: Colors.black,
          child: const Text(
            'White on Black',
            style: TextStyle(color: Colors.white),
          ),
        ),
      ),
    );

    // Manual contrast checking (in real tests, use contrast calculation)
    // WCAG AA requires 4.5:1 for normal text, 3:1 for large text
    // White on black has 21:1 ratio - excellent contrast
  });
}
```

## Build Verification

### Build Configuration Tests

```dart
// test/build_config_test.dart
import 'dart:io';
import 'package:flutter_test/flutter_test.dart';
import 'package:yaml/yaml.dart';

void main() {
  test('pubspec.yaml has correct version', () {
    final file = File('pubspec.yaml');
    final yaml = loadYaml(file.readAsStringSync());

    expect(yaml['version'], matches(RegExp(r'^\d+\.\d+\.\d+\+\d+$')));
  });

  test('android build.gradle has correct settings', () {
    final file = File('android/app/build.gradle');
    final content = file.readAsStringSync();

    expect(content, contains('minSdkVersion 21'));
    expect(content, contains('targetSdkVersion 33'));
    expect(content, contains('compileSdkVersion 33'));
  });

  test('iOS Podfile has correct platform version', () {
    final file = File('ios/Podfile');
    final content = file.readAsStringSync();

    expect(content, contains("platform :ios, '12.0'"));
  });

  test('release builds have correct signing config', () {
    final androidFile = File('android/app/build.gradle');
    final androidContent = androidFile.readAsStringSync();

    expect(androidContent, contains('signingConfig signingConfigs.release'));

    // For iOS, check in project.pbxproj or export options
    final iosFile = File('ios/Runner.xcodeproj/project.pbxproj');
    if (iosFile.existsSync()) {
      final iosContent = iosFile.readAsStringSync();
      expect(iosContent, contains('CODE_SIGN_IDENTITY'));
    }
  });
}
```

### App Signing Verification

```bash
#!/bin/bash
# verify_signing.sh

# Android APK verification
echo "Verifying Android APK signing..."
apksigner verify --verbose build/app/outputs/flutter-apk/app-release.apk

if [ $? -eq 0 ]; then
    echo "Android APK signing verified"
else
    echo "Android APK signing failed"
    exit 1
fi

# Android Bundle verification
echo "Verifying Android Bundle signing..."
jarsigner -verify -verbose -certs build/app/outputs/bundle/release/app-release.aab

if [ $? -eq 0 ]; then
    echo "Android Bundle signing verified"
else
    echo "Android Bundle signing failed"
    exit 1
fi

# iOS IPA verification (requires macOS)
if [[ "$OSTYPE" == "darwin"* ]]; then
    echo "Verifying iOS IPA signing..."
    codesign -dv --verbose=4 build/ios/iphoneos/Runner.app

    if [ $? -eq 0 ]; then
        echo "iOS app signing verified"
    else
        echo "iOS app signing failed"
        exit 1
    fi
fi
```

## Asset Verification

### Asset Existence Tests

```dart
// test/asset_test.dart
import 'dart:io';
import 'package:flutter_test/flutter_test.dart';
import 'package:yaml/yaml.dart';

void main() {
  group('asset verification', () {
    test('all declared assets exist', () {
      final pubspec = File('pubspec.yaml');
      final yaml = loadYaml(pubspec.readAsStringSync());

      final assets = yaml['flutter']?['assets'] as List?;
      if (assets != null) {
        for (final asset in assets) {
          final assetPath = asset.toString();

          if (assetPath.endsWith('/')) {
            // Directory - check it exists
            final dir = Directory(assetPath);
            expect(dir.existsSync(), isTrue, reason: 'Asset directory $assetPath does not exist');
          } else {
            // File - check it exists
            final file = File(assetPath);
            expect(file.existsSync(), isTrue, reason: 'Asset file $assetPath does not exist');
          }
        }
      }
    });

    test('no unused assets in project', () {
      // Find all asset references in code
      final assetReferences = <String>{};

      // Scan lib directory for asset references
      final libDir = Directory('lib');
      libDir.listSync(recursive: true).forEach((entity) {
        if (entity is File && entity.path.endsWith('.dart')) {
          final content = entity.readAsStringSync();
          final regex = RegExp(r"['\"]assets/[^'\"]+['\"]");
          final matches = regex.allMatches(content);
          for (final match in matches) {
            assetReferences.add(match.group(0)!.replaceAll("'", '').replaceAll('"', ''));
          }
        }
      });

      // Check all assets are referenced
      final pubspec = File('pubspec.yaml');
      final yaml = loadYaml(pubspec.readAsStringSync());
      final assets = yaml['flutter']?['assets'] as List?;

      if (assets != null) {
        for (final asset in assets) {
          if (!asset.toString().endsWith('/')) {
            expect(
              assetReferences.contains(asset.toString()),
              isTrue,
              reason: 'Asset $asset is declared but never used',
            );
          }
        }
      }
    });

    test('images have appropriate sizes', () {
      final imageDir = Directory('assets/images');
      if (!imageDir.existsSync()) return;

      imageDir.listSync(recursive: true).forEach((entity) {
        if (entity is File &&
            (entity.path.endsWith('.png') ||
             entity.path.endsWith('.jpg') ||
             entity.path.endsWith('.jpeg'))) {
          final size = entity.lengthSync();

          // Warn if image is larger than 1MB
          expect(
            size,
            lessThan(1024 * 1024),
            reason: 'Image ${entity.path} is larger than 1MB (${size} bytes). Consider compressing.',
          );
        }
      });
    });
  });
}
```

### Font Verification

```dart
void main() {
  test('all declared fonts exist', () {
    final pubspec = File('pubspec.yaml');
    final yaml = loadYaml(pubspec.readAsStringSync());

    final fonts = yaml['flutter']?['fonts'] as List?;
    if (fonts != null) {
      for (final fontFamily in fonts) {
        final fontList = fontFamily['fonts'] as List;
        for (final font in fontList) {
          final fontPath = font['asset'].toString();
          final file = File(fontPath);
          expect(
            file.existsSync(),
            isTrue,
            reason: 'Font file $fontPath does not exist',
          );
        }
      }
    }
  });

  testWidgets('custom fonts load correctly', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: const Text(
          'Custom Font',
          style: TextStyle(fontFamily: 'CustomFont'),
        ),
      ),
    );

    // Verify text renders without errors
    expect(find.text('Custom Font'), findsOneWidget);
  });
}
```

## Localization Coverage

### ARB File Completeness

```dart
// test/localization_test.dart
import 'dart:convert';
import 'dart:io';
import 'package:flutter_test/flutter_test.dart';

void main() {
  group('localization coverage', () {
    test('all locales have same keys as template', () {
      final l10nDir = Directory('lib/l10n');
      if (!l10nDir.existsSync()) return;

      // Load template ARB (usually English)
      final templateFile = File('lib/l10n/app_en.arb');
      final templateContent = json.decode(templateFile.readAsStringSync()) as Map<String, dynamic>;

      // Get all translation keys (excluding metadata keys starting with @)
      final templateKeys = templateContent.keys
          .where((key) => !key.startsWith('@'))
          .toSet();

      // Check each locale
      l10nDir.listSync().forEach((entity) {
        if (entity is File &&
            entity.path.endsWith('.arb') &&
            !entity.path.endsWith('app_en.arb')) {

          final localeContent = json.decode(entity.readAsStringSync()) as Map<String, dynamic>;
          final localeKeys = localeContent.keys
              .where((key) => !key.startsWith('@'))
              .toSet();

          // Check for missing keys
          final missingKeys = templateKeys.difference(localeKeys);
          expect(
          

…(truncated)
