Rails 3.2.1 app, using the minitest and autotest-rails gems.
If I run "rake test" the output is in color. But if I run autotest, the output is not in color.
How can I get color output when using autotest?
Here's my test_helper.rb:
ENV["RAILS_ENV"] = "test"
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
require 'turn/autorun'
Turn.config do |c|
# use one of output formats:
# :outline - turn's original case/test outline mode [default]
# :progress - indicates progress with progress bar
# :dotted - test/unit's traditional dot-progress mode
# :pretty - new pretty reporter
# :marshal - dump output as YAML (normal run mode only)
# :cue - interactive testing
c.format = :pretty
# turn on invoke/execute tracing, enable full backtrace
c.trace = true
# use humanized test names (works only with :outline format)
c.natural = true
end
class ActiveSupport::TestCase
# Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
#
# Note: You'll currently still have to declare fixtures explicitly in integration tests
# -- they do not yet inherit this setting
fixtures :all
# Add more helper methods to be used by all tests here...
end
If I run "rake test" the output is in color.
This is because under autotest the "terminal" that your test processess is running in is not a tty
, and when you run directly, it is.
Firstly how it works, color codes are defined in escape sequences, which if you wrote them down would look like something like \E[48mPRINT ME IN RED\E[0m
(details).
Your terminal understands these escape sequences (normally), replacing them with colors, improving the appearance of the output.
By using environmental variables defined by the terminal emulator, and looking at it's it's input, and output streams (that is $stdin
, $stdout
, and $stderr
) processe(s) can determine color support, and whether it's connected to a terminal (tty
) or a file, or another process, or etc.
When one process starts another process, your process, not the terminal is the owner, so your test
output isn't talking to a terminal that understands colored escape sequences, it's talking to autotest, which doesn't.
The same behaviour would happen, running your tests, but redirecting the output to a file, the escape codes and sequences would be meaningless.
The relationship looks like this:
# rake test
Terminal Application
\- Bash
\- rake # Rake's $stdout.tty? => true
# (Bash is a terminal emulator)
# autotest
Terminal Application
\- Bash
\- autotest
\- rake # Rake's $stdout.tty? => false
# (Autotest is not a terminal emulator)
There's a few ways to fake the support, so that autotest runs in colour, one way documented here would appear to be the most robust, without having tested it myself.
The other way, is simply to short-circuit it's "check for color support" using this technique
The method #tty?
on the streams isn't just useful for the above, but also consider the case that one runs Ruby-debug, or some other "interactive" command, when the controlling process isn't a tty, there's no way ruby-debug can prompt the user, if it's connected to another application, which might not understand the prompts, so when streaming output to a file, or running one process inside another, smart software always checks first, to see if the parent process might be confused by prompting for input, or sending non-standard output.
If you want to do some additional reading, take a look at $stdin.tty?
from the Ruby documentation, it explains the difference between the processes input and output streams being considered to be ttys and the effect that has on how things execute.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With