【问题标题】:Is this an alternative to the walking 1's algorithm?这是步行 1 算法的替代方案吗?
【发布时间】:2015-07-01 03:07:10
【问题描述】:

好的,这篇文章很长,请多多包涵。问题在最后一段。

我的应用程序从 100 多个离散输入中读取布尔数据,并将它们打包成一堆整数,然后通过串行输出。我正处于开发的测试阶段,需要检查每个输入是否放入正确的输出位。我的第一个直觉是使用步行 1 的算法。不过,这会产生数百个测试用例,这需要时间和精力来创建、维护、审查等。所以我被鼓励将测试数量减少到我觉得舒服的程度,即使这意味着有些用例不会t 被覆盖(可能他们会被其他团队的测试覆盖)。我对不彻底测试我的代码感到不舒服,但我意识到如果可能的话,我希望减少测试用例的数量。步行 1 的测试会产生 N 个测试用例,其中 N 是输入的数量。

想了一会儿,我想出了以下3个测试。如果其中任何一个失败,则说明输入转换有问题。

  1. 奇数测试 - 将每个奇数输入设置为“开”,在输出中产生交替的位模式。

  2. 偶数测试 - 将每个偶数输入设置为“开启”,从而在输出中产生交替的位模式。

  3. 步行 3 的测试 - 这是我自己的测试名称,因为它与步行 1 的测试相似。将前两个输入设置为“on”。然后将接下来的两个输入设置为“on”,依此类推,直到剩下 0 或 1 个输入。

对于每个测试,将输出与输入进行比较以查看是否匹配。如果它们不匹配,则可以使用 XOR 来获取错误位。

这个想法是奇数和偶数测试证明这些位独立于它们的相邻位。如果 10101 是输入(奇数测试),则输出 10101 表示在设置奇数位时未设置偶数位(独立于奇数位)。偶数位也是如此。这将可能的相关位的集合减少了一半。然后通过测试 3,我们可以证明其余位的独立性。例如,如果输入为 00011,输出为 00011,我们从奇数/偶数测试中知道位 1 独立于位 0,现在我们从 3 的测试中知道位 0 和 1 独立于其余位,否则这些位中至少有一个为 1。继续该示例,如果输入 00011 给我们 00111 用于输出,我们通过 XOR 知道位 2 取决于位 0(请记住,偶数和赔率测试通过,所以位 0是唯一可能的依赖来源)。或者,如果输入 00011 给我们输出 00110,我们通过 XOR 再次知道位 0 和 2 再次是问题(在这种情况下,它们似乎被交换了)。

下面是一个 5 位序列的示例(在我的应用程序中,它实际上是一系列 19 位序列)。这些示例考虑了交换两个位的情况。只能通过奇偶测试来检测卡住或关闭的位。

与walking 1 的测试相比,这3 个测试产生floor(N/2) + 2 测试用例。但是这些是否可以有效替代步行 1 的测试?我的例子似乎表明了这一点(至少出于我的目的),但我不确定。我本来希望在其他地方看到这种技术,但我还没有找到它。当然,我不知道我应该找什么名字。

交换位 0 和 1 |输入 |方法 |输出 |检测到? | |-------|---------|--------|------------| | 10101 |赔率 | 10110 |是 | | 01010 |偶数 | 01001 |是 | | 00011 | 3 的 (1) | 00011 |没有 | | 01100 | 3 的 (2) | 01100 |没有 | 交换位 0 和 2 |输入 |方法 |输出 |检测到? | |-------|---------|--------|------------| | 10101 |赔率 | 10101 |没有 | | 01010 |偶数 | 01010 |没有 | | 00011 | 3 的 (1) | 00110 |是 | | 01100 | 3 的 (2) | 01100 |没有 | 交换位 0 和 3 |输入 |方法 |输出 |检测到? | |-------|---------|--------|------------| | 10101 |赔率 | 11100 |是 | | 01010 |偶数 | 00011 |是 | | 00011 | 3 的 (1) | 01010 |是 | | 01100 | 3 的 (2) | 00101 |是 | 交换位 0 和 4 |输入 |方法 |输出 |检测到? | |-------|---------|--------|------------| | 10101 |赔率 | 10101 |没有 | | 01010 |偶数 | 01010 |没有 | | 00011 | 3 的 (1) | 10010 |是 | | 01100 | 3 的 (2) | 01100 |没有 | 交换位 1 和 2 |输入 |方法 |输出 |检测到? | |-------|---------|--------|------------| | 10101 |赔率 | 10011 |是 | | 01010 |偶数 | 01100 |是 | | 00011 | 3 的 (1) | 00101 |是 | | 01100 | 3 的 (2) | 01010 |是 | 交换位 1 和 3 |输入 |方法 |输出 |检测到? | |-------|---------|--------|------------| | 10101 |赔率 | 10101 |没有 | | 01010 |偶数 | 01010 |没有 | | 00011 | 3 的 (1) | 01001 |是 | | 01100 | 3 的 (2) | 00110 |是 | 交换位 1 和 4 |输入 |方法 |输出 |检测到? | |-------|---------|--------|------------| | 10101 |赔率 | 00111 |是 | | 01010 |偶数 | 11000 |是 | | 00011 | 3 的 (1) | 10001 |是 | | 01100 | 3 的 (2) | 01100 |没有 | 交换位 2 和 3 |输入 |方法 |输出 |检测到? | |-------|---------|--------|------------| | 10101 |赔率 | 11001 |是 | | 01010 |偶数 | 00110 |是 | | 00011 | 3 的 (1) | 00011 |没有 | | 01100 | 3 的 (2) | 01100 |没有 | 交换位 2 和 4 |输入 |方法 |输出 |检测到? | |-------|---------|--------|------------| | 10101 |赔率 | 10101 |没有 | | 01010 |偶数 | 01010 |没有 | | 00011 | 3 的 (1) | 00011 |没有 | | 01100 | 3 的 (2) | 11000 |是 | 交换位 3 和 4 |输入 |方法 |输出 |检测到? | |-------|---------|--------|------------| | 10101 |赔率 | 01101 |是 | | 01010 |偶数 | 10010 |是 | | 00011 | 3 的 (1) | 00011 |没有 | | 01100 | 3 的 (2) | 10100 |是 |

【问题讨论】:

  • 实际需要测试什么?为什么会有 N 个离散测试用例?
  • 这取决于你如何定义“依赖”。如果位 x 依赖于位 y 意味着这两个位总是具有相同的值,那么测试看起来不错。如果依赖意味着他们有某种逻辑关系,那么可能不是因为例如位 1 始终不是输入中的位 2
  • @user2864740 - 需要测试的是,如果我将其中一个离散输入接地(打开),则需要在输出中设置其相应位。 N 个测试用例,每个输入一个软件。
  • @samgak - 依赖,我的意思是如果我打开第 0 位,并且我的输出中同时打开第 0 位和第 1 位。输入之间没有逻辑关系。它基本上只是枚举它们。我一次从硬件读取 24 个输入,但由于协议开销,只能输出 19 位。所以我正在尝试测试我的位移是否正确。

标签: algorithm testing bit-manipulation


【解决方案1】:

您需要考虑可能的错误是什么,是什么决定了单个测试的成本,以及有时在测试失败的情况下诊断潜在问题的难易程度。在某些设备上,walk one 测试很容易输入,因为您只需清除一个开关并设置其邻居即可让 1 穿过,并且非常容易检查,因为它会在输出时产生独特的模式。它会检查很多看似合理的错误接线和非接线。 (步行 1 和步行 3 似乎都需要相同数量的开关动作)

如果最合理的错误是您的打包代码中的一些错误,那么生活就更复杂了——像在您应该使用 & 的地方使用 + 之类的错误可能仅在设置了足够的输入导致溢出时才会出现。您可以尝试少量完全随机的输入模式,或查看https://en.wikipedia.org/wiki/All-pairs_testing。这样做的问题是,您需要将开关设置为显然完全随机的模式,这可能比简单地沿着它们走 1 更令人沮丧和容易出错。

在使用更复杂的测试之前或使用更复杂的测试之前,您可以看到可以通过显示或自动警报提供哪些支持,以使测试人员的生活更轻松,更不容易出错。

【讨论】:

  • 最可能的错误是我的位打包代码中有一个错误,这就是这些测试用例将尝试检查的内容。测试本身将是自动化的,并在硬件没有问题(接线错误等)的模拟环境中运行。单个测试的成本与其说是运行时成本,不如说是最小的,而是生成文档、审查、维护和发布文档的成本。
  • 如果你可以自动化所有事情,我至少会有一个测试,它使用随机数生成器来生成随机模式,对其进行编码、解码,并检查它是否能恢复到最初的状态。然后我会在一夜之间运行它。
  • 这将是一个很好的健壮性测试用例。对于我的正常测试,David 的回答很有信心。
【解决方案2】:

使用n 位,您可以使用ceil(log2(n + 2)) 测试来检测置换和卡住位,其中在测试i(范围从0ceil(log2(n + 2)) - 1)中,位j 的值(范围从1n) 是j 二进制表示中的2**i 对应的位。

test 0: 10101010101010
test 1: 01100110011001
test 2: 00011110000111
test 3: 00000001111111

【讨论】:

  • 恐怕我不能仅从描述中理解。你能举个例子吗?
  • 这种技术是否有任何我可以用作参考的常用名称?
  • @njpaul 有很多现有技术,但我不确定这种技术是否有简洁的名称。
【解决方案3】:

要回答我的问题,不,这不是步行 1 的替代方案。行走 1 可以检测位之间的耦合。例如,位 4 也打开位 2,走 1 会检测到这一点。我的算法不会在所有情况下都检测到这一点。

行走1 位 4 也开启位 2 |输入 |我 |输出 |检测到? | |-------|---|--------|-----------| | 00001 | 0 | 00001 |没有 | | 00010 | 1 | 00010 |没有 | | 00100 | 2 | 00100 |没有 | | 01000 | 3 | 01000 |没有 | | 10000 | 4 | 10100 |是 | 我的算法 位 4 也开启位 2 |输入 |方法 |输出 |检测到? | |-------|---------|--------|------------| | 10101 |赔率 | 10101 |没有 | | 01010 |偶数 | 01010 |没有 | | 00011 | 3 的 (1) | 00011 |没有 | | 01100 | 3 的 (2) | 01100 |没有 | David Eisenstat 的算法 位 0 也开启位 2 |输入 |我 |输出 |检测到? | |-------|---|--------|-----------| | 10101 | 0 | 10101 |没有 | | 00110 | 1 | 00110 |没有 | | 11000 | 2 | 11000 |没有 |

所以我想这取决于您需要什么级别的检查。如果您需要检查耦合位,步行 1 似乎是要走的路。如果您只需要检查卡位和排列,David Eisenstat 的算法会比我的算法更有效。

在我的例子中,我做了很多位操作,我可能不小心耦合了 2 个位,所以我认为它必须是行走 1。

编辑 实际上,在更仔细地检查了我的应用程序的行为之后,我决定使用 David Eisenstat 的算法。在我的应用程序中,如果位操作错误,例如位 0 开启位 2,位 2 也无法按预期开启,算法会检测到该错误。

【讨论】:

    猜你喜欢
    • 2019-11-18
    • 2010-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-03
    • 1970-01-01
    相关资源
    最近更新 更多