diff --git a/modules/core/test/test_misc.cpp b/modules/core/test/test_misc.cpp index 8ed0afe771..cb89dcf573 100644 --- a/modules/core/test/test_misc.cpp +++ b/modules/core/test/test_misc.cpp @@ -917,5 +917,41 @@ REGISTER_TYPED_TEST_CASE_P(Rect_Test, Overflows); typedef ::testing::Types RectTypes; INSTANTIATE_TYPED_TEST_CASE_P(Negative_Test, Rect_Test, RectTypes); +// Expected that SkipTestException thrown in the constructor should skip test but not fail +struct TestFixtureSkip: public ::testing::Test { + TestFixtureSkip(bool throwEx = true) { + if (throwEx) { + throw SkipTestException("Skip test at constructor"); + } + } +}; + +TEST_F(TestFixtureSkip, NoBodyRun) { + FAIL() << "Unreachable code called"; +} + +// Check no test body started in case of skip exception at static SetUpTestCase +struct TestSetUpTestCaseSkip: public ::testing::Test { + static void SetUpTestCase() { + throw SkipTestException("Skip test at SetUpTestCase"); + } +}; + +TEST_F(TestSetUpTestCaseSkip, NoBodyRun) { + FAIL() << "Unreachable code called"; +} +TEST_F(TestSetUpTestCaseSkip, NoBodyRun2) { + FAIL() << "Unreachable code called"; +} + +struct TestSetUpSkip: public ::testing::Test { + virtual void SetUp() { + throw SkipTestException("Skip test at SetUp"); + } +}; + +TEST_F(TestSetUpSkip, NoBodyRun) { + FAIL() << "Unreachable code called"; +} }} // namespace diff --git a/modules/python/test/tests_common.py b/modules/python/test/tests_common.py index ec49f46d0d..d673dd7b78 100644 --- a/modules/python/test/tests_common.py +++ b/modules/python/test/tests_common.py @@ -36,6 +36,8 @@ class NewOpenCVTests(unittest.TestCase): return candidate if required: self.fail('File ' + filename + ' not found') + else: + self.skipTest('File ' + filename + ' not found') return None diff --git a/modules/ts/include/opencv2/ts/ts_ext.hpp b/modules/ts/include/opencv2/ts/ts_ext.hpp index efa4860510..4603dba4f7 100644 --- a/modules/ts/include/opencv2/ts/ts_ext.hpp +++ b/modules/ts/include/opencv2/ts/ts_ext.hpp @@ -47,6 +47,18 @@ bool checkBigDataTests(); } \ } \ +#define CV__TEST_SETUP_IMPL(parent_class) \ + { \ + try { \ + parent_class::SetUp(); \ + } catch (const cvtest::details::SkipTestExceptionBase& e) { \ + printf("[ SKIP ] %s\n", e.what()); \ + } \ + } + +struct DummyTest : public ::testing::Test { + virtual void TestBody() CV_OVERRIDE {} +}; #undef TEST #define TEST_(test_case_name, test_name, parent_class, bodyMethodName, BODY_ATTR, BODY_IMPL) \ @@ -60,6 +72,17 @@ bool checkBigDataTests(); GTEST_DISALLOW_COPY_AND_ASSIGN_(\ GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\ };\ + class test_case_name##test_name##_factory : public ::testing::internal::TestFactoryBase { \ + public:\ + virtual ::testing::Test* CreateTest() { \ + try { \ + return new GTEST_TEST_CLASS_NAME_(test_case_name, test_name); \ + } catch (const cvtest::details::SkipTestExceptionBase& e) { \ + printf("[ SKIP ] %s\n", e.what()); \ + return new DummyTest(); \ + } \ + } \ + };\ \ ::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\ ::test_info_ =\ @@ -69,8 +92,7 @@ bool checkBigDataTests(); (::testing::internal::GetTestTypeId()), \ parent_class::SetUpTestCase, \ parent_class::TearDownTestCase, \ - new ::testing::internal::TestFactoryImpl<\ - GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\ + new test_case_name##test_name##_factory);\ void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() BODY_IMPL( #test_case_name "_" #test_name ) \ void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::bodyMethodName() @@ -109,10 +131,22 @@ bool checkBigDataTests(); private:\ virtual void TestBody() CV_OVERRIDE;\ virtual void Body(); \ + virtual void SetUp() CV_OVERRIDE; \ static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_;\ GTEST_DISALLOW_COPY_AND_ASSIGN_(\ GTEST_TEST_CLASS_NAME_(test_fixture, test_name));\ };\ + class test_fixture##test_name##_factory : public ::testing::internal::TestFactoryBase { \ + public:\ + virtual ::testing::Test* CreateTest() { \ + try { \ + return new GTEST_TEST_CLASS_NAME_(test_fixture, test_name); \ + } catch (const cvtest::details::SkipTestExceptionBase& e) { \ + printf("[ SKIP ] %s\n", e.what()); \ + return new DummyTest(); \ + } \ + } \ + };\ \ ::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_fixture, test_name)\ ::test_info_ =\ @@ -122,9 +156,9 @@ bool checkBigDataTests(); (::testing::internal::GetTypeId()), \ test_fixture::SetUpTestCase, \ test_fixture::TearDownTestCase, \ - new ::testing::internal::TestFactoryImpl<\ - GTEST_TEST_CLASS_NAME_(test_fixture, test_name)>);\ + new test_fixture##test_name##_factory);\ void GTEST_TEST_CLASS_NAME_(test_fixture, test_name)::TestBody() CV__TEST_BODY_IMPL( #test_fixture "_" #test_name ) \ + void GTEST_TEST_CLASS_NAME_(test_fixture, test_name)::SetUp() CV__TEST_SETUP_IMPL(test_fixture) \ void GTEST_TEST_CLASS_NAME_(test_fixture, test_name)::Body() // Don't use directly diff --git a/modules/ts/src/ts_tags.cpp b/modules/ts/src/ts_tags.cpp index 8bed1b739f..21653e17ee 100644 --- a/modules/ts/src/ts_tags.cpp +++ b/modules/ts/src/ts_tags.cpp @@ -11,7 +11,7 @@ namespace cvtest { static bool printTestTag = false; static std::vector currentDirectTestTags, currentImpliedTestTags; -static std::vector skipped_tests; +static std::vector skipped_tests; static std::map& getTestTagsSkipCounts() { @@ -26,7 +26,7 @@ static std::map& getTestTagsSkipExtraCounts() void testTagIncreaseSkipCount(const std::string& tag, bool isMain, bool appendSkipTests) { if (appendSkipTests) - skipped_tests.push_back(::testing::UnitTest::GetInstance()->current_test_info()); + skipped_tests.push_back(::testing::UnitTest::GetInstance()->current_test_case()); std::map& counts = isMain ? getTestTagsSkipCounts() : getTestTagsSkipExtraCounts(); std::map::iterator i = counts.find(tag); if (i == counts.end()) @@ -280,6 +280,11 @@ static bool isTestTagSkipped(const std::string& testTag, CV_OUT std::string& ski void checkTestTags() { + if (std::find(skipped_tests.begin(), skipped_tests.end(), + ::testing::UnitTest::GetInstance()->current_test_case()) != skipped_tests.end()) { + throw details::SkipTestExceptionBase(false); + } + std::string skipTag; const std::vector& testTags = currentDirectTestTags; { @@ -307,7 +312,7 @@ void checkTestTags() } if (found != tags.size()) { - skipped_tests.push_back(::testing::UnitTest::GetInstance()->current_test_info()); + skipped_tests.push_back(::testing::UnitTest::GetInstance()->current_test_case()); throw details::SkipTestExceptionBase("Test tags don't pass required tags list (--test_tag parameter)", true); } } @@ -341,7 +346,7 @@ void checkTestTags() if (!skip_message.empty()) { - skipped_tests.push_back(::testing::UnitTest::GetInstance()->current_test_info()); + skipped_tests.push_back(::testing::UnitTest::GetInstance()->current_test_case()); throw details::SkipTestExceptionBase(skip_message, true); } }