测验,信任对每一个搞程序的都不会陌生,然后咱们会联想到什么单元测验,集成测验,发布测验,黑盒测验,白盒测验等等一系列的名词。但在单片机范畴,更多的功用测验。测验人员,在试用产品后,发现bug然后陈述给研制人员,往往疏忽中心的单元测验,在开发的进程中就确保各模块的功用。
关于一些JAVA, C++++开发人员,cppunit, junit这些主动化测验结构,但是,关于单片机开发人员,又怎样完成主动化测验呢?
下面就UART驱动的测验说起。
测验的意图
首要承认 功用这条主线能够走通。比方UART发送字符这个功用主线是:SysCtl 装备MCU时钟源,装备UART时钟源, SysCtl使能UART外设, GPIO装备RX, TX管脚的复用,装备BAUD作业形式等,然后才是发送。 也便是说,想要成功发送一个字符,前面的每一个都不能缺失。
其次是功用的正确性。
在其次是改善,改善,优化。
什么是一个测验
测验,给定一个条件,然后会得到一个成果,希望的成果与实践的成果比较,假如共同,就说测验经过,不然,失利。待测功用,就像是一个方程式,咱们一个一个的代入,看每一次的成果是否正确。
关于人来说,终究的成果,需求经过人的听觉或视觉感知的。从终端看到一个Pass阐明测验经过,LCD正确显现了字符,也阐明晰经过。我把测验分了一下类:
不能通进程序读到成果的,只能经过人看到或听到的,比方LCD, 这类无法完成主动化测验。
一类能够通进程序读到成果的,一般是履行了一些程式,会得到一个状况/成果,程序正好能够读到。比方 Write后Read.
能够把底一类转换成第二类的。比方UART的发送,能够经过超级终端看到成果判别,也能够凭借UART2(功用正确的), 它们之间通讯,来完成主动化。
都说C言语 = 函数 + 数据,测验相同。好点的代码,是不会把数据与函数混在一同的。那么什么是测验数据呢?
typedef struct
{
tTestCondiTIon sCondiTIon;
tTestResult sExpectResult;
}tTestData;
tTestData psTestDataTable[] = {
{ , },
{ , },
};
一个一个测验,将构成这样一个结构体数组。测验数据的添加,或修正只是需求修正这个数组就能够,而无需修正代码。测验,相同变的很好保护。
什么是主动化测验
主动化测验,其实便是主动调用每一个测验,一个一个调用,然后,以人能够感知的方法,陈述成果。比方,在超级终端中打印PASS.
每一个测验,都或许需求首要结构它们自己的初始环境。每一个测验之间,它们不能相互影响。也便是说,测验履行完后,它需求复原环境到复位状况。
下面描绘下,我常常用到的测验结构,这是我从一个开源项目中改动过来的:
一个测验工程,有多组测验(Suite), 一个组(Suite)下或许有多个测验。组的概念,其实便是组件,把类似的放在一组,就像文件夹安排。
//*****************************************************************************
//
//! brief Structure represenTIng a test case.
//
//*****************************************************************************
typedef struct
{
//
//! brief Test case name get funcTIon.
//
char* (*GetTest)(void);
//
//! brief Test case preparation function.
//
void (*Setup)(void);
//
//! brief Test case clean up function.
//
void (*TearDown)(void);
//
//! brief Test case execution function.
//
void (*Execute)(void);
}
tTestCase;
Setup是为了结构测验需求的环境。TearDown是在测验履行后,复原测验环境。Execute才是测验主体。Execute中能够进行一些TestAssert, 来履行一个一个的判别。
GetTest只是是为了在终端打印一下这个测验的内容。
下面是结构main:
xtBoolean
TestMain(void)
{
int i, j;
TestIOInit();
PrintLine(“”);
PrintLine(“*** CooCox CoIDE components test suites”);
PrintLine(“***”);
#ifdef TEST_COMPONENTS_NAME
Print(“*** Components: ”);
PrintLine(TEST_COMPONENTS_NAME);
#endif
#ifdef TEST_COMPONENTS_VERSION
Print(“*** Version: ”);
PrintLine(TEST_COMPONENTS_VERSION);
#endif
#ifdef TEST_BOARD_NAME
Print(“*** Test Board: ”);
PrintLine(TEST_BOARD_NAME);
#endif
PrintLine(“”);
g_bGlobalFail = xfalse;
i = 0;
while (g_psPatterns[i])
{
j = 0;
while (g_psPatterns[i][j])
{
PrintNewLine();
Print(“— Test Case ”);
PrintN(i + 1);
Print(“。”);
PrintN(j + 1);
Print(“ (”);
Print(g_psPatterns[i][j]-》GetTest());
PrintLine(“)”);
ExecuteTest(g_psPatterns[i][j]);
if (g_bLocalFail == xtrue)
{
Print(“— Result: FAILURE ”);
PrintLine(“”);
//
//printf error information
//
Print(g_pcErrorInfoBuffer);
PrintLine(“”);
if (g_pcTokensBuffer 《 g_pcTok)
{
Print(“ The tokens in buffer is: ”);
PrintTokens();
PrintLine(“”);
}
}
else
{
PrintLine(“— Result: SUCCESS ”);
}
j++;
}
i++;
}
PrintNewLine();
PrintLine(“”);
Print(“Final result: ”);
if (g_bGlobalFail == xtrue)
PrintLine(“FAILURE”);
else
PrintLine(“SUCCESS”);
return g_bGlobalFail;
}
如需完好的测验结构代码,请联络我,或前往咱们的开源项目:https://github.com/coocox/cox.
这是一个一致API规范的外设库。根据CoX的驱动,无需移植,就能够用到其他MCU渠道。