成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

[譯]我們?nèi)绾螠y(cè)試 Rails 應(yīng)用

wenhai.he / 1117人閱讀

摘要:無(wú)論合適,優(yōu)先使用的,而不是。這是一個(gè)很有用的工具在測(cè)試中用來(lái)視圖化。這點(diǎn)非常好,因?yàn)槲覀儾幌肴魏螠y(cè)試數(shù)據(jù)會(huì)對(duì)別的測(cè)試產(chǎn)生副作用。為了遵照的最佳實(shí)踐,我們用測(cè)試間諜,這樣我們的期待會(huì)進(jìn)入最佳的狀態(tài)。下一步這僅僅是個(gè)如何開(kāi)始測(cè)試應(yīng)用的概覽。

Josh Steiner January 14, 2014

我常常被問(wèn)到,怎樣開(kāi)始測(cè)試 Rails 程序。其實(shí)最為一個(gè)測(cè)試新手,最難得地方在于你不知道一些專業(yè)術(shù)語(yǔ)或者該問(wèn)怎樣的問(wèn)題。下面所寫(xiě)的是一些概覽,關(guān)于我們使用什么工具,為什么使用這些工具,和一些需要牢記在心的建議。

RSpec

我們用 RSpec 而不是 Test::Unit,是因?yàn)檎Z(yǔ)法更友好,可讀性更高。當(dāng)然,你可以花幾天時(shí)間爭(zhēng)論到底該用哪個(gè)框架,每個(gè)框架都有自己的優(yōu)點(diǎn)。最主要的是你在用他們進(jìn)行測(cè)試。

Feature specs

Feature specs,可以測(cè)試你整個(gè)程序的高級(jí)測(cè)試工具,保證每個(gè)部件都工作正常,挺贊的。他是從用戶的角度編寫(xiě)的,比如用戶點(diǎn)擊或者填寫(xiě)表單。我們用 RSpec 和 Capybara,他們?cè)试S你寫(xiě)照這樣編寫(xiě)可以和網(wǎng)頁(yè)進(jìn)行交互的測(cè)試。

這是一個(gè) RSpec feature 測(cè)試的栗子:

# spec/features/user_creates_a_foobar_spec.rb

feature "User creates a foobar" do
  scenario "they see the foobar on the page" do
    visit new_foobar_path

    fill_in "Name", with: "My foobar"
    click_button "Create Foobar"

    expect(page).to have_css ".foobar-name", "My foobar"
  end
end

這個(gè)測(cè)試,模擬了一個(gè)用戶打開(kāi)新建foobar的表單,填入信息,點(diǎn)擊“Create”。這個(gè)測(cè)試然后假設(shè)頁(yè)面正如期待,正確地顯示剛才創(chuàng)建的foobar。

這些對(duì)于測(cè)試高級(jí)功能來(lái)說(shuō)很棒,但是記住,feature specs 跑起來(lái)很慢。在用 Capybara 測(cè)試應(yīng)用所有的可能路徑的時(shí)候,把測(cè)試的邊緣情況留模型,視圖,控制器的 sepecs。

我傾向于關(guān)于怎么區(qū)分 Rspec 和 Capybara 方法的不同點(diǎn)。Capybara 方法實(shí)際上是和頁(yè)面進(jìn)行交互,比如點(diǎn)擊,表單操作,或者在頁(yè)面上查找元素。你可以在 Capybara 的finders,matchers,和 actions 查看更多文檔。

Model specs

Model specs 經(jīng)常被用來(lái)測(cè)試系統(tǒng)中較小的部件,比如類或方法,這點(diǎn)和單元測(cè)試挺相似的。有時(shí),他們也會(huì)和數(shù)據(jù)庫(kù)進(jìn)行交互。他們運(yùn)行起來(lái)很快,也可以處理正在測(cè)試系統(tǒng)(system under test)中的一些邊緣情況。

在 RSpec 中,他們看起來(lái)像這樣:

# spec/models/user_spec.rb

# Prefix class methods with a "."
describe User, ".active" do
  it "returns only active users" do
    # setup
    active_user = create(:user, active: true)
    non_active_user = create(:user, active: false)

    # exercise
    result = User.active

    # verify
    expect(result).to eq [active_user]

    # teardown is handled for you by RSpec
  end
end

# Prefix instance methods with a "#"
describe User, "#name" do
  it "returns the concatenated first and last name" do
    # setup
    user = build(:user, first_name: "Josh", last_name: "Steiner")

    # excercise and verify
    expect(user.name).to eq "Josh Steiner"
  end
end

為了維護(hù)的可讀性,確保你寫(xiě)的測(cè)試是 Four Phase Test


?

The Four-Phase Test is a testing pattern, applicable to all programming languages and unit tests (not so much integration tests).
It takes the following general form:

test do
  setup
  exercise
  verify
  teardown
end

比如:

it "encrypts the password" do
  user = User.new(password: "password")
  user.save
  user.encrypted_password.should_not be_nil
end
Controller specs

當(dāng)通過(guò)一個(gè)控制器測(cè)試多個(gè)路徑的時(shí)候,我們喜歡用 controller specs 而不是 feature specs,因?yàn)樗芸?,而且?xiě)起來(lái)容易。

一個(gè)好的測(cè)試驗(yàn)證的 use case:

# spec/controllers/sessions_controller_spec.rb

describe "POST #create" do
  context "when password is invalid" do
    it "renders the page with error" do
      user = create(:user)

      post :create, session: { email: user.email, password: "invalid" }

      expect(response).to render_template(:new)
      expect(flash[:notice]).to match(/^Email and password do not match/)
    end
  end

  context "when password is valid" do
    it "sets the user in the session and redirects them to their dashboard" do
      user = create(:user)

      post :create, session: { email: user.email, password: user.password }

      expect(response).to redirect_to "/dashboard"
      expect(controller.current_user).to eq user
    end
  end
end
View specs

View specs 對(duì)于測(cè)試在模板中根據(jù)條件顯示不同信息來(lái)說(shuō)非常有用,但是很多開(kāi)發(fā)者卻忘了這個(gè),而用 feature specs。然后絞盡腦汁為什么他們花了那么長(zhǎng)時(shí)間跑測(cè)試。當(dāng)然,你可以用 feature spec 覆蓋每一個(gè)條件視圖,但我更喜歡像這樣使用 view specs :

# spec/views/products/_product.html.erb_spec.rb

describe "products/_product.html.erb" do
  context "when the product has a url" do
    it "displays the url" do
      assign(:product, build(:product, url: "http://example.com")

      render

      expect(rendered).to have_link "Product", href: "http://example.com"
    end
  end

  context "when the product url is nil" do
    it "displays "None"" do
      assign(:product, build(:product, url: nil)

      render

      expect(rendered).to have_content "None"
    end
  end
end
FactoryGirl

當(dāng)編寫(xiě)測(cè)試代碼的時(shí)候,你會(huì)需要在不同場(chǎng)景往數(shù)據(jù)庫(kù)里灌數(shù)據(jù)。你可以使用內(nèi)建的User.create,但是當(dāng) model 中有很多 validations 時(shí)候,這樣好乏味啊。通過(guò)User.create,即便你的測(cè)試代碼和這些驗(yàn)證無(wú)關(guān),你也不得不指定屬性來(lái)滿足 validations。最重要的是,如果后來(lái)你修改了 validations,你還要重新修改測(cè)試套件的代碼。解決方案就是用 factories(工廠,數(shù)據(jù)生成器) 或者 fixtures(夾具)來(lái)創(chuàng)建模型。

我們更喜歡 factories(和 FactoryGirl)勝過(guò) Rails 的 fixgures,因?yàn)?fixtures 是神秘嘉賓。夾具讓人很難看到內(nèi)因和效果,因?yàn)椴糠诌壿嬙谀闶褂盟臅r(shí)候已經(jīng)在文件中被定義好了。因?yàn)閵A具遠(yuǎn)在在測(cè)試之前就已經(jīng)被生成,他們變得很難控制。

Factories,另一方面來(lái)說(shuō),把邏輯正確地放到測(cè)試中。這讓我們很容易地看到正在發(fā)生什么,而且對(duì)于不同的場(chǎng)景更加靈活。Factories 比夾具更慢,但是從靈活性和可讀性上來(lái)說(shuō),這點(diǎn)犧牲是值得的!

把數(shù)據(jù)固化到數(shù)據(jù)庫(kù)也會(huì)減慢測(cè)試速度。無(wú)論合適,優(yōu)先使用 FactoryGirl 的 build_stubbed,而不是createbuild_stubbed 會(huì)在內(nèi)存中生成,避免寫(xiě)入磁盤(pán)。如果你測(cè)試一些查詢操作(User.where(admin: true)),你會(huì)希望從數(shù)據(jù)庫(kù)里進(jìn)行查找,這就意味著你必須使用create。

跑帶有 JavaScript 的 specs

你會(huì)最終碰到一種場(chǎng)景,你需要測(cè)試一些依賴 JavaScript 代碼的功能。用默認(rèn)的驅(qū)動(dòng)跑 specs 不會(huì)執(zhí)行頁(yè)面中任何 JavaScript 代碼。

你需要兩個(gè)法器,來(lái)跑帶有 JavaScript 代碼的功能 specs

安裝一個(gè) JavaScript 驅(qū)動(dòng)

有兩種類型的 JavaScript 驅(qū)動(dòng)。比如像 Selenium,它會(huì)打開(kāi)一個(gè) GUI 窗口瀏覽器,然后在你看著它的時(shí)候,在頁(yè)面上點(diǎn)擊。這是一個(gè)很有用的工具在測(cè)試中用來(lái)視圖化。但是不幸的是,啟動(dòng)一整個(gè) GUI 窗口瀏覽器很慢。由于這個(gè)原因,我們傾向于使用 headless 瀏覽器。對(duì)于 Rails 來(lái)說(shuō),你可能會(huì)使用 Poltergeist 或者 [Capybara] Webkit(https://github.com/thoughtbot/capybara-webkit)。

對(duì)于特定的測(cè)試使用 JavaScript 元數(shù)據(jù)關(guān)鍵字

feature "User creates a foobar" do
   scenario "they see the foobar on the page", js: true do
     ...
   end
 end

用合適的關(guān)鍵字,RSpec 會(huì)根據(jù)需要運(yùn)行任何 JavaScript。

清理數(shù)據(jù)庫(kù)

默認(rèn)情況下,跑 Rails 測(cè)試的時(shí)候,Rails 會(huì)把每個(gè)場(chǎng)景都存在數(shù)據(jù)庫(kù)事務(wù)中。這就說(shuō)明,在每個(gè)測(cè)試結(jié)束的時(shí)候,Rails 會(huì)回滾所有在測(cè)試中的修改。這點(diǎn)非常好,因?yàn)槲覀儾幌肴魏螠y(cè)試數(shù)據(jù)會(huì)對(duì)別的測(cè)試產(chǎn)生副作用。

不幸的是,當(dāng)我們使用 JavaScript 驅(qū)動(dòng)的時(shí)候,這個(gè)測(cè)試實(shí)在另一個(gè)線程進(jìn)行的。這就意味著,它并沒(méi)有和程序共用同一個(gè)數(shù)據(jù)庫(kù)連接,而且為了運(yùn)行程序看到測(cè)試結(jié)果,你的測(cè)試會(huì)提交這個(gè)事務(wù)。為了解決這個(gè)問(wèn)題,我們可以允許數(shù)據(jù)庫(kù)提交這些數(shù)據(jù),然后接著,在每個(gè) spec 后 Truncate 數(shù)據(jù)庫(kù)。這樣會(huì)比事務(wù)慢一點(diǎn),所以,我們只在需要的時(shí)候使用 truncation。

這就是 Database Cleaner 的用處。Database Cleaner 允許你配置策略。我建議閱讀下 Avdi 的文章 看看血淋淋的細(xì)節(jié)。這是個(gè)極(喪)其(心)詳(?。┘?xì)(狂)的配置過(guò)程,所以我通常在項(xiàng)目中來(lái)回拷貝這個(gè)文件,或者使用 Suspenders,這樣就可以輕易搞定了。

doubles 和 stubs 方法

double 方法可以模擬系統(tǒng)中另外一個(gè)對(duì)象。經(jīng)常的,你會(huì)需要一個(gè)替身,并且只測(cè)試一個(gè)屬性,所以不值得加載整個(gè) ActiveRecord 對(duì)象。

car = double(:car)

當(dāng)你使用 stubs,你是在告訴一個(gè)對(duì)象去響應(yīng)一個(gè)已給出的方法。如果 stub 之前的 double

car.stub(:max_speed).and_return(120)

我們現(xiàn)在可以期待當(dāng)訪問(wèn) max_speed 我們的 car 對(duì)象總是返回120。臨時(shí)產(chǎn)生可以響應(yīng)一個(gè)方法的對(duì)象而且?guī)в型瑯拥囊蕾囮P(guān)系,而不用系統(tǒng)中真的存在的對(duì)象,這是很棒的方法!在這個(gè)栗子中,我們?cè)谝粋€(gè) double 出來(lái)的對(duì)象上進(jìn)行了 stub,實(shí)際上你還可以在別的對(duì)象 stub 任何方法。

我們可以把上邊的代碼簡(jiǎn)化為這樣:

car = double(:car, max_spped: 120)

測(cè)試間諜(Test Spies)

當(dāng)測(cè)試你的程序時(shí),你會(huì)碰到你想驗(yàn)證當(dāng)一個(gè)對(duì)象接收到一個(gè)指定的方法的場(chǎng)景。為了遵照 Four Phase Test 的最佳實(shí)踐,我們用測(cè)試間諜,這樣我們的期待會(huì)進(jìn)入最佳的 verify 狀態(tài)。之前,我們用 Bourne 做到這點(diǎn),但是 RSpec 已經(jīng)在 RSpec Mocks 中包括了這項(xiàng)功能??纯次臋n中的這個(gè)栗子:

invitation = double("invitation", accept: true)

user.accept_invitation(invitation)

expect(invitation).to have_received(:accept)
用 Webmock stub 外部請(qǐng)求

基于三方服務(wù)的測(cè)試套件跑起來(lái)很慢的,會(huì)因?yàn)榫W(wǎng)絡(luò)連接的斷開(kāi)導(dǎo)致失敗,而且也可能會(huì)因?yàn)榉?wù)頻率限制或者缺少沙盒環(huán)境導(dǎo)致失敗。

確保你的測(cè)試套件在用 Webmock stub 外部請(qǐng)求的時(shí)候,不會(huì)和三方服務(wù)交互。這個(gè)可以配置在 spec/spec_helper.rb

require "webmock/rspec"
WebMock.disable_net_connect!(allow_localhost: true)

避免使用三方請(qǐng)求,學(xué)習(xí)怎樣 stub 外部服務(wù)請(qǐng)求。

下一步

這僅僅是個(gè)如何開(kāi)始測(cè)試 Rails 應(yīng)用的概覽。為了促進(jìn)學(xué)習(xí),我非常推薦你上我們的 TDD workshop,在這里,你可以通過(guò)從零開(kāi)始建立兩個(gè) Rails 應(yīng)用,來(lái)深度學(xué)這些課程。課程覆蓋到重構(gòu),為確保應(yīng)用和測(cè)試代碼的可維護(hù)性。TDDworkshop 的學(xué)生也可以介入我們的工作時(shí)間,你實(shí)時(shí)地可以問(wèn)我們攻城獅任何問(wèn)題。

當(dāng)我是新手的時(shí)候我學(xué)習(xí)了這個(gè)課程,我墻裂推薦!

source: http://www.tuicool.com/articles/JrQzyi

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/8681.html

相關(guān)文章

  • 用Jasmine和Sinon測(cè)試Backbone應(yīng)用 ()

    摘要:框架本身可以很好地支持自下而上的單元測(cè)試。在中,這些原因可以分為性能真實(shí)的操作,依靠定時(shí)行為及網(wǎng)絡(luò)活動(dòng)減慢了測(cè)試隔離單元測(cè)試應(yīng)把重點(diǎn)放在小的一塊功能成為可能,并解耦不可靠的或低依賴使用對(duì)象是擁抱和的基本組成部分。 最近在慢慢深入Backbone,也試著寫(xiě)一些測(cè)試,找一些合適的文檔來(lái)學(xué)習(xí)。于是就找到了一個(gè)系列的文章 : Testing Backbone applications with...

    ralap 評(píng)論0 收藏0
  • 代碼級(jí)干貨 | 如何利用Docker與Rails API gem構(gòu)建微服務(wù)

    摘要:今天小數(shù)給大家?guī)?lái)的是一篇代碼級(jí)干貨文章,與大家分享一些利用以微服務(wù)形式設(shè)置應(yīng)用的經(jīng)驗(yàn)與心得。為何選擇加在我效力的企業(yè)中,我們一直在利用為全部工程師構(gòu)建開(kāi)發(fā)環(huán)境。運(yùn)行命令,從而利用構(gòu)建鏡像并安裝。 今天小數(shù)給大家?guī)?lái)的是一篇代碼級(jí)干貨文章,與大家分享一些利用Rails API以微服務(wù)形式設(shè)置應(yīng)用的經(jīng)驗(yàn)與心得。 為何選擇Docker加Rails API? 在我效力的企業(yè)中,我們一直在利用...

    stefanieliang 評(píng)論0 收藏0
  • Vuejs自己的構(gòu)建工具

    摘要:然而,這些模板并不限制你自己對(duì)于使用的架構(gòu)組織和選擇類庫(kù)。目前可用的模板包括全功能的,包括熱加載,靜態(tài)檢測(cè),單元測(cè)試一個(gè)簡(jiǎn)易的,以便于快速開(kāi)始。 最近, 尤大在和人對(duì)噴的時(shí)候,悄然放出了一個(gè)大招,于是為了追趕他的步伐,趕緊試驗(yàn)了下,并且把原文給大家翻譯下。 原文地址:Announcing vue-cli 譯文源地址: Vuejs自己的構(gòu)建工具 先上原文翻譯: 最近有很多大量關(guān)于Reac...

    leoperfect 評(píng)論0 收藏0
  • 】PHP:40+開(kāi)發(fā)工具推薦

    摘要:今天,就為開(kāi)發(fā)者介紹個(gè)方便的工具。對(duì)開(kāi)發(fā)者來(lái)說(shuō),是一個(gè)非常有用的工具,它提供了超過(guò)個(gè)有用的函數(shù)。該工具檢查輸入源代碼和報(bào)告任何違反給定的標(biāo)準(zhǔn)。框架是一個(gè)開(kāi)發(fā)的工具。它側(cè)重于安全性和性能,絕對(duì)是最安全的開(kāi)發(fā)框架之一。 PHP是為Web開(kāi)發(fā)設(shè)計(jì)的服務(wù)器腳本語(yǔ)言,但也是一種通用的編程語(yǔ)言。超過(guò)2.4億個(gè)索引域使用PHP,包括很多重要的網(wǎng)站,例如Facebook、Digg和WordPress。...

    dreambei 評(píng)論0 收藏0
  • 測(cè)試驅(qū)動(dòng)開(kāi)發(fā):使用 Node.js 和 MongoDB 構(gòu)建 Todo API

    摘要:首先安裝單元測(cè)試環(huán)境使用模塊來(lái)模擬定義的模型。根據(jù)刪除這是單元測(cè)試的最后一小節(jié)。需要根據(jù)需求和單元測(cè)試用例來(lái)編寫(xiě)應(yīng)用邏輯,使我們的程序更加穩(wěn)定。我們會(huì)運(yùn)行自動(dòng)測(cè)試用例,一直重構(gòu),直到所有單元測(cè)試都通過(guò)。 本文轉(zhuǎn)載自:眾成翻譯譯者:文藺鏈接:http://www.zcfy.cc/article/746原文:https://semaphoreci.com/community/tutoria...

    邱勇 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<