测试“验证...,格式=>与”

时间:2013-01-27 05:09:48

标签: rspec rspec-rails

我有一个带有此验证的用户模型

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

端     端

然后我为每个规格运行获得一个新名称。

我不想测试它是否使用了一些正则表达式,因为那时我会测试实现而不是行为,而且我也不想只测试一个硬编码的情况。

我的问题是:我应该这样做吗?真的需要吗?它更好还是没用?你知道更好的方法来测试那种验证吗?

编辑:另一个问题,如何生成无效的随机名称?有没有办法创建包含至少一个超出允许值的字符的随机名称?我不能硬编码所有无效值的数组来随机化它,因为它会太大

3 个答案:

答案 0 :(得分:4)

为了测试有效和无效的格式(我认为正则表达式可以定义要验证的格式),如何在一些帮助器实用程序方法中定义您认为有效和无效名称的内容,您可以随着时间的推移进行优化如有必要。例如:

<强>规格/支持/ utilities.rb

def valid_names
  %w[Homer bart LISA]
end

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

然后,您可以使用RSpec,shoulda-matchersFactory Girl编写:name(和:lastname)的测试,如下所示:

<强>规格/模型/ 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

如果您打算将来的应用程序国际化,请记住并非所有世界名称都符合此格式。

答案 1 :(得分:2)

查看开源项目Shoulda Matchers: https://github.com/thoughtbot/shoulda-matchers

编辑:抱歉,我注意到Paul Fioravanti也提到过了。但是,您无需使用FactoryGirl来创建模型的实例。验证测试不需要使用create

您可以直接在模型上创建单元测试:


describe User, 'Validations' do
  it { should allow_value("Name").for(:name) }
  it { should_not allow_value("Inv4lid_").for(:name) }
end

答案 2 :(得分:1)

针对随机数据进行测试是一种常见的测试技术,称为Fuzzing。我会看一下使用FuzzBert's生成器来创建真正的随机二进制数据来进行测试。

以下是一些您不希望通过验证的随机数据示例。

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失败,请查看它失败的字符串,如果它是一个有效的字符串,那么只需重新运行。

测试所有可能性

您永远无法测试所有无效字符串(除非您的最大长度很短),但通过使用Fuzz Testing,您将能够针对包含大量有效和无效字符的字符串进行测试。 / p>