Skip to content

Commit 7c2b108

Browse files
dlatypovshuahkh
authored andcommitted
Documentation: kunit: add tips.rst for small examples
./usage.rst contains fairly long examples and explanations of things like how to fake a class and how to use parameterized tests (and how you could do table-driven tests yourself). It's not exactly necessary information, so we add a new page with more digestible tips like "use kunit_kzalloc() instead of kzalloc() so you don't have to worry about calling kfree() yourself" and the like. Change start.rst to point users to this new page first and let them know that usage.rst is more of optional further reading. Signed-off-by: Daniel Latypov <[email protected]> Reviewed-by: Brendan Higgins <[email protected]> Signed-off-by: Shuah Khan <[email protected]>
1 parent c9ef2d3 commit 7c2b108

File tree

3 files changed

+120
-1
lines changed

3 files changed

+120
-1
lines changed

Documentation/dev-tools/kunit/index.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ KUnit - Unit Testing for the Linux Kernel
1313
api/index
1414
style
1515
faq
16+
tips
1617

1718
What is KUnit?
1819
==============
@@ -88,6 +89,7 @@ How do I use it?
8889
================
8990

9091
* :doc:`start` - for new users of KUnit
92+
* :doc:`tips` - for short examples of best practices
9193
* :doc:`usage` - for a more detailed explanation of KUnit features
9294
* :doc:`api/index` - for the list of KUnit APIs used for testing
9395
* :doc:`kunit-tool` - for more information on the kunit_tool helper script

Documentation/dev-tools/kunit/start.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,5 +234,7 @@ Congrats! You just wrote your first KUnit test!
234234

235235
Next Steps
236236
==========
237-
* Check out the :doc:`usage` page for a more
237+
* Check out the :doc:`tips` page for tips on
238+
writing idiomatic KUnit tests.
239+
* Optional: see the :doc:`usage` page for a more
238240
in-depth explanation of KUnit.
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
.. SPDX-License-Identifier: GPL-2.0
2+
3+
============================
4+
Tips For Writing KUnit Tests
5+
============================
6+
7+
Exiting early on failed expectations
8+
------------------------------------
9+
10+
``KUNIT_EXPECT_EQ`` and friends will mark the test as failed and continue
11+
execution. In some cases, it's unsafe to continue and you can use the
12+
``KUNIT_ASSERT`` variant to exit on failure.
13+
14+
.. code-block:: c
15+
16+
void example_test_user_alloc_function(struct kunit *test)
17+
{
18+
void *object = alloc_some_object_for_me();
19+
20+
/* Make sure we got a valid pointer back. */
21+
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, object);
22+
do_something_with_object(object);
23+
}
24+
25+
Allocating memory
26+
-----------------
27+
28+
Where you would use ``kzalloc``, you should prefer ``kunit_kzalloc`` instead.
29+
KUnit will ensure the memory is freed once the test completes.
30+
31+
This is particularly useful since it lets you use the ``KUNIT_ASSERT_EQ``
32+
macros to exit early from a test without having to worry about remembering to
33+
call ``kfree``.
34+
35+
Example:
36+
37+
.. code-block:: c
38+
39+
void example_test_allocation(struct kunit *test)
40+
{
41+
char *buffer = kunit_kzalloc(test, 16, GFP_KERNEL);
42+
/* Ensure allocation succeeded. */
43+
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buffer);
44+
45+
KUNIT_ASSERT_STREQ(test, buffer, "");
46+
}
47+
48+
49+
Testing static functions
50+
------------------------
51+
52+
If you don't want to expose functions or variables just for testing, one option
53+
is to conditionally ``#include`` the test file at the end of your .c file, e.g.
54+
55+
.. code-block:: c
56+
57+
/* In my_file.c */
58+
59+
static int do_interesting_thing();
60+
61+
#ifdef CONFIG_MY_KUNIT_TEST
62+
#include "my_kunit_test.c"
63+
#endif
64+
65+
Injecting test-only code
66+
------------------------
67+
68+
Similarly to the above, it can be useful to add test-specific logic.
69+
70+
.. code-block:: c
71+
72+
/* In my_file.h */
73+
74+
#ifdef CONFIG_MY_KUNIT_TEST
75+
/* Defined in my_kunit_test.c */
76+
void test_only_hook(void);
77+
#else
78+
void test_only_hook(void) { }
79+
#endif
80+
81+
TODO([email protected]): add an example of using ``current->kunit_test`` in
82+
such a hook when it's not only updated for ``CONFIG_KASAN=y``.
83+
84+
Customizing error messages
85+
--------------------------
86+
87+
Each of the ``KUNIT_EXPECT`` and ``KUNIT_ASSERT`` macros have a ``_MSG`` variant.
88+
These take a format string and arguments to provide additional context to the automatically generated error messages.
89+
90+
.. code-block:: c
91+
92+
char some_str[41];
93+
generate_sha1_hex_string(some_str);
94+
95+
/* Before. Not easy to tell why the test failed. */
96+
KUNIT_EXPECT_EQ(test, strlen(some_str), 40);
97+
98+
/* After. Now we see the offending string. */
99+
KUNIT_EXPECT_EQ_MSG(test, strlen(some_str), 40, "some_str='%s'", some_str);
100+
101+
Alternatively, one can take full control over the error message by using ``KUNIT_FAIL()``, e.g.
102+
103+
.. code-block:: c
104+
105+
/* Before */
106+
KUNIT_EXPECT_EQ(test, some_setup_function(), 0);
107+
108+
/* After: full control over the failure message. */
109+
if (some_setup_function())
110+
KUNIT_FAIL(test, "Failed to setup thing for testing");
111+
112+
Next Steps
113+
==========
114+
* Optional: see the :doc:`usage` page for a more
115+
in-depth explanation of KUnit.

0 commit comments

Comments
 (0)