通过某些 GTest TEST_F 的 CLion 执行挂起,逐步调试倒退?

CLion execution through some GTest TEST_F hangs, step-by-step debugging goes backwards?

我正在调试我在 CLion 中使用 C++ 编写的应用程序,并正在使用 Google 测试对其进行测试。这是我发现的计算机视觉论文的实现,我正在使用 OpenCV 作为其 Mat class 和图像处理功能。

我的三个测试函数的行为非常不稳定;这是一个。

/**
 * Create a flat point cloud and flip it horizontally
 */
TEST_F(PointCloudTest, FlipHorizontal) {
    // load image & set constants
    cv::Mat image = omar::imreadAsGrayDouble(dirname + "uttower.png");
    cv::Mat flippedImage = omar::imreadAsGrayDouble(dirname + "uttower_horz.png");
    double fLength = 200.0; // for this, the flength is arbitrary as long as it's the same.

    // build point cloud
    omar::PointCloud pc(image, fLength);

    /* Build the other camera pose
     * Specifically, rotated pi over Y
     * and 2 focal lengths out into Z+ space.
     * It's written as 2.001 to test whether small variations affect point placement*/
    omar::Pose otherCamera(0.0, 0.0, 2.001, 0.0, M_PI, 0.0);

    // flip horizontally
    omar::PointCloud newPc = pc.viewPoints(otherCamera);
    cv::Mat newImage = newPc.renderToImage(fLength, image.rows, image.cols);
    omar::assertMatEquals(flippedImage, newImage, 10 * DBL_EPSILON);
}

GTest 调试系统将提供完成时的输出:

[ OK ] PointCloudTest.FlipHorizontal (205 ms)

但图标从未更改为表明测试已完成的东西。

我去debug的时候,如果我在函数最下面打个断点,它就会停止,然后每按一次"Step Over,"它就会跳转up 剩下的几行,一行一行,然后写完。这原来是所有测试的调试行为。

挂起测试与通过的不同测试仅略有不同。具体来说,该行是 viewPoints 行。这是相关代码:

PointCloud::PointCloud(const PointCloud& other) {
    pointsAndIntensities = other.pointsAndIntensities.clone();
}
PointCloud PointCloud::viewPoints(omar::Pose otherCameraPose) {
    PointCloud otherPointCloud = PointCloud(*this);
    otherPointCloud.transform(otherCameraPose);
    return otherPointCloud;
}

void PointCloud::transform(omar::Pose otherCameraPose) {
    cv::Mat transformedPoints = otherCameraPose.world2camera(pointsAndIntensities(cv::Range(0, 3), cv::Range::all()));
    cv::Mat replaceablePoints(pointsAndIntensities, cv::Range(0, 3));
    transformedPoints.copyTo(replaceablePoints);
}

我想了解此排序的原因,但它可能与真正的问题有关,也可能与挂起测试无关。从技术上讲,所有三个测试都通过了,但我认为这个问题会在未来造成很多问题。我没办法。感谢帮助和跟进问题!

TL;DR: 确保你的打印语句以新行结尾。

我在描述问题时遗漏了一个非常非常重要的细节。我决定 trim 删除 cout 行,这些行用于从我的描述中调试一些信息。原码为:

void PointCloud::transform(omar::Pose otherCameraPose) {
    //cv::Mat oldPoints(pointsAndIntensities, cv::Range(0, 3));

    cv::Mat transformedPoints = otherCameraPose.world2camera(pointsAndIntensities(cv::Range(0, 3), cv::Range::all()));
    cv::Mat replaceablePoints(pointsAndIntensities, cv::Range(0, 3));
    std::cout << "Transformed: " << transformedPoints.col(3) << std::endl;
    std::cout << "Original: " << replaceablePoints.col(3) << std::endl;
    transformedPoints.copyTo(replaceablePoints);
    std::cout << "Replaced?: " << pointsAndIntensities.col(3);
}

我决定深入研究代码以找到导致挂起的确切行,以防内存中出现某些错误。我追踪到上面的 transform 方法,结果是我在那里的 std::cout 行。我不知道在测试中使用流是否会导致一些问题。事实证明,我没有以 std::endl.

结束我的最后一个打印语句

我的直觉是 CLion 依赖于 GTest 的 cout 输出来确定测试是通过还是失败,并且因为 [ OK ] PointCloudTest.FlipHorizontal (205 ms) 不在新行上,所以它没有无法识别测试已成功完成。