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

结束结束

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

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

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

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

4

3 回答 3

7

查看开源项目 Shoulda Matchers: https ://github.com/thoughtbot/should-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
于 2013-04-10T14:59:20.313 回答
4

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

规范/支持/实用程序.rb

def valid_names
  %w[Homer bart LISA]
end

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

然后,您可以使用 RSpec、shouda-matchersFactory Girl:name为(and )编写测试,如下所示::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

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

于 2013-01-27T06:40:51.617 回答
1

针对随机数据进行测试是一种称为Fuzzing的常见测试技术。我会考虑使用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 回答