missing-test-assertion
- Group
- Correctness
- Path
lint/correctness/missing-test-assertion- Default
- On (recommended)
- Origin
- Falcon
- Domain
- test
- Rule
- 269 of 512
Reports inline test callbacks that contain no recognized assertion calls.
Only _test.dart files importing test or flutter_test are inspected,
and test/testWidgets must resolve to a framework package. Assertions
include framework expectations, asynchronous expectation wrappers, fail,
and mockito/mocktail verification calls. Assertions in unused local closures
or functions and nested tests do not satisfy the enclosing test.
Options
include-assertions is a list of additional assertion function names. These
names explicitly trust project helpers, including local functions; prefixed
names can be supplied as written at their call sites.
Invalid
import 'package:test/test.dart';
import 'package:test/test.dart' as t;
import 'package:flutter_test/flutter_test.dart' as f;
void main() {
test('empty', () {});
test('setup only', () { final value = 1; print(value); });
t.test('arrow', () => print('nothing asserted'));
test('unused closure', () { final assertion = () { expect(1, 1); }; });
test('local shadow', () { void expect(Object? a, Object? b) {} expect(1, 1); });
test('unused local function', () { void assertion() { expect(1, 1); } });
f.testWidgets('widget without expectation', (tester) async { await tester.pump(); });
}
class Checker { void expect(Object? a, Object? b) {} }
void objectAssertion() {
test('object method is not an assertion', () { Checker().expect(1, 1); });
}void main() { test('empty', () {}); test('empty', () {}); test('setup only', () { final value = 1; print(value); }); test('setup only', () { final value = 1; print(value); }); t.test('arrow', () => print('nothing asserted')); t.test('arrow', () => print('nothing asserted')); test('unused closure', () { final assertion = () { expect(1, 1); }; }); test('unused closure', () { final assertion = () { expect(1, 1); }; }); test('local shadow', () { void expect(Object? a, Object? b) {} expect(1, 1); }); test('local shadow', () { void expect(Object? a, Object? b) {} expect(1, 1); }); test('unused local function', () { void assertion() { expect(1, 1); } }); test('unused local function', () { void assertion() { expect(1, 1); } }); f.testWidgets('widget without expectation', (tester) async { await tester.pump(); });void objectAssertion() { test('object method is not an assertion', () { Checker().expect(1, 1); });Valid
import 'package:test/test.dart';
import 'package:test/test.dart' as t;
import 'package:flutter_test/flutter_test.dart' as f;
import 'package:mocktail/mocktail.dart' as mock;
void checkResult() {}
void main() {
test('expect', () { expect(1, 1); });
t.test('prefixed', () => t.expect(1, 1));
test('later', () async { await expectLater(1, 1); });
test('async wrapper', () { expectAsync0(() {}); });
test('async argument wrapper', () { expectAsync1((value) {}); });
test('async until', () { expectAsyncUntil1((value) {}, () => true); });
test('fail', () { fail('unreachable'); });
test('verify', () { mock.verify(() {}); });
test('verify never', () { mock.verifyNever(() {}); });
test('verify order', () { mock.verifyInOrder([() {}]); });
test('configured helper', () { checkResult(); });
f.testWidgets('widget', (tester) async { await tester.pump(); f.expect(1, 1); });
}
class OtherSuite { void test(String name, Function body) {} void run() { test('not a package test', () {}); } }
void localSuite() { void test(String name, Function body) {} test('local', () {}); }
void runCallback(void Function() callback) => callback();
void nestedAssertions() {
test('passed callback', () { runCallback(() { expect(1, 1); }); });
test('invoked closure', () { (() { expect(1, 1); })(); });
test('called local function', () { void check() { expect(1, 1); } check(); });
test('passed local closure', () { final check = () { expect(1, 1); }; runCallback(check); });
test('collection callback', () { [1].forEach((value) { expect(value, 1); }); });
}
void interactionAssertions(Object instance) {
test('no more interactions', () { mock.verifyNoMoreInteractions(instance); });
test('zero interactions', () { mock.verifyZeroInteractions(instance); });
}Configure missing-test-assertion
Set its severity in falcon.json. See the configuration guide.
{
"linter": {
"rules": {
"correctness": {
"missing-test-assertion": "error"
}
}
}
}Or silence one occurrence with a suppression comment; the reason is required.
// falcon-ignore lint/correctness/missing-test-assertion: <reason>More correctness rules
- no-adjacent-strings-in-list
no_adjacent_strings_in_listrecommendedFlags adjacent string literals used as an element of a list or set literal.
- no-import-cyclescross-file
Report mutually dependent components of imported or exported library files.
- no-logic-in-create-state
no_logic_in_create_staterecommendedflutterRequire
StatefulWidget.createStateto return only a fresh zero-argument FlutterStateconstruction. - no-self-assignments
no_self_assignmentsrecommendedFlags assignments of a variable to itself, such as
x = x;. - null-check-on-nullable-type-parameter
null_check_on_nullable_type_parameterrecommendedFlags a null assertion
x!on a nullable type parameterT?whose expected type isTorT?for a potentially nullableT, and null-assert patterns whose matched value is a nullable type parameter. - null-closures
null_closuresrecommendedReject literal
nullin the closure slots of curated SDK APIs. - prefer-correct-json-casts
Decode JSON containers using their actual runtime generic types.
- prefer-define-hero-tagflutter
Require an explicit heroTag on Flutter
FloatingActionButtonconstructors.