새로 만든 작은 기능을 커밋하기 직전, 전체 통합 테스트를 돌립니다. 화면에 점들이 찍혀 나가기를 바라보며 기다리고 또 기다리던 어느 순간…
......FF....
:-(
테스트가 모두 끝나기까지는 아직 몇 분이나 남았습니다. 하지만 지금 실행을 중단하면 어떤 테스트가 실패했는지 전혀 알 수 없습니다.
과연 실패한 테스트를 보려면 전체 실행이 끝날 때까지 기다리는 수밖에 없을까요?
Ctrl-T가 구원자입니다!
맥(Mac)을 사용하고 있다면 테스트 실패를 미리 확인할 수 있는 방법이 있습니다.
테스트가 실행되는 동안 Ctrl-T를 눌러 보세요.
그러면 현재 실행 중인 테스트 케이스가 무엇인지, 그리고 얼마나 오래 실행되고 있는지 확인할 수 있습니다. 여기에 더해, 그때까지 실패한 테스트가 있다면 그 실패 내역까지도 함께 표시됩니다. 덕분에 다음 실행을 기다릴 필요 없이 바로 수정 작업에 착수할 수 있습니다!
이 단축키는 멈춰 버린(hang) 테스트를 디버깅할 때도 놀랍도록 유용합니다. Ctrl-T를 누르면 어떤 테스트가 실행되려고 하는 중인지 알려주기 때문에, 해당 테스트 하나만 따로 분리해 문제를 추적하고 해결할 수 있습니다.
저는 개인적으로 테스트가 눈에 띄게 오래 걸릴 때(예: 1초 이상) Ctrl-T를 누르는 습관을 들였습니다. 이 덕분에 속도 개선이 꼭 필요한 느린 테스트들을 적잖이 발견할 수 있었습니다.
Ctrl-T는 어떻게 작동할까?
맥에서 Ctrl-T는 현재 실행 중인 프로그램에 INFO라는 이름의 메시지, 즉 시그널(signal)을 전송합니다.
puts "Starting..."
trap("INFO") { puts "INFO triggered!" }
loop { print "."; sleep 0.1}
~/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는 INFO 시그널을 인식하도록 만들어져 있으며, 이 시그널을 받으면 테스트 실행 관련 정보를 출력합니다.
~/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
............................
꽤 쓸모 있죠?
이런 동작이 가능하다는 사실을 알면, 다른 애플리케이션에서도 INFO 시그널을 활용할 방법을 떠올릴 수 있습니다.
- Rails는 현재 실행 중인 컨트롤러 액션이나 성능 통계를 화면에 표시할 수 있습니다.
- Sidekiq는 각 워커(worker)가 지금 무슨 작업을 하고 있는지 알려줘서, 어디서 병목이 걸렸는지 파악하는 데 도움을 줄 수 있습니다.
실제로 Sidekiq는 과거에 INFO 시그널을 사용해 각 스레드의 백트레이스(backtrace)를 출력했었습니다. 하지만 INFO는 리눅스 환경에서 지원되지 않기 때문에 결국 다른 시그널로 전환했습니다. 안타깝게도 그 대체 시그널은 INFO처럼 키보드 단축키 한 번으로 트리거할 수 없습니다.
INFO가 리눅스에서는 사용할 수 없는 데다, 애초에 이런 용도로 INFO를 쓰는 것이 완전히 올바른 행위는 아니라고 보는 의견도 있기 때문에, 이 기능은 그 가능성만큼 널리 보급되지는 못했습니다.
그래도 다양한 상황에서 유용하게 써먹을 수 있는 작지만 확실한 도움입니다. 애플리케이션을 개발하고 있다면, 필요할 때 사용자가 요청해서 확인할 수 있는 온디맨드(on-demand) 상태 메시지로 무엇을 제공할 수 있을지 한번쯤 고민해볼 가치가 충분합니다.