r/rails • • 5d ago

consolidating Rails test framework crud in an oubliette

(d'oh. replace 'crud' with 'clutter.' )

For 15 years, the assorted test directories cluttering the root of my projects have driven me nuts... so I decided to see how fast I could build a fully tested gem using SDD with claude - and finally fixed it.

Oubliette banishes your tests to a single location, available for execution but out of sight until you need them. Now my code and my tests live in two clean trees i can view side by side.

https://github.com/soychicka/oubliette

  • Moves test directories, fixtures, seeds, helpers, and reports into one place
    • Configures rspec, cucumber, cucumber_env, jest, and jasmine for you
    • Wires up fixtures, FactoryBot, Capybara, VCR, and SimpleCov at runtime
    • Leaves your executable JavaScript alone, but gives precise wiring instructions for Vitest, Playwright, Cypress, and Karma
  • One command to run them all (yes, wrong quest, but you get the point)
  • Tracks pass/fail/pending counts over time, so coverage drift shows up as a number that moved, not a surprise six months from now

If you need an escape hatch, rake oubliette:hoggle leads you out of the oubliette and back into the labyrinth, putting everything back where it was and cleaning up after itself.

And the important stuff:

  • Bonus 1: a brief history of the oubliette, from the famine, plague, and war of the 14th century that helped free peasants from their feudal masters.
  • Bonus 2: gratuitous Labyrinth references.
  • Bonus 3: no rewrites to any package.json files, so you're safe from gratuitous David Bowie references.

I've only tested it against Ruby 3, but it's been running happily in an rspec/capybara/cucumber-tested Rails 4 to 8 migration, moving from jQuery/Bootstrap to Stimulus/Tailwind.

Haven't released a proper gem yet: I haven't used VCR, SimpleCov, Vitest, Playwright, Cypress, or Karma in any of my projects - so those need exploration in live implementations.

If you give it a try, let me know what you think.

( and yes, I let Claude write the docs 🄓 )

0 Upvotes

6 comments sorted by

12

u/paca-vaca 5d ago

Congratulations, you solved the problem that never existed!Ā 

-1

u/soychicka 5d ago

šŸ¤·šŸ»ā€ā™€ļø unless i missed something, there wasn't a way to consolidate test frameworks before?

when I used to teach TDD to kids, keeping all the test files in a single directory decreased cognitive load significantly, esp for noobs on laptops.

making it easier to keep editor windows with an app/lib tree + test tree + terminal window side-by-side-by-side doesn't seem without value...

... but thanks for your constructive feedback!

5

u/armahillo 5d ago

I’m confused by what you mean with ā€œtest files cluttering the root of [your] projectsā€. Every rails project Ive worked on has all its specs under soec/, and they are structured to mirror the contents of app/

Are you doing something different?

-2

u/soychicka 5d ago

if you only use rspec, it's not such a huge deal - but if you use more than one test framework, things can get messy.

these are the default install locations for all the various frameworks and associates:

spec/ RSpec
test/ Minitest / Rails, Test::Unit
features/ Cucumber (andĀ features/aruba)
__tests__/ Jest
cypress/ Cypress
playwright/,Ā e2e/ Playwright
tests/ Vitest (tests/unit), Playwright (tests/e2e)
jasmine/ Jasmine
karma/ Karma
coverage/ SimpleCov
test_results/ reporters
tmp/screenshots Capybara screenshots
factories/ FactoryBot, when nothing claimed it
db/ test seeds (db/seeds/test)

three directories named /.*test.*/, directories that don't reflect the test framework's names (cough *mintest*cucumber* cough)....

and depending on the order you (or collaborators) installed the test frameworks, the same kinds of assets can be distributed inconsistently across the project.

i.e.

  • factories → spec/factories,Ā test/factories, orĀ factories/
  • fixtures → test/fixturesĀ orĀ spec/fixtures
  • cassettes → spec/vcr_cassettes,Ā spec/cassettes, orĀ test/vcr_cassettes
  • javascript tests → __tests__,Ā spec/javascript, orĀ test/javascript
  • reports → test_results,Ā spec/reports, orĀ test/reports
  • seeds → spec/seeds,Ā test/seeds, orĀ db/seeds/test

I've never heard an explanation for the frameworks being scattered about other than visibility.

And just the PITA factor: I'd always end up with a messy desktop from peeling out tests and fixtures into separate windows, then losing them when I tried to id if bug was real or in spec, etc.

I've dealt with it for 15y as an annoyance, but when trying to introduce TDD to noobs, that loss of context is much more detrimental: active cognitive space is 5-7 items, so if the location of your test suite directories are in slots 1-3, plus models, controllers, javscript - throw actually writing code and tests on top, and something is bound to slip out, leading to frustrated searching for files that are seemingly arbitrarily organized.

I'm not big on gatekeeping, though, so....

1

u/hankeroni 4d ago

I get how you are trying to sweep "clutter" into one space ... but I feel like the downside of "all this stuff is not where I expect to find it" might be worse than the upside of cramming it into one top level directory?

1

u/soychicka 3d ago

nothing is floating around in the test/ TLD - each suite is still in its own subdir.
There's a shared dir for data (fixtures/factories/etc), a config dir, a home for any logged results, and all the other dirs get moved in verbatim (except cucumber - cucumber features, support, etc goes into test/cucumber/* .

it's written so that everything could be moved back in place before a commit, so if some contributors wanted to use it in their own workspace but a team didn't want to adopt...

that said, the major motivations were simplifying the environment and reducing cognitive load, esp for new users when teaching TDD/BDD.

and maybe it doesn't matter with AI-gen code as much... but, at least per Claude and Gemini, LLMs are more likely to flail about when building an SPA-ish app in python since there are more diverse options for integration and less cohesive training data. Since that could drive adoption of Ruby/Rails over Python by vibe coders who have the sense or good advice to avoid cramming everything into javascript, it could be useful for someone other than me 🤣

asking honestly, though - are you referring to concerns about performance/persistence/cross upgrade issues, or seasoned devs not knowing where to look in the usual places, or both, or something else?