NoMagicStringInTestsRule class

Warns when magic strings are used in test files.

Since: v4.3.0 | Updated: v5.0.0 | Rule version: v5

Context: This is the test-specific variant of no_magic_string, which skips test files entirely (default TestRelevance.never). The production rule enforces strict avoidance of magic strings in application code, while this rule provides appropriate, relaxed enforcement for test code.

Rationale: Test files legitimately use more literal strings than production code for:

  • Test descriptions (automatically allowed as first arg to test(), group())
  • Common test data (hex strings, single letters, placeholder values)
  • Simple assertions ('foo', 'bar', 'hello', 'world')
  • Regex patterns (automatically detected via RegExp() constructor)
  • Strings in expect() calls (assertion values, both actual and expected)
  • Strings passed as arguments to functions under test (fixture data)

However, meaningful domain strings (like email addresses, URLs, API keys, or business identifiers) should still use named constants to make tests self-documenting and maintainable.

Automatically allowed:

  • Test descriptions: test('description', ...) - first argument
  • Regex patterns: RegExp(r'\d+') or RegExp('pattern')
  • Import/export paths: import 'foo.dart'
  • Annotations: @Tag('integration')
  • Const contexts: const name = 'value'
  • Interpolated strings: 'Result: $value'
  • Very short strings: 1-3 characters

Allowed literal values:

  • Common punctuation: '', ' ', ', ', ': ', '.', '...', '-', '_', '/', ''
  • Single letters: 'a', 'b', 'c', 'x', 'y', 'z'
  • Test placeholders: 'foo', 'bar', 'baz', 'test', 'example', 'hello', 'world'
  • String representations: 'true', 'false', 'null', '0', '1'

Tier: Comprehensive (optional, style enforcement) Severity: INFO Performance: Medium cost (addSimpleStringLiteral registry)

Example

BAD:

test('validates email', () {
  final user = User(email: 'user@example.com'); // Magic string
  expect(user.isValid, true);
});

test('fetches from API', () async {
  final data = await fetch('https://api.example.com/users'); // Magic URL
  expect(data, isNotEmpty);
});

test('parses hex color', () {
  final color = parseColor('7FfFfFfFfFfFfFfF'); // Magic hex string
  expect(color.isValid, true);
});

GOOD:

test('validates email', () {
  const testEmail = 'user@example.com'; // Named constant for clarity
  final user = User(email: testEmail);
  expect(user.isValid, true);
});

test('fetches from API', () async {
  const apiUrl = 'https://api.example.com/users'; // Named constant
  final data = await fetch(apiUrl);
  expect(data, isNotEmpty);
});

test('parses hex color', () {
  const testHexString = '7FfFfFfFfFfFfFfF'; // Named constant
  final color = parseColor(testHexString);
  expect(color.isValid, true);
});

// Automatically allowed patterns:
test('validates empty string', () { // Test description - OK
  final result = validate(''); // OK: Empty string
  expect(result.errors, isEmpty);
});

test('matches regex pattern', () {
  final regex = RegExp(r'\d+'); // OK: Regex pattern
  expect(regex.hasMatch('123'), true);
});

test('handles simple values', () {
  final result = process('x'); // OK: Single letter
  expect(result.value, 'foo'); // OK: Common test placeholder
});
  • no_magic_string - Production code variant (skips test files)
  • no_magic_number - Similar pattern for numeric literals
  • no_magic_number_in_tests - Test-specific variant for numbers
Inheritance

Constructors

NoMagicStringInTestsRule()

Properties

accuracyTarget AccuracyTarget?
Optional accuracy target for this rule (for documentation and tooling). Does not enforce; used by reports and rule-audit scripts.
no setterinherited
applicableFileTypes Set<FileType>?
The file types this rule applies to.
no setteroverride
canUseParsedResult bool
Indicates whether this analysis rule can work with just the parsed information or if it requires a resolved unit.
no setterinherited
certIds List<String>
CERT coding standard identifiers (e.g. STR02-C). Populate only where there is a clear mapping; leave empty for most rules initially.
no setterinherited
code → LintCode
The lint code for this rule.
no setterinherited
configAliases List<String>
Alternate config keys that can be used to reference this rule.
no setterinherited
conflictingRules List<String>
Curated opposite/competing rule names.
no setterinherited
cost RuleCost
The estimated execution cost of this rule.
no setteroverride
cweIds List<int>
CWE identifiers this rule helps prevent or detect. https://cwe.mitre.org/ — e.g. CWE-798 (Hardcoded Credentials).
no setterinherited
description String
Short description suitable for display in console output and IDEs.
finalinherited
diagnosticCode → DiagnosticCode
The code to report for a violation.
no setterinherited
diagnosticCodes List<DiagnosticCode>
The diagnostic codes associated with this analysis rule.
no setterinherited
documentationUrl String
Returns the documentation URL for this rule.
no setterinherited
effectiveSeverity → DiagnosticSeverity?
Get the effective severity for this rule, considering overrides.
no setterinherited
exampleBad String?
Short code example that VIOLATES this rule (shown in CLI walkthrough).
no setterinherited
exampleGood String?
Short code example of COMPLIANT code (shown in CLI walkthrough).
no setterinherited
fixGenerators List<SaropaFixGenerator>
Fix producer generators for this rule.
no setterinherited
hashCode int
The hash code for this object.
no setterinherited
hyphenatedName String
Returns the rule name in hyphenated format for display.
no setterinherited
impact LintImpact
The business impact of this rule's violations.
no setteroverride
incompatibleRules List<String>
A list of incompatible rule names.
no setterinherited
isDisabled bool
Check if this rule is disabled via configuration.
no setterinherited
maximumLineCount int
Maximum line count for this rule to run.
no setterinherited
minimumLineCount int
Minimum line count for this rule to run.
no setterinherited
name String
The rule name.
finalinherited
owasp OwaspMapping?
OWASP categories this rule helps prevent.
no setterinherited
pubspecVisitor → PubspecVisitor?
A visitor that visits a Pubspec to perform analysis.
no setterinherited
relatedRules List<String>
Curated "see also" rule names for discoverability in docs/IDE tooling.
no setterinherited
reporter ← DiagnosticReporter
Sets the DiagnosticReporter for the CompilationUnit currently being visited.
no getterinherited
requiredPatterns Set<String>?
String patterns that must be present in the file for this rule to run.
no setterinherited
requiresAsync bool
Whether this rule only applies to async code.
no setterinherited
requiresBlocImport bool
Whether this rule only applies to files that import Bloc.
no setterinherited
requiresClassDeclaration bool
Whether this rule only applies to files with class declarations.
no setterinherited
requiresFlutterImport bool
Whether this rule only applies to files that import Flutter.
no setterinherited
requiresImports bool
Whether this rule only applies to files with imports.
no setterinherited
requiresMainFunction bool
Whether this rule only applies to files with a main() function.
no setterinherited
requiresProviderImport bool
Whether this rule only applies to files that import Provider.
no setterinherited
requiresRiverpodImport bool
Whether this rule only applies to files that import Riverpod.
no setterinherited
requiresWidgets bool
Whether this rule only applies to Flutter widget code.
no setterinherited
ruleStatus RuleStatus
Lifecycle status. Default RuleStatus.ready. Use RuleStatus.beta for new or heuristic-heavy rules; RuleStatus.deprecated for sunset.
no setterinherited
ruleType RuleType?
Semantic type of this rule. Default null = unspecified (legacy). When set, used for quality gates, accuracy targets, and reporting.
no setteroverride
runtimeType Type
A representation of the runtime type of the object.
no setterinherited
skipExampleFiles bool
Whether to skip example files (example/**).
no setterinherited
skipFixtureFiles bool
Whether to skip fixture files (fixture/, fixtures/).
no setterinherited
skipGeneratedCode bool
Whether to skip generated files (*.g.dart, *.freezed.dart, *.gen.dart).
no setterinherited
skipTestFiles bool
Whether to skip test files (*_test.dart, test/**).
no setterinherited
state → RuleState
The state of this analysis rule.
finalinherited
supersedesRules List<String>
Rule names this rule supersedes/replaces.
no setterinherited
tags Set<String>
Tags for filtering and discovery (e.g. in docs, IDE, or CI). Examples: 'performance', 'accessibility', 'suspicious', 'convention'.
no setteroverride
testRelevance TestRelevance
How this rule relates to test files.
no setterinherited

Methods

noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
registerNodeProcessors(RuleVisitorRegistry registry, RuleContext ruleContext) → void
Registers node processors in the given registry.
inherited
reportAtNode(AstNode? node, {List<Object> arguments = const [], List<DiagnosticMessage>? contextMessages}) → Diagnostic?
Reports a diagnostic at node with message arguments and contextMessages.
inherited
reportAtOffset(int offset, int length, {List<Object> arguments = const [], List<DiagnosticMessage>? contextMessages}) → Diagnostic
Reports a diagnostic at offset, with length, with message arguments and contextMessages.
inherited
reportAtPubNode(PubspecNode node, {List<Object> arguments = const [], List<DiagnosticMessage> contextMessages = const []}) → Diagnostic
Reports a diagnostic at Pubspec node, with message arguments and contextMessages.
inherited
reportAtSourceRange(SourceRange sourceRange, {List<Object> arguments = const [], List<DiagnosticMessage>? contextMessages}) → Diagnostic
Reports a diagnostic at sourceRange, with message arguments and contextMessages.
inherited
reportAtToken(Token token, {List<Object> arguments = const [], List<DiagnosticMessage>? contextMessages}) → Diagnostic?
Reports a diagnostic at token, with message arguments and contextMessages.
inherited
runWithReporter(SaropaDiagnosticReporter reporter, SaropaContext context) → void
Override this method to implement your lint rule.
override
shouldSkipFile(String path) bool
Check if a file path should be skipped based on context settings.
inherited
toString() String
A string representation of this object.
inherited

Operators

operator ==(Object other) bool
The equality operator.
inherited