如何在ruby中对不同长度的有符号整数的二进制字符串表示进行单元测试?

如何在ruby中对不同长度的有符号整数的二进制字符串表示进行单元测试?,ruby,unit-testing,Ruby,Unit Testing,我想写一个测试来验证不同长度的有符号整数的二进制字符串表示。我不知道如何计算以二进制字符串表示的随机正整数和负整数的期望值,具有不同的二进制长度(8,16,32,64)。到目前为止,我有一个测试,它只打印出值供检查 下面是测试(只打印结果,没有断言)和函数: # test def test_binary_string_with_length 10.times do n = -rand(128) puts "n: #{n} -> bin8: #{binary_stri

我想写一个测试来验证不同长度的有符号整数的二进制字符串表示。我不知道如何计算以二进制字符串表示的随机正整数和负整数的期望值,具有不同的二进制长度(8,16,32,64)。到目前为止,我有一个测试,它只打印出值供检查

下面是测试(只打印结果,没有断言)和函数:

# test

def test_binary_string_with_length
  10.times do 
    n = -rand(128)
    puts "n: #{n} -> bin8: #{binary_string_with_length(n, 8)}"

    n = rand(256)
    puts "n: #{n} -> bin8: #{binary_string_with_length(n, 8)}"

    n = -rand(2 ** 15) 
    puts "n: #{n} -> bin16: #{binary_string_with_length(n, 16)}"

    n = rand(2 ** 16) 
    puts "n: #{n} -> bin16: #{binary_string_with_length(n, 16)}"

    n = -rand(2 ** 31)
    puts "n: #{n} -> bin32: #{binary_string_with_length(n, 32)}"

    n = rand(2 ** 32)
    puts "n: #{n} -> bin32: #{binary_string_with_length(n, 32)}"

    n = -rand(2 ** 63)
    puts "n: #{n} -> bin64: #{binary_string_with_length(n, 64)}"

    n = rand(2 ** 64)
    puts "n: #{n} -> bin64: #{binary_string_with_length(n, 64)}"
  end
end

# function

def binary_string_with_length(n, int_length_in_bits)
  pack = 'Q' # default is 64 bit
  case int_length_in_bits
  when 8
    pack = 'C'
  when 16
    pack = 'S'
  when 32
    pack = 'L'
  when 64
    pack = 'Q'
  end
  sprintf('%b', [n].pack(pack).unpack(pack)[0])
end

如何编写断言来验证每个字符串表示是否正确?

不要在单元测试中测试随机的任意值。选择一组输入,对照其已知的预期输出进行测试。包括边缘案例。在生产过程中添加额外的测试用例,以确保不会引入回归


用最简单的术语来说,将输入构建为期望值的散列,然后迭代该散列并断言实际值等于期望值。

不要在单元测试中测试随机的任意值。选择一组输入,对照其已知的预期输出进行测试。包括边缘案例。在生产过程中添加额外的测试用例,以确保不会引入回归



用最简单的术语来说,将输入构建为期望值的散列,然后迭代该散列并断言实际值等于期望值。

好的,我将从学习如何计算正数和负数的二进制表示开始。然后实现您的转换。并根据ruby的逻辑进行测试。就这么简单。@SergioTulentsev-我要澄清我的问题-我知道如何计算正数和负数的二进制表示-这个问题是ruby特有的,它是动态类型的,内部没有一个特定的整数大小(以字节为单位)。大小本身似乎随着整数的增长而增长(整数可以任意大,ruby的增长只支持内存限制的整数)。计算不同大小的二进制表示的方法是我在上面的函数中所做的。我现在如何验证其准确性?将澄清放在您的问题中,插入您最初输入的位置。不要使用“更新”或“编辑”标记。如果需要,我们可以知道添加了什么。这样,每个人都可以看到信息,而不必阅读每一条评论。@theTinMan-我也想这样做-我过去也这样做过,但有时响应者不喜欢这样做,因为他们的旧答案可能与问题不同步-通过在问题中添加“修订历史记录”,用户可以更好地映射响应。所有问题和答案都有一个自动应用的内置修订系统,这就是为什么不需要使用“编辑”和“更新”标记的原因。对该修订历史记录的访问基于用户信誉。看见读得好,我会从学习如何计算正数和负数的二进制表示开始。然后实现您的转换。并根据ruby的逻辑进行测试。就这么简单。@SergioTulentsev-我要澄清我的问题-我知道如何计算正数和负数的二进制表示-这个问题是ruby特有的,它是动态类型的,内部没有一个特定的整数大小(以字节为单位)。大小本身似乎随着整数的增长而增长(整数可以任意大,ruby的增长只支持内存限制的整数)。计算不同大小的二进制表示的方法是我在上面的函数中所做的。我现在如何验证其准确性?将澄清放在您的问题中,插入您最初输入的位置。不要使用“更新”或“编辑”标记。如果需要,我们可以知道添加了什么。这样,每个人都可以看到信息,而不必阅读每一条评论。@theTinMan-我也想这样做-我过去也这样做过,但有时响应者不喜欢这样做,因为他们的旧答案可能与问题不同步-通过在问题中添加“修订历史记录”,用户可以更好地映射响应。所有问题和答案都有一个自动应用的内置修订系统,这就是为什么不需要使用“编辑”和“更新”标记的原因。对该修订历史记录的访问基于用户信誉。看见另外,使用随机输入读取@Anand,并计算预期输出会破坏编写测试的目的。现在,您有两个相互测试的实现,而不是根据已知的良好值测试一个实现。现在,您的测试需要测试。@Anand说,随机测试有时间和地点,而不是单元测试。与简单的单元测试相比,“混沌猴子”在堆栈上的操作数量级更高。随机测试是一种很好的方法,可以确保你错过最有价值的边缘案例。@Anand我完全不同意。在单元测试中,随机输入通常没有价值,在这种情况下,绝对没有价值。你需要大约12个病例才能对这种方法完全有信心,而使用随机病例没有额外的信心。边缘病例是测试生存或死亡的地方。了解你的边界并积极地测试它们。检查代码以查看其分支位置,并练习每个分支。如果你需要,使用覆盖工具,如果这有助于确保你不会错过任何东西。随机测试(如模糊测试)是测试的重要组成部分,但它不是您应该采取的第一种方法。您需要已知良好的输出,以执行所有边界条件。@Anand有时我会生成大量随机数据,通过测试、工作版本的方法运行这些数据,并冻结输出(例如YAML或JSON结构)。然后,我围绕这一点构建测试,以避免在执行优化代码之类的操作时出现倒退。这避免了双重实现,您只是比较当前的实现