diff --git a/googletest/src/gtest-internal-inl.h b/googletest/src/gtest-internal-inl.h index cc6f0048..6a39b93b 100644 --- a/googletest/src/gtest-internal-inl.h +++ b/googletest/src/gtest-internal-inl.h @@ -826,6 +826,10 @@ class GTEST_API_ UnitTestImpl { bool catch_exceptions() const { return catch_exceptions_; } private: + // Returns true if a warning should be issued if no tests match the test + // filter flag. + bool ShouldWarnIfNoTestsMatchFilter() const; + struct CompareTestSuitesByPointer { bool operator()(const TestSuite* lhs, const TestSuite* rhs) const { return lhs->name_ < rhs->name_; diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc index 26959dfc..09af1517 100644 --- a/googletest/src/gtest.cc +++ b/googletest/src/gtest.cc @@ -6113,6 +6113,17 @@ bool UnitTestImpl::RunAllTests() { environments_.clear(); } + // Try to warn the user if no tests matched the test filter. + if (ShouldWarnIfNoTestsMatchFilter()) { + const std::string filter_warning = + std::string("filter \"") + GTEST_FLAG_GET(filter) + + "\" did not match any test; no tests were run\n"; + ColoredPrintf(GTestColor::kRed, "WARNING: %s", filter_warning.c_str()); +#if GTEST_HAS_FILE_SYSTEM + AppendToTestWarningsOutputFile(filter_warning); +#endif // GTEST_HAS_FILE_SYSTEM + } + if (!gtest_is_initialized_before_run_all_tests) { ColoredPrintf( GTestColor::kRed, @@ -6281,6 +6292,30 @@ int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { return num_selected_tests; } +// Returns true if a warning should be issued if no tests match the test filter +// flag. We can't simply count the number of tests that ran because, for +// instance, test sharding and death tests might mean no tests are expected to +// run in this process, but will run in another process. +bool UnitTestImpl::ShouldWarnIfNoTestsMatchFilter() const { + if (total_test_count() == 0) { + // No tests were linked in to program. + // This case is handled by a different warning. + return false; + } + const PositiveAndNegativeUnitTestFilter gtest_flag_filter( + GTEST_FLAG_GET(filter)); + for (auto* test_suite : test_suites_) { + const std::string& test_suite_name = test_suite->name_; + for (TestInfo* test_info : test_suite->test_info_list()) { + const std::string& test_name = test_info->name_; + if (gtest_flag_filter.MatchesTest(test_suite_name, test_name)) { + return false; + } + } + } + return true; +} + // Prints the given C-string on a single line by replacing all '\n' // characters with string "\\n". If the output takes more than // max_length characters, only prints the first max_length characters diff --git a/googletest/test/googletest-filter-unittest.py b/googletest/test/googletest-filter-unittest.py index f1f3c7a5..a44882a6 100755 --- a/googletest/test/googletest-filter-unittest.py +++ b/googletest/test/googletest-filter-unittest.py @@ -97,6 +97,9 @@ TOTAL_SHARDS_ENV_VAR = 'GTEST_TOTAL_SHARDS' SHARD_INDEX_ENV_VAR = 'GTEST_SHARD_INDEX' SHARD_STATUS_FILE_ENV_VAR = 'GTEST_SHARD_STATUS_FILE' +# The environment variable for the test warnings output file. +TEST_WARNINGS_OUTPUT_FILE = 'TEST_WARNINGS_OUTPUT_FILE' + # The command line flag for specifying the test filters. FILTER_FLAG = 'gtest_filter' @@ -419,6 +422,22 @@ class GTestFilterUnitTest(gtest_test_utils.TestCase): self.RunAndVerify('BadFilter', []) self.RunAndVerifyAllowingDisabled('BadFilter', []) + def testBadFilterWithWarningFile(self): + """Tests the warning file when a filter that matches nothing.""" + + warning_file = os.path.join( + gtest_test_utils.GetTempDir(), 'testBadFilterWithWarningFile' + ) + extra_env = {TEST_WARNINGS_OUTPUT_FILE: warning_file} + args = ['--%s=%s' % (FILTER_FLAG, 'BadFilter')] + InvokeWithModifiedEnv(extra_env, RunAndReturnOutput, args) + with open(warning_file, 'r') as f: + warning_file_contents = f.read() + self.assertEqual( + warning_file_contents, + 'filter "BadFilter" did not match any test; no tests were run\n', + ) + def testFullName(self): """Tests filtering by full name."""