簡體   English   中英

Rails:minitest是否使用schema.rb重新創建測試模式?

[英]Rails: does minitest use schema.rb to recreate the test schema?

我試圖讓傳統的Rails系統達到更新的標准,但是在測試數據庫反映schema.rb的狀態以及通過遷移進行的更改方面遇到了問題。

tl; dr運行rake minitest:all調用與rake db:schema:load相同的代碼?

環境

  • Rails 3.2.20
  • Ruby 1.9.3
  • Minitest gem 4.6.2
  • minitest-rails 0.5.2
  • MySQL 5.1
  • 本地OS X,測試和生產Linux

原始系統狀態

該系統最初是由非軟件工程師,不知道Rails等人員建立的。添加了幾種特定於MySQL的類型(例如unsigned int ),這些類型沒有使用Rails的遷移和schema.rb特別支持。 所以系統使用了structure.sql並且對於如何保持更新,檢入git等等非常草率。

此外,在某些時候,有人決定用包含自生成GUID的varchar 替換一些通常的數字,自動遞增主鍵id字段。 字段名稱仍然是id但它是一種新的數據類型。

但是所有的數百個測試(他們確實寫了很多測試)已經寫入基於id的參考夾具實例,而不是夾具名稱,夾具之間存在依賴關系等。他們決定堅持使用,而不是更新測試。用於測試的舊模式(帶有數字id ),並使用新模式(在id使用varchar GUID)進行生產。

OP深呼吸......

各種環境的數據庫不同步,有數百次遷移,但由於共享了“開發”數據庫,它們停止了工作......你知道,這是一團糟。

我試圖修復所有這些,並最終轉移到PostgreSQL。

我做了什么

我使用RAILS_ENV=production rake db:structure:dump在本地從生產數據庫中轉儲了模式 - 這產生了一個權威的structure.sql 我創建了一個新的開發數據庫,​​並使用rake db:structure:load加載了它的模式 - 我仔細比較了生產和開發模式,它們是相同的,甚至是我上面提到的特定於MySQL的unsigned int。

我想轉向使用schema.rb有兩個原因。 首先,我想進入一個不依賴於MySQL的系統。 其次,當使用structure.sql我們檢查一個文件,該文件具有自動增量值,數據庫設置以及運行最新db:migrate的任何機器的其他特性。 這可能會產生我寧願避免的問題。

因此,我在本地更改了配置設置:sql以使用:ruby設置生成schema.rb

schema.rb真的不喜歡將id字段轉換為varchar的想法 - 我確保所有使用它的模型聲明self.primary_key = :id ,然后我創建了一個新的遷移來替換所有舊的,“匯總遷移”,其內容主要是新的schema.rb ,但在幾個方面進行了修改。

特別是,如果id字段是GUID varchar我就像這樣設置表(從遷移中):

class RolledUpStateAsOf20150403 < ActiveRecord::Migration

  def up

    # ... all other table definitions in the system

    create_table "users", :id => false, :force => false do |t|
      t.string   "id", :limit => 36, :default => "", :null => false
      t.string   "login"
      # and all the other user fields
    end
    execute("ALTER TABLE users ADD PRIMARY KEY (id);")

    #...
  end

  def down
    raise ActiveRecord::IrreversibleMigration
  end
end

所以:

  • :id => false以防止遷移創建正常ID
  • :force => false以確保此遷移不會破壞生產數據庫
  • t.string "id"具有大小和其他類似主鍵的設置
  • execute(ALTER TABLE ...)以將id聲明為主鍵

每次我在將來創建一個新的遷移時, schema.rb都會更新 - 它現在不准確(直到我們以后擺脫那些古怪的id字段)。 遷移將尊重正常的Rails實踐。

一旦生產,登台,開發和其他數據庫同步,那么一切都很順利。

除了我們測試。

那么為什么當我運行Minitest時這不起作用?

我正在使用minitest運行測試,如下所示:

RAILS_ENV=test rake db:drop
RAILS_ENV=test rake db:create
RAILS_ENV=test rake db:migrate
RAILS_ENV=test rake minitest:all

但后來我開始看到錯誤,錯誤是由於id列被定義為int而不是varchar

如果我在運行minitest之前檢查架構(在dropcreate和my magic migration之后),那就是正確的:根據需要,時髦的主鍵是varchar

但是在測試期間的某個地方看起來模式正在變回Rails標准。 我可以返回並檢查ID列返回int

據推測,模式是從實際的schema.rb

這是正常/預期的行為嗎? 關於如何實現我的目標的任何建議,簡單地說:

  • 遷移再次工作
  • 開發,測試,分期,生產數據庫在結構上是相同的
  • 我現在需要使用瘋狂的varchar基於GUID的id字段
  • 我不喜歡使用structure.sql如果可能的話

好吧,我相信下面的是真實的:MINITEST,或測試運行db:schema:load ...或db:structure:load運行時RAILS_ENV=test -這可以通過運行既可以觀察到rake test --tracerake minitest:all --trace

所以,因為我的schema.rb不會完全重新創建數據庫,因為varchar而不是int用於名為id的字段...我不得不恢復使用structure.sql

解決方案的其余部分,包括添加手動修改版本的schema.rb作為第一個“匯總”遷移工作很好,后續遷移很好。 未來的某個時候,我會把ids變回自然形態; 目前,這是一個合適的解決方案,如果不是優雅的話。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM