0

我们部门使用的测试用例是从 SpiraTeam 迁移到 TFS 中的。SpiraTeam 允许将测试用例存储在文件夹层次结构中,例如

Ordering/Order & Stock/发送订单/测试一:发送普通订单

TFS 不支持此层次结构,因此在迁移过程中,我们将每个测试的文件夹层次结构复制为纯文本,现在将其存储在 TFS 工作项中名为“文件夹”的纯文本字段中。

我正在开发一个小型 C# 应用程序,该应用程序将允许在此层次结构中查看测试用例并从中进行编辑。

我计划从层次结构中构建一个 TreeView 来显示测试用例。

我拥有检索测试用例的所有功能,并且目前将它们存储在应用程序内的 WorkItemStore 中,但我有两个问题:

  1. 如何在 TreeView 中呈现这些信息?我知道我将不得不使用递归算法,但是关于这个主题的任何研究都会带回有关如何从实际 Windows 目录构建 TreeView 的说明,而不是我需要使用的纯文本字段。我首先使用 .Split 方法将“文件夹”字段拆分为字符串数组。

  2. 一旦我将信息输入到 TreeView 中,我将如何根据来自 TreeView 的选择导航到 WorkItemStore 中的正确测试用例,因为 TreeView 节点似乎是基于字符串的?以上面的路径为例,我想要一个比从商店选择工作项更优雅的解决方案 WHERE [Title] = 'Test 1: Send a normal order'。

也许我的第二个问题的解决方案将决定我如何实现这一点,而我的第一个问题可能无关紧要。

对此的一些指示将不胜感激。

谢谢,

安迪

4

1 回答 1

1

这是一个可以在 LinqPad 中运行的示例程序。它需要一个 WorkItem (在这种情况下是我创建的一个类)并在将其拆分后沿 Path 遍历,/沿行创建节点,如果它在同一集合中找到具有相同文本的节点,则使用该节点反而。

void Main()
{
    //Create a treeview with a root node.
    TreeView tv = new TreeView();
    tv.ShowNodeToolTips = true; //Turn on tooltips for this demo.
    tv.Nodes.Add(new TreeNode("Root"));

    //These may need ordering by path before you start.
    var tfsTestCases = new[]
    {
        new WorkItem { Path = "Module/Feature1/SubFeature1/Test1", WorkItemId = 1, },
        new WorkItem { Path = "Module/Feature1/SubFeature1/Test2", WorkItemId = 2, },
        new WorkItem { Path = "Module/Feature1/SubFeature2/Test1", WorkItemId = 3, },
        new WorkItem { Path = "Module/Feature1/SubFeature2/Test2", WorkItemId = 4, },
        new WorkItem { Path = "Module/Feature2/SubFeature1/Test1", WorkItemId = 5, },
        new WorkItem { Path = "Module/Feature2/SubFeature1/Test2", WorkItemId = 6, },
    };

    //Looping through the test cases...
    foreach (var testCase in tfsTestCases)
    {
        //Start at the root of the tree for each work item.
        TreeNode lastNode = tv.Nodes[0];

        //Loop through each part of the path and create a new node.
        //Use the NodeCollection from the one we just created each time through the loop.
        //This allows the next iteration to "walk down" as it goes.
        foreach (var part in testCase.Path.Split('/'))
            lastNode = AddTreeNode(lastNode.Nodes, part);

        //Set the Tag on the last node in the loop, this is the one with the actual Test Case.
        //You can reference the Tag property of "tv.SelectedNode" to get access to the Work Item. If the Tag is null, then it's not a Test Case.
        lastNode.Tag = testCase;
        lastNode.ToolTipText = testCase.WorkItemId.ToString();  //Set for this DEMO.
    }
    //Display the tree.
    tv.Dump();
}

TreeNode AddTreeNode(TreeNodeCollection nodes, String path)
{
    //Try and find a node in the collection matching the specified pathPath.
    var node = nodes.Cast<TreeNode>().Where(node => node.Text == path).SingleOrDefault();
    //If it's not found, create it and add it to the collection of nodes we just searched.
    if (node == null)
    {
        node = new TreeNode(path);
        nodes.Add(parentNode);
    }
    //We need this later, so pass it back.
    return node;
}

class WorkItem
{
    public String Path { get; set; }
    public Int32 WorkItemId { get; set; }
    //etc.
}
于 2012-07-27T19:21:44.023 回答