Каков наилучший способ для smoke test промежуточной/производственной среды в Rails?
Сначала настройка...
В настоящее время я разрабатываю приложение Rails 3 в Mac OS X с использованием Ruby 1.8.7 MRI, запускает тесты и локальные разработчики в отношении базы данных MySQL. У меня есть 3 "другие" нелокальные среды, которые мы используем в моей компании для каждого приложения, называемого dev, tqa и prod. Они запускаются в Tomcat с использованием JRuby (1.8.7) с Oracle в качестве бэкэнд.
Как вы можете видеть, среда совсем другая, и мы столкнулись с некоторыми ошибками при развертывании в среде Oracle/JRuby, которые не существуют локально (например, обработка даты и указание схем по умолчанию в Oracle).
Мне нравится запускать что-то вроде Cucumber/Webrat/Capybara локально, чтобы поразить каждый URL, открытый в приложении, чтобы убедиться, что основной материал работает (т.е. smoke test). В идеале он попадает на каждый URL-адрес и выполняет некоторые простые вещи, такие как ввод данных в формы и нажатие на кнопки и т.д.
В идеале, когда я развертываю dev/tqa, я буду запускать что-то похожее, за исключением указаний на развернутое приложение вместо локального приложения. Cucumber кажется оптимизированным для попадания в локально запущенное приложение и хорошо интегрируется с Rails, но не может работать против того, что для всех намерений является "внешним" приложением (или, по крайней мере, я не могу найти простой способ, который действительно работает).
Кроме того, когда я развертываю prod, я бы хотел, чтобы аналогичный набор тестов дыма запускался, за исключением того, что он не изменил бы состояние текущей производственной базы данных (т.е. просто GET URL-адреса).
Что-то вроде Selenium можно использовать, я думаю, но мне бы очень хотелось просто запустить задачу рейка и вернуть результаты, как я делаю с Cucumber.
Есть ли способ Rails/Ruby сделать это, или все остальные просто катят свое решение с помощью wget или Selenium?
Здесь был задан аналогичный вопрос: Автоматически smoke test все веб-страницы в приложении после развертывания
Я не уверен, что вопрос именно в том, что я имею в виду.
Ответы
Ответ 1
Да, вы можете написать тесты дыма с помощью Cucumber и Capybara и запустить их на удаленных серверах. Я сделал это, и он работает. Я также делал curl
/wget
и тому подобное в некоторых проектах, но Cucumber + Capybara позволяет вам взаимодействовать со страницами (даже теми, которые используют Javascript), а не просто очищать их.
- Драйвер Capybara
Rack::Test
не поддерживает удаленные запросы; его драйверы Javascript делают. Независимо от того, нужен ли вам на самом деле Javascript для работы на страницах, которые вы тестируете, вам нужно использовать Javascript-драйвер. Настройте Capybara для использования Javascript-драйвера в документах драйвера и пометьте теги @javascript
. (Я рекомендую драйвер poltergeist/PhantomJS, он быстрее, чем Selenium, дает лучшие ошибки, чем capybara-webkit, и его легко настроить). Бонус: вы можете делать что-то в своих тестах, которые нуждаются в Javascript, тестирование всего вашего стека, включая Javascript.
- Напишите свои тесты, чтобы они либо не нуждались в очистке после себя, либо делали это безопасно в производственной базе данных. Они не могут использовать DatabaseCleaner. (Чтобы предотвратить несчастные случаи, поместите тесты в свой проект с помощью Gemfile, который не содержит DatabaseCleaner.) Поскольку тесты дыма будут выполняться на удаленном сервере и, следовательно, не могут использовать транзакции для их очистки, они либо не должны изменять базы данных или должны удалять только те объекты, которые они создают.
- Установить
Capybara.app_host = "http://your-server.yourco.com"
- Установить
Capybara.run_server = false
(не требуется, но нет точки, на которой работает локальный сервер, который вы не будете использовать)
- Если ваши тесты модифицируют базу данных, установите среду тестовой базы данных в среду, в которой вы хотите провести smoke тест.
- Развертывание и тестирование.
Ответ 2
Один из способов просто побить ваше приложение, чтобы увидеть, если он взорвался, - это захватить список запросов GET из файла журнала вашего производственного веб-сервера и передать их в программу типа curl
или wget
, которая будет их извлекать все как можно быстрее.
Вот простой пример:
#!/usr/bin/env ruby
# rerun
require 'uri'
def extract_from_log(base_uri, log_path)
File.open(log_path) do |log|
while (line = log.gets)
if (line.match(%r{"GET (/\S+) HTTP/\d\.\d"}))
uri = URI.join(base_uri, $1)
puts uri.to_s
end
end
end
end
base_uri, log_path = ARGV
if (base_uri and log_path)
extract_from_log(ARGV[0], ARGV[1])
else
puts "Usage: #{File.basename($0)} <base_uri> <log_path>"
exit(-1)
end
Учитывая стандартный файл веб-журнала с строками, соответствующими "GET /... HTTP/1.1"
, вы можете легко извлечь пути, но необходимо предоставить базовый URI:
rerun http://example.com/ example.log
В этом списке будут указаны все URL-адреса, найденные в этом файле журнала. Вы можете передать это значение в wget
для получения данных:
rerun http://example.com/ example.log | wget -i -
Если вы что-то сломали, вы начнете получать ошибки в своем приложении, и с помощью надлежащей системы уведомлений вы сможете их поймать и отследить.