7

この検証を使用したユーザーモデルがあります

validates :name, :lastname, :format => {:with => /^[a-zA-Z]+$/, :message => 'Only letters and spaces allowed.'}

適切にテストする方法がわかりません。

a-zA-z文字の配列から10文字で作成されたランダムな文字列を返す関数を実行しました。

def get_random_name
  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".split('').shuffle[0..10].join

エンドエンド

次に、仕様を実行するたびに新しい名前を取得します。

正規表現を使用していることをテストしたくありません。これは、動作ではなく実装をテストするためです。また、ハードコードされた1つのケースのみをテストしたくないためです。

私の質問は次のとおりです。本当に必要ですか?それは良いですか、それとも役に立たないですか?その種の検証をテストするためのより良い方法を知っていますか?

編集:別の質問、無効なランダムな名前を生成するのはどうですか?許可された値の外側に少なくとも1つの文字を含むランダムな名前を作成する方法はありますか?すべての無効な値の配列をハードコーディングしてランダム化することはできません。大きすぎるためです。

4

3 に答える 3

7

オープンソースプロジェクトShouldaMatchersをチェックアウトしてください: https ://github.com/thoughtbot/shoulda-matchers

編集:申し訳ありませんが、Paul FioravantiShouldaについても言及していることに気づきました。ただし、モデルのインスタンスを作成するためにFactoryGirlを使用する必要はありません。create検証テストでは使用する必要はありません。

モデル上で直接単体テストを作成できます。


describe User, 'Validations' do
  it { should allow_value("Name").for(:name) }
  it { should_not allow_value("Inv4lid_").for(:name) }
end
于 2013-04-10T14:59:20.313 に答える
4

有効な形式と無効な形式をテストするために(正規表現は検証する形式を定義するのに適していると思います)、必要に応じて時間をかけて改良できるヘルパーユーティリティメソッドに有効な名前と無効な名前を定義するのはどうでしょうか。例えば:

spec / support / Utilities.rb

def valid_names
  %w[Homer bart LISA]
end

def invalid_names
  %w[BuRn$ 5M1+h3Rs♡]
end

次に、RSpec、shoulda -matchers、およびFactory Girl:nameを使用して、次のようなテストを作成できます。:lastname

spec / models / user_spec.rb

describe User do

  let(:user) { FactoryGirl.create(:user) }

  # ...

  describe "validations" do
    context "for name, lastname" do
      context "when format is invalid" do
        invalid_names.each do |invalid_name|
          it { should_not allow_value(invalid_name).for(:name) }
          it { should_not allow_value(invalid_name).for(:lastname) }
        end
      end

      context "when format is valid" do
        valid_names.each do |valid_name|
          it { should allow_value(valid_name).for(:name) }
          it { should allow_value(valid_name).for(:lastname) }
        end
      end
      # ...
    end
    # ...
  end
  # ...
end

将来、アプリを国際化する予定がある場合は、世界中の名前のすべてがこの形式に準拠しているわけではないことを覚えておいてください。

于 2013-01-27T06:40:51.617 に答える
1

ランダムデータに対するテストは、ファジングと呼ばれる一般的なテスト手法です。FuzzBertのジェネレーターを使用して、テストする真のランダムバイナリデータを作成することを検討します。

これは、検証を通過したくないいくつかの優れたランダムデータの例です。

irb> require 'fuzzbert'
       => true
irb> test_string = FuzzBert::Generators.random_fixlen(10)[]
       => "S\x1EU1\x11HVY\x0E\xD0"
irb> puts test_string
     S▲U1◄HVY♫�
       => nil

ランダムは良いです

ランダムなバイナリビットを文字列に変換しているため、テストするための非常にファンキーな結果が得られます。それは良いことです!?のような既知の記号の使用に対してテストするだけでなく、有効な文字と無効な文字のあらゆる種類の組み合わせに対してもテストします。

ランダムは時々有効です

非常にまれですが、時々有効なデータを取得する可能性があります。また、作成するランダムな文字列が長くなるほど、有効なデータを取得する可能性が低くなります。

この問題を解決する最初の試みは、すべての出力に無効な文字を追加することかもしれませんが、私はそれを提案しません。たとえば、常に「!」を追加すると、文字列に「!」が含まれていないことを確認するのと同等のテストになります。その中で、完全な正規表現の可能性の真のテストではありません。

同じ正規表現に対してランダムな文字列をテストすることをお勧めします。合格した場合は、テストする別の文字列を生成します。

最後に、ランダムデータが有効であるというまれな可能性を無視することができます。この特定のrspecが失敗するたびに失敗した場合は、失敗した文字列を確認し、それが有効な文字列であった場合は、再実行してください。

すべての可能性をテストする

無効な文字列をすべてテストすることはできませんが(最大長が短い場合を除く)、ファズテストを使用すると、さまざまな有効な文字と無効な文字を含む文字列に対してテストできます。

于 2013-04-10T03:56:45.213 に答える