Skip to content

Commit e5669fd

Browse files
derekmaurocopybara-github
authored andcommitted
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
1 parent 5450174 commit e5669fd

File tree

2 files changed

+101
-10
lines changed

2 files changed

+101
-10
lines changed

googletest/src/gtest.cc

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -192,12 +192,17 @@ static const char kDefaultOutputFormat[] = "xml";
192192
// The default output file.
193193
static const char kDefaultOutputFile[] = "test_detail";
194194

195+
// These environment variables are set by Bazel.
196+
// https://bazel.build/reference/test-encyclopedia#initial-conditions
197+
//
195198
// The environment variable name for the test shard index.
196199
static const char kTestShardIndex[] = "GTEST_SHARD_INDEX";
197200
// The environment variable name for the total number of test shards.
198201
static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS";
199202
// The environment variable name for the test shard status file.
200203
static const char kTestShardStatusFile[] = "GTEST_SHARD_STATUS_FILE";
204+
// The environment variable name for the test output warnings file.
205+
static const char kTestWarningsOutputFile[] = "TEST_WARNINGS_OUTPUT_FILE";
201206

202207
namespace internal {
203208

@@ -5875,6 +5880,23 @@ TestSuite* UnitTestImpl::GetTestSuite(
58755880
static void SetUpEnvironment(Environment* env) { env->SetUp(); }
58765881
static void TearDownEnvironment(Environment* env) { env->TearDown(); }
58775882

5883+
// If the environment variable TEST_WARNINGS_OUTPUT_FILE was provided, appends
5884+
// `str` to the file, creating the file if necessary.
5885+
#if GTEST_HAS_FILE_SYSTEM
5886+
static void AppendToTestWarningsOutputFile(const std::string& str) {
5887+
const char* const filename = posix::GetEnv(kTestWarningsOutputFile);
5888+
if (filename == nullptr) {
5889+
return;
5890+
}
5891+
auto* const file = posix::FOpen(filename, "a");
5892+
if (file == nullptr) {
5893+
return;
5894+
}
5895+
GTEST_CHECK_(fwrite(str.data(), 1, str.size(), file) == str.size());
5896+
GTEST_CHECK_(posix::FClose(file) == 0);
5897+
}
5898+
#endif // GTEST_HAS_FILE_SYSTEM
5899+
58785900
// Runs all tests in this UnitTest object, prints the result, and
58795901
// returns true if all tests are successful. If any exception is
58805902
// thrown during a test, the test is considered to be failed, but the
@@ -5896,12 +5918,26 @@ bool UnitTestImpl::RunAllTests() {
58965918
// user didn't call InitGoogleTest.
58975919
PostFlagParsingInit();
58985920

5899-
if (GTEST_FLAG_GET(fail_if_no_test_linked) && total_test_count() == 0) {
5921+
// Handle the case where the program has no tests linked.
5922+
// Sometimes this is a programmer mistake, but sometimes it is intended.
5923+
if (total_test_count() == 0) {
5924+
constexpr char kNoTestLinkedMessage[] =
5925+
"This test program does NOT link in any test case.";
5926+
constexpr char kNoTestLinkedFatal[] =
5927+
"This is INVALID. Please make sure to link in at least one test case.";
5928+
constexpr char kNoTestLinkedWarning[] =
5929+
"Please make sure this is intended.";
5930+
const bool fail_if_no_test_linked = GTEST_FLAG_GET(fail_if_no_test_linked);
59005931
ColoredPrintf(
5901-
GTestColor::kRed,
5902-
"This test program does NOT link in any test case. This is INVALID. "
5903-
"Please make sure to link in at least one test case.\n");
5904-
return false;
5932+
GTestColor::kRed, "%s %s\n", kNoTestLinkedMessage,
5933+
fail_if_no_test_linked ? kNoTestLinkedFatal : kNoTestLinkedWarning);
5934+
if (fail_if_no_test_linked) {
5935+
return false;
5936+
}
5937+
#if GTEST_HAS_FILE_SYSTEM
5938+
AppendToTestWarningsOutputFile(std::string(kNoTestLinkedMessage) + ' ' +
5939+
kNoTestLinkedWarning + '\n');
5940+
#endif // GTEST_HAS_FILE_SYSTEM
59055941
}
59065942

59075943
#if GTEST_HAS_FILE_SYSTEM

googletest/test/googletest-fail-if-no-test-linked-test.py

Lines changed: 60 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,21 +31,26 @@
3131

3232
"""Tests for Google Test's --gtest_fail_if_no_test_linked flag."""
3333

34+
import os
3435
from googletest.test import gtest_test_utils
3536

3637
# The command line flag for enabling the fail-if-no-test-linked behavior.
3738
FAIL_IF_NO_TEST_LINKED_FLAG = "gtest_fail_if_no_test_linked"
3839

40+
# The environment variable for the test output warnings file.
41+
TEST_WARNINGS_OUTPUT_FILE = "TEST_WARNINGS_OUTPUT_FILE"
42+
3943

4044
class GTestFailIfNoTestLinkedTest(gtest_test_utils.TestCase):
4145
"""Tests the --gtest_fail_if_no_test_linked flag."""
4246

43-
def Run(self, program_name, flag=None):
47+
def Run(self, program_name, flag=None, env=None):
4448
"""Run the given program with the given flag.
4549
4650
Args:
4751
program_name: Name of the program to run.
4852
flag: The command line flag to pass to the program, or None.
53+
env: Dictionary with environment to pass to the subprocess.
4954
5055
Returns:
5156
True if the program exits with code 0, false otherwise.
@@ -55,59 +60,109 @@ def Run(self, program_name, flag=None):
5560
args = [exe_path]
5661
if flag is not None:
5762
args += [flag]
58-
process = gtest_test_utils.Subprocess(args, capture_stderr=False)
63+
process = gtest_test_utils.Subprocess(args, capture_stderr=False, env=env)
5964
return process.exited and process.exit_code == 0
6065

6166
def testSucceedsIfNoTestLinkedAndFlagNotSpecified(self):
6267
"""Tests the behavior of no test linked and flag not specified."""
63-
6468
self.assertTrue(
6569
self.Run("googletest-fail-if-no-test-linked-test-without-test_")
6670
)
6771

72+
def testSucceedsIfNoTestLinkedAndFlagNotSpecifiedWithWarningFile(self):
73+
"""Tests that no test linked results in warning file output."""
74+
75+
warning_file = os.path.join(gtest_test_utils.GetTempDir(), "NO_TEST_LINKED")
76+
self.assertTrue(
77+
self.Run(
78+
"googletest-fail-if-no-test-linked-test-without-test_",
79+
env={TEST_WARNINGS_OUTPUT_FILE: warning_file},
80+
)
81+
)
82+
warning_file_contents = open(warning_file, "r").read()
83+
self.assertEqual(
84+
warning_file_contents,
85+
"This test program does NOT link in any test case. Please make sure"
86+
" this is intended.\n",
87+
)
88+
6889
def testFailsIfNoTestLinkedAndFlagSpecified(self):
6990
"""Tests the behavior of no test linked and flag specified."""
7091

92+
warning_file = os.path.join(
93+
gtest_test_utils.GetTempDir(), "SHOULD_NOT_EXIST"
94+
)
7195
self.assertFalse(
7296
self.Run(
7397
"googletest-fail-if-no-test-linked-test-without-test_",
7498
f"--{FAIL_IF_NO_TEST_LINKED_FLAG}",
99+
env={TEST_WARNINGS_OUTPUT_FILE: warning_file},
75100
)
76101
)
102+
with self.assertRaises(FileNotFoundError):
103+
open(warning_file, "r")
77104

78105
def testSucceedsIfEnabledTestLinkedAndFlagNotSpecified(self):
79106
"""Tests the behavior of enabled test linked and flag not specified."""
80107

108+
warning_file = os.path.join(
109+
gtest_test_utils.GetTempDir(), "SHOULD_NOT_EXIST"
110+
)
81111
self.assertTrue(
82-
self.Run("googletest-fail-if-no-test-linked-test-with-enabled-test_")
112+
self.Run(
113+
"googletest-fail-if-no-test-linked-test-with-enabled-test_",
114+
env={TEST_WARNINGS_OUTPUT_FILE: warning_file},
115+
)
83116
)
117+
with self.assertRaises(FileNotFoundError):
118+
open(warning_file, "r")
84119

85120
def testSucceedsIfEnabledTestLinkedAndFlagSpecified(self):
86121
"""Tests the behavior of enabled test linked and flag specified."""
87122

123+
warning_file = os.path.join(
124+
gtest_test_utils.GetTempDir(), "SHOULD_NOT_EXIST"
125+
)
88126
self.assertTrue(
89127
self.Run(
90128
"googletest-fail-if-no-test-linked-test-with-enabled-test_",
91129
f"--{FAIL_IF_NO_TEST_LINKED_FLAG}",
130+
env={TEST_WARNINGS_OUTPUT_FILE: warning_file},
92131
)
93132
)
133+
with self.assertRaises(FileNotFoundError):
134+
open(warning_file, "r")
94135

95136
def testSucceedsIfDisabledTestLinkedAndFlagNotSpecified(self):
96137
"""Tests the behavior of disabled test linked and flag not specified."""
97138

139+
warning_file = os.path.join(
140+
gtest_test_utils.GetTempDir(), "SHOULD_NOT_EXIST"
141+
)
98142
self.assertTrue(
99-
self.Run("googletest-fail-if-no-test-linked-test-with-disabled-test_")
143+
self.Run(
144+
"googletest-fail-if-no-test-linked-test-with-disabled-test_",
145+
env={TEST_WARNINGS_OUTPUT_FILE: warning_file},
146+
)
100147
)
148+
with self.assertRaises(FileNotFoundError):
149+
open(warning_file, "r")
101150

102151
def testSucceedsIfDisabledTestLinkedAndFlagSpecified(self):
103152
"""Tests the behavior of disabled test linked and flag specified."""
104153

154+
warning_file = os.path.join(
155+
gtest_test_utils.GetTempDir(), "SHOULD_NOT_EXIST"
156+
)
105157
self.assertTrue(
106158
self.Run(
107159
"googletest-fail-if-no-test-linked-test-with-disabled-test_",
108160
f"--{FAIL_IF_NO_TEST_LINKED_FLAG}",
161+
env={TEST_WARNINGS_OUTPUT_FILE: warning_file},
109162
)
110163
)
164+
with self.assertRaises(FileNotFoundError):
165+
open(warning_file, "r")
111166

112167

113168
if __name__ == "__main__":

0 commit comments

Comments
 (0)