.cursor/skills/testing/SKILL.md
Testing for Serbia Open Data Explorer. Writes and validates tests for API clients, Riverpod providers, and Flutter widgets. USE WHEN: writing new tests, verifying test coverage, running the test suite.
npx skillsauth add rus89/serbia_open_data_explorer testingInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
data.gov.rs API. Do not use mockito or any mock framework.@Tags(['integration']) so they can be run separately.ProviderScope with real or overridden providers.// ABOUTME: ).flutter test # All tests (integration + unit)
flutter test --exclude-tags=integration # Widget/unit tests only (fast, no network)
flutter test --tags=integration # Integration tests only (requires network)
flutter test test/path/to/test.dart # Single file
flutter analyze # Static analysis (must be clean before commit)
// ABOUTME: Tests for DataGovRsApiClient against the live data.gov.rs API.
// ABOUTME: Requires network access. Tagged 'integration'.
import 'package:flutter_test/flutter_test.dart';
import 'package:serbia_open_data_explorer/src/data/api/data_gov_rs_api_client.dart';
@Tags(['integration'])
void main() {
late DataGovRsApiClient client;
setUp(() {
client = DataGovRsApiClient(baseUrl: 'https://data.gov.rs/api/1/');
});
test('searchDatasets returns list', () async {
final response = await client.searchDatasets(page: 1, limit: 5);
expect(response.data, isA<List>());
}, timeout: const Timeout(Duration(seconds: 30)));
}
// ABOUTME: Widget tests for DatasetListScreen.
// ABOUTME: Uses ProviderScope with provider overrides for fast, isolated tests.
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('shows loading indicator while fetching', (tester) async {
await tester.pumpWidget(
ProviderScope(
child: MaterialApp(home: DatasetListScreen()),
),
);
expect(find.byType(CircularProgressIndicator), findsOneWidget);
});
}
// ABOUTME: Tests for Riverpod dataset providers.
// ABOUTME: Verifies provider state transitions with real API.
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:serbia_open_data_explorer/src/data/providers/dataset_providers.dart';
@Tags(['integration'])
void main() {
test('datasetSearchResultsProvider returns data', () async {
final container = ProviderContainer();
addTearDown(container.dispose);
final result = await container.read(datasetSearchResultsProvider.future);
expect(result.data, isNotEmpty);
}, timeout: const Timeout(Duration(seconds: 30)));
}
| What | Where |
|------|-------|
| API client tests | test/src/data/api/ |
| Provider tests | test/src/data/providers/ |
| Widget tests | test/src/presentation/ |
Target: 80%+ for all non-generated code. Run flutter test --coverage to check.
Excluded from coverage: main.dart, generated files.
development
Git Workflow Manager - Auto-activating skill for DevOps Basics. Triggers on: git workflow manager, git workflow manager Part of the DevOps Basics skill category.
development
Flutter development for screens, features, and business logic. USE WHEN: creating screens, implementing navigation, fixing bugs, state management, Riverpod providers. Examples: <example> Context: User needs a new feature screen. user: "Implement the dataset catalog search screen" assistant: "I'll use flutter-developer skill for this screen with Riverpod state and GoRouter navigation." <commentary>Screens with state and navigation use flutter-developer.</commentary> </example>
tools
Use when work should span one or more detached tasks but still behave like one job with a single owner context. TaskFlow is the durable flow substrate under authoring layers like Lobster, ACPX, plugins, or plain code. Keep conditional logic in the caller; use TaskFlow for flow identity, child-task linkage, waiting state, revision-checked mutations, and user-facing emergence.
tools
# Lobster Lobster executes multi-step workflows with approval checkpoints. Use it when: - User wants a repeatable automation (triage, monitor, sync) - Actions need human approval before executing (send, post, delete) - Multiple tool calls should run as one deterministic operation ## When to use Lobster | User intent | Use Lobster? | | ------------------------------------------------------ | --------------------------