Stop Minitest/NoTestCases from flagging the ExecutableLoadedInTest cop class; add lessons for three Minitest cops #1445

Open
opened 2026-10-27 21:09:55 +00:00 by jared · 4 comments
Owner

Problem

Minitest/NoTestCases reports the cop class RuboCop::Cop::Sdlc::Structural::ExecutableLoadedInTest as a test class with no tests. The class is a cop, not a test. The offense stays in the os-sdlc batch phase, so bin/lint-worklist --target os-sdlc never prints "Worklist clear". Three cops in the same batch also have no lint lesson: Minitest/NoTestCases, Minitest/NoAssertions, Minitest/MultipleAssertions. #1440 covers the Metrics/MethodLength lesson.

Observed

After the fix-lints unit merged (main 5ddde177), the only os-sdlc offense left is this one.

plugins/os-sdlc/bin/lint-worklist --target os-sdlc
Phase batch (1 offenses, 1 files, 1 dispatch groups)
plugins/os-sdlc/lib/os_sdlc/cops/structural/executable_loaded_in_test.rb
  Minitest/NoTestCases :9 -- Test class should have test cases.

rubocop-minitest treats a class as a test class when it has a superclass and its name ends in Test. ExecutableLoadedInTest < RuboCop::Cop::Base matches that rule.

Reproduce

plugins/os-sdlc/bin/lint-worklist --target os-sdlc

Approach

Needs a ruling. Option A: rename the cop class so its name does not end in Test. This changes the public cop name Sdlc/Structural/ExecutableLoadedInTest that .rubocop.yml files and the lesson reference. Option B: change how Minitest/* cops select files (for example, run them only on test paths) in the gate config. The fix-lints unit was not permitted to change a cop name or the config, so it left the offense.

Separately, write lint lessons for Minitest/NoTestCases, Minitest/NoAssertions, Minitest/MultipleAssertions.

Origin

  • Trigger: /os-sdlc:fix-lints on target os-sdlc, 2026-10-27
  • Improvised this session: none; the offense was left in place and reported as a false positive.
  • Chain: batch phase never empties ← Minitest/NoTestCases matches a cop class ← rubocop-minitest selects test classes by name suffix (UPSTREAM-TOOL: rubocop-minitest test_class?)
  • Root candidate: none found; searched NoTestCases, ExecutableLoadedInTest, NoAssertions, MultipleAssertions, MethodLength, lesson (#1352 same cop, different fault; #1440 covers MethodLength lesson)
  • Where: plugins/os-sdlc/lib/os_sdlc/cops/structural/executable_loaded_in_test.rb:9
  • Session: 9f415790-a6bd-4850-8d70-3dd45004ce2b
  • Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/9f415790-a6bd-4850-8d70-3dd45004ce2b.jsonl

VERDICT: CREATE

## Problem `Minitest/NoTestCases` reports the cop class `RuboCop::Cop::Sdlc::Structural::ExecutableLoadedInTest` as a test class with no tests. The class is a cop, not a test. The offense stays in the os-sdlc batch phase, so `bin/lint-worklist --target os-sdlc` never prints "Worklist clear". Three cops in the same batch also have no lint lesson: `Minitest/NoTestCases`, `Minitest/NoAssertions`, `Minitest/MultipleAssertions`. #1440 covers the `Metrics/MethodLength` lesson. ## Observed After the fix-lints unit merged (main 5ddde177), the only os-sdlc offense left is this one. ``` plugins/os-sdlc/bin/lint-worklist --target os-sdlc ``` ``` Phase batch (1 offenses, 1 files, 1 dispatch groups) plugins/os-sdlc/lib/os_sdlc/cops/structural/executable_loaded_in_test.rb Minitest/NoTestCases :9 -- Test class should have test cases. ``` rubocop-minitest treats a class as a test class when it has a superclass and its name ends in `Test`. `ExecutableLoadedInTest < RuboCop::Cop::Base` matches that rule. ## Reproduce ``` plugins/os-sdlc/bin/lint-worklist --target os-sdlc ``` ## Approach Needs a ruling. Option A: rename the cop class so its name does not end in `Test`. This changes the public cop name `Sdlc/Structural/ExecutableLoadedInTest` that `.rubocop.yml` files and the lesson reference. Option B: change how `Minitest/*` cops select files (for example, run them only on test paths) in the gate config. The fix-lints unit was not permitted to change a cop name or the config, so it left the offense. Separately, write lint lessons for `Minitest/NoTestCases`, `Minitest/NoAssertions`, `Minitest/MultipleAssertions`. ## Origin - Trigger: `/os-sdlc:fix-lints` on target os-sdlc, 2026-10-27 - Improvised this session: none; the offense was left in place and reported as a false positive. - Chain: batch phase never empties ← `Minitest/NoTestCases` matches a cop class ← rubocop-minitest selects test classes by name suffix (UPSTREAM-TOOL: rubocop-minitest `test_class?`) - Root candidate: none found; searched NoTestCases, ExecutableLoadedInTest, NoAssertions, MultipleAssertions, MethodLength, lesson (#1352 same cop, different fault; #1440 covers MethodLength lesson) - Where: plugins/os-sdlc/lib/os_sdlc/cops/structural/executable_loaded_in_test.rb:9 - Session: 9f415790-a6bd-4850-8d70-3dd45004ce2b - Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/9f415790-a6bd-4850-8d70-3dd45004ce2b.jsonl VERDICT: CREATE
Author
Owner

Occurrence: Add a lint lesson for Minitest/NoAssertions
Seen: plugins/os-aidd-lint/tests/zeitwerk_eager_load_test.rb (fix-lints on os-aidd-lint, batch phase, 2026-10-27)
Run: session 9f415790-a6bd-4850-8d70-3dd45004ce2b
Adds: a live NoAssertions site. With no lesson, the agent fixed a test that only ran the Zeitwerk eager load by wrapping the load in assert_silent. The smell-analysis can use this site as its real offense.

Occurrence: Add a lint lesson for Minitest/NoAssertions Seen: plugins/os-aidd-lint/tests/zeitwerk_eager_load_test.rb (fix-lints on os-aidd-lint, batch phase, 2026-10-27) Run: session 9f415790-a6bd-4850-8d70-3dd45004ce2b Adds: a live NoAssertions site. With no lesson, the agent fixed a test that only ran the Zeitwerk eager load by wrapping the load in assert_silent. The smell-analysis can use this site as its real offense.
Author
Owner

Applied option B (gate config), as the #1337 track planned: Minitest/NoTestCases in plugins/os-sdlc/.rubocop.yml now has a cop-level Include of **/test/**/* and **/tests/**/* (commit 50e55c14 on branch ticket-1337, merging with #1337).

Cause: the rubocop-minitest department Include has **/*_test.rb, and the cop file name executable_loaded_in_test.rb matches it, so the cop class was judged a test class. The new cop own_entry_point_spawned_in_test.rb would have hit the same false positive.

Result: rubocop --only Minitest/NoTestCases plugins/os-sdlc reports no offenses, and bin/lint-worklist --target os-os-sdlc has no batch phase. No cop was renamed.

This ticket stays open: the lessons for Minitest/NoTestCases, Minitest/NoAssertions and Minitest/MultipleAssertions are still missing.

Applied option B (gate config), as the #1337 track planned: `Minitest/NoTestCases` in `plugins/os-sdlc/.rubocop.yml` now has a cop-level `Include` of `**/test/**/*` and `**/tests/**/*` (commit 50e55c14 on branch ticket-1337, merging with #1337). Cause: the rubocop-minitest department `Include` has `**/*_test.rb`, and the cop file name `executable_loaded_in_test.rb` matches it, so the cop class was judged a test class. The new cop `own_entry_point_spawned_in_test.rb` would have hit the same false positive. Result: `rubocop --only Minitest/NoTestCases plugins/os-sdlc` reports no offenses, and `bin/lint-worklist --target os-os-sdlc` has no batch phase. No cop was renamed. This ticket stays open: the lessons for `Minitest/NoTestCases`, `Minitest/NoAssertions` and `Minitest/MultipleAssertions` are still missing.
Author
Owner

Correction to the comment above: the command is bin/lint-worklist --target os-sdlc.

Correction to the comment above: the command is `bin/lint-worklist --target os-sdlc`.
Author
Owner

Ruling 2026-10-28 (Jared): B. Keep the config fix 50e55c14 (Minitest/NoTestCases Include limited to test folders); do not rename ExecutableLoadedInTest. The fix covers every future cop file named *_in_test.rb. This ticket stays open only for the 3 Minitest lessons (NoTestCases, NoAssertions, MultipleAssertions), written by hand with /os-sdlc:smell-analysis.

Ruling 2026-10-28 (Jared): B. Keep the config fix 50e55c14 (Minitest/NoTestCases Include limited to test folders); do not rename ExecutableLoadedInTest. The fix covers every future cop file named *_in_test.rb. This ticket stays open only for the 3 Minitest lessons (NoTestCases, NoAssertions, MultipleAssertions), written by hand with /os-sdlc:smell-analysis.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
jared/cc-os#1445
No description provided.