Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
181 views
in Technique[技术] by (71.8m points)

c++ - Using opencv objects in gtest : test never ends after success

I made a simple test

TEST_F( DummyTest, testALL )
{
    auto dum = Dummy::MakeDummy();
    cv::imwrite( "D:/test/gogol.png", dum->GetTestingImage() );
}

which actually doesn't test anything but save an image... This just for the illustration of my problem.

Class Dummy is very simple and I propose to show you 2 implementations : one which succeeds and properly ends the test. And one which makes the test succeeded but never ends.

Dummy.h

#pragma once
 
#include <QObject>

#include <opencv2/core.hpp> 

namespace klns
{
class Dummy : public QObject
{
    Q_OBJECT

public: 
    ~Dummy();
    static std::unique_ptr<Dummy> MakeDummy(){ return std::unique_ptr<Dummy>( new Dummy() ); }

    bool operator==( const Dummy & p_other ) const;
    bool operator!=( const Dummy & p_other ) const;

    cv::Mat GetTestingImage() const { return m_testingMat; }

private:
    Dummy(); 

    QString m_labelText{ "" };
    cv::Mat m_testingMat;
};
} 

What is interesting to us is the implementations of constructor.

First case, which properly ends the test process:

Dummy::Dummy()
{
    m_testingMat = cv::Mat{ 4096, 4096, CV_8UC3 }; 
    cv::MatIterator_<cv::Vec3b> it, end;
    auto index{ 0 };
    for( it = m_testingMat.begin<cv::Vec3b>(), end = m_testingMat.end<cv::Vec3b>(); it != end; ++it )
    {
        auto blueVal = static_cast<uchar>( index / ( 256 * 256 ) );
        auto intermediateValue = index % ( 256 * 256 );   
        auto greenValue = static_cast<uchar>( intermediateValue / 256 );
        auto redValue = static_cast<uchar>( intermediateValue % 256 ); 

        ( *it )[0] = blueVal;
        ( *it )[1] = greenValue;
        ( *it )[2] = redValue;
        index++;
    }
}

Then the second implementation which makes the test succeed but never ends :

Dummy::Dummy()
{
    m_testingMat = cv::Mat( 4096, 4096, CV_8UC3 ); 
    cv::MatIterator_<cv::Vec3b> it, end;
    auto index{ 0 };
    for( it = m_testingMat.begin<cv::Vec3b>(), end = m_testingMat.end<cv::Vec3b>(); it != end; ++it )
    {
        auto blueVal = static_cast<uchar>( index / ( 256 * 256 ) );
        auto intermediateValue = index % ( 256 * 256 );   
        auto greenValue = static_cast<uchar>( intermediateValue / 256 );
        auto redValue = static_cast<uchar>( intermediateValue % 256 ); 

        ( *it )[0] = blueVal;
        ( *it )[1] = greenValue;
        ( *it )[2] = redValue;
        index++;
    }
}

The only difference stands in the construction of m_testingMat.

In the case (first one) which properly ends : the braces make that he takes the arguments 4096,4096,CV_8UC3 as an initializer list and constructs a cv:Mat with only one element, one uchar.

In the case (second one) which does not properly ends : the parentheses make that we properly construct a cv::Mat of 4096x4096 elements RGB.

When the first implementation is used in the above test, it saves an image of 1 pixel... and properly ends the test process. But when the second implementation is used in the above test, it properly saves an image of 4096x4096 with the colors as expected but the test is blocked, stucked after the test passes and in my Task manager, the process Dummy_test.exe never ends.

This happens with any class linked to openCV and used in gtest. My problem does not match the one : OpenCV and Gtest conflict in CMake as I am not using opencv_ts library. Here is how I link openCV :

# Dummy library for problem of unit tests with openCV
add_library( Dummy STATIC Dummy.h Dummy.cpp  )
target_link_libraries( Dummy Qt5::Core opencv_core )
adam_add_test_file( Dummy_test Dummy opencv_imgcodecs )

With this problem it is difficult (impossible) to test classes using openCV and I aim at doing that.

Here is the output I have from ctest in Visual Studio :

[GTA] >>>>>>>>>>>>>>> Output of command 'C:ProjetsxxxxRelWithDebInfo_VSinDummy_test.exe --gtest_output="xml:C:Usersxxxxxxx.kAppDataLocalTempmpBC90.tmp" --gtest_catch_exceptions=1 --gtest_break_on_failure=0'
[GTA] [==========] Running 1 test from 1 test suite.
[GTA] [----------] Global test environment set-up.
[GTA] [----------] 1 test from DummyTest
[GTA] [ RUN      ] DummyTest.testALL
[GTA] [       OK ] DummyTest.testALL (145848 ms)
[GTA] [----------] 1 test from DummyTest (2267445 ms total)
[GTA] 
[GTA] [----------] Global test environment tear-down
[GTA] [==========] 1 test from 1 test suite ran. (2267446 ms total)
[GTA] [  PASSED  ] 1 test.
[GTA] <<<<<<<<<<<<<<< End of Output
[GTA] Executable C:ProjetsxxxxRelWithDebInfo_VSinDummy_test.exe returned with exit code -1
[GTA] Reported 1 test results to VS during test execution, executable: 'C:ProjetsxxxxRelWithDebInfo_VSinDummy_test.exe'
[GTA] Execution took 00:47:41.9170274
[GTA] No settings configured for test executable 'C:ProjetsxxxxRelWithDebInfo_VSinDummy_test.exe'; running with solution settings
[GTA] Google Test execution completed, overall duration: 00:47:41.9818064.
The active test run was aborted. Reason: Test host process crashed
========== Test run aborted: 0 Tests run in 47,7 min (0 Passed, 0 Failed, 0 Skipped) ==========

Herer, I manually stopped after 47minutes, but just before I stopped manually, it was stucked at line :

[GTA] [  PASSED  ] 1 test.

and the tear down of gtest environnment class was passed (I can see it thanks to additional logs)

question from:https://stackoverflow.com/questions/66049641/using-opencv-objects-in-gtest-test-never-ends-after-success

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...