Bug 1876177 [wpt PR 44153] - [FedCM] Add a WPT test for authz, a=testonly
[gecko.git] / docs / gtest / index.rst
bloba685f8ea8a280fd76c2fce820e6cbe909880d93b
1 GTest
2 =====
4 GTest (googletest) is Google's framework for writing C++ tests on a
5 variety of platforms (Linux, Mac OS X, Windows, ...).
6 Based on the xUnit architecture, it supports automatic test
7 discovery, a rich set of assertions, user-defined assertions, death
8 tests, fatal and non-fatal failures, value- and type-parameterized
9 tests, various options for running the tests, and XML test report
10 generation.
12 Integration
13 -----------
15 GTest is run as a standard test task on Win/Mac/Linux and Android, under
16 treeherder symbol 'GTest'.
19 Running tests
20 -------------
22 The Firefox build process will build GTest on supported platforms as
23 long as you don't disable tests in your mozconfig. However xul-gtest will
24 only be built when tests are required to save an expensive second
25 linking process.
27 To run the unit tests use 'mach gtest' when invoking Gecko.
29 Running selected tests
30 ~~~~~~~~~~~~~~~~~~~~~~
32 Tests can be selected using mach. You can also use environment variables
33 support by GTest. See `Running Test Programs: Running a Subset of the
34 Tests <https://github.com/google/googletest/blob/master/docs/advanced.md#running-a-subset-of-the-tests>`__
35 for more details.
39    mach gtest Moz2D.*
42 Configuring GTest
43 ~~~~~~~~~~~~~~~~~
45 GTest can be controlled from other environment variables. See `Running
46 Test Programs: Advanced
47 Options <https://github.com/google/googletest/blob/master/docs/advanced.md#running-test-programs-advanced-options>`__
48 for more details.
51 Debugging a GTest Unit Test
52 ---------------------------
54 To debug a gtest, pass --debug to the normal command.
56 .. code-block:: shell
58    ./mach gtest --debug [ Prefix.Test ]
60 If that doesn't work, you can try running the firefox binary under the
61 debugger with the MOZ_RUN_GTEST environment variable set to 1.
63 .. code-block:: shell
65    MOZ_RUN_GTEST=1 ./mach run --debug [--debugger gdb]
67 .. warning::
69    Don't forget to build + run 'mach gtest' to relink when using
70    MOZ_RUN_GTEST since it's not part of a top level build.
72 Note that this will load an alternate libxul - the one which has the
73 test code built in, which resides in a gtest/subdirectory of your
74 objdir. This gtest-enabled libxul is not built as part of the regular
75 build, so you must ensure that it is built before running the above
76 command. A simple way to do this is to just run "mach gtest" which will
77 rebuild libxul and run the tests. You can also extract the commands
78 needed to just rebuild that libxul `from
79 mach <https://hg.mozilla.org/mozilla-central/file/3673d2c688b4/python/mozbuild/mozbuild/mach_commands.py#l486>`__
80 and run those directly. Finally, note that you may have to run through
81 the tests once for gdb to load all the relevant libraries and for
82 breakpoint symbols to resolve properly.
84 Note that you can debug a subset of the tests (including a single test)
85 by using the GTEST_FILTER environment variable:
87 .. code-block:: shell
89    GTEST_FILTER='AsyncPanZoom*' MOZ_RUN_GTEST=1 ./mach run --debug [--debugger gdb]
92 Debugging with Xcode
93 ~~~~~~~~~~~~~~~~~~~~
95 See :ref:`Debugging On macOS` for initial
96 setup. You'll likely want to create a separate scheme for running GTest
97 ("Product" > "Scheme" > "New Scheme…"). In addition to GTEST_FILTER, Set
98 the following environment variables:
102    MOZ_XRE_DIR=/path-to-object-directory/obj-ff-dbg/dist/bin
103    MOZ_RUN_GTEST=True
105 and under the "Options" tab for the scheme, set the working directory
110    ☑️ Use custom working directory: /path-to-object-directory/obj-ff-dbg/_tests/gtest
113 Debugging with Visual Studio Code
114 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
116 Add a configuration like this to your launch.json file (you can edit it
117 via Run / Open Configurations):
121            {
122                "name": "(gdb) Launch gtest",
123                "type": "cppdbg",
124                "request": "launch",
125                "program": "${workspaceFolder}/obj-x86_64-pc-linux-gnu/dist/bin/firefox",
126                "args": [],
127                "stopAtEntry": false,
128                "cwd": "${workspaceFolder}/obj-x86_64-pc-linux-gnu/_tests/gtest",
129                "environment": [{"name": "MOZ_RUN_GTEST", "value": "True"},
130                                {"name": "GTEST_FILTER", "value": "AsyncPanZoom*"}],
131                "externalConsole": false,
132                "MIMode": "gdb",
133                "setupCommands": [
134                    {
135                        "description": "Enable pretty-printing for gdb",
136                        "text": "-enable-pretty-printing",
137                        "ignoreFailures": true
138                    }
139                ]
140            },
143 Writing a GTest Unit Test
144 -------------------------
146 Most of the `GTest
147 documentation <https://github.com/google/googletest/blob/master/googletest/README.md>`__
148 will apply here. The `GTest
149 primer <https://github.com/google/googletest/blob/master/docs/primer.md>`__
150 is a recommended read.
152 .. warning::
154    GTest will run tests in parallel. Don't add unit tests that are not
155    threadsafe, such as tests that require focus or use specific sockets.
157 .. warning::
159    GTest will run without initializing mozilla services. Initialize and
160    tear down any dependencies you have in your test fixtures. Avoid
161    writing integration tests and focus on testing individual units.
163 See https://hg.mozilla.org/mozilla-central/rev/ed612eec41a44867a for an
164 example of how to add a simple test.
166 If you're converting an existing C++ unit test to a GTest, `this
167 commit <https://hg.mozilla.org/mozilla-central/rev/40740cddc131>`__ may
168 serve as a useful reference.
171 Setting prefs for a test
172 ~~~~~~~~~~~~~~~~~~~~~~~~
174 If tests cover functionality that is disabled by default, you'll have to
175 change the relevant preferences either in the individual test:
179    bool oldPref = Preferences::GetBool(prefKey);
180    Preferences::SetBool(prefKey, true);
181    … // test code
182    Preferences::SetBool(prefKey, oldPref);
184 or, if it applies more broadly, the change can be applied to the whole
185 fixture (see `the GTest
186 docs <https://github.com/google/googletest/blob/master/googletest/README.md>`__,
188 `AutoInitializeImageLib <https://searchfox.org/mozilla-central/search?q=AutoInitializeImageLib%3A%3AAutoInitializeImageLib&path=>`__
189 as an example).
192 Adding a test to the build system
193 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
195 Find a gtest directory appropriate for the module. If none exist create
196 a directory using the following convention: '<submodule>/tests/gtest'.
197 Create a moz.build file (in the newly created directory) with a module
198 declaration, replacing gfxtest with a unique name, and set
199 UNIFIED_SOURCES to contain all of the test file names.
201 What we're doing here is creating a list of source files that will be
202 compiled and linked only against the gtest version of libxul. This will
203 let these source files call internal xul symbols without making them
204 part of the binary we ship to users.
206 .. code-block::
208    # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
209    # vim: set filetype=python:
210    # This Source Code Form is subject to the terms of the Mozilla Public
211    # License, v. 2.0. If a copy of the MPL was not distributed with this
212    # file, you can obtain one at https://mozilla.org/MPL/2.0/.
214    Library('gfxtest')
216    UNIFIED_SOURCES = [
217        <ListTestFiles>,
218    ]
220    FINAL_LIBRARY = 'xul-gtest'
222 Update '<submodule>/moz.build' in the parent directory to build your new
223 subdirectory in:
225 .. code-block:: python
227    TEST_DIRS += [
228        "gtest",
229    ]
231 When adding tests to an existing moz.build file (it has FINAL_LIBRARY =
232 'xul-gtest'), add the following. That's it--there is no test manifest
233 required. Your tests will be automatically registered using a static
234 constructor.
236 .. code-block:: python
238    UNIFIED_SOURCES = [
239        'TestFoo.cpp',
240    ]
242 Notes
243 ~~~~~
245 The include file for the class you are testing may not need to be
246 globally exported, but it does need to be made available to the unit
247 test you are writing. In that case, add something like this to the
248 Makefile.in inside of the testing directory.
250 .. code-block:: python
252     LOCAL_INCLUDES += [
253         '/gfx/2d',
254         '/gfx/2d/unittest',
255         '/gfx/layers',
256     ]
258 Gtests currently run from the test package under the **GTest** symbol on
259 `Treeherder <https://treeherder.mozilla.org/>`__ if you want to verify
260 that your test is working. Formerly they were run under the **B**
261 symbol, during \`make check`.
264 MozGTestBench
265 -------------
267 A Mozilla GTest Microbench is just a GTest that reports the test
268 duration to perfherder. It's an easy way to add low level performance
269 test. Keep in mind that there's a non-zero cost to monitoring
270 performance test so use them sparingly. You can still perform test
271 assertions.
274 Writing a Microbench GTest
275 ~~~~~~~~~~~~~~~~~~~~~~~~~~
277 Use 'MOZ_GTEST_BENCH' instead of 'TEST' to time the execution of your
278 test. Example:
280 .. code-block:: cpp
282    #include "gtest/MozGTestBench.h" // For MOZ_GTEST_BENCH
284    ...
286    MOZ_GTEST_BENCH(GfxBench, TEST_NAME, []{
287      // Test to time the execution
288    });
290 Make sure this file is registered with the file system using the
291 instructions above. If everything worked correctly you should see this
292 in the GTest log for your corresponding test:
294 .. code-block:: js
296    PERFHERDER_DATA: {"framework": {"name": "platform_microbench"}, "suites": [{"name": "GfxBench", "subtests": [{"name": "CompositorSimpleTree", "value": 252674, "lowerIsBetter": true}]}]}
299 Sheriffing policy
300 ~~~~~~~~~~~~~~~~~
302 Microbench tests measure the speed of a very specific operation. A
303 regression in a micro-benchmark may not lead to a user visible
304 regression and should not be treated as strictly as a Talos regression.
305 Large changes in microbench scores will also be expected when the code
306 is directly modified and should be accepted if the developer intended to
307 change that code. Micro-benchmarks however provide a framework for
308 adding performance tests for platform code and regression tests for
309 performance fixes. They will catch unintended regressions in code and
310 when correlated with a Talos regression might indicate the source of the
311 regression.