missing-test-assertion

Path
lint/correctness/missing-test-assertion
Default
On (recommended)
Origin
Falcon
Domain
test
Rule
269 of 512
recommendedtest

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

example.dartdart
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); });
}
This test has no assertion; add an expectation or verification.
4void main() {
5 test('empty', () {});
This test has no assertion; add an expectation or verification.
5 test('empty', () {});
6 test('setup only', () { final value = 1; print(value); });
This test has no assertion; add an expectation or verification.
6 test('setup only', () { final value = 1; print(value); });
7 t.test('arrow', () => print('nothing asserted'));
This test has no assertion; add an expectation or verification.
7 t.test('arrow', () => print('nothing asserted'));
8 test('unused closure', () { final assertion = () { expect(1, 1); }; });
This test has no assertion; add an expectation or verification.
8 test('unused closure', () { final assertion = () { expect(1, 1); }; });
9 test('local shadow', () { void expect(Object? a, Object? b) {} expect(1, 1); });
This test has no assertion; add an expectation or verification.
9 test('local shadow', () { void expect(Object? a, Object? b) {} expect(1, 1); });
10 test('unused local function', () { void assertion() { expect(1, 1); } });
This test has no assertion; add an expectation or verification.
10 test('unused local function', () { void assertion() { expect(1, 1); } });
11 f.testWidgets('widget without expectation', (tester) async { await tester.pump(); });
This test has no assertion; add an expectation or verification.
14void objectAssertion() {
15 test('object method is not an assertion', () { Checker().expect(1, 1); });

Valid

example.dartdart
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.

falcon.jsonjson
{
  "linter": {
    "rules": {
      "correctness": {
        "missing-test-assertion": "error"
      }
    }
  }
}

Or silence one occurrence with a suppression comment; the reason is required.

example.dartdart
// falcon-ignore lint/correctness/missing-test-assertion: <reason>
  • no-adjacent-strings-in-listno_adjacent_strings_in_listrecommended

    Flags 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-stateno_logic_in_create_staterecommendedflutter

    Require StatefulWidget.createState to return only a fresh zero-argument Flutter State construction.

  • no-self-assignmentsno_self_assignmentsrecommended

    Flags assignments of a variable to itself, such as x = x;.

  • null-check-on-nullable-type-parameternull_check_on_nullable_type_parameterrecommended

    Flags a null assertion x! on a nullable type parameter T? whose expected type is T or T? for a potentially nullable T, and null-assert patterns whose matched value is a nullable type parameter.

  • null-closuresnull_closuresrecommended

    Reject literal null in 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 FloatingActionButton constructors.