mirror of
https://git.mirrors.martin98.com/https://github.com/google/googletest.git
synced 2025-06-04 11:25:34 +08:00
Output to the test warning file if no tests are linked.
Bazel sets the environment variable TEST_WARNINGS_OUTPUT_FILE https://bazel.build/reference/test-encyclopedia#initial-conditions If no tests are linked and the new flag --gtest_fail_if_no_test_linked is not true (which is the current default), we can still warn the user as this may be a programming error without failing the test (which would break existing users). PiperOrigin-RevId: 731402363 Change-Id: Ia481689efd4bd18889feaaa38bc56049a3f651cd
This commit is contained in:
parent
54501746a6
commit
e5669fdffc
@ -192,12 +192,17 @@ static const char kDefaultOutputFormat[] = "xml";
|
|||||||
// The default output file.
|
// The default output file.
|
||||||
static const char kDefaultOutputFile[] = "test_detail";
|
static const char kDefaultOutputFile[] = "test_detail";
|
||||||
|
|
||||||
|
// These environment variables are set by Bazel.
|
||||||
|
// https://bazel.build/reference/test-encyclopedia#initial-conditions
|
||||||
|
//
|
||||||
// The environment variable name for the test shard index.
|
// The environment variable name for the test shard index.
|
||||||
static const char kTestShardIndex[] = "GTEST_SHARD_INDEX";
|
static const char kTestShardIndex[] = "GTEST_SHARD_INDEX";
|
||||||
// The environment variable name for the total number of test shards.
|
// The environment variable name for the total number of test shards.
|
||||||
static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS";
|
static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS";
|
||||||
// The environment variable name for the test shard status file.
|
// The environment variable name for the test shard status file.
|
||||||
static const char kTestShardStatusFile[] = "GTEST_SHARD_STATUS_FILE";
|
static const char kTestShardStatusFile[] = "GTEST_SHARD_STATUS_FILE";
|
||||||
|
// The environment variable name for the test output warnings file.
|
||||||
|
static const char kTestWarningsOutputFile[] = "TEST_WARNINGS_OUTPUT_FILE";
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
@ -5875,6 +5880,23 @@ TestSuite* UnitTestImpl::GetTestSuite(
|
|||||||
static void SetUpEnvironment(Environment* env) { env->SetUp(); }
|
static void SetUpEnvironment(Environment* env) { env->SetUp(); }
|
||||||
static void TearDownEnvironment(Environment* env) { env->TearDown(); }
|
static void TearDownEnvironment(Environment* env) { env->TearDown(); }
|
||||||
|
|
||||||
|
// If the environment variable TEST_WARNINGS_OUTPUT_FILE was provided, appends
|
||||||
|
// `str` to the file, creating the file if necessary.
|
||||||
|
#if GTEST_HAS_FILE_SYSTEM
|
||||||
|
static void AppendToTestWarningsOutputFile(const std::string& str) {
|
||||||
|
const char* const filename = posix::GetEnv(kTestWarningsOutputFile);
|
||||||
|
if (filename == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto* const file = posix::FOpen(filename, "a");
|
||||||
|
if (file == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
GTEST_CHECK_(fwrite(str.data(), 1, str.size(), file) == str.size());
|
||||||
|
GTEST_CHECK_(posix::FClose(file) == 0);
|
||||||
|
}
|
||||||
|
#endif // GTEST_HAS_FILE_SYSTEM
|
||||||
|
|
||||||
// Runs all tests in this UnitTest object, prints the result, and
|
// Runs all tests in this UnitTest object, prints the result, and
|
||||||
// returns true if all tests are successful. If any exception is
|
// returns true if all tests are successful. If any exception is
|
||||||
// thrown during a test, the test is considered to be failed, but the
|
// thrown during a test, the test is considered to be failed, but the
|
||||||
@ -5896,13 +5918,27 @@ bool UnitTestImpl::RunAllTests() {
|
|||||||
// user didn't call InitGoogleTest.
|
// user didn't call InitGoogleTest.
|
||||||
PostFlagParsingInit();
|
PostFlagParsingInit();
|
||||||
|
|
||||||
if (GTEST_FLAG_GET(fail_if_no_test_linked) && total_test_count() == 0) {
|
// Handle the case where the program has no tests linked.
|
||||||
|
// Sometimes this is a programmer mistake, but sometimes it is intended.
|
||||||
|
if (total_test_count() == 0) {
|
||||||
|
constexpr char kNoTestLinkedMessage[] =
|
||||||
|
"This test program does NOT link in any test case.";
|
||||||
|
constexpr char kNoTestLinkedFatal[] =
|
||||||
|
"This is INVALID. Please make sure to link in at least one test case.";
|
||||||
|
constexpr char kNoTestLinkedWarning[] =
|
||||||
|
"Please make sure this is intended.";
|
||||||
|
const bool fail_if_no_test_linked = GTEST_FLAG_GET(fail_if_no_test_linked);
|
||||||
ColoredPrintf(
|
ColoredPrintf(
|
||||||
GTestColor::kRed,
|
GTestColor::kRed, "%s %s\n", kNoTestLinkedMessage,
|
||||||
"This test program does NOT link in any test case. This is INVALID. "
|
fail_if_no_test_linked ? kNoTestLinkedFatal : kNoTestLinkedWarning);
|
||||||
"Please make sure to link in at least one test case.\n");
|
if (fail_if_no_test_linked) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#if GTEST_HAS_FILE_SYSTEM
|
||||||
|
AppendToTestWarningsOutputFile(std::string(kNoTestLinkedMessage) + ' ' +
|
||||||
|
kNoTestLinkedWarning + '\n');
|
||||||
|
#endif // GTEST_HAS_FILE_SYSTEM
|
||||||
|
}
|
||||||
|
|
||||||
#if GTEST_HAS_FILE_SYSTEM
|
#if GTEST_HAS_FILE_SYSTEM
|
||||||
// Even if sharding is not on, test runners may want to use the
|
// Even if sharding is not on, test runners may want to use the
|
||||||
|
@ -31,21 +31,26 @@
|
|||||||
|
|
||||||
"""Tests for Google Test's --gtest_fail_if_no_test_linked flag."""
|
"""Tests for Google Test's --gtest_fail_if_no_test_linked flag."""
|
||||||
|
|
||||||
|
import os
|
||||||
from googletest.test import gtest_test_utils
|
from googletest.test import gtest_test_utils
|
||||||
|
|
||||||
# The command line flag for enabling the fail-if-no-test-linked behavior.
|
# The command line flag for enabling the fail-if-no-test-linked behavior.
|
||||||
FAIL_IF_NO_TEST_LINKED_FLAG = "gtest_fail_if_no_test_linked"
|
FAIL_IF_NO_TEST_LINKED_FLAG = "gtest_fail_if_no_test_linked"
|
||||||
|
|
||||||
|
# The environment variable for the test output warnings file.
|
||||||
|
TEST_WARNINGS_OUTPUT_FILE = "TEST_WARNINGS_OUTPUT_FILE"
|
||||||
|
|
||||||
|
|
||||||
class GTestFailIfNoTestLinkedTest(gtest_test_utils.TestCase):
|
class GTestFailIfNoTestLinkedTest(gtest_test_utils.TestCase):
|
||||||
"""Tests the --gtest_fail_if_no_test_linked flag."""
|
"""Tests the --gtest_fail_if_no_test_linked flag."""
|
||||||
|
|
||||||
def Run(self, program_name, flag=None):
|
def Run(self, program_name, flag=None, env=None):
|
||||||
"""Run the given program with the given flag.
|
"""Run the given program with the given flag.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
program_name: Name of the program to run.
|
program_name: Name of the program to run.
|
||||||
flag: The command line flag to pass to the program, or None.
|
flag: The command line flag to pass to the program, or None.
|
||||||
|
env: Dictionary with environment to pass to the subprocess.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
True if the program exits with code 0, false otherwise.
|
True if the program exits with code 0, false otherwise.
|
||||||
@ -55,59 +60,109 @@ class GTestFailIfNoTestLinkedTest(gtest_test_utils.TestCase):
|
|||||||
args = [exe_path]
|
args = [exe_path]
|
||||||
if flag is not None:
|
if flag is not None:
|
||||||
args += [flag]
|
args += [flag]
|
||||||
process = gtest_test_utils.Subprocess(args, capture_stderr=False)
|
process = gtest_test_utils.Subprocess(args, capture_stderr=False, env=env)
|
||||||
return process.exited and process.exit_code == 0
|
return process.exited and process.exit_code == 0
|
||||||
|
|
||||||
def testSucceedsIfNoTestLinkedAndFlagNotSpecified(self):
|
def testSucceedsIfNoTestLinkedAndFlagNotSpecified(self):
|
||||||
"""Tests the behavior of no test linked and flag not specified."""
|
"""Tests the behavior of no test linked and flag not specified."""
|
||||||
|
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
self.Run("googletest-fail-if-no-test-linked-test-without-test_")
|
self.Run("googletest-fail-if-no-test-linked-test-without-test_")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def testSucceedsIfNoTestLinkedAndFlagNotSpecifiedWithWarningFile(self):
|
||||||
|
"""Tests that no test linked results in warning file output."""
|
||||||
|
|
||||||
|
warning_file = os.path.join(gtest_test_utils.GetTempDir(), "NO_TEST_LINKED")
|
||||||
|
self.assertTrue(
|
||||||
|
self.Run(
|
||||||
|
"googletest-fail-if-no-test-linked-test-without-test_",
|
||||||
|
env={TEST_WARNINGS_OUTPUT_FILE: warning_file},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
warning_file_contents = open(warning_file, "r").read()
|
||||||
|
self.assertEqual(
|
||||||
|
warning_file_contents,
|
||||||
|
"This test program does NOT link in any test case. Please make sure"
|
||||||
|
" this is intended.\n",
|
||||||
|
)
|
||||||
|
|
||||||
def testFailsIfNoTestLinkedAndFlagSpecified(self):
|
def testFailsIfNoTestLinkedAndFlagSpecified(self):
|
||||||
"""Tests the behavior of no test linked and flag specified."""
|
"""Tests the behavior of no test linked and flag specified."""
|
||||||
|
|
||||||
|
warning_file = os.path.join(
|
||||||
|
gtest_test_utils.GetTempDir(), "SHOULD_NOT_EXIST"
|
||||||
|
)
|
||||||
self.assertFalse(
|
self.assertFalse(
|
||||||
self.Run(
|
self.Run(
|
||||||
"googletest-fail-if-no-test-linked-test-without-test_",
|
"googletest-fail-if-no-test-linked-test-without-test_",
|
||||||
f"--{FAIL_IF_NO_TEST_LINKED_FLAG}",
|
f"--{FAIL_IF_NO_TEST_LINKED_FLAG}",
|
||||||
|
env={TEST_WARNINGS_OUTPUT_FILE: warning_file},
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
with self.assertRaises(FileNotFoundError):
|
||||||
|
open(warning_file, "r")
|
||||||
|
|
||||||
def testSucceedsIfEnabledTestLinkedAndFlagNotSpecified(self):
|
def testSucceedsIfEnabledTestLinkedAndFlagNotSpecified(self):
|
||||||
"""Tests the behavior of enabled test linked and flag not specified."""
|
"""Tests the behavior of enabled test linked and flag not specified."""
|
||||||
|
|
||||||
self.assertTrue(
|
warning_file = os.path.join(
|
||||||
self.Run("googletest-fail-if-no-test-linked-test-with-enabled-test_")
|
gtest_test_utils.GetTempDir(), "SHOULD_NOT_EXIST"
|
||||||
)
|
)
|
||||||
|
self.assertTrue(
|
||||||
|
self.Run(
|
||||||
|
"googletest-fail-if-no-test-linked-test-with-enabled-test_",
|
||||||
|
env={TEST_WARNINGS_OUTPUT_FILE: warning_file},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
with self.assertRaises(FileNotFoundError):
|
||||||
|
open(warning_file, "r")
|
||||||
|
|
||||||
def testSucceedsIfEnabledTestLinkedAndFlagSpecified(self):
|
def testSucceedsIfEnabledTestLinkedAndFlagSpecified(self):
|
||||||
"""Tests the behavior of enabled test linked and flag specified."""
|
"""Tests the behavior of enabled test linked and flag specified."""
|
||||||
|
|
||||||
|
warning_file = os.path.join(
|
||||||
|
gtest_test_utils.GetTempDir(), "SHOULD_NOT_EXIST"
|
||||||
|
)
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
self.Run(
|
self.Run(
|
||||||
"googletest-fail-if-no-test-linked-test-with-enabled-test_",
|
"googletest-fail-if-no-test-linked-test-with-enabled-test_",
|
||||||
f"--{FAIL_IF_NO_TEST_LINKED_FLAG}",
|
f"--{FAIL_IF_NO_TEST_LINKED_FLAG}",
|
||||||
|
env={TEST_WARNINGS_OUTPUT_FILE: warning_file},
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
with self.assertRaises(FileNotFoundError):
|
||||||
|
open(warning_file, "r")
|
||||||
|
|
||||||
def testSucceedsIfDisabledTestLinkedAndFlagNotSpecified(self):
|
def testSucceedsIfDisabledTestLinkedAndFlagNotSpecified(self):
|
||||||
"""Tests the behavior of disabled test linked and flag not specified."""
|
"""Tests the behavior of disabled test linked and flag not specified."""
|
||||||
|
|
||||||
self.assertTrue(
|
warning_file = os.path.join(
|
||||||
self.Run("googletest-fail-if-no-test-linked-test-with-disabled-test_")
|
gtest_test_utils.GetTempDir(), "SHOULD_NOT_EXIST"
|
||||||
)
|
)
|
||||||
|
self.assertTrue(
|
||||||
|
self.Run(
|
||||||
|
"googletest-fail-if-no-test-linked-test-with-disabled-test_",
|
||||||
|
env={TEST_WARNINGS_OUTPUT_FILE: warning_file},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
with self.assertRaises(FileNotFoundError):
|
||||||
|
open(warning_file, "r")
|
||||||
|
|
||||||
def testSucceedsIfDisabledTestLinkedAndFlagSpecified(self):
|
def testSucceedsIfDisabledTestLinkedAndFlagSpecified(self):
|
||||||
"""Tests the behavior of disabled test linked and flag specified."""
|
"""Tests the behavior of disabled test linked and flag specified."""
|
||||||
|
|
||||||
|
warning_file = os.path.join(
|
||||||
|
gtest_test_utils.GetTempDir(), "SHOULD_NOT_EXIST"
|
||||||
|
)
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
self.Run(
|
self.Run(
|
||||||
"googletest-fail-if-no-test-linked-test-with-disabled-test_",
|
"googletest-fail-if-no-test-linked-test-with-disabled-test_",
|
||||||
f"--{FAIL_IF_NO_TEST_LINKED_FLAG}",
|
f"--{FAIL_IF_NO_TEST_LINKED_FLAG}",
|
||||||
|
env={TEST_WARNINGS_OUTPUT_FILE: warning_file},
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
with self.assertRaises(FileNotFoundError):
|
||||||
|
open(warning_file, "r")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
Loading…
x
Reference in New Issue
Block a user