Rails开发中的测试、调试、基准测试与生产部署
一、无头模式与集成测试
在开发过程中,无头模式是进行集成测试的强大工具。在接受重定向之前,我们可以检查最后请求的URL,使用如下代码:
>> app.request.original_fullpath
=> "storiesnew"
作为集成测试的一部分,无头模式还能让我们访问会话和cookie变量:
>> app.cookies
=>
#
<Rack::Test::CookieJar:0x007ff5680f2548 @default_host="www.example.com", @
[#
<Rack::Test::Cookie:0x007ff56187fb50 @default_host="www.example.com", @nam
{"path"=>"/",
"HttpOnly"=>nil,
"domain"=>"www.example.com"}>,
#
<Rack::Test::Cookie:0x007ff56183d020 @default_host="www.example.com", @nam
{"path"=>"/",
"max-
age"=>"0", "expires"=>"Thu, 01 Jan 1970 00:00:00 -0000", "domain"=>"www.ex
>> app.session[:user_id]
=> 1
当我们对测试结果满意后,就可以打开文本编辑器,将控制台的结果转化为自动化测试。
二、Pry的简介与使用
Rails自带的调试和内省工具很不错,但Pry是标准IRB shell的强大替代方案。使用Pry时,我们可以:
1. 像在命令提示符中更改目录一样更改当前上下文
2. 搜索命令历史记录
3. 直接编辑Ruby文件,并自动加载更改
4. 轻松列出给定对象或类的方法和常量
要在项目中使用Pry,我们可以添加 pry-rails 到 Gemfile 中:
group :development, :test do
gem 'byebug'
gem 'pry-rails'
end
然后运行 bundle install 。之后,使用 rails c 启动Rails控制台时,会看到新的提示符:
$ rails c
[1] pry(main)>
我们可以使用Pry的一些工具来探索对象,例如获取第一个故事对象:
[1] pry(main)> s = Story.first
=> #<Story:0x007fd72a3df6e0
id: 2,
name: "SitePoint Forums",
link: "http://community.sitepoint.com",
created_at: Sun, 13 Mar 2016 14:47:48 UTC +00:00,
updated_at: Wed, 27 Apr 2016 16:48:55 UTC +00:00,
user_id: 1,
votes_count: 8,
description: nil>
使用 cd 命令进入故事对象的上下文:
[2] pry(main)> cd s
[3] pry(#<Story>):1>
此时,我们可以直接访问故事对象的属性:
[3] pry(#<Story>):1> link
=> "http://community.sitepoint.com"
使用 ls 命令列出当前对象的方法和变量:
[4] pry(#<Story>):1> ls
ActiveRecord::Core#methods:
<=> == connection_handler encode_with eql? freeze frozen?
ActiveRecord::Persistence#methods:
becomes decrement delete destroyed? increment! persisted?
becomes! decrement! destroy! increment new_record? toggle
ActiveRecord::Scoping#methods: initialize_internals_callback populate_
ActiveRecord::Sanitization#methods: quoted_id
ActiveRecord::AttributeAssignment#methods: assign_attributes attribute
ActiveModel::Conversion#methods: to_model to_partial_path
ActiveRecord::Integration#methods: cache_key
ActiveModel::Validations#methods: errors invalid? read_attribute_for_
ActiveSupport::Callbacks#methods: run_callbacks
ActiveModel::Validations::HelperMethods#methods:
validates_absence_of validates_confirmation_of validates_format_
validates_acceptance_of validates_exclusion_of validates_inclusi
...
如果只需要实例和类变量,可以使用 ls -i :
[5] pry(#<Story>):1> ls -i
instance variables:
@_start_transaction_state @association_cache @destroyed
@aggregation_cache @attributes @destroyed_by_association
class variables:
@@configurations @@logger @@raise_in_tra
@@default_timezone @@maintain_test_schema @@schema_forma
@@dump_schema_after_migration @@primary_key_prefix_type @@time_zone_aw
我们还可以查看方法的源代码:
[6] pry(#<Story>):1> show-method to_param
From: Usersggoodrich/projects/sitepoint/readitappmodels/story.rb @ line 13:
Owner: Story
Visibility: public
Number of lines: 3
def to_param
"#{id}-#{name.gsub(/\W/, '-').downcase}"
end
要返回主上下文,只需输入 cd ... 。此外,还可以在Pry中轻松访问 ri 文档:
[6] pry(main):1> ri Array
Array < Object
----------------------------------------------------------------------
--------
Includes:
Enumerable (from ruby site)
(from ruby site)
----------------------------------------------------------------------
--------
Arrays are ordered, integer-indexed collections of any object.
...
三、基准测试
作为软件开发人员,了解应用程序各部分的性能至关重要。基准测试是测量应用程序性能并根据初始测量结果进行改进的过程。
1. 从日志文件获取基准信息
在开发和测试模式下,Rails会在日志文件中提供各种基准测试信息。例如,对于一个请求的日志记录如下:
Started GET "/stories" for 127.0.0.1 at 2016-05-06 08:11:11 -0400
Processing by StoriesController#index as HTML
这些行表示单个页面请求日志块的开始,包含控制器和动作名称、客户端IP地址、请求时间、请求方法和请求格式。
接下来是数据库查询记录:
User Load (0.3ms) SELECT "users".* FROM "users" WHERE (1) ORDER BY "use
(0.3ms) SELECT COUNT(*) FROM "stories" WHERE (votes_count >= 5)
Story Load (0.1ms) SELECT "stories".* FROM "stories" WHERE (votes_count
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ?
ActsAsTaggableOn::Tag Load (1.2ms) SELECT "tags".* FROM "tags" INNER JO
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIM
ActsAsTaggableOn::Tag Load (0.1ms) SELECT "tags".* FROM "tags" INNER JO
然后是模板渲染记录:
Rendered stories/_story.html.erb (52.8ms)
Rendered stories/index.html.erb within layouts/application (63.4ms)
最后是请求的摘要信息:
Completed 200 OK in 325ms (Views: 278.9ms | ActiveRecord: 3.1ms)
这个摘要包含了应用程序各部分处理请求所花费的总时间。
2. 手动基准测试
Rails日志文件的默认信息适合了解某个动作的大致执行时间,但无法提供特定代码块的计时信息。为此,Ruby提供了 Benchmark 模块。
例如,为 StoriesController 类中的 fetch_stories 方法添加基准测试信息:
class StoriesController < ApplicationController
⋮ class methods…
def fetch_stories(conditions)
results = Benchmark.measure do
@stories = Story.where(conditions).order("id ASC")
end
Rails.logger.info results
end
end
当请求相关页面时,基准测试信息会被添加到 log/development.log 文件中。
四、生产环境的影响
将应用程序部署到生产环境会带来四个主要变化:
1. 类不再重新加载 :在生产模式下,Ruby类不会在每次请求时重新加载,以提高性能。如果要使代码更改生效,需要重启应用程序。
2. 错误信息简化 :用户只会看到简短的错误信息,而不是详细的堆栈跟踪。可以使用 Exception Notification gem将详细的错误信息发送给系统管理员。
3. 缓存可用 :可以对页面、动作和页面片段进行缓存,以提高应用程序的性能。
4. 静态资源预编译 :Rails期望静态资源(如JavaScript和CSS文件)被预编译成单个文件,并进行摘要处理,以提高缓存性能。
五、选择生产环境
Rails应用程序的生产部署主要涉及两个主要组件:Web服务器和应用程序服务器。
- Web服务器 :擅长提供静态内容,如HTML页面、图像、JavaScript和CSS文件等。
- 应用程序服务器 :用于处理动态内容,接受请求,将其转发给Rails应用程序,并返回Web服务器和浏览器可以理解的响应。
以下是生产环境部署的流程图:
graph LR
A[客户端请求] --> B[Web服务器]
B -->|静态内容| C[返回静态文件]
B -->|动态内容| D[应用程序服务器]
D --> E[Rails应用程序]
E --> D[返回响应]
D --> B[返回响应给Web服务器]
B --> A[返回响应给客户端]
通过合理选择和配置这两个组件,可以确保应用程序在生产环境中稳定运行。
Rails开发中的测试、调试、基准测试与生产部署
六、生产环境的服务器软件选择
在选择生产环境的服务器软件时,需要考虑Web服务器和应用程序服务器的特点和适用性。以下是一些常见的选择:
| 服务器类型 | 示例 | 特点 |
|---|---|---|
| Web服务器 | Nginx、Apache | 处理静态内容效率高,可作为反向代理将请求转发给应用程序服务器 |
| 应用程序服务器 | Puma、Unicorn | 与Rails应用程序紧密集成,处理动态请求 |
七、Exception Notification gem的使用
为了在生产环境中处理错误信息,我们可以使用 Exception Notification gem。以下是使用步骤:
- 在
Gemfile中添加Exception Notificationgem:
gem 'exception_notification'
- 运行
bundle install安装gem。 - 配置
Exception Notification。在config/environments/production.rb中添加以下代码:
config.middleware.use ExceptionNotification::Rack,
email: {
email_prefix: "[ERROR] ",
sender_address: %{"notifier" <notifier@example.com>},
exception_recipients: %w{admin@example.com}
}
这样,当应用程序在生产环境中出现错误时,管理员会收到包含详细错误信息的邮件。
八、静态资源的预编译
Rails期望静态资源在生产环境中进行预编译。以下是具体的操作步骤:
- 确保
config/environments/production.rb中config.assets.compile设置为false,表示不允许在运行时编译资产。
config.assets.compile = false
- 运行以下命令进行预编译:
RAILS_ENV=production bundle exec rake assets:precompile
这个命令会将所有的JavaScript和CSS文件编译成单个文件,并进行摘要处理,提高缓存性能。
九、生产环境部署流程
为了确保Rails应用程序在生产环境中稳定运行,我们可以遵循以下部署流程:
graph LR
A[代码准备] --> B[服务器配置]
B --> C[数据库迁移]
C --> D[静态资源预编译]
D --> E[应用程序部署]
E --> F[启动应用程序]
F --> G[测试与监控]
具体步骤如下:
1. 代码准备 :确保代码已经推送到生产服务器的代码仓库。
2. 服务器配置 :配置Web服务器和应用程序服务器,确保它们可以正常工作。
3. 数据库迁移 :运行 RAILS_ENV=production bundle exec rake db:migrate 迁移数据库。
4. 静态资源预编译 :运行 RAILS_ENV=production bundle exec rake assets:precompile 预编译静态资源。
5. 应用程序部署 :将代码部署到生产服务器。
6. 启动应用程序 :启动应用程序服务器。
7. 测试与监控 :对应用程序进行测试,确保其正常运行,并设置监控工具,实时监控应用程序的性能。
十、总结
本文介绍了Rails开发中的测试、调试、基准测试以及生产部署的相关知识。通过使用无头模式进行集成测试,利用Pry进行调试,使用基准测试工具了解应用程序性能,以及正确配置生产环境,可以提高开发效率和应用程序的稳定性。
在生产部署方面,我们需要考虑生产环境的影响,选择合适的服务器软件,处理错误信息,预编译静态资源,并遵循合理的部署流程。通过这些措施,可以确保Rails应用程序在生产环境中能够高效、稳定地运行。
超级会员免费看
11

被折叠的 条评论
为什么被折叠?



