Как я могу получить цветной вывод в автотесте, используя Test / Unit, MiniTest? - PullRequest
6 голосов
/ 22 февраля 2012

Приложение Rails 3.2.1, использующее гем minitest и autotest-rails.

Если я запускаю «тест рейка», вывод будет цветным. Но если я запускаю автотест, вывод не цветной.

Как получить вывод цвета при использовании автотеста?

Вот мой 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

1 Ответ

8 голосов
/ 23 февраля 2012

Если я запускаю «тест рейка», вывод будет цветным.

Это связано с тем, что при автотестировании «терминал», на котором запущен ваш тестовый процесс, не является tty, а при непосредственном запуске -

Во-первых, как это работает, цветовые коды определяются в escape-последовательностях, которые, если вы их записали, будут выглядеть примерно так: \E[48mPRINT ME IN RED\E[0m ( details ).

Ваш терминал понимает эти escape-последовательности (обычно), заменяя их цветами, улучшая внешний вид вывода.

Используя переменные окружения, определенные эмулятором терминала, и глядя на его входные и выходные потоки (то есть $stdin, $stdout и $stderr), процесс (ы) может определить поддержку цвета, и может ли он подключен к терминалу (tty) или файлу, или другому процессу, и т. д.

Когда один процесс запускает другой процесс, ваш процесс, а не терминал, является владельцем, поэтому ваш вывод test не говорит с терминалом, который распознает цветные escape-последовательности, он обращается к автотесту, а это не так.

Такое же поведение будет происходить при выполнении ваших тестов, но перенаправляя вывод в файл, коды и последовательности escape-кода будут бессмысленными.

Отношения выглядят так:

# 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)

Есть несколько способов подделать поддержку, так что автотест выполняется в цвете, один из способов , задокументированный здесь , кажется самым надежным, без его самостоятельного тестирования.

Другой способ - просто замкнуть накоротко это «проверка на поддержку цвета» с использованием этой техники

Метод #tty? для потоков не только полезен для вышеперечисленного, но также учитывает случай, когда запускается Ruby-debug или какая-то другая «интерактивная» команда, когда процесс управления не является tty, нет никакой возможности, чтобы ruby-debug мог запросить пользователя, если он подключен к другому приложению, которое может не понимать подсказки, поэтому при потоковой передаче вывода в файл или при запуске одного процесса внутри другого интеллектуальное программное обеспечение всегда сначала проверяет, чтобы убедиться, что родительский процесс может быть сбит с толку, запрашивая ввод или отправляя нестандартный вывод.

Если вы хотите провести дополнительное чтение, взгляните на $stdin.tty? из документации Ruby, она объясняет разницу между входными и выходными потоками процессов, которые считаются ttys, и влияние, которое оказывает на выполнение вещей.

...