UnitTest仅在所有测试立即执行时失败

时间:2015-04-29 12:50:37

标签: c++ unit-testing binary-search-tree

我在VS2013中运行Microsoft C ++ UnitTest时遇到了一个奇怪的问题。

每次在IDE中执行Run All测试时测试失败,但是当我在特定测试中使用Run Selected Tests时,测试成功。

我正在测试的是使用我自己的BinarySearchTree课程。如果失败,将返回异常代码C0000005(这可能是由于指针的内部链接错误)。

那么这可能是什么原因?

其他

测试在最后一段代码中失败,我在其中生成随机ID字符串,将它们单独添加到我的BST并随机删除它们,直到整个BST再次为空。

BinarySearchTree clientList;
Client client;

// test random adding & deletion
std::vector<std::string> idAddList;
for (unsigned int i = 0; i < 100; i++)
    idAddList.push_back(randomID(20));

std::vector<std::string> idRemoveList;
unsigned int id;
while (idAddList.size() > 0)
{
    // pick random id from list and delete it
    id = rand() % idAddList.size();
    client.uniqueID = idAddList.at(id);
    clientList.add(client);
    if (clientList.lastICLResult() == iList::ICLResult::OK)
        idRemoveList.push_back(idAddList.at(id));
    idAddList.erase(idAddList.begin() + id);
}

    while (idRemoveList.size() > 0)
{
    // pick random client from list and delete it
    id = rand() % idRemoveList.size();
    clientList.remove(idRemoveList.at(id));
    if (clientList.lastICLResult() == iList::ICLResult::OK)
        idRemoveList.erase(idRemoveList.begin() + id);
}

Assert::AreEqual<unsigned int>(0, clientList.size());

这里是randomID()函数的代码:

std::string randomID(const unsigned int maxLength)
{
    static const char alphanum[] =
        "0123456789"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        "abcdefghijklmnopqrstuvwxyz"
        "öÖäÄüÜ"
        "!=[]$%&";

    std::string result;
    for (unsigned int i = 0; i < maxLength; i++)
        result += alphanum[rand() % (sizeof(alphanum - 1))];

    return result;
}

此问题的相关特定于类的代码将是removeMatch()函数和相应的Node类。 BSTClient类作为其add()函数的数据对象,并且只有在其{ID 1}}中的ID字符串尚未添加时才添加给定客户端。内部还有函数BSTfetchMinNode(),它们可以检索指向fetchMaxNode()中最左侧或最右侧节点的指针。主/根节点名为BST,如果m_rootNode变空,则会为其分配nullptr

如果是BST函数,我总是寻找要删除的节点的正确子节点/子树,并且 - 如果可能 - 在特定位置重新分配内部节点树。

removeMatch()

这里有相应的私人功能:

[私人] void iList::removeMatch(Node* toBeDeletedNode) { if (toBeDeletedNode) { // IN CASE GIVEN NODE IS THE ROOT NODE if (!toBeDeletedNode->parent) { // Case 1: root node is the only node in the BST if (!toBeDeletedNode->left && !toBeDeletedNode->right) handleRootLeaf(toBeDeletedNode); // Case 2: either both child nodes are available or just the right // child node is available else if ((toBeDeletedNode->left && toBeDeletedNode->right) || toBeDeletedNode->right) handleRootRSubtree(toBeDeletedNode); // Case 3: only left child node is present else handleRootLSubtree(toBeDeletedNode); } // IN CASE GIVEN NODE IS ANY CHILD NODE else { // Case 1: if given node is a leaf node if (!toBeDeletedNode->left && !toBeDeletedNode->right) handleChildLeaf(toBeDeletedNode); // Case 2: if given node has either both child nodes or just a right child node else if ((toBeDeletedNode->left && toBeDeletedNode->right) || toBeDeletedNode->right) handleChildRSubtree(toBeDeletedNode); // Case 3: if given node has only a left child node else handleChildLSubtree(toBeDeletedNode); } m_elementCount--; } }

handleRootLSubtree()

[私人] void handleRootLSubtree(Node* toBeDeletedNode) { // fetch max node in left subtree Node* maxNode = fetchMaxNode(toBeDeletedNode->left); // in case left child node is the max node if (maxNode->parent != toBeDeletedNode) { if (maxNode->left) { maxNode->left->parent = maxNode->parent; maxNode->parent->right = maxNode->left; } else maxNode->parent->right = nullptr; maxNode->left = toBeDeletedNode->left; maxNode->parent->parent = maxNode; } maxNode->parent = nullptr; // cut linkage toBeDeletedNode->left = nullptr; delete toBeDeletedNode; m_rootNode = maxNode; }

handleRootRSubtree()

[私人] void handleRootRSubtree(Node* toBeDeletedNode) { // fetch min node in right subtree Node* minNode = fetchMinNode(toBeDeletedNode->right); // in case right child node isn't the min node if (minNode->parent != toBeDeletedNode) { if (minNode->right) { minNode->right->parent = minNode->parent; minNode->parent->left = minNode->right; } else minNode->parent->left = nullptr; minNode->right = toBeDeletedNode->right; toBeDeletedNode->right->parent = minNode; } minNode->left = toBeDeletedNode->left; minNode->parent = nullptr; if (toBeDeletedNode->left) toBeDeletedNode->left->parent = minNode; // cut linkage toBeDeletedNode->left = nullptr; toBeDeletedNode->right = nullptr; delete toBeDeletedNode; m_rootNode = minNode; }

handleRootLeaf()

[私人] void handleRootLeaf(Node* toBeDeletedNode) { delete m_rootNode; m_rootNode = nullptr; }

handleChildLSubtree()

[私人] void handleChildLSubtree(Node* toBeDeletedNode) { // fetch max node in left subtree Node* maxNode = fetchMaxNode(toBeDeletedNode->left); // in case left child node is the max node if (maxNode->parent == toBeDeletedNode) maxNode->parent = toBeDeletedNode->parent; else { if (maxNode->left) { maxNode->left->parent = maxNode->parent; maxNode->parent->right = maxNode->left; } else maxNode->parent->right = nullptr; maxNode->left = toBeDeletedNode->left; toBeDeletedNode->left->parent = maxNode; maxNode->parent = toBeDeletedNode->parent; } if (toBeDeletedNode->parent->left && toBeDeletedNode->parent->left == toBeDeletedNode) toBeDeletedNode->parent->left = maxNode; else toBeDeletedNode->parent->right = maxNode; // cut linkage toBeDeletedNode->left = nullptr; toBeDeletedNode->right = nullptr; delete toBeDeletedNode; }

handleChildRSubtree()

[私人] void handleChildRSubtree(Node* toBeDeletedNode) { // fetch min node in right subtree Node* minNode = fetchMinNode(toBeDeletedNode->right); // in case right child node is the min node if (minNode->parent == toBeDeletedNode) { if (toBeDeletedNode->left) { minNode->left = toBeDeletedNode->left; toBeDeletedNode->left->parent = minNode; } minNode->parent = toBeDeletedNode->parent; } else { if (minNode->right) { minNode->right->parent = minNode->parent; minNode->parent->left = minNode->right; } else minNode->parent->left = nullptr; minNode->left = toBeDeletedNode->left; if (toBeDeletedNode->left) toBeDeletedNode->left->parent = minNode; minNode->right = toBeDeletedNode->right; toBeDeletedNode->right->parent = minNode; minNode->parent = toBeDeletedNode->parent; } if (toBeDeletedNode->parent->left && toBeDeletedNode->parent->left == toBeDeletedNode) toBeDeletedNode->parent->left = minNode; else toBeDeletedNode->parent->right = minNode; // cut linkage toBeDeletedNode->left = nullptr; toBeDeletedNode->right = nullptr; delete toBeDeletedNode; }

handleChildLeaf()

void handleChildLeaf(Node* toBeDeletedNode) { if (toBeDeletedNode->parent->left && toBeDeletedNode->parent->left == toBeDeletedNode) toBeDeletedNode->parent->left = nullptr; else toBeDeletedNode->parent->right = nullptr; delete toBeDeletedNode; } 上课:

Node

1 个答案:

答案 0 :(得分:0)

错误原因在于handleRootLSubtree()函数:

该行

  

maxNode-&gt; parent-&gt; parent = maxNode;

必须替换为

  

toBeDeletedNode-&gt; left-&gt; parent = maxNode;