diff options
Diffstat (limited to 'docs')
-rw-r--r-- | docs/_data/navigation.yml | 4 | ||||
-rw-r--r-- | docs/advanced.md | 76 | ||||
-rw-r--r-- | docs/faq.md | 36 | ||||
-rw-r--r-- | docs/gmock_cheat_sheet.md | 33 | ||||
-rw-r--r-- | docs/gmock_cook_book.md | 22 | ||||
-rw-r--r-- | docs/quickstart-bazel.md | 161 | ||||
-rw-r--r-- | docs/quickstart-cmake.md | 156 |
7 files changed, 411 insertions, 77 deletions
diff --git a/docs/_data/navigation.yml b/docs/_data/navigation.yml index b79f2505..355ebc8e 100644 --- a/docs/_data/navigation.yml +++ b/docs/_data/navigation.yml @@ -3,6 +3,10 @@ nav: items: - title: "Supported Platforms" url: "/platforms.html" + - title: "Quickstart: Bazel" + url: "/quickstart-bazel.html" + - title: "Quickstart: CMake" + url: "/quickstart-cmake.html" - section: "Guides" items: - title: "GoogleTest Primer" diff --git a/docs/advanced.md b/docs/advanced.md index 4103507b..fa9e5bc2 100644 --- a/docs/advanced.md +++ b/docs/advanced.md @@ -813,7 +813,8 @@ initialized from the command-line flag `--gtest_death_test_style`). consideration to be run - much like the `threadsafe` mode on POSIX. Other values for the variable are illegal and will cause the death test to fail. -Currently, the flag's default value is **"fast"** +Currently, the flag's default value is +**`"fast"`**. 1. the child's exit status satisfies the predicate, and 2. the child's stderr matches the regular expression. @@ -1204,10 +1205,10 @@ class FooTest : public testing::Test { } // You can define per-test set-up logic as usual. - virtual void SetUp() { ... } + void SetUp() override { ... } // You can define per-test tear-down logic as usual. - virtual void TearDown() { ... } + void TearDown() override { ... } // Some expensive resource shared by all tests. static T* shared_resource_; @@ -1238,7 +1239,7 @@ First, you subclass the `::testing::Environment` class to define a test environment, which knows how to set-up and tear-down: ```c++ -class Environment : public testing::Environment { +class Environment : public ::testing::Environment { public: ~Environment() override {} @@ -1374,7 +1375,7 @@ The following statement will instantiate tests from the `FooTest` test suite each with parameter values `"meeny"`, `"miny"`, and `"moe"`. ```c++ -INSTANTIATE_TEST_SUITE_P(InstantiationName, +INSTANTIATE_TEST_SUITE_P(MeenyMinyMoe, FooTest, testing::Values("meeny", "miny", "moe")); ``` @@ -1383,51 +1384,54 @@ INSTANTIATE_TEST_SUITE_P(InstantiationName, NOTE: The code above must be placed at global or namespace scope, not at function scope. -Per default, every `TEST_P` without a corresponding `INSTANTIATE_TEST_SUITE_P` -causes a failing test in test suite `GoogleTestVerification`. If you have a test -suite where that omission is not an error, for example it is in a library that -may be linked in for other reason or where the list of test cases is dynamic and -may be empty, then this check can be suppressed by tagging the test suite: - -```c++ -GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(FooTest); -``` +The first argument to `INSTANTIATE_TEST_SUITE_P` is a unique name for the +instantiation of the test suite. The next argument is the name of the test +pattern, and the last is the parameter generator. -To distinguish different instances of the pattern (yes, you can instantiate it -more than once), the first argument to `INSTANTIATE_TEST_SUITE_P` is a prefix -that will be added to the actual test suite name. Remember to pick unique -prefixes for different instantiations. The tests from the instantiation above -will have these names: +You can instantiate a test pattern more than once, so to distinguish different +instances of the pattern, the instantiation name is added as a prefix to the +actual test suite name. Remember to pick unique prefixes for different +instantiations. The tests from the instantiation above will have these names: -* `InstantiationName/FooTest.DoesBlah/0` for `"meeny"` -* `InstantiationName/FooTest.DoesBlah/1` for `"miny"` -* `InstantiationName/FooTest.DoesBlah/2` for `"moe"` -* `InstantiationName/FooTest.HasBlahBlah/0` for `"meeny"` -* `InstantiationName/FooTest.HasBlahBlah/1` for `"miny"` -* `InstantiationName/FooTest.HasBlahBlah/2` for `"moe"` +* `MeenyMinyMoe/FooTest.DoesBlah/0` for `"meeny"` +* `MeenyMinyMoe/FooTest.DoesBlah/1` for `"miny"` +* `MeenyMinyMoe/FooTest.DoesBlah/2` for `"moe"` +* `MeenyMinyMoe/FooTest.HasBlahBlah/0` for `"meeny"` +* `MeenyMinyMoe/FooTest.HasBlahBlah/1` for `"miny"` +* `MeenyMinyMoe/FooTest.HasBlahBlah/2` for `"moe"` You can use these names in [`--gtest_filter`](#running-a-subset-of-the-tests). -This statement will instantiate all tests from `FooTest` again, each with -parameter values `"cat"` and `"dog"`: +The following statement will instantiate all tests from `FooTest` again, each +with parameter values `"cat"` and `"dog"`: ```c++ const char* pets[] = {"cat", "dog"}; -INSTANTIATE_TEST_SUITE_P(AnotherInstantiationName, FooTest, - testing::ValuesIn(pets)); +INSTANTIATE_TEST_SUITE_P(Pets, FooTest, testing::ValuesIn(pets)); ``` The tests from the instantiation above will have these names: -* `AnotherInstantiationName/FooTest.DoesBlah/0` for `"cat"` -* `AnotherInstantiationName/FooTest.DoesBlah/1` for `"dog"` -* `AnotherInstantiationName/FooTest.HasBlahBlah/0` for `"cat"` -* `AnotherInstantiationName/FooTest.HasBlahBlah/1` for `"dog"` +* `Pets/FooTest.DoesBlah/0` for `"cat"` +* `Pets/FooTest.DoesBlah/1` for `"dog"` +* `Pets/FooTest.HasBlahBlah/0` for `"cat"` +* `Pets/FooTest.HasBlahBlah/1` for `"dog"` Please note that `INSTANTIATE_TEST_SUITE_P` will instantiate *all* tests in the given test suite, whether their definitions come before or *after* the `INSTANTIATE_TEST_SUITE_P` statement. +Additionally, by default, every `TEST_P` without a corresponding +`INSTANTIATE_TEST_SUITE_P` causes a failing test in test suite +`GoogleTestVerification`. If you have a test suite where that omission is not an +error, for example it is in a library that may be linked in for other reasons or +where the list of test cases is dynamic and may be empty, then this check can be +suppressed by tagging the test suite: + +```c++ +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(FooTest); +``` + You can see [sample7_unittest.cc] and [sample8_unittest.cc] for more examples. [sample7_unittest.cc]: https://github.com/google/googletest/blob/master/googletest/samples/sample7_unittest.cc "Parameterized Test example" @@ -1970,13 +1974,13 @@ Here's an example: ```c++ class MinimalistPrinter : public testing::EmptyTestEventListener { // Called before a test starts. - virtual void OnTestStart(const testing::TestInfo& test_info) { + void OnTestStart(const testing::TestInfo& test_info) override { printf("*** Test %s.%s starting.\n", test_info.test_suite_name(), test_info.name()); } // Called after a failed assertion or a SUCCESS(). - virtual void OnTestPartResult(const testing::TestPartResult& test_part_result) { + void OnTestPartResult(const testing::TestPartResult& test_part_result) override { printf("%s in %s:%d\n%s\n", test_part_result.failed() ? "*** Failure" : "Success", test_part_result.file_name(), @@ -1985,7 +1989,7 @@ Here's an example: } // Called after a test ends. - virtual void OnTestEnd(const testing::TestInfo& test_info) { + void OnTestEnd(const testing::TestInfo& test_info) override { printf("*** Test %s.%s ending.\n", test_info.test_suite_name(), test_info.name()); } diff --git a/docs/faq.md b/docs/faq.md index da443e33..40712321 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -60,9 +60,10 @@ the rule. ## Why does googletest support `EXPECT_EQ(NULL, ptr)` and `ASSERT_EQ(NULL, ptr)` but not `EXPECT_NE(NULL, ptr)` and `ASSERT_NE(NULL, ptr)`? -First of all you can use `EXPECT_NE(nullptr, ptr)` and `ASSERT_NE(nullptr, -ptr)`. This is the preferred syntax in the style guide because nullptr does not -have the type problems that NULL does. Which is why NULL does not work. +First of all, you can use `nullptr` with each of these macros, e.g. +`EXPECT_EQ(ptr, nullptr)`, `EXPECT_NE(ptr, nullptr)`, `ASSERT_EQ(ptr, nullptr)`, +`ASSERT_NE(ptr, nullptr)`. This is the preferred syntax in the style guide +because `nullptr` does not have the type problems that `NULL` does. Due to some peculiarity of C++, it requires some non-trivial template meta programming tricks to support using `NULL` as an argument of the `EXPECT_XX()` @@ -70,22 +71,21 @@ and `ASSERT_XX()` macros. Therefore we only do it where it's most needed (otherwise we make the implementation of googletest harder to maintain and more error-prone than necessary). -The `EXPECT_EQ()` macro takes the *expected* value as its first argument and the -*actual* value as the second. It's reasonable that someone wants to write -`EXPECT_EQ(NULL, some_expression)`, and this indeed was requested several times. -Therefore we implemented it. +Historically, the `EXPECT_EQ()` macro took the *expected* value as its first +argument and the *actual* value as the second, though this argument order is now +discouraged. It was reasonable that someone wanted +to write `EXPECT_EQ(NULL, some_expression)`, and this indeed was requested +several times. Therefore we implemented it. -The need for `EXPECT_NE(NULL, ptr)` isn't nearly as strong. When the assertion +The need for `EXPECT_NE(NULL, ptr)` wasn't nearly as strong. When the assertion fails, you already know that `ptr` must be `NULL`, so it doesn't add any information to print `ptr` in this case. That means `EXPECT_TRUE(ptr != NULL)` works just as well. -If we were to support `EXPECT_NE(NULL, ptr)`, for consistency we'll have to -support `EXPECT_NE(ptr, NULL)` as well, as unlike `EXPECT_EQ`, we don't have a -convention on the order of the two arguments for `EXPECT_NE`. This means using -the template meta programming tricks twice in the implementation, making it even -harder to understand and maintain. We believe the benefit doesn't justify the -cost. +If we were to support `EXPECT_NE(NULL, ptr)`, for consistency we'd have to +support `EXPECT_NE(ptr, NULL)` as well. This means using the template meta +programming tricks twice in the implementation, making it even harder to +understand and maintain. We believe the benefit doesn't justify the cost. Finally, with the growth of the gMock matcher library, we are encouraging people to use the unified `EXPECT_THAT(value, matcher)` syntax more often in tests. One @@ -706,12 +706,12 @@ whether the code is under test. ## How do I temporarily disable a test? If you have a broken test that you cannot fix right away, you can add the -DISABLED_ prefix to its name. This will exclude it from execution. This is -better than commenting out the code or using #if 0, as disabled tests are still -compiled (and thus won't rot). +`DISABLED_` prefix to its name. This will exclude it from execution. This is +better than commenting out the code or using `#if 0`, as disabled tests are +still compiled (and thus won't rot). To include disabled tests in test execution, just invoke the test program with -the --gtest_also_run_disabled_tests flag. +the `--gtest_also_run_disabled_tests` flag. ## Is it OK if I have two separate `TEST(Foo, Bar)` test methods defined in different namespaces? diff --git a/docs/gmock_cheat_sheet.md b/docs/gmock_cheat_sheet.md index 723cb7e1..90be4a3e 100644 --- a/docs/gmock_cheat_sheet.md +++ b/docs/gmock_cheat_sheet.md @@ -123,7 +123,7 @@ TEST(BarTest, DoesThis) { .WillRepeatedly(Return("Category 5")); // ... other expectations ... - EXPECT_EQ("good", MyProductionFunction(&foo)); // #5 + EXPECT_EQ(MyProductionFunction(&foo), "good"); // #5 } // #6 ``` @@ -162,8 +162,8 @@ Example usage: auto buzz1 = mock_buzzer_.MakeBuzz("hello"); auto buzz2 = mock_buzzer_.MakeBuzz("hello"); - EXPECT_NE(nullptr, buzz1); - EXPECT_NE(nullptr, buzz2); + EXPECT_NE(buzz1, nullptr); + EXPECT_NE(buzz2, nullptr); EXPECT_NE(buzz1, buzz2); // Resets the default action for return type std::unique_ptr<Buzz>, @@ -362,10 +362,11 @@ messages, you can use: int len)` -- see [Multi-argument Matchers](#MultiArgMatchers)). * The array being matched may be multi-dimensional (i.e. its elements can be arrays). -* `m` in `Pointwise(m, ...)` should be a matcher for `::std::tuple<T, U>` - where `T` and `U` are the element type of the actual container and the - expected container, respectively. For example, to compare two `Foo` - containers where `Foo` doesn't support `operator==`, one might write: +* `m` in `Pointwise(m, ...)` and `UnorderedPointwise(m, ...)` should be a + matcher for `::std::tuple<T, U>` where `T` and `U` are the element type of + the actual container and the expected container, respectively. For example, + to compare two `Foo` containers where `Foo` doesn't support `operator==`, + one might write: ```cpp using ::std::get; @@ -384,12 +385,28 @@ messages, you can use: | `Field(field_name, &class::field, m)` | The same as the two-parameter version, but provides a better error message. | | `Key(e)` | `argument.first` matches `e`, which can be either a value or a matcher. E.g. `Contains(Key(Le(5)))` can verify that a `map` contains a key `<= 5`. | | `Pair(m1, m2)` | `argument` is an `std::pair` whose `first` field matches `m1` and `second` field matches `m2`. | -| `FieldsAre(m...)` | `argument` is a compatible object where each field matches piecewise with `m...`. A compatible object is any that supports the `std::tuple_size<Obj>`+`get<I>(obj)` protocol. In C++17 and up this also supports types compatible with structured bindings, like aggregates. | +| `FieldsAre(m...)` | `argument` is a compatible object where each field matches piecewise with the matchers `m...`. A compatible object is any that supports the `std::tuple_size<Obj>`+`get<I>(obj)` protocol. In C++17 and up this also supports types compatible with structured bindings, like aggregates. | | `Property(&class::property, m)` | `argument.property()` (or `argument->property()` when `argument` is a plain pointer) matches matcher `m`, where `argument` is an object of type _class_. The method `property()` must take no argument and be declared as `const`. | | `Property(property_name, &class::property, m)` | The same as the two-parameter version, but provides a better error message. **Notes:** +* You can use `FieldsAre()` to match any type that supports structured + bindings, such as `std::tuple`, `std::pair`, `std::array`, and aggregate + types. For example: + + ```cpp + std::tuple<int, std::string> my_tuple{7, "hello world"}; + EXPECT_THAT(my_tuple, FieldsAre(Ge(0), HasSubstr("hello"))); + + struct MyStruct { + int value = 42; + std::string greeting = "aloha"; + }; + MyStruct s; + EXPECT_THAT(s, FieldsAre(42, "aloha")); + ``` + * Don't use `Property()` against member functions that you do not own, because taking addresses of functions is fragile and generally not part of the contract of the function. diff --git a/docs/gmock_cook_book.md b/docs/gmock_cook_book.md index 8ba5c989..c6a99912 100644 --- a/docs/gmock_cook_book.md +++ b/docs/gmock_cook_book.md @@ -251,9 +251,9 @@ tests. ### Mocking Free Functions -It's possible to use gMock to mock a free function (i.e. a C-style function or a -static method). You just need to rewrite your code to use an interface (abstract -class). +It is not possible to directly mock a free function (i.e. a C-style function or +a static method). If you need to, you can rewrite your code to use an interface +(abstract class). Instead of calling a free function (say, `OpenFile`) directly, introduce an interface for it and have a concrete subclass that calls the free function: @@ -268,7 +268,7 @@ class FileInterface { class File : public FileInterface { public: ... - virtual bool Open(const char* path, const char* mode) { + bool Open(const char* path, const char* mode) override { return OpenFile(path, mode); } }; @@ -512,9 +512,9 @@ The trick is to redispatch the method in the mock class: class ScopedMockLog : public LogSink { public: ... - virtual void send(LogSeverity severity, const char* full_filename, + void send(LogSeverity severity, const char* full_filename, const char* base_filename, int line, const tm* tm_time, - const char* message, size_t message_len) { + const char* message, size_t message_len) override { // We are only interested in the log severity, full file name, and // log message. Log(severity, full_filename, std::string(message, message_len)); @@ -2705,18 +2705,10 @@ behavior nondeterministic. A better way is to use gMock actions and `Notification` objects to force your asynchronous test to behave synchronously. ```cpp -using ::testing::DoAll; -using ::testing::InvokeWithoutArgs; -using ::testing::Return; - class MockEventDispatcher : public EventDispatcher { MOCK_METHOD(bool, DispatchEvent, (int32), (override)); }; -ACTION_P(Notify, notification) { - notification->Notify(); -} - TEST(EventQueueTest, EnqueueEventTest) { MockEventDispatcher mock_event_dispatcher; EventQueue event_queue(&mock_event_dispatcher); @@ -2724,7 +2716,7 @@ TEST(EventQueueTest, EnqueueEventTest) { const int32 kEventId = 321; absl::Notification done; EXPECT_CALL(mock_event_dispatcher, DispatchEvent(kEventId)) - .WillOnce(Notify(&done)); + .WillOnce([&done] { done.Notify(); }); event_queue.EnqueueEvent(kEventId); done.WaitForNotification(); diff --git a/docs/quickstart-bazel.md b/docs/quickstart-bazel.md new file mode 100644 index 00000000..362ee6d0 --- /dev/null +++ b/docs/quickstart-bazel.md @@ -0,0 +1,161 @@ +# Quickstart: Building with Bazel + +This tutorial aims to get you up and running with GoogleTest using the Bazel +build system. If you're using GoogleTest for the first time or need a refresher, +we recommend this tutorial as a starting point. + +## Prerequisites + +To complete this tutorial, you'll need: + +* A compatible operating system (e.g. Linux, macOS, Windows). +* A compatible C++ compiler that supports at least C++11. +* [Bazel](https://bazel.build/), the preferred build system used by the + GoogleTest team. + +See [Supported Platforms](platforms.md) for more information about platforms +compatible with GoogleTest. + +If you don't already have Bazel installed, see the +[Bazel installation guide](https://docs.bazel.build/versions/master/install.html). + +{: .callout .note} +Note: The terminal commands in this tutorial show a Unix shell prompt, but the +commands work on the Windows command line as well. + +## Set up a Bazel workspace + +A +[Bazel workspace](https://docs.bazel.build/versions/master/build-ref.html#workspace) +is a directory on your filesystem that you use to manage source files for the +software you want to build. Each workspace directory has a text file named +`WORKSPACE` which may be empty, or may contain references to external +dependencies required to build the outputs. + +First, create a directory for your workspace: + +``` +$ mkdir my_workspace && cd my_workspace +``` + +Next, you’ll create the `WORKSPACE` file to specify dependencies. A common and +recommended way to depend on GoogleTest is to use a +[Bazel external dependency](https://docs.bazel.build/versions/master/external.html) +via the +[`http_archive` rule](https://docs.bazel.build/versions/master/repo/http.html#http_archive). +To do this, in the root directory of your workspace (`my_workspace/`), create a +file named `WORKSPACE` with the following contents: + +``` +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + +http_archive( + name = "com_google_googletest", + urls = ["https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip"], + strip_prefix = "googletest-609281088cfefc76f9d0ce82e1ff6c30cc3591e5", +) +``` + +The above configuration declares a dependency on GoogleTest which is downloaded +as a ZIP archive from GitHub. In the above example, +`609281088cfefc76f9d0ce82e1ff6c30cc3591e5` is the Git commit hash of the +GoogleTest version to use; we recommend updating the hash often to point to the +latest version. + +Bazel also needs a dependency on the +[`rules_cc` repository](https://github.com/bazelbuild/rules_cc) to build C++ +code, so add the following to the `WORKSPACE` file: + +``` +http_archive( + name = "rules_cc", + urls = ["https://github.com/bazelbuild/rules_cc/archive/40548a2974f1aea06215272d9c2b47a14a24e556.zip"], + strip_prefix = "rules_cc-40548a2974f1aea06215272d9c2b47a14a24e556", +) +``` + +Now you're ready to build C++ code that uses GoogleTest. + +## Create and run a binary + +With your Bazel workspace set up, you can now use GoogleTest code within your +own project. + +As an example, create a file named `hello_test.cc` in your `my_workspace` +directory with the following contents: + +```cpp +#include <gtest/gtest.h> + +// Demonstrate some basic assertions. +TEST(HelloTest, BasicAssertions) { + // Expect two strings not to be equal. + EXPECT_STRNE("hello", "world"); + // Expect equality. + EXPECT_EQ(7 * 6, 42); +} +``` + +GoogleTest provides [assertions](primer.md#assertions) that you use to test the +behavior of your code. The above sample includes the main GoogleTest header file +and demonstrates some basic assertions. + +To build the code, create a file named `BUILD` in the same directory with the +following contents: + +``` +load("@rules_cc//cc:defs.bzl", "cc_test") + +cc_test( + name = "hello_test", + size = "small", + srcs = ["hello_test.cc"], + deps = ["@com_google_googletest//:gtest_main"], +) +``` + +This `cc_test` rule declares the C++ test binary you want to build, and links to +GoogleTest (`//:gtest_main`) using the prefix you specified in the `WORKSPACE` +file (`@com_google_googletest`). For more information about Bazel `BUILD` files, +see the +[Bazel C++ Tutorial](https://docs.bazel.build/versions/master/tutorial/cpp.html). + +Now you can build and run your test: + +<pre> +<strong>my_workspace$ bazel test --test_output=all //:hello_test</strong> +INFO: Analyzed target //:hello_test (26 packages loaded, 362 targets configured). +INFO: Found 1 test target... +INFO: From Testing //:hello_test: +==================== Test output for //:hello_test: +Running main() from gmock_main.cc +[==========] Running 1 test from 1 test suite. +[----------] Global test environment set-up. +[----------] 1 test from HelloTest +[ RUN ] HelloTest.BasicAssertions +[ OK ] HelloTest.BasicAssertions (0 ms) +[----------] 1 test from HelloTest (0 ms total) + +[----------] Global test environment tear-down +[==========] 1 test from 1 test suite ran. (0 ms total) +[ PASSED ] 1 test. +================================================================================ +Target //:hello_test up-to-date: + bazel-bin/hello_test +INFO: Elapsed time: 4.190s, Critical Path: 3.05s +INFO: 27 processes: 8 internal, 19 linux-sandbox. +INFO: Build completed successfully, 27 total actions +//:hello_test PASSED in 0.1s + +INFO: Build completed successfully, 27 total actions +</pre> + +Congratulations! You've successfully built and run a test binary using +GoogleTest. + +## Next steps + +* [Check out the Primer](primer.md) to start learning how to write simple + tests. +* [See the code samples](samples.md) for more examples showing how to use a + variety of GoogleTest features. diff --git a/docs/quickstart-cmake.md b/docs/quickstart-cmake.md new file mode 100644 index 00000000..420f1d3a --- /dev/null +++ b/docs/quickstart-cmake.md @@ -0,0 +1,156 @@ +# Quickstart: Building with CMake + +This tutorial aims to get you up and running with GoogleTest using CMake. If +you're using GoogleTest for the first time or need a refresher, we recommend +this tutorial as a starting point. If your project uses Bazel, see the +[Quickstart for Bazel](quickstart-bazel.md) instead. + +## Prerequisites + +To complete this tutorial, you'll need: + +* A compatible operating system (e.g. Linux, macOS, Windows). +* A compatible C++ compiler that supports at least C++11. +* [CMake](https://cmake.org/) and a compatible build tool for building the + project. + * Compatible build tools include + [Make](https://www.gnu.org/software/make/), + [Ninja](https://ninja-build.org/), and others - see + [CMake Generators](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html) + for more information. + +See [Supported Platforms](platforms.md) for more information about platforms +compatible with GoogleTest. + +If you don't already have CMake installed, see the +[CMake installation guide](https://cmake.org/install). + +{: .callout .note} +Note: The terminal commands in this tutorial show a Unix shell prompt, but the +commands work on the Windows command line as well. + +## Set up a project + +CMake uses a file named `CMakeLists.txt` to configure the build system for a +project. You'll use this file to set up your project and declare a dependency on +GoogleTest. + +First, create a directory for your project: + +``` +$ mkdir my_project && cd my_project +``` + +Next, you'll create the `CMakeLists.txt` file and declare a dependency on +GoogleTest. There are many ways to express dependencies in the CMake ecosystem; +in this quickstart, you'll use the +[`FetchContent` CMake module](https://cmake.org/cmake/help/latest/module/FetchContent.html). +To do this, in your project directory (`my_project`), create a file named +`CMakeLists.txt` with the following contents: + +```cmake +cmake_minimum_required(VERSION 3.14) +project(my_project) + +# GoogleTest requires at least C++11 +set(CMAKE_CXX_STANDARD 11) + +include(FetchContent) +FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip +) +# For Windows: Prevent overriding the parent project's compiler/linker settings +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) +FetchContent_MakeAvailable(googletest) +``` + +The above configuration declares a dependency on GoogleTest which is downloaded +from GitHub. In the above example, `609281088cfefc76f9d0ce82e1ff6c30cc3591e5` is +the Git commit hash of the GoogleTest version to use; we recommend updating the +hash often to point to the latest version. + +For more information about how to create `CMakeLists.txt` files, see the +[CMake Tutorial](https://cmake.org/cmake/help/latest/guide/tutorial/index.html). + +## Create and run a binary + +With GoogleTest declared as a dependency, you can use GoogleTest code within +your own project. + +As an example, create a file named `hello_test.cc` in your `my_project` +directory with the following contents: + +```cpp +#include <gtest/gtest.h> + +// Demonstrate some basic assertions. +TEST(HelloTest, BasicAssertions) { + // Expect two strings not to be equal. + EXPECT_STRNE("hello", "world"); + // Expect equality. + EXPECT_EQ(7 * 6, 42); +} +``` + +GoogleTest provides [assertions](primer.md#assertions) that you use to test the +behavior of your code. The above sample includes the main GoogleTest header file +and demonstrates some basic assertions. + +To build the code, add the following to the end of your `CMakeLists.txt` file: + +```cmake +enable_testing() + +add_executable( + hello_test + hello_test.cc +) +target_link_libraries( + hello_test + gtest_main +) + +include(GoogleTest) +gtest_discover_tests(hello_test) +``` + +The above configuration enables testing in CMake, declares the C++ test binary +you want to build (`hello_test`), and links it to GoogleTest (`gtest_main`). The +last two lines enable CMake's test runner to discover the tests included in the +binary, using the +[`GoogleTest` CMake module](https://cmake.org/cmake/help/git-stage/module/GoogleTest.html). + +Now you can build and run your test: + +<pre> +<strong>my_project$ cmake -S . -B build</strong> +-- The C compiler identification is GNU 10.2.1 +-- The CXX compiler identification is GNU 10.2.1 +... +-- Build files have been written to: .../my_project/build + +<strong>my_project$ cmake --build build</strong> +Scanning dependencies of target gtest +... +[100%] Built target gmock_main + +<strong>my_project$ cd build && ctest</strong> +Test project .../my_project/build + Start 1: HelloTest.BasicAssertions +1/1 Test #1: HelloTest.BasicAssertions ........ Passed 0.00 sec + +100% tests passed, 0 tests failed out of 1 + +Total Test time (real) = 0.01 sec +</pre> + +Congratulations! You've successfully built and run a test binary using +GoogleTest. + +## Next steps + +* [Check out the Primer](primer.md) to start learning how to write simple + tests. +* [See the code samples](samples.md) for more examples showing how to use a + variety of GoogleTest features. |