mirror of
https://github.com/google/googletest.git
synced 2025-04-02 19:08:12 +00:00
Adds support for a --gtest_fail_if_no_test_linked flag
to fail the test program if no test case is linked in (a common programmer mistake). PiperOrigin-RevId: 730571311 Change-Id: I1dab04adfe35581274d0b4ec79a017014d50e1ea
This commit is contained in:
parent
3fbe4db9a3
commit
54501746a6
@ -1929,6 +1929,20 @@ the `--gtest_also_run_disabled_tests` flag or set the
|
||||
You can combine this with the `--gtest_filter` flag to further select which
|
||||
disabled tests to run.
|
||||
|
||||
### Enforcing Having At Least One Test Case
|
||||
|
||||
A not uncommon programmer mistake is to write a test program that has no test
|
||||
case linked in. This can happen, for example, when you put test case definitions
|
||||
in a library and the library is not marked as "always link".
|
||||
|
||||
To catch such mistakes, run the test program with the
|
||||
`--gtest_fail_if_no_test_linked` flag or set the `GTEST_FAIL_IF_NO_TEST_LINKED`
|
||||
environment variable to a value other than `0`. Now the program will fail if no
|
||||
test case is linked in.
|
||||
|
||||
Note that *any* test case linked in makes the program valid for the purpose of
|
||||
this check. In particular, even a disabled test case suffices.
|
||||
|
||||
### Repeating the Tests
|
||||
|
||||
Once in a while you'll run into a test whose result is hit-or-miss. Perhaps it
|
||||
|
@ -258,6 +258,12 @@ GTEST_DEFINE_bool_(
|
||||
testing::GetDefaultFailFast()),
|
||||
"True if and only if a test failure should stop further test execution.");
|
||||
|
||||
GTEST_DEFINE_bool_(
|
||||
fail_if_no_test_linked,
|
||||
testing::internal::BoolFromGTestEnv("fail_if_no_test_linked", false),
|
||||
"True if and only if the test should fail if no test case (including "
|
||||
"disabled test cases) is linked.");
|
||||
|
||||
GTEST_DEFINE_bool_(
|
||||
also_run_disabled_tests,
|
||||
testing::internal::BoolFromGTestEnv("also_run_disabled_tests", false),
|
||||
@ -5890,6 +5896,14 @@ bool UnitTestImpl::RunAllTests() {
|
||||
// user didn't call InitGoogleTest.
|
||||
PostFlagParsingInit();
|
||||
|
||||
if (GTEST_FLAG_GET(fail_if_no_test_linked) && total_test_count() == 0) {
|
||||
ColoredPrintf(
|
||||
GTestColor::kRed,
|
||||
"This test program does NOT link in any test case. This is INVALID. "
|
||||
"Please make sure to link in at least one test case.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
#if GTEST_HAS_FILE_SYSTEM
|
||||
// Even if sharding is not on, test runners may want to use the
|
||||
// GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding
|
||||
@ -6677,6 +6691,7 @@ static bool ParseGoogleTestFlag(const char* const arg) {
|
||||
GTEST_INTERNAL_PARSE_FLAG(death_test_style);
|
||||
GTEST_INTERNAL_PARSE_FLAG(death_test_use_fork);
|
||||
GTEST_INTERNAL_PARSE_FLAG(fail_fast);
|
||||
GTEST_INTERNAL_PARSE_FLAG(fail_if_no_test_linked);
|
||||
GTEST_INTERNAL_PARSE_FLAG(filter);
|
||||
GTEST_INTERNAL_PARSE_FLAG(internal_run_death_test);
|
||||
GTEST_INTERNAL_PARSE_FLAG(list_tests);
|
||||
|
@ -47,33 +47,36 @@ cc_test(
|
||||
"*.h",
|
||||
],
|
||||
exclude = [
|
||||
"gtest-unittest-api_test.cc",
|
||||
"googletest/src/gtest-all.cc",
|
||||
"gtest_all_test.cc",
|
||||
"gtest-death-test_ex_test.cc",
|
||||
"gtest-listener_test.cc",
|
||||
"gtest-unittest-api_test.cc",
|
||||
"googletest-param-test-test.cc",
|
||||
"googletest-param-test2-test.cc",
|
||||
# go/keep-sorted start
|
||||
"googletest-break-on-failure-unittest_.cc",
|
||||
"googletest-catch-exceptions-test_.cc",
|
||||
"googletest-color-test_.cc",
|
||||
"googletest-death-test_ex_test.cc",
|
||||
"googletest-env-var-test_.cc",
|
||||
"googletest-fail-if-no-test-linked-test-with-disabled-test_.cc",
|
||||
"googletest-fail-if-no-test-linked-test-with-enabled-test_.cc",
|
||||
"googletest-failfast-unittest_.cc",
|
||||
"googletest-filter-unittest_.cc",
|
||||
"googletest-global-environment-unittest_.cc",
|
||||
"googletest-break-on-failure-unittest_.cc",
|
||||
"googletest-list-tests-unittest_.cc",
|
||||
"googletest-listener-test.cc",
|
||||
"googletest-message-test.cc",
|
||||
"googletest-output-test_.cc",
|
||||
"googletest-list-tests-unittest_.cc",
|
||||
"googletest-shuffle-test_.cc",
|
||||
"googletest-setuptestsuite-test_.cc",
|
||||
"googletest-uninitialized-test_.cc",
|
||||
"googletest-death-test_ex_test.cc",
|
||||
"googletest-param-test-test",
|
||||
"googletest-throw-on-failure-test_.cc",
|
||||
"googletest-param-test-invalid-name1-test_.cc",
|
||||
"googletest-param-test-invalid-name2-test_.cc",
|
||||
"googletest-param-test-test",
|
||||
"googletest-param-test-test.cc",
|
||||
"googletest-param-test2-test.cc",
|
||||
"googletest-setuptestsuite-test_.cc",
|
||||
"googletest-shuffle-test_.cc",
|
||||
"googletest-throw-on-failure-test_.cc",
|
||||
"googletest-uninitialized-test_.cc",
|
||||
"googletest/src/gtest-all.cc",
|
||||
"gtest-death-test_ex_test.cc",
|
||||
"gtest-listener_test.cc",
|
||||
"gtest-unittest-api_test.cc",
|
||||
"gtest_all_test.cc",
|
||||
# go/keep-sorted end
|
||||
],
|
||||
) + select({
|
||||
"//:windows": [],
|
||||
@ -323,6 +326,26 @@ cc_binary(
|
||||
deps = ["//:gtest"],
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "googletest-fail-if-no-test-linked-test-without-test_",
|
||||
testonly = 1,
|
||||
deps = ["//:gtest_main"],
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "googletest-fail-if-no-test-linked-test-with-disabled-test_",
|
||||
testonly = 1,
|
||||
srcs = ["googletest-fail-if-no-test-linked-test-with-disabled-test_.cc"],
|
||||
deps = ["//:gtest_main"],
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "googletest-fail-if-no-test-linked-test-with-enabled-test_",
|
||||
testonly = 1,
|
||||
srcs = ["googletest-fail-if-no-test-linked-test-with-enabled-test_.cc"],
|
||||
deps = ["//:gtest_main"],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "gtest_skip_test",
|
||||
size = "small",
|
||||
@ -363,6 +386,18 @@ py_test(
|
||||
deps = [":gtest_test_utils"],
|
||||
)
|
||||
|
||||
py_test(
|
||||
name = "googletest-fail-if-no-test-linked-test",
|
||||
size = "small",
|
||||
srcs = ["googletest-fail-if-no-test-linked-test.py"],
|
||||
data = [
|
||||
":googletest-fail-if-no-test-linked-test-with-disabled-test_",
|
||||
":googletest-fail-if-no-test-linked-test-with-enabled-test_",
|
||||
":googletest-fail-if-no-test-linked-test-without-test_",
|
||||
],
|
||||
deps = [":gtest_test_utils"],
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "googletest-shuffle-test_",
|
||||
srcs = ["googletest-shuffle-test_.cc"],
|
||||
|
@ -0,0 +1,38 @@
|
||||
// Copyright 2025, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Unit test for Google Test's --gtest_fail_if_no_test_linked flag.
|
||||
//
|
||||
// This program will be invoked from a Python test.
|
||||
// Don't run it directly.
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
// A dummy test that is disabled.
|
||||
TEST(SomeTest, DISABLED_Test1) {}
|
@ -0,0 +1,38 @@
|
||||
// Copyright 2025, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Unit test for Google Test's --gtest_fail_if_no_test_linked flag.
|
||||
//
|
||||
// This program will be invoked from a Python test.
|
||||
// Don't run it directly.
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
// A dummy test that is enabled.
|
||||
TEST(SomeTest, Test1) {}
|
114
googletest/test/googletest-fail-if-no-test-linked-test.py
Executable file
114
googletest/test/googletest-fail-if-no-test-linked-test.py
Executable file
@ -0,0 +1,114 @@
|
||||
#!/usr/bin/env python3 # pylint: disable=g-interpreter-mismatch
|
||||
#
|
||||
# Copyright 2025, Google Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following disclaimer
|
||||
# in the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Google Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
"""Tests for Google Test's --gtest_fail_if_no_test_linked flag."""
|
||||
|
||||
from googletest.test import gtest_test_utils
|
||||
|
||||
# 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"
|
||||
|
||||
|
||||
class GTestFailIfNoTestLinkedTest(gtest_test_utils.TestCase):
|
||||
"""Tests the --gtest_fail_if_no_test_linked flag."""
|
||||
|
||||
def Run(self, program_name, flag=None):
|
||||
"""Run the given program with the given flag.
|
||||
|
||||
Args:
|
||||
program_name: Name of the program to run.
|
||||
flag: The command line flag to pass to the program, or None.
|
||||
|
||||
Returns:
|
||||
True if the program exits with code 0, false otherwise.
|
||||
"""
|
||||
|
||||
exe_path = gtest_test_utils.GetTestExecutablePath(program_name)
|
||||
args = [exe_path]
|
||||
if flag is not None:
|
||||
args += [flag]
|
||||
process = gtest_test_utils.Subprocess(args, capture_stderr=False)
|
||||
return process.exited and process.exit_code == 0
|
||||
|
||||
def testSucceedsIfNoTestLinkedAndFlagNotSpecified(self):
|
||||
"""Tests the behavior of no test linked and flag not specified."""
|
||||
|
||||
self.assertTrue(
|
||||
self.Run("googletest-fail-if-no-test-linked-test-without-test_")
|
||||
)
|
||||
|
||||
def testFailsIfNoTestLinkedAndFlagSpecified(self):
|
||||
"""Tests the behavior of no test linked and flag specified."""
|
||||
|
||||
self.assertFalse(
|
||||
self.Run(
|
||||
"googletest-fail-if-no-test-linked-test-without-test_",
|
||||
f"--{FAIL_IF_NO_TEST_LINKED_FLAG}",
|
||||
)
|
||||
)
|
||||
|
||||
def testSucceedsIfEnabledTestLinkedAndFlagNotSpecified(self):
|
||||
"""Tests the behavior of enabled test linked and flag not specified."""
|
||||
|
||||
self.assertTrue(
|
||||
self.Run("googletest-fail-if-no-test-linked-test-with-enabled-test_")
|
||||
)
|
||||
|
||||
def testSucceedsIfEnabledTestLinkedAndFlagSpecified(self):
|
||||
"""Tests the behavior of enabled test linked and flag specified."""
|
||||
|
||||
self.assertTrue(
|
||||
self.Run(
|
||||
"googletest-fail-if-no-test-linked-test-with-enabled-test_",
|
||||
f"--{FAIL_IF_NO_TEST_LINKED_FLAG}",
|
||||
)
|
||||
)
|
||||
|
||||
def testSucceedsIfDisabledTestLinkedAndFlagNotSpecified(self):
|
||||
"""Tests the behavior of disabled test linked and flag not specified."""
|
||||
|
||||
self.assertTrue(
|
||||
self.Run("googletest-fail-if-no-test-linked-test-with-disabled-test_")
|
||||
)
|
||||
|
||||
def testSucceedsIfDisabledTestLinkedAndFlagSpecified(self):
|
||||
"""Tests the behavior of disabled test linked and flag specified."""
|
||||
|
||||
self.assertTrue(
|
||||
self.Run(
|
||||
"googletest-fail-if-no-test-linked-test-with-disabled-test_",
|
||||
f"--{FAIL_IF_NO_TEST_LINKED_FLAG}",
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
gtest_test_utils.Main()
|
Loading…
x
Reference in New Issue
Block a user