• Routes✅
  • Helper Methods✅
  • Controllers and Requests✅
  • Simulating Requests⚠️,看之前的博客
  • What to Expect in a Request Spec ✅
  • Older Rails Controller Tests ❌
  • Testing Mailers ❌
  • Testing Views and View Markup✅
  • Using Presenters ❌没看需要额外gem
  • Testing Jobs and Cables
这些测试有2方面的讨论:
  • 在集成测试中应测试什么,在单元测试中应测试什么
  • 什么代码应归入controller, view, mailer,job,or其他,什么应该被提取出来放入一个不同的对象?
Rails团队更喜欢集成测试,抛弃了控制器测试,它们的观点rails中额外的layers是不需要的。因为你想让代码保持Rails结构,就多用集成测试开发,少用单元测试开发。

Testing Routes (官方不推荐)

集成测试中也有visit , have_current_path .

RSpec-Rails 把routing test 放入spec/routing 目录。

rspec-rails中定义的匹配器route_to , be_routable

例子:

RSpec.describe "project routing", :aggregate_failures, type::routing do

it "routes projects" do

expect(get: "projects/new").to route_to(

controller:"projects", action:"show", id:"1")

    expect(delete: "/projects/1").to route_to(

controller: "projects", action: "destroy", id: "1")

expect( get: "/projects/search/fred").not_to  be_routable ,#路径不存在。

end

end


Testing Helper Methods (不推荐使用)

Helper modules

设计用于保存可反复用的视图逻辑。 视图指定的数据的存在,或者条件逻辑:关于内容显示。

因为测试它们的有点tricky,一般不测试helper modules.

目录: spec/helpers

例子:

对页面的project的显示状态schedule进行不同的设计。设计使用css,根据是否在计划表中使用不同的css进行装饰。因此会根据project的schedule相关属性来改变css.

given: 一个project,和它的schedule属性

when:调用helper方法name_with_status,返回一个<span>及对应的class。

then: 判断返回的结过,是否是希望的selector.

RSpec.describe ProjectsHelper, type: :helper do
  let(:project) { Project.new(name: "Project Runway") }
  it "augments with status info when on schedule" do
    allow(project).to receive(:on_schedule?).and_return(true) 
    actual = helper.name_with_status(project)
    expect(actual).to have_selector("span.on_schedule", text: "Project Runway")
  end
  it "augments with status info when behind schedule" do
    allow(project).to receive(:on_schedule?).and_return(false)
    actual = name_with_status(project)
    expect(actual).to have_selector("span.behind_schedule", text:"Project Runway")
  end
end
然后运行出错,在app/helpers/projects_helper.rb文件中。
module ProjectsHelper
  def name_with_status(project)
    if  project.on_schedule?
      dom_class = "on_schedule"
    else
      dom_class = "behind_schedule"
    end
    content_tag(:span, project.name, class: dom_class)
  end
end
再测试成功

#helper是对象,删掉不影响测试。

Block作为wrapper也是很有帮助的,它可以包含许多不同类型的text:

例子:

def if_logged_in

yield if logged_in?

end

对应的是:

<% if_logged_in do%>

<%= link_to "logout", logout_path %>

<% end %>

对应的测试方法:

it "displays if logged in" do
login_as users( :quentin )
expect(logged_in?).to be_truthy
expect(if_logged_in { "logged in" }).to eq( "logged in" )

end


Testing Controllers and Requests (官方已遗弃)

官方放弃了控制器测试的一些功能。

本章看RSpec features in Rails 5,然后回顾控制器测试在之前的版本如何工作的。

reason

  • 有经验的Rails coders ,新用rails5可能会用这些功能
  • 新手,你很可能会邂逅控制器测试,所以你想要看看它做什么。
RSpec for Rails5有2种测试类型,设计用于测试单一的控制器行为,它们类似:
  • Request specs 是wrappers around集成测试
  • controller test 是 RSpec wrappers around Rails5 controller tests.

Simulating Requests

models比requests更容易测试 ,容易提取,在一个测试框架内使用独立。

需要用到HTTP verb

What to Expect in a Request Spec

have_http_status (:success/:missing/:redirect/:error)

:success 200–299

:redirect 300–399

:missing 404

:error 500–599

参考博文:

https://www.cnblogs.com/chentianwei/p/9055336.html 

https://www.cnblogs.com/chentianwei/p/9060522.html 


Testing Mailers (没看)

mailers功能还不是很了解。


Testing Views and View Markup

之前测试了一个project status的helper,但在浏览器这个新status DOM元素没有显示。因为模版view还没有改动。 此时:

  • 如果原则上没有逻辑的改变,或对大的架构无关紧要,并且很容易检查。就无需测试
  • 可以写个集成测试使用Capybara.如果你是out-in development,你已经在集成测试中写了测试。
  • 如果是个新加的功能,还有第三种办法,写一个Rails view test。比集成测试快。
默认的约定目录: spec/views/projects/index.html.erb_spec.rb

RSpec 允许视图测试独立于控制器。也不推荐在控制器测试中加入视图测试。

视图测试文件加后缀_spec 和 视图文件一一对应。

作者说:

很少写这类测试,因为文件结构很难维持一致(经常变化?)。作者在视图中建立的逻辑常常在集成测试和对象中测试。总的来说,完全的TDD-view很难,先写视图代码,再测试更容易。

现在用第三个办法实做:

require "rails_helper"
describe "projects/index" do #会定位到app/views/projects/index_html.erb
  let(:on_schedule) { FactoryBot.build_stubbed(:project, 
  due_date: 1.year.from_now, name: "On Schedule") }
  let(:behind_schedule) { FactoryBot.build_stubbed(:project,
due_date: 1.day.from_now, name: "Behind Schedule") }
  let(:completed_task) { FactoryBot.build_stubbed(:task, completed_at: 1.day.ago,

project_id: on_schedule.id) }

  let(:incomplete_task) { FactoryBot.build_stubbed(:task,

project_id:behind_schedule.id) }

  it "renders the index page with correct dom elements" do
    @projects = [on_schedule, behind_schedule]
    render

#可以写完整的,如果是partial,就要写清楚了如:render partial:""

    expect(rendered).to have_selector(
      "#project_#{on_schedule.id} .on_schedule")
    expect(rendered).to have_selector(
      "#project_#{behind_schedule.id} .behind_schedule")
  end
end

测试❌,因为没改view 。

      <tr class="project-row" id="<%= dom_id(project) %>">

<td class="name"> <%=  name_with_status(project)  %> </td>



Testing Jobs and Cables


先看一下指导。

Active Job Basics(假设开发者不是新人了。我还没有看懂,需要实例,案例及相关讲解)

说明创建,入队和执行后台作业的基础知识。

1.介绍

Jobs是一个框架,声明jobs并让它们在各种队列后端运行。这些jobs可以是任意事情,从定期规范的清理,到账单收费,到发邮件。任何事情都能被分成多个小单位的工作并平行运行。

2.目的

确保Rails apps将有一个工作基础设施。我们然后把框架特点和其他gems建立在它的上面。 无需担心不同jobs运行程序(Resque/Delayed)的API之间的差异。

3.创建 Jobs

 bin/rails generate job guests_cleanup
 invoke  test_unit
 create    test/jobs/guests_cleanup_job_test.rb
 create  app/jobs/guests_cleanup_job.rb

class GuestsCleanupJob < ApplicationJob

queue_as :default

def perform(*args)

# Do sth later

end

end

4 Enqueue the job 作业入队

#入队一个作业,作业在队列系统空闲的时候就立刻执行。

GuestsCleanupJob.perform_later guest

#入队一个作业,设定在明天的中午执行。

GuestsCleanupJob.set(wait_until: Date.tomorrow.noon).perform_later(guest)

#set(options={})具体见API,创建一个job并预制一些设置参数。可以和perform_later连用。

wait: 1.week

wait_until:

queue:指定作业在哪个队列中运行。

#'perform_later'"perform_now" 会在幕后调用perform

GuestsCleanupJob.perform_later(guest1,guest2, filter:"some_filter")

5. 执行jobs

生产环境中的多数应用应该挑选一个持久后端,即第三方队列库。

5.1backend后端

Active Job 为多种队列后端(Sidekiq、8000+星)内置了适配器。

5.2设置后端

在config/application.rb中设置,或者在各个作业中配置后端也行。

http://guides.rubyonrails.org/active_job_basics.html

5.3 启动后端

看Sidekiq相关配置:

https://github.com/mperham/sidekiq/wiki/Active+Job

6 queue队列

可以把作业调动到具体的队列中。

class PublishToFeedJob < ActiveJob::Base
queue_as :feeds def perform(post)
post.to_feed!
end
end

7callback回调

钩子。

class GuestsCleanupJob < ApplicationJob
  queue_as :default
 
  around_perform :around_cleanup
 
  def perform
    # Do something later
  end
 
  private
    def around_cleanup(job)
      # Do something before perform
      yield
      # Do something after perform
    end
end
8 Action Mailer
常见的作业是在请求-响应循环之外发生邮件,无需用户等待。Active Job和Mailer是

集成的。使用deliver_now/deliver_later

9-11 国际化异步发送邮件;处理异常


Testing Jobs and Cables

大概讲了一下。没有案例。Cable没有支持单元测试




Rails 5 Test Prescriptions 第11章其他部分的测试。的更多相关文章

  1. Rails 5 Test Prescriptions 第8章 Integration Testing with Capybara and Cucumber

    Capybara:  A complete reference is available atrubydoc.info. 集成测试就是把局部的程序组合起来测试. 端到端测试是一个特殊的集成测试,覆盖了 ...

  2. Rails 5 Test Prescriptions 第3章Test-Driven Rails

    本章,你将扩大你的模型测试,测试整个Rails栈的逻辑(从请求到回复,使用端到端测试). 使用Capybara来帮助写end-to-end 测试. 好的测试风格,包括端到端测试,大量目标明确的单元测试 ...

  3. Rails 5 Test Prescriptions 第10章 Unit_Testing JavaScript(新工具,learn曲线太陡峭,pass)

    对Js的单元测试是一个大的题目.作者认为Ruby的相关测试工具比Js的测试工具更灵活 大多数Js代码最终是关于响应用户的行为和改变DOM中的元素 没有什么javascript的知识点.前两节用了几个新 ...

  4. Rails 5 Test Prescriptions 第9章 Testing-JavaScript: Integration Testing,❌挂一个问题webpacker::helper

    使用Capybara进行JS的集成测试 谈论驱动 让测试通过 Webpack in Development Mode Js设计 是用户在网页上有好的体验的重要因素. 尽管如此,许多网页不测试JS. 部 ...

  5. Rails 5 Test Prescriptions 第6章Adding Data to Tests

    bcreate the data quickly and easily.考虑测试运行的速度. fixtures and factories.以及下章讨论的test doubles,还有原生的creat ...

  6. Rails 5 Test Prescriptions 第5章 Testing Models

    Rails,model层包含业务逻辑和储存逻辑.其中储存逻辑被ActiveRecord处理. 在model中,不是每件事都必须是ActiveRecord对象.model layer可以包含各种服务,对 ...

  7. Rails 5 Test Prescriptions 第4章 什么制造了伟大的测试

    伴随着程序成长,测试变长,复杂性增加,如何更高效的写测试,对以后开发不会造成麻烦. 测试本身没发被测试,所以一定要清楚,可控.不要加循环,不要过于复杂的自动编程. Cost and Value 成本和 ...

  8. Rails 5 Test Prescriptions 第10章 Testing for Security

    Web 安全是一个可怕的主题.所有的你的程序都依靠密码学,代码超出了你的控制. 尽管如此,你还是可以控制部分网页安全 --所有的logins和access checks和injection error ...

  9. Rails 5 Test Prescriptions 第7章 double stub mock

    https://relishapp.com/rspec/rspec-mocks/v/3-7/docs/basics/test-doubles 你有一个问题,如果想为程序添加一个信用卡程序用于自己挣钱. ...

随机推荐

  1. 麦子学院bootstrap实战项目官网,后台,jquery.singlePageNav.min.js ,wow.min.js,animate.css使用

    1.源码笔记 我的源码+笔记(很重要):链接: https://pan.baidu.com/s/1eSxgLV0 密码: 2pi2 感谢麦子学院项目相关视频:链接: https://pan.baidu ...

  2. Squirrel语言初探(可以使用VC6或者MinGW编译)

    Squirrel语言初探 为啥我要关注Squirrel语言?原来Squirrel就很像我希望设计出的理想中的语言(当然也不完全符合).比如我觉得Lua的语法表述不清晰,累赘,于是想用C系语法来代替Lu ...

  3. APM最佳实践: 诊断平安城市视频网性能问题

    前言: 平安城市已经是一个关系你我他的民生工程,但由于本身系统的复杂性,给运维工作带来了极大的挑战.如何保障摄像头在线率?如何在系统中找到视频系统故障的问题所在?在我们某一次项目经历中,APM在发现问 ...

  4. SSL/TSL握手过程详解

    1. Client Hello 握手第一步是客户端向服务端发送 Client Hello 消息,这个消息里包含了一个客户端生成的随机数 Random1.客户端支持的加密套件(Support Ciphe ...

  5. SaltStack系列(一)之环境部署、命令及配置文件详解

    一.SaltStack介绍 1.1 saltstack简介: saltstack是基于python开发的一套C/S架构配置管理工具,它的底层使用ZeroMQ消息队列pub/sub方式通信,使用SSL证 ...

  6. PAT 1061 Dating[简单]

    1061 Dating(20 分) Sherlock Holmes received a note with some strange strings: Let's date! 3485djDkxh4 ...

  7. Python---2. 函数

    转载: Py西游攻关之函数 补充: map函数和reduce函数的区别

  8. VS2010/MFC编程入门之十一(对话框:模态对话框及其弹出过程)

    加法计算器对话框程序大家照着做一遍后,相信对基于对话框的程序有些了解了,有个好的开始对于以后的学习大有裨益.趁热打铁,鸡啄米这一节讲讲什么是模态对话框和非模态对话框,以及模态对话框怎样弹出. 一.模态 ...

  9. FTP服务器配置实践

    1.为linux系统分配IP地址:192.168.X.1/24,并重启网络服务,客户端XP系统IP地址为:192.168.X.2/24, 2.查询本机是否安装了vsftpd服务,结果显示未安装,挂载光 ...

  10. mongo增删改查封装(C#)

    Framework版本:.Net Framework 4 ConnectionUtil源码参见:https://www.cnblogs.com/threadj/p/10536273.html usin ...