单元测试简单的树结构操作

时间:2013-12-12 10:06:50

标签: c# unit-testing tree c#-3.0 pattern-matching

给出一个非常简单的结构,例如:

public class TreeNode
{
    public int ID { get; set; }
    public List<TreeNode> Children { get; set; }
}

TreeNode可能还有其他属性。

以下列方式使用时:

var tree = new List<TreeNode>(); //no root node

如果我根据某些条件在树上执行添加/更新/删除操作。例如,基于我上面提到的一个或多个其他属性删除节点,我想比较更改前后的树图,然后通过单元测试验证一些遵循:

  • 树保持不变
  • 删除指定的节点
  • 添加指定的节点
  • 指定的节点已更新
  • 上面的3,同时也验证了树的其余部分没有改变。

理想情况下,我会抛出一个列出未找到但未预期的节点的预期等。但是,在这个阶段,我会对我的支票中的真/假感到满意。

现有项目是否有任何已知的模式/算法可以帮助解决这个问题?

我很高兴其他语言中的伪代码或示例,只要它们不依赖于我无法在.NET中复制的功能。

我的树不太可能超过7或8级,总共不超过100个节点,因为它将是测试数据,所以强力循环很好,此时性能不是考虑因素。 / p>

我真的在寻找有关如何处理此问题的提示,技巧,建议和代码。

TIA

2 个答案:

答案 0 :(得分:1)

当我对树结构进行单元测试时,我只是构建了一个已知结构的ad-hoc树,对其执行操作并验证更改是我所期望的,这是一种非常简单但可用的方法,如果你创建好的测试用例。

无论我的经验如何,您可能会想到树节点的一些递归比较方法,这些方法可能会返回不同的子节点列表。所以基本的想法是保持两个相同的树,对其中一个执行操作,然后检查更改的内容。

如果您没有任何显示树的UI,我还建议使用http://www.graphviz.org/对树进行可视化,您可以在某些操作之前和之后生成树的图片,这样您就可以了将看到整个结构是如何改变的(不适用于单元测试,但无论如何)。

最后一点,我建议有一个根节点,它会简化你的递归算法。如果您没有root,由于UI的某些要求,您可以修改该部分以忽略根。

答案 1 :(得分:0)

您还可以使用一个函数来获取树的字符串表示形式,并仅比较2个字符串表示形式,而不是比较2个树 我本周早些时候做了 示例函数(快速)

 public var description: String {
        var s = "\(value)"
        if !children.isEmpty {
            s += " {" + children.map { "\($0.description)"}.joined(separator: ", ") + "}"
        }
        return s
    }

您可以这样测试

XCTAssert ( tree.description == "beverages {hot {tea {black, green, chai}, coffee, cocoa}, cold {soda {ginger ale, bitter lemon}, milk}}");