blob: f96c56abc0d6fa11fd2286e1400f835d58e48423 [file] [log] [blame]
Wyatt Heplerf9fb90f2020-09-30 18:59:33 -07001.. _module-pw_unit_test:
Alexei Frolov199045a2020-08-28 13:02:30 -07002
Armando Montanez4ddaa9e2021-12-07 15:40:51 -08003============
Alexei Frolovea395522020-03-13 13:35:07 -07004pw_unit_test
Armando Montanez4ddaa9e2021-12-07 15:40:51 -08005============
Alexei Frolovea395522020-03-13 13:35:07 -07006``pw_unit_test`` unit testing library with a `Google Test`_-compatible API,
7built on top of embedded-friendly primitives.
8
Rob Mohr2f6662c2021-05-21 15:50:11 -07009.. _Google Test: https://github.com/google/googletest/blob/HEAD/docs/primer.md
Alexei Frolov80246792020-11-05 21:12:45 -080010
Alexei Frolovea395522020-03-13 13:35:07 -070011``pw_unit_test`` is a portable library which can run on almost any system from
Shiva Rajagopal64d10962021-05-10 15:33:40 -070012bare metal to a full-fledged desktop OS. It does this by offloading the
Alexei Frolovea395522020-03-13 13:35:07 -070013responsibility of test reporting and output to the underlying system,
14communicating its results through a common interface. Unit tests can be written
15once and run under many different environments, empowering developers to write
16robust, high quality code.
17
18``pw_unit_test`` is still under development and lacks many features expected in
19a complete testing framework; nevertheless, it is already used heavily within
20Pigweed.
21
22.. note::
23
24 This documentation is currently incomplete.
25
Armando Montanez4ddaa9e2021-12-07 15:40:51 -080026------------------
Alexei Frolovea395522020-03-13 13:35:07 -070027Writing unit tests
Armando Montanez4ddaa9e2021-12-07 15:40:51 -080028------------------
Alexei Frolovea395522020-03-13 13:35:07 -070029``pw_unit_test``'s interface is largely compatible with `Google Test`_. Refer to
30the Google Test documentation for examples of to define unit test cases.
31
32.. note::
33
Wyatt Hepler581abf22022-02-23 10:03:42 -080034 Many of Google Test's more advanced features are not yet implemented. Missing
35 features include:
36
37 * Any GoogleMock features (e.g. :c:macro:`EXPECT_THAT`)
38 * Floating point comparison macros (e.g. :c:macro:`EXPECT_FLOAT_EQ`)
39 * Death tests (e.g. :c:macro:`EXPECT_DEATH`); ``EXPECT_DEATH_IF_SUPPORTED``
40 does nothing but silently passes
41 * Value-parameterized tests
42
43 To request a feature addition, please
Armando Montanez3d92e812020-03-19 12:13:36 -070044 `let us know <mailto:pigweed@googlegroups.com>`_.
Alexei Frolovea395522020-03-13 13:35:07 -070045
Tom Craigb894ed62022-03-23 18:44:55 -070046 See `Using upstream Googletest and Googlemock` below for information
47 about using upstream Googletest instead.
48
Armando Montanez4ddaa9e2021-12-07 15:40:51 -080049------------------------
Alexei Frolovea395522020-03-13 13:35:07 -070050Using the test framework
Armando Montanez4ddaa9e2021-12-07 15:40:51 -080051------------------------
Alexei Frolovea395522020-03-13 13:35:07 -070052
53The EventHandler interface
Armando Montanez4ddaa9e2021-12-07 15:40:51 -080054==========================
Alexei Frolovea395522020-03-13 13:35:07 -070055The ``EventHandler`` class in ``public/pw_unit_test/event_handler.h`` defines
56the interface through which ``pw_unit_test`` communicates the results of its
57test runs. A platform using ``pw_unit_test`` must register an event handler with
58the unit testing framework to receive test output.
59
60As the framework runs tests, it calls the event handler's callback functions to
61notify the system of various test events. The system can then choose to perform
62any necessary handling or aggregation of these events, and report them back to
63the developer.
64
65Predefined event handlers
66-------------------------
67Pigweed provides some standard event handlers upstream to simplify the process
68of getting started using ``pw_unit_test``.
69
70* ``SimplePrintingEventHandler``: An event handler that writes Google Test-style
71 output to a specified sink.
72
73 .. code::
74
75 [==========] Running all tests.
76 [ RUN ] Status.Default
77 [ OK ] Status.Default
78 [ RUN ] Status.ConstructWithStatusCode
79 [ OK ] Status.ConstructWithStatusCode
80 [ RUN ] Status.AssignFromStatusCode
81 [ OK ] Status.AssignFromStatusCode
82 [ RUN ] Status.CompareToStatusCode
83 [ OK ] Status.CompareToStatusCode
84 [ RUN ] Status.Ok_OkIsTrue
85 [ OK ] Status.Ok_OkIsTrue
86 [ RUN ] Status.NotOk_OkIsFalse
87 [ OK ] Status.NotOk_OkIsFalse
88 [ RUN ] Status.KnownString
89 [ OK ] Status.KnownString
90 [ RUN ] Status.UnknownString
91 [ OK ] Status.UnknownString
92 [==========] Done running all tests.
93 [ PASSED ] 8 test(s).
94
95
96* ``LoggingEventHandler``: An event handler which uses the ``pw_log`` module to
97 output test results, to integrate with the system's existing logging setup.
98
99.. _running-tests:
100
101Running tests
Armando Montanez4ddaa9e2021-12-07 15:40:51 -0800102=============
Alexei Frolovea395522020-03-13 13:35:07 -0700103To run unit tests, link the tests into a single binary with the unit testing
104framework, register an event handler, and call the ``RUN_ALL_TESTS`` macro.
105
106.. code:: cpp
107
108 #include "pw_unit_test/framework.h"
109 #include "pw_unit_test/simple_printing_event_handler.h"
110
111 void WriteString(const std::string_view& string, bool newline) {
112 printf("%s", string.data());
113 if (newline) {
114 printf("\n");
115 }
116 }
117
118 int main() {
119 pw::unit_test::SimplePrintingEventHandler handler(WriteString);
120 pw::unit_test::RegisterEventHandler(&handler);
121 return RUN_ALL_TESTS();
122 }
123
Alexei Frolov47a43042021-04-06 14:19:55 -0700124Test filtering
Armando Montanez4ddaa9e2021-12-07 15:40:51 -0800125==============
Alexei Frolov47a43042021-04-06 14:19:55 -0700126If using C++17, filters can be set on the test framework to run only a subset of
127the registered unit tests. This is useful when many tests are bundled into a
128single application image.
129
130Currently, only a test suite filter is supported. This is set by calling
131``pw::unit_test::SetTestSuitesToRun`` with a list of suite names.
132
133.. note::
134 Test filtering is only supported in C++17.
135
Alexei Frolovea395522020-03-13 13:35:07 -0700136Build system integration
Armando Montanez4ddaa9e2021-12-07 15:40:51 -0800137========================
Alexei Frolovea395522020-03-13 13:35:07 -0700138``pw_unit_test`` integrates directly into Pigweed's GN build system. To define
Armando Montaneza761e322020-06-15 16:30:40 -0700139simple unit tests, set the ``pw_unit_test_MAIN`` build variable to a target
Alexei Frolovea395522020-03-13 13:35:07 -0700140which configures the test framework as described in the :ref:`running-tests`
141section, and use the ``pw_test`` template to register your test code.
142
143.. code::
144
145 import("$dir_pw_unit_test/test.gni")
146
147 pw_test("foo_test") {
148 sources = [ "foo_test.cc" ]
149 }
150
Alexei Frolovbcac2c92020-05-19 10:24:20 -0700151The ``pw_unit_test`` module provides a few optional libraries to simplify setup:
Armando Montanez0054a9b2020-03-13 13:06:24 -0700152
Shiva Rajagopal64d10962021-05-10 15:33:40 -0700153 - ``simple_printing_event_handler``: When running tests, output test results
Armando Montanez0054a9b2020-03-13 13:06:24 -0700154 as plain text over ``pw_sys_io``.
155 - ``simple_printing_main``: Implements a ``main()`` function that simply runs
156 tests using the ``simple_printing_event_handler``.
157 - ``logging_event_handler``: When running tests, log test results as
158 plain text using pw_log (ensure your target has set a ``pw_log`` backend).
159 - ``logging_main``: Implements a ``main()`` function that simply runs tests
160 using the ``logging_event_handler``.
161
162
Alexei Frolovbcac2c92020-05-19 10:24:20 -0700163pw_test template
164----------------
Alexei Frolovfbe68ff2020-11-16 13:44:52 -0800165``pw_test`` defines a single unit test suite. It creates several sub-targets.
Alexei Frolovbcac2c92020-05-19 10:24:20 -0700166
Alexei Frolovfbe68ff2020-11-16 13:44:52 -0800167* ``<target_name>``: The test suite within a single binary. The test code is
168 linked against the target set in the build arg ``pw_unit_test_MAIN``.
169* ``<target_name>.run``: If ``pw_unit_test_AUTOMATIC_RUNNER`` is set, this
170 target runs the test as part of the build.
171* ``<target_name>.lib``: The test sources without ``pw_unit_test_MAIN``.
Alexei Frolovbcac2c92020-05-19 10:24:20 -0700172
173**Arguments**
174
175* All GN executable arguments are accepted and forwarded to the underlying
176 ``pw_executable``.
177* ``enable_if``: Boolean indicating whether the test should be built. If false,
178 replaces the test with an empty target. Default true.
Michael Spang6aa8eb02020-06-11 20:19:05 -0400179* ``test_main``: Target label to add to the tests's dependencies to provide the
180 ``main()`` function. Defaults to ``pw_unit_test_MAIN``. Set to ``""`` if
181 ``main()`` is implemented in the test's ``sources``.
Alexei Frolovbcac2c92020-05-19 10:24:20 -0700182
183**Example**
184
185.. code::
186
187 import("$dir_pw_unit_test/test.gni")
188
189 pw_test("large_test") {
190 sources = [ "large_test.cc" ]
191 enable_if = device_has_1m_flash
192 }
193
Alexei Frolovbcac2c92020-05-19 10:24:20 -0700194pw_test_group template
195----------------------
Alexei Frolovfbe68ff2020-11-16 13:44:52 -0800196``pw_test_group`` defines a collection of tests or other test groups. It creates
197several sub-targets:
Alexei Frolovbcac2c92020-05-19 10:24:20 -0700198
Alexei Frolovfbe68ff2020-11-16 13:44:52 -0800199* ``<target_name>``: The test group itself.
200* ``<target_name>.run``: If ``pw_unit_test_AUTOMATIC_RUNNER`` is set, this
201 target runs all of the tests in the group and all of its group dependencies
202 individually.
203* ``<target_name>.lib``: The sources of all of the tests in this group and its
204 dependencies.
205* ``<target_name>.bundle``: All of the tests in the group and its dependencies
206 bundled into a single binary.
207* ``<target_name>.bundle.run``: Automatic runner for the test bundle.
Alexei Frolovbcac2c92020-05-19 10:24:20 -0700208
209**Arguments**
210
211* ``tests``: List of the ``pw_test`` targets in the group.
212* ``group_deps``: List of other ``pw_test_group`` targets on which this one
213 depends.
214* ``enable_if``: Boolean indicating whether the group target should be created.
215 If false, an empty GN group is created instead. Default true.
216
217**Example**
218
219.. code::
220
221 import("$dir_pw_unit_test/test.gni")
222
223 pw_test_group("tests") {
224 tests = [
225 ":bar_test",
226 ":foo_test",
227 ]
228 }
229
230 pw_test("foo_test") {
231 # ...
232 }
233
234 pw_test("bar_test") {
235 # ...
236 }
237
Armando Montanez72b93852020-11-10 15:33:22 -0800238pw_facade_test template
239-----------------------
240Pigweed facade test templates allow individual unit tests to build under the
241current device target configuration while overriding specific build arguments.
242This allows these tests to replace a facade's backend for the purpose of testing
243the facade layer.
244
245.. warning::
246 Facade tests are costly because each facade test will trigger a re-build of
247 every dependency of the test. While this sounds excessive, it's the only
248 technically correct way to handle this type of test.
249
250.. warning::
251 Some facade test configurations may not be compatible with your target. Be
252 careful when running a facade test on a system that heavily depends on the
253 facade being tested.
254
Armando Montanez4ddaa9e2021-12-07 15:40:51 -0800255Build arguments
256---------------
257
258.. option:: pw_unit_test_AUTOMATIC_RUNNER <executable>
259
260 Path to a test runner to automatically run unit tests after they are built.
261
262 If set, a ``pw_test`` target's ``<target_name>.run`` action will invoke the
263 test runner specified by this argument, passing the path to the unit test to
264 run. If this is unset, the ``pw_test`` target's ``<target_name>.run`` step
265 will do nothing.
266
267 Targets that don't support parallelized execution of tests (e.g. a on-device
268 test runner that must flash a device and run the test in serial) should
269 set pw_unit_test_POOL_DEPTH to 1.
270
271 Type: string (name of an executable on the PATH, or path to an executable)
272 Usage: toolchain-controlled only
273
Edwin Vane81f8aa62021-12-07 21:46:37 -0500274.. option:: pw_unit_test_AUTOMATIC_RUNNER_ARGS <args>
275
276 An optional list of strings to pass as args to the test runner specified
277 by pw_unit_test_AUTOMATIC_RUNNER.
278
279 Type: list of strings (args to pass to pw_unit_test_AUTOMATIC_RUNNER)
280 Usage: toolchain-controlled only
281
Austin Foxleybad57472022-02-03 23:45:05 +0000282.. option:: pw_unit_test_AUTOMATIC_RUNNER_TIMEOUT <timeout_seconds>
283
284 An optional timeout to apply when running the automatic runner. Timeout is
285 in seconds. Defaults to empty which means no timeout.
286
287 Type: string (number of seconds to wait before killing test runner)
288 Usage: toolchain-controlled only
289
Armando Montanez4ddaa9e2021-12-07 15:40:51 -0800290.. option:: pw_unit_test_PUBLIC_DEPS <dependencies>
291
292 Additional dependencies required by all unit test targets. (For example, if
293 using a different test library like Googletest.)
294
295 Type: list of strings (list of dependencies as GN paths)
296 Usage: toolchain-controlled only
297
298.. option:: pw_unit_test_MAIN <source_set>
299
300 Implementation of a main function for ``pw_test`` unit test binaries.
301
302 Type: string (GN path to a source set)
303 Usage: toolchain-controlled only
304
305.. option:: pw_unit_test_POOL_DEPTH <pool_depth>
306
307 The maximum number of unit tests that may be run concurrently for the
308 current toolchain. Setting this to 0 disables usage of a pool, allowing
309 unlimited parallelization.
310
311 Note: A single target with two toolchain configurations (e.g. release/debug)
312 will use two separate test runner pools by default. Set
313 pw_unit_test_POOL_TOOLCHAIN to the same toolchain for both targets to
314 merge the pools and force serialization.
315
316 Type: integer
317 Usage: toolchain-controlled only
318
319.. option:: pw_unit_test_POOL_TOOLCHAIN <toolchain>
320
321 The toolchain to use when referring to the pw_unit_test runner pool. When
322 this is disabled, the current toolchain is used. This means that every
323 toolchain will use its own pool definition. If two toolchains should share
324 the same pool, this argument should be by one of the toolchains to the GN
325 path of the other toolchain.
326
327 Type: string (GN path to a toolchain)
328 Usage: toolchain-controlled only
329
Alexei Frolov80246792020-11-05 21:12:45 -0800330RPC service
331===========
332``pw_unit_test`` provides an RPC service which runs unit tests on demand and
333streams the results back to the client. The service is defined in
334``pw_unit_test_proto/unit_test.proto``, and implemented by the GN target
335``$dir_pw_unit_test:rpc_service``.
Alexei Frolovbcac2c92020-05-19 10:24:20 -0700336
Alexei Frolov80246792020-11-05 21:12:45 -0800337To set up RPC-based unit tests in your application, instantiate a
338``pw::unit_test::UnitTestService`` and register it with your RPC server.
339
340.. code:: c++
341
342 #include "pw_rpc/server.h"
343 #include "pw_unit_test/unit_test_service.h"
344
345 // Server setup; refer to pw_rpc docs for more information.
346 pw::rpc::Channel channels[] = {
347 pw::rpc::Channel::Create<1>(&my_output),
348 };
349 pw::rpc::Server server(channels);
350
351 pw::unit_test::UnitTestService unit_test_service;
352
353 void RegisterServices() {
354 server.RegisterService(unit_test_services);
355 }
Alexei Frolov8cc11022020-12-07 15:03:44 -0800356
357All tests flashed to an attached device can be run via python by calling
358``pw_unit_test.rpc.run_tests()`` with a RPC client services object that has
359the unit testing RPC service enabled. By default, the results will output via
360logging.
361
362.. code:: python
363
Alexei Frolovd3e5cb72021-01-08 13:08:45 -0800364 from pw_hdlc.rpc import HdlcRpcClient
Alexei Frolov8cc11022020-12-07 15:03:44 -0800365 from pw_unit_test.rpc import run_tests
366
367 PROTO = Path(os.environ['PW_ROOT'],
368 'pw_unit_test/pw_unit_test_proto/unit_test.proto')
369
370 client = HdlcRpcClient(serial.Serial(device, baud), PROTO)
371 run_tests(client.rpcs())
Alexei Frolov47a43042021-04-06 14:19:55 -0700372
373pw_unit_test.rpc
Armando Montanez4ddaa9e2021-12-07 15:40:51 -0800374----------------
Alexei Frolov47a43042021-04-06 14:19:55 -0700375.. automodule:: pw_unit_test.rpc
376 :members: EventHandler, run_tests
Max Koopmanf4789282021-05-14 11:01:55 -0700377
378Module Configuration Options
379============================
380The following configurations can be adjusted via compile-time configuration of
381this module.
382
Erik Gilling723d6f02022-01-28 18:46:18 +0000383.. c:macro:: PW_UNIT_TEST_CONFIG_EVENT_BUFFER_SIZE
384
385 The size of the event buffer that the UnitTestService contains.
386 This buffer is used to encode events. By default this is set to
387 128 bytes.
388
Max Koopmanf4789282021-05-14 11:01:55 -0700389.. c:macro:: PW_UNIT_TEST_CONFIG_MEMORY_POOL_SIZE
390
391 The size of the memory pool to use for test fixture instances. By default this
392 is set to 16K.
Tom Craigb894ed62022-03-23 18:44:55 -0700393
394Using upstream Googletest and Googlemock
395========================================
396
397If you want to use the full upstream Googletest/Googlemock, you must do the
398following:
399
400* Set the GN var ``dir_pw_third_party_googletest`` to the location of the
401 googletest source. You can use ``pw package install googletest`` to fetch the
402 source if desired.
403* Set the GN var ``pw_unit_test_MAIN = "//third_party/googletest:gmock_main"``
404* Set the GN var ``pw_unit_test_PUBLIC_DEPS = [ "//third_party/googletest" ]``
405
406.. note::
407
408 Not all unit tests build properly with upstream Googletest yet. This is a
409 work in progress.