在Rails中测试暂存/生产环境的最佳方法是什么?

时间:2011-04-13 13:22:37

标签: ruby-on-rails ruby cucumber smoke-testing

首先,设置......

我目前正在使用Ruby 1.8.7 MRI在Mac OS X上开发Rails 3应用程序,针对MySQL数据库运行测试和本地开发。我有3个“其他”非本地环境,我们在公司为每个名为dev,tqa和prod的应用程序使用。它们使用JRuby(1.8.7)和Oracle作为后端在Tomcat中运行。

正如您所看到的,环境完全不同,我们在部署到本地不存在的Oracle / JRuby环境时会遇到一些错误(例如日期处理和在Oracle中指定默认架构)。

我喜欢在本地运行像Cucumber / Webrat / Capybara这样的东西来点击应用程序中暴露的每个URL,以确保基本的东西正常工作(即,冒烟测试)。理想情况下,它会点击每个网址,并会执行一些简单的操作,例如在表单中输入数据和点击按钮等。

理想情况下,当我部署到dev / tqa时,我会运行类似的东西,除了指向已部署的应用程序而不是本地应用程序。黄瓜似乎已经过优化,可以在本地运行的应用程序中运行并与Rails很好地集成,但是无法针对所有意图运行“外部”应用程序(或者至少我找不到实际工作的简单方法)。

此外,当我部署到prod时,我想要运行一组类似的冒烟测试,除非它不会改变当前生产数据库的状态(即,只会获取URL)。

我猜想可以使用像Selenium这样的东西,但是我真的很喜欢只运行rake任务并像使用Cucumber那样取回结果。

是否有任何Rails / Ruby方法可以执行此操作,或者其他人是否只使用wget或Selenium推出自己的解决方案?

此处提出了类似的问题:Automatically smoke test all webpages in application, after deployment

我不确定这个问题究竟是我的想法。

2 个答案:

答案 0 :(得分:7)

是的,您可以使用Cucumber和Capybara编写冒烟测试,并针对远程服务器运行它们。我做到了,它的确有效。我还在某些项目上完成了curl / wget等等,但Cucumber + Capybara允许您与页面(甚至是使用Javascript的页面)进行交互,而不仅仅是抓取它们。

  • Capybara的Rack::Test驱动程序不支持远程请求;它的Javascript驱动程序。无论您是否确实需要Javascript来处理您正在测试的页面,您都需要使用Javascript驱动程序。根据驱动程序的文档配置Capybara使用Javascript驱动程序并标记您的测试@javascript。 (我推荐使用poltergeist / PhantomJS驱动程序;它比Selenium更快,比capybara-webkit提供更好的错误,并且易于设置。)额外奖励:你可以在你的测试中做一些需要Javascript的事情,你会被吸烟 - 测试整个堆栈,包括Javascript。
  • 编写测试,以便他们不需要自己清理或以生产数据库中安全的方式进行清理。他们不能使用DatabaseCleaner。 (为防止发生事故,请使用不包含DatabaseCleaner的Gemfile将测试放在自己的项目中。)由于冒烟测试将针对远程服务器运行,因此无法使用事务进行清理,因此必须不修改数据库或必须专门删除他们创建的对象。
  • 设置Capybara.app_host = "http://your-server.yourco.com"
  • 设置Capybara.run_server = false(不是必需的,但没有必要运行您不会使用的本地服务器)
  • 如果测试修改了数据库,请将测试数据库环境设置为要进行冒烟测试的环境。
  • 部署并测试。

答案 1 :(得分:5)

简单地打败您的应用程序以查看它是否爆炸的一种方法是从生产Web服务器日志文件中获取GET请求列表,并将其提供给curlwget等程序这将尽快获取所有内容。

这是一个简单的例子:

#!/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

给定一个标准的Web日志文件,其中的行与"GET /... HTTP/1.1"匹配,您可以轻松地提取路径,但是必须提供基本URI:

rerun http://example.com/ example.log

这将列出该日志文件中找到的所有URL。您可以将此管道传输到wget以进行抓取:

rerun http://example.com/ example.log | wget -i -

如果您已经破坏了任何内容,您将开始在应用程序中收到错误,并且通过适当的通知系统,您将能够捕获这些并跟踪它们。