Skip to content

Commit dcf7bce

Browse files
authored
Merge pull request #2041 from zhaojuntao/utest-dev
[components][utilities] 增加 utest(单元测试框架)
2 parents a5b22a5 + bce7f85 commit dcf7bce

File tree

6 files changed

+498
-0
lines changed

6 files changed

+498
-0
lines changed

components/utilities/Kconfig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,4 +230,8 @@ config RT_USING_ULOG
230230
sfotware module version number
231231
endif
232232

233+
config RT_USING_UTEST
234+
bool "Enable utest (RT-Thread test framework)"
235+
default n
236+
233237
endmenu
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from building import *
2+
3+
cwd = GetCurrentDir()
4+
src = Glob('*.c')
5+
CPPPATH = [cwd]
6+
group = DefineGroup('utest', src, depend = ['RT_USING_UTEST'], CPPPATH = CPPPATH)
7+
8+
Return('group')

components/utilities/utest/utest.c

Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
/*
2+
* Copyright (c) 2006-2018, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2018-11-19 MurphyZhao the first version
9+
*/
10+
11+
#include "utest.h"
12+
#include <rtthread.h>
13+
#include <finsh.h>
14+
15+
#undef DBG_SECTION_NAME
16+
#undef DBG_LEVEL
17+
#undef DBG_COLOR
18+
#undef DBG_ENABLE
19+
20+
#define DBG_ENABLE
21+
#define DBG_SECTION_NAME "utest"
22+
#ifdef UTEST_DEBUG
23+
#define DBG_LEVEL DBG_LOG
24+
#else
25+
#define DBG_LEVEL DBG_INFO
26+
#endif
27+
#define DBG_COLOR
28+
#include <rtdbg.h>
29+
30+
#if RT_CONSOLEBUF_SIZE < 256
31+
#error "RT_CONSOLEBUF_SIZE is less than 256!"
32+
#endif
33+
34+
static utest_tc_export_t tc_table = RT_NULL;
35+
static rt_size_t tc_num;
36+
static struct utest local_utest = {UTEST_PASSED, 0, 0};
37+
38+
#if defined(__ICCARM__) || defined(__ICCRX__) /* for IAR compiler */
39+
#pragma section="UtestTcTab"
40+
#endif
41+
42+
int utest_init(void)
43+
{
44+
/* initialize the utest commands table.*/
45+
#if defined(__CC_ARM) /* ARM C Compiler */
46+
extern const int UtestTcTab$$Base;
47+
extern const int UtestTcTab$$Limit;
48+
tc_table = (utest_tc_export_t)&UtestTcTab$$Base;
49+
tc_num = (utest_tc_export_t)&UtestTcTab$$Limit - tc_table;
50+
#elif defined (__ICCARM__) || defined(__ICCRX__) /* for IAR Compiler */
51+
tc_table = (utest_tc_export_t)__section_begin("UtestTcTab");
52+
tc_num = (utest_tc_export_t)__section_end("UtestTcTab") - tc_table;
53+
#elif defined (__GNUC__) /* for GCC Compiler */
54+
extern const int __rt_utest_tc_tab_start;
55+
extern const int __rt_utest_tc_tab_end;
56+
tc_table = (utest_tc_export_t)&__rt_utest_tc_tab_start;
57+
tc_num = (utest_tc_export_t) &__rt_utest_tc_tab_end - tc_table;
58+
#endif /* defined(__CC_ARM) */
59+
60+
LOG_I("utest is initialize success.");
61+
LOG_I("total utest testcase num: (%d)", tc_num);
62+
return tc_num;
63+
}
64+
INIT_COMPONENT_EXPORT(utest_init);
65+
66+
static void utest_tc_list(void)
67+
{
68+
rt_size_t i = 0;
69+
70+
LOG_I("Commands list : ");
71+
72+
for (i = 0; i < tc_num; i++)
73+
{
74+
LOG_I("[testcase name]:%s; [run timeout]:%d", tc_table[i].name, tc_table[i].run_timeout);
75+
}
76+
}
77+
MSH_CMD_EXPORT_ALIAS(utest_tc_list, utest_list, output all utest testcase);
78+
79+
static const char *file_basename(const char *file)
80+
{
81+
char *end_ptr = RT_NULL;
82+
char *rst = RT_NULL;
83+
84+
if (!((end_ptr = strrchr(file, '\\')) != RT_NULL || \
85+
(end_ptr = strrchr(file, '/')) != RT_NULL) || \
86+
(rt_strlen(file) < 2))
87+
{
88+
rst = (char *)file;
89+
}
90+
else
91+
{
92+
rst = (char *)(end_ptr + 1);
93+
}
94+
return (const char *)rst;
95+
}
96+
97+
static void utest_run(const char *utest_name)
98+
{
99+
rt_size_t i = 0;
100+
101+
LOG_I("[==========] [ utest ] started");
102+
while(i < tc_num)
103+
{
104+
if (utest_name && rt_strcmp(utest_name, tc_table[i].name))
105+
{
106+
i++;
107+
continue;
108+
}
109+
110+
LOG_I("[----------] [ testcase ] (%s) started", tc_table[i].name);
111+
if (tc_table[i].init != RT_NULL)
112+
{
113+
if (tc_table[i].init() != RT_EOK)
114+
{
115+
LOG_I("[ FAILED ] [ result ] testcase (%s)", tc_table[i].name);
116+
goto __tc_continue;
117+
}
118+
}
119+
120+
if (tc_table[i].tc != RT_NULL)
121+
{
122+
tc_table[i].tc();
123+
if (local_utest.failed_num == 0)
124+
{
125+
LOG_I("[ PASSED ] [ result ] testcase (%s)", tc_table[i].name);
126+
}
127+
else
128+
{
129+
LOG_I("[ FAILED ] [ result ] testcase (%s)", tc_table[i].name);
130+
}
131+
}
132+
else
133+
{
134+
LOG_I("[ FAILED ] [ result ] testcase (%s)", tc_table[i].name);
135+
}
136+
137+
if (tc_table[i].cleanup != RT_NULL)
138+
{
139+
if (tc_table[i].cleanup() != RT_EOK)
140+
{
141+
LOG_I("[ FAILED ] [ result ] testcase (%s)", tc_table[i].name);
142+
goto __tc_continue;
143+
}
144+
}
145+
146+
__tc_continue:
147+
LOG_I("[----------] [ testcase ] (%s) finished", tc_table[i].name);
148+
149+
i++;
150+
}
151+
LOG_I("[==========] [ utest ] finished");
152+
}
153+
154+
static void utest_testcase_run(int argc, char** argv)
155+
{
156+
char utest_name[UTEST_NAME_MAX_LEN];
157+
158+
if (argc == 1)
159+
{
160+
utest_run(RT_NULL);
161+
}
162+
else if (argc == 2)
163+
{
164+
rt_memset(utest_name, 0x0, sizeof(utest_name));
165+
rt_strncpy(utest_name, argv[1], sizeof(utest_name) -1);
166+
utest_run(utest_name);
167+
}
168+
else
169+
{
170+
LOG_E("[ error ] at (%s:%d), in param error.", __func__, __LINE__);
171+
}
172+
}
173+
MSH_CMD_EXPORT_ALIAS(utest_testcase_run, utest_run, utest_run [testcase name]);
174+
175+
utest_t utest_handle_get(void)
176+
{
177+
return (utest_t)&local_utest;
178+
}
179+
180+
void utest_unit_run(test_unit_func func, const char *unit_func_name)
181+
{
182+
// LOG_I("[==========] utest unit name: (%s)", unit_func_name);
183+
local_utest.error = UTEST_PASSED;
184+
local_utest.passed_num = 0;
185+
local_utest.failed_num = 0;
186+
187+
if (func != RT_NULL)
188+
{
189+
func();
190+
}
191+
}
192+
193+
void utest_assert(int value, const char *file, int line, const char *func, const char *msg)
194+
{
195+
if (!(value))
196+
{
197+
local_utest.error = UTEST_FAILED;
198+
local_utest.failed_num ++;
199+
LOG_E("[ ASSERT ] [ unit ] at (%s); func: (%s:%d); msg: (%s)", file_basename(file), func, line, msg);
200+
}
201+
else
202+
{
203+
LOG_D("[ OK ] [ unit ] (%s:%d) is passed", func, line);
204+
local_utest.error = UTEST_PASSED;
205+
local_utest.passed_num ++;
206+
}
207+
}
208+
209+
void utest_assert_string(const char *a, const char *b, rt_bool_t equal, const char *file, int line, const char *func, const char *msg)
210+
{
211+
if (a == RT_NULL || b == RT_NULL)
212+
{
213+
utest_assert(0, file, line, func, msg);
214+
}
215+
216+
if (equal)
217+
{
218+
if (rt_strcmp(a, b) == 0)
219+
{
220+
utest_assert(1, file, line, func, msg);
221+
}
222+
else
223+
{
224+
utest_assert(0, file, line, func, msg);
225+
}
226+
}
227+
else
228+
{
229+
if (rt_strcmp(a, b) == 0)
230+
{
231+
utest_assert(0, file, line, func, msg);
232+
}
233+
else
234+
{
235+
utest_assert(1, file, line, func, msg);
236+
}
237+
}
238+
}

0 commit comments

Comments
 (0)