Rails 5 Test Prescriptions 第11章其餘部分的測試。

  • 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 (官方不推薦)css

集成測試中也有visit , have_current_path .html

 

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

rspec-rails中定義的匹配器route_to , be_routablegithub

 

例子:後端

RSpec.describe "project routing", :aggregate_failures, type::routing do瀏覽器

  it "routes projects" doruby

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

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

    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隊列 

能夠把做業調動到具體的隊列中。
 
       7callback回調 
      

鉤子。

 
 
 

8 Action Mailer 常見的做業是在請求-響應循環以外發生郵件,無需用戶等待。Active Job和Mailer是

集成的。使用deliver_now/deliver_later

9-11 國際化異步發送郵件;處理異常 


Testing Jobs and Cables

大概講了一下。沒有案例。Cable沒有支持單元測試 

class PublishToFeedJob < ActiveJob::Base queue_as :feeds def perform(post) post.to_feed! end endclassGuestsCleanupJob < ApplicationJob  queue_as:default  around_perform:around_cleanup  defperform    # Do something later  end  private    defaround_cleanup(job)      # Do something before perform      yield      # Do something after perform    endend
相關文章
相關標籤/搜索