C ++测试用例的基本字符串差异

时间:2011-07-26 15:00:45

标签: c++ string unit-testing diff

我有一个C ++函数,它返回一个多行std::string。在测试用例中,我将每一行与已知值进行比较 - 如:

std::string known = "good\netc";
std::string output = "bad\netc";

std::vector<std::string> knownvec;
pystring::splitlines(known, knownvec); // splits on \n

std::vector<std::string> outvec;
pystring::splitlines(output, outvec);

CHECK_EQUAL(osvec.size(), resvec.size());

for(unsigned int i = 0; i < std::min(outvec.size(), knownvec.size()); ++i)
    CHECK_EQUAL(pystring::strip(outvec[i]), pystring::strip(knownvec[i]));

这样可行,但是说添加了一个新行,所有后续的CHECK_EQUAL断言都失败了,这使得输出难以阅读

是否有更好的方法来比较两个字符串,理想情况是以一种漂亮的,自包含的方式(即不与giantdifflib链接,或将字符串写入文件并调用diff命令!)

[编辑]我正在使用OpenImageIO's rather simple unittest.h

被比较的数据主要是YAML或颜色查找表。 Here's an example test case - 基本上是几行标题,然后是很多数字:

 Version 1
 Format any
 Type ...
 LUT:
 Pre {
   0.0
   0.1
   ...
   1.0
 }
 3D {
   0.0
   0.1
   ...
   1.0
 }

3 个答案:

答案 0 :(得分:1)

最简单的方法是在字符串不再匹配时突破循环:

for(unsigned int i = 0; i < std::min(outvec.size(), knownvec.size()); ++i)
{
    bool areEqual = pystring::strip(outvec[i]) == pystring::strip(knownvec[i]);
    CHECK_EQUAL(pystring::strip(outvec[i]), pystring::strip(knownvec[i]));
    if (!areEqual)
        break;
}

如果CHECK_EQUAL返回一个布尔值,那么显然可以简化上面的例子。

如果希望您的单元测试框架在比较多行字符串时提供与diff相同的输出,那么我担心您对单元测试框架的期望过高。如果您不想链接到外部库,或者从测试程序中执行diff,那么您必须自己编写某种diff算法。

查看其他question有关差异算法和库的信息。

如果您发现自己实施差异算法并不值得(可能不是),那么请查看Google Diff-Match-Patch库。

答案 1 :(得分:1)

短:

出于单元测试的目的,您只需要标记它们是不同的。单元测试不能修复失败的单元测试,程序员可以修复失败的单元测试。

长:

如果序列大小可能不同,则没有简单的通用方法来比较它们。我认为你需要一个巨大的difflib做得很差,更不用说了。

我认为如果你不能说序数不是一个身份,那么你将不得不使用搜索来添加信息。

考虑这种退行性案例:

a b c d e f
d e f a b c

您是否选择其中一种解决方案将归结为对结果的评分或实施的一些工件:

      a b c d e f
d e f a b c

a b c d e f
      d e f a b c

我的意见是,如果您必须为结果分配分数,那么单位测试不太可能适用。

比较容器通常不是很容易,如果结果不能按字典顺序排序,我不确定任何计算结果会提供信息,除非告诉你它的不同。

这显然是一个有趣的问题,但它可能超出了单元测试的范围。

答案 2 :(得分:0)

基本的差异算法很容易实现,如果不是非常有效的话。 This Wikipedia article是一个很好的起点。