<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:thoughtbot="https://thoughtbot.com/feeds/">
  <title>Giant Robots Smashing Into Other Giant Robots</title>
  <subtitle>Written by thoughtbot, your expert partner for design and development.
</subtitle>
  <id>https://robots.thoughtbot.com/</id>
  <link href="https://thoughtbot.com/blog"/>
  <link href="https://feed.thoughtbot.com" rel="self"/>
  <updated>2026-05-06T00:00:00+00:00</updated>
  <author>
    <name>thoughtbot</name>
  </author>
<entry>
  <title>The output must be cleaned (with skill)</title>
  <link rel="alternate" href="https://thoughtbot.com/blog/the-output-must-be-cleaned-with-skill"/>
  <author>
    <name>Jared Turner</name>
  </author>
  <id>https://thoughtbot.com/blog/the-output-must-be-cleaned-with-skill</id>
  <published>2026-05-06T00:00:00+00:00</published>
  <updated>2026-05-05T14:47:35Z</updated>
  <content type="html">&lt;aside class="info"&gt;
  Presenting &lt;a href="https://github.com/thoughtbot/clean-rspec-output"&gt;clean-rspec-output&lt;/a&gt;, a
  Claude skill that systematically eliminates unexpected output from a Ruby on Rails RSpec test suite.
&lt;/aside&gt;

&lt;p&gt;You know the feeling. You run &lt;code&gt;bundle exec rspec&lt;/code&gt; and instead of a clean wall of dots, you get this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;❯ bundle exec rspec
DEPRECATION WARNING: Defining enums with keyword arguments is deprecated and will be removed in Rails 8.0. Positional arguments should be used instead
.......Warning: The code in the `before_worker_boot` block will not execute in
the current Puma configuration...
............Checking for expected text of nil is confusing and/or pointless...
...Checking for expected text of nil is confusing and/or pointless...
..WARNING: Using the `raise_error` matcher without providing a specific error...
.....Payment ID: 2789
Payment2 ID: 2790
.........true
true
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Your eyes water. Your OCD bleeds. Somewhere, a Toyota engineer reaches for the Andon cord.&lt;/p&gt;

&lt;p&gt;Drop everything. Yes, everything. That critical production bug? It can wait. The six-month
feature you are one PR away from shipping? Not important. There is only one priority now,
and it stares back at you from your terminal in a cascade of deprecation warnings and
orphaned &lt;code&gt;puts&lt;/code&gt; calls from 2019.&lt;/p&gt;

&lt;p&gt;The. Output. Must. Be. Cleaned.&lt;/p&gt;
&lt;h2 id="right-after-this-other-thing"&gt;
  
    …right after this other thing
  
&lt;/h2&gt;

&lt;p&gt;Except, of course, you don’t drop everything. You scroll past it. You’ve always scrolled
past it (I always scroll past it). There’s a real bug to fix, a PR to review, a meeting
in ten minutes. The noisy output is annoying, but it’s not a crisis. It goes on “the list”.&lt;/p&gt;

&lt;p&gt;And there it stays.&lt;/p&gt;
&lt;h2 id="the-smoke-alarm-problem"&gt;
  
    The smoke alarm problem
  
&lt;/h2&gt;

&lt;p&gt;That pesky noise compounds though.&lt;/p&gt;

&lt;p&gt;Every time you run the suite and scroll past a wall of warnings, you’re training yourself
to treat the output as wallpaper. Which is fine, until it’s not. A real deprecation that’s
about to become a breaking change. A stray &lt;code&gt;puts&lt;/code&gt; that’s leaking sensitive data in CI logs.
A warning that signals a subtle misconfiguration in your test environment.&lt;/p&gt;

&lt;p&gt;It’s the smoke alarm that goes off every time someone makes toast. Eventually you &lt;a href="https://www.matheusrich.com/kitchen-sink/"&gt;stop
evacuating&lt;/a&gt;. You know how that story ends.&lt;/p&gt;

&lt;p&gt;The noisy suite isn’t a crisis. But it is slowly eroding your ability to notice when
something actually is.&lt;/p&gt;
&lt;h2 id="the-bottom-of-the-list"&gt;
  
    The bottom of the list
  
&lt;/h2&gt;

&lt;p&gt;Cleaning up test output is genuinely tedious work. For each piece of noise you need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Find the test that’s producing it&lt;/li&gt;
&lt;li&gt;Reproduce it in isolation&lt;/li&gt;
&lt;li&gt;Track down the root cause (which is rarely where you expect)&lt;/li&gt;
&lt;li&gt;Fix it without accidentally breaking what the test covers&lt;/li&gt;
&lt;li&gt;Verify the output is actually gone&lt;/li&gt;
&lt;li&gt;Commit, ship and verify nothing broke&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then do it again. For every warning. Every orphaned debug call. Every gem that decided
its deprecation notice belongs in your test output.&lt;/p&gt;

&lt;p&gt;It’s not hard, necessarily. It’s just slow, fiddly, and aggressively unglamorous. The kind
of thing that’s &lt;em&gt;very&lt;/em&gt; easy to justify deferring when there’s a feature to ship.&lt;/p&gt;
&lt;h2 id="i-know-skill-fu"&gt;
  
    I know skill-fu
  
&lt;/h2&gt;

&lt;p&gt;This is exactly the kind of work AI is good at.&lt;/p&gt;

&lt;p&gt;So I built a Claude skill, creatively named &lt;a href="https://github.com/thoughtbot/clean-rspec-output"&gt;clean-rspec-output&lt;/a&gt;, that works through
noisy RSpec output one issue at a time. It&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Captures the full suite output&lt;/li&gt;
&lt;li&gt;Scans for the unexpected&lt;/li&gt;
&lt;li&gt;For each it:

&lt;ul&gt;
&lt;li&gt;Locates the source test&lt;/li&gt;
&lt;li&gt;Reproduces the output in isolation&lt;/li&gt;
&lt;li&gt;Fixes the root cause&lt;/li&gt;
&lt;li&gt;Verifies the fix&lt;/li&gt;
&lt;li&gt;Commits&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One fix per commit, so you can review or cherry-pick each change independently.&lt;/p&gt;

&lt;p&gt;The whole thing runs while you get on with something else. Afterwards, bliss:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;❯ bundle exec rspec
..............................................................................................................................
..............................................................................................................................
..............................................................................................................................

Finished in 4 minutes 2 seconds (files took 8.06 seconds to load)
892 examples, 0 failures
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="don39t-do-the-bad-thing"&gt;
  
    Don’t do the bad thing
  
&lt;/h2&gt;

&lt;p&gt;The tempting shortcut (especially for machines) when test output is noisy is to simplify
the test until the noise stops. Delete the code branch that’s producing the warning. Use a
different value in the assertion, one that happens not to trigger the deprecation.&lt;/p&gt;

&lt;p&gt;The output disappears. The test still passes. Nobody notices that you’ve just quietly
removed a scenario the test was written to cover. Bad bot.&lt;/p&gt;

&lt;p&gt;The skill won’t do this. Or at least, there are some strong attempts at guardrails to 
defend against this kind of lazy just-get-my-test-to-pass AI fun. A fix may change &lt;em&gt;how&lt;/em&gt;
a test runs. It must not change &lt;em&gt;what&lt;/em&gt; it covers. If a warning is coming from a code path
the test genuinely needs to exercise, the fix belongs in the application code or test
configuration, not in the test itself.&lt;/p&gt;

&lt;p&gt;These guardrails were driven by dogfooding the skill repeatedly against a number of 100K+
LOC test suites until this author was satisfied with the results.&lt;/p&gt;
&lt;h2 id="getting-started"&gt;
  
    Getting started
  
&lt;/h2&gt;

&lt;p&gt;Install the &lt;a href="https://github.com/thoughtbot/clean-rspec-output"&gt;skill&lt;/a&gt; by copying it to your Claude Code skills folder:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/thoughtbot/clean-rspec-output ~/.claude/skills/clean-rspec-output
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then from inside a Claude Code session, in the root of your Rails project:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/clean-rspec-output
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It’ll ask which branch to work on before doing anything. From there, it handles the rest.&lt;/p&gt;

&lt;p&gt;Try it out in some gnarly codebases and see how it goes. Hopefully it saves you some time
and resatisfies your OCD. But if you notice any funky behaviour or unpleasantness, &lt;a href="https://github.com/thoughtbot/clean-rspec-output/issues"&gt;feedback&lt;/a&gt;
is always welcome!&lt;/p&gt;

&lt;aside class="related-articles"&gt;&lt;h2&gt;If you enjoyed this post, you might also like:&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://thoughtbot.com/blog/unpopular-developer-2-down-with-big-testing"&gt;Unpopular Developer 2: Down With Big Testing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://thoughtbot.com/blog/shhh-your-test-unit-backtraces-are-too-noisy"&gt;Shhh! Your Test::Unit backtraces are too noisy!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://thoughtbot.com/blog/shoulda-4-0-1-the-lean-and-mean-release"&gt;Shoulda 4.0.1 - the lean and mean release&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/aside&gt;
</content>
  <summary>A Claude skill for the noisy RSpec output you've always wanted to clean up.</summary>
  <thoughtbot:auto_social_share>true</thoughtbot:auto_social_share>
</entry>
</feed>
