You’re about to check in your next small feature, so you kick off a full integration test run. You wait, and wait, as the dots fill your screen, until…

......FF....

:-(

You still have a few minutes before your tests finish running. But if you quit the test run early, you’ll have no idea which tests failed.

Do you really have to wait for the entire run to finish before you can see those failures?

Ctrl-T to the rescue!

If you’re using a Mac, there’s a way to see your test failures early:

Hit Ctrl-T while your tests are running.

When you do, you’ll see which test case is currently running, and how long it’s been running for. If any tests have failed so far, you’ll also see those failures, so you can get a head start on fixing them before your next run!

This is also really handy for debugging tests that just hang. Ctrl-T will tell you which test is trying to run, so you can isolate just that one test and fix it.

Finally, I’ve built a habit of hitting Ctrl-T anytime a test takes a noticeably long time (say, a second or longer) to finish. It’s pointed me to plenty of slow tests that I need to make faster.

How does Ctrl-T work?

On a Mac, Ctrl-T sends a message, or signal, called INFO, to whichever program is running:

signal_test.rb
1
2
3
4
puts "Starting..."
trap("INFO") { puts "INFO triggered!" }

loop { print "."; sleep 0.1}
1
2
3
4
5
6
7
8
9
10
11
12
~/Source jweiss$ ruby signal_test.rb
Starting...
........^Tload: 7.14  cmd: ruby 6121 running 0.10u 0.08s
INFO triggered!
.......^Tload: 7.14  cmd: ruby 6121 running 0.10u 0.08s
INFO triggered!
................^Tload: 11.77  cmd: ruby 6121 running 0.10u 0.08s
.INFO triggered!
......^Csignal_test.rb:5:in `sleep': Interrupt
 from signal_test.rb:5:in `block in <main>'
  from signal_test.rb:5:in `loop'
 from signal_test.rb:5:in `<main>'

Minitest knows about INFO, and responds to it by printing information about the test run:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
~/Source/rails/activesupport[master] jweiss$ be rake
/usr/local/Cellar/ruby/2.2.0/bin/ruby -w -I"lib:test"  "/usr/local/Cellar/ruby/2.2.0/lib/ruby/2.2.0/rake/rake_test_loader.rb" "test/**/*_test.rb"
Run options: --seed 33445

# Running:

.................F........^Tload: 1.62  cmd: ruby 29646 running 4.37u 1.40s
Current results:


  1) Failure:
CleanLoggerTest#test_format_message [/Users/jweiss/Source/rails/activesupport/test/clean_logger_test.rb:13]:
Expected "error\n" to not be equal to "error\n".



Current: DigestUUIDExt#test_invalid_hash_class 0.02s
............................

Pretty nice!

Knowing that this is possible, you might think of ways other apps could handle INFO:

  • Rails could display the currently running controller action or some performance stats.
  • Sidekiq could tell you what each worker is doing, so you could see where they get stuck.

And Sidekiq actually used to use INFO to print a backtrace of each thread it ran. But because INFO isn’t supported on Linux, Sidekiq switched to a different signal. Unfortunately, that signal can’t be triggered by a keyboard shortcut the way INFO can.

Because INFO isn’t available on Linux (and some might say that using INFO this way isn’t totally right, anyway), this behavior isn’t as widespread as it could be.

Still, it’s a little bit of extra help that could be useful in a wide range of situations. If you’re building an app, it’s worth thinking about what kind of status messages you could display on-demand to people who are interested.

Did you like this post? You should read these:

Finished another Rails tutorial and still don’t know how to start?

Have you slogged through the same guide three times and still can't retain enough to write apps on your own?

In my free 7-part course, you’ll discover the fastest way to learn and remember new Rails ideas, so you can use them when you need them. And you'll learn to use what you already know to build your own Rails project.



Comments