flutter-testing-apps — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited flutter-testing-apps (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Write tests test-first: red (failing test), green (minimum code to pass), refactor. Every suite must keep the FIRST properties:
inspection.
Every suite must cover three path classes, not just the happy path:
allowed).
Target around 90% line coverage of real logic. Measure it with flutter test --coverage, which writes coverage/lcov.info. Never weaken or delete an assertion to make a test green; fix the code or the test setup instead.
Balance your testing suite across three main categories to optimize for confidence, maintenance cost, dependencies, and execution speed.
#### Unit Tests Use unit tests to verify the correctness of a single function, method, or class under various conditions.
test or flutter_test package.#### Widget Tests Use widget tests (component tests) to ensure a single widget's UI looks and interacts as expected.
WidgetTester.Finder classes to locate widgets and Matcher constants to verify their existence and state.#### Integration Tests Use integration tests (end-to-end or GUI testing) to validate how individual pieces of an app work together and to capture performance metrics on real devices.
integration_test package as a dependency.Design your application for observability and testability. Ensure all components can be tested both in isolation and together.
testing frameworks.
HTTP clients, local databases).
isolate the UI.
Fake implementations of your repositories (e.g., FakeUserRepository) over usingmocking libraries when testing ViewModels and Views to ensure well-defined inputs and outputs.
When testing plugins, combine Dart tests with native platform tests to ensure full coverage across the method channel.
android/src/test/.example/ios/RunnerTests/ and example/macos/RunnerTests/.linux/test/ and windows/test/.communication.
method channel entry point using native unit tests, and test the Dart public API using Dart unit tests.
#### Workflow: Implementing a Component Test Suite Copy and track this checklist when implementing tests for a new architectural feature.
Fake implementations for any new Repositories or Services.flutter test --coverage and confirm around 90% line coverage of real logic before declaring done.#### Workflow: Running Integration Tests Follow conditional logic based on the target platform when executing integration tests.
flutter test integration_test/app_test.dartchromedriver --port=4444flutter drive --driver=test_driver/integration_test.dart --target=integration_test/app_test.dart -d chromexvfb-run to provide a display environment.xvfb-run flutter test integration_test/app_test.dart -d linuxflutter build apk --debug and ./gradlew app:assembleAndroidTest#### Example: ViewModel Unit Test Demonstrates testing a ViewModel using a Fake Repository.
import 'package:flutter_test/flutter_test.dart';
void main() {
group('HomeViewModel tests', () {
test('Load bookings successfully', () {
// Given a repository seeded with exactly one known booking
final viewModel = HomeViewModel(
bookingRepository: FakeBookingRepository()..createBooking(kBooking),
userRepository: FakeUserRepository(),
);
// When reading the exposed bookings
final bookings = viewModel.bookings;
// Then the count and the booking content match the seeded data
expect(bookings, hasLength(1));
expect(bookings.single.id, kBooking.id);
expect(bookings.single.title, kBooking.title);
});
});
}#### Example: View Widget Test Demonstrates testing a View by pumping a localized widget tree with fake dependencies.
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
group('HomeScreen tests', () {
late HomeViewModel viewModel;
late FakeBookingRepository bookingRepository;
setUp(() {
bookingRepository = FakeBookingRepository()..createBooking(kBooking);
viewModel = HomeViewModel(
bookingRepository: bookingRepository,
userRepository: FakeUserRepository(),
);
});
testWidgets('renders bookings list', (WidgetTester tester) async {
// Given a HomeScreen wired to a view model with one seeded booking
// When the widget is pumped and the first frame is built
await tester.pumpWidget(
MaterialApp(
home: HomeScreen(viewModel: viewModel),
),
);
// Then the list renders and the seeded booking is visible
expect(find.byType(ListView), findsOneWidget);
expect(find.text('Booking 1'), findsOneWidget);
});
});
}#### Example: Integration Test Demonstrates a full end-to-end test using the integration_test package.
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:my_app/main.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
group('end-to-end test', () {
testWidgets('tap on the floating action button, verify counter', (tester) async {
// Given the app loaded at its initial counter state of 0
await tester.pumpWidget(const MyApp());
expect(find.text('0'), findsOneWidget);
// When the increment button is tapped and the frame settles
final fab = find.byKey(const ValueKey('increment'));
await tester.tap(fab);
await tester.pumpAndSettle();
// Then the counter advances to exactly 1
expect(find.text('1'), findsOneWidget);
});
});
}~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.