STM32 | 分享几个开源的测试框架

发布者:MindfulBeing最新更新时间:2021-08-11 来源: eefocus关键字:STM32  测试框架 手机看文章 扫描二维码
随时随地手机看文章

这是一篇测试相关的笔记。我们软件开发最终都离不开测试的,可以通过测试来发现很多问题。在这之前先扯谈一波:


在这给还没找工作的朋友提个醒,能找开发的职位就别找测试的职位,除非你真的很喜欢测试。亲身经历,做测试很不好受。测试其实有两类,一种是自己去测自己测的东西,另一种是去测别人做的东西。如果是第一种,我倒是很愿意做,因为我们本质上还是开发工程师,大概80%的工作时间在做开发,20%的工作时间在测自己开发的东西。这个测试的时间值得花,可以通过测试来发现我们在开发过程中没有注意到的点。如果是第二种,我们本质上就是测试工程师了,大概80%的时间在测别人的东西,20%的时间在想着怎么测别人的东西。如果是这一种的话,那我们就只能当别人的配角了。


找工作时,有一点要注意:有些职位写着嵌入式软件工程师,实则测试工程师,这个得问清楚。


回归正题,下面开始我们的这篇笔记:


几个开源的测试框架

框架(framework)是一个框子——指其约束性,也是一个架子——指其支撑性。是一个基本概念上的结构,用于去解决或者处理复杂的问题。 框架这个广泛的定义使用的十分流行,尤其在软件概念。比如我们套用一些测试框架来测试我们写的一些功能函数,的出来的测试结果大概是这样子的:

======000

从输出结果中看,我们可以清晰地看出测试的情况。下面分享几个开源的测试框架:

1、 Unity测试框架

这里的Unity并不是那个游戏开发工具 ,而是一个开源的测试框架。Unity测试框架的项目链接:

https://github.com/ThrowTheSwitch/Unity/releases1.

目前更新到v2.5.0:

======001

Unity 是一个轻量级的测试框架,它使用 C 语言实现, 代码本身很小 。其代码中大多数是宏定义,所以实际编译后的代码会更小, 比较适合在嵌入式测试应用。


2、 CuTest测试框架

CuTest项目链接:

https://sourceforge.net/projects/cutest/1.

CuTest是一款微小的C语言单元测试框,只有2个文件,CuTest.c和CuTest.h,全部代码加起来不到一千行。麻雀虽小,五脏俱全,测试的构建、测试的管理、测试语句,都全部包含在内。


3、 Embedded Unit测试框架

Embedded Unit项目链接:

https://sourceforge.net/projects/embunit 1.

Embedded Unit是个纯标准c构建的单元测试框架,主要用在嵌入式c的单体测试上,其主要特点是不依赖于任何C的标准库,所有的对象都是静态分配。


4、 gtest 测试框架

gtest项目链接:

https://github.com/google/googletest/releases/tag/release-1.8.01.

gtest 是 google 公司开发的一个开源的单元测试框架,基于 C++开发,可以对 C++语言和 C 语言进行单元测试。 gtest 有以下特点:

  • 提供强大的断言集,支持布尔型、整型、浮点型、字符串以及所有实现了比较运
    算符和输出运算符的自定义类的判断;

  • 提供断言扩展功能,当所需要的断言在 gtest 中没有提供时,可以使用 gtest 提供
    的方法进行扩展;

  • gtest 会自动收集我们的测试用例,开发者不需要对测试用例进行组织;

  • 提供死亡测试的功能,用于测试代码在特定情况下异常崩溃的情况;

  • 可将公共的用例初始化和清理工作放入测试夹具中,由 gtest 自动调用;

  • 使用参数化自动生成多个相似的测试用例

Unity的使用分享

这里分享Unity在STM32平台上的移植与使用(keil工程)。移植的过程很简单,一般这些测试框架都是打印的方式把测试结果输出。在STM32中 ,我们一般是通过串口输出到串口上位机,所以我们在移植Unity的时候,处理好这个问题就可以用在STM32上了。


首先,把Unity源码目录下的unity.c、unity.h、unity_internals.h三个文件复制至我们的工程目录下,并把unity.c添加到我们的keil工程中,然后添加文件路径:

======003

======004

我们打开unity_internals.h文件,发现其有包含一个头文件unity_config.h:

======005

这个文件是配置文件,我们与平台相关的特性放在这个文件中。而这个文件Unity源码中并未提供,所以需要我们自己建立,我这边新建的unity_config.h文件的内容如下:

======006

主要在这里面放了硬件相关的头文件包含以及两个必要的宏定义。第一个宏定义用于重定向输出至串口,第二个宏定义就是我们的串口初始化。

在unity_internals.h中我们发现unity_config.h文件被条件编译屏蔽掉了,我们需要定义宏把它打开:

======007

最后在我们的main.c中包含头文件unity.h即可使用unity测试框架。在unity_internals.h中有很多可修改的配置,比如在不同的平台中,整数的长度是不一样的,在 Unity 中,允许开发者设置整数的长度。如果没有设置, 


下面开始编写测试用例。 在 Unity 中,每个测试用例是一个函数, 该函数没有参数和返回值。下面我们来测试一个闰年判断函数:

======008

在测试函数中用到 TEST_ASSERT_TRUE 和 TEST_ASSERT_FALSE , 是 Unity 实现的两个断言, 用于判断布尔型表达式的值为真或为假。这些测试框架一般都是用断言来进行测试的,包括以上分享的几个框架都是如此。本例中只用到了两个断言,在 Unity 中还有很多断言,如下是部分断言列举:

======009

======010

Unity 默认需要实现用例初始化函数 setUp 和用例清理函数 tearDown,这两个函数均没有参数和返回值。 在闰年判断函数的测试用例中,由于不需要初始化和清理操作,实现的两个函数如下:

======021

在编写了测试用例后, 接下来就可以在 main 函数中运行测试用例。在 Unity 中,使用宏 RUN_TEST 运行测试用例,参数为要运行的测试用例的函数名称。主函数如下:

======011

UNITY_BEGIN函数就是UNITY初始化函数,我们的串口初始化也是在这里面被调用的:

======012

======013

RUN_TEST函数用于运行我们的测试用例。UNITY_END函数就是返回我们的测试结果。最终,运行得到如下结果:

======014

假如,我们把测试闰年的测试函数里的2000改为2001:

======015

那么输出结果就变为:

======016

可以从结果看出没有通过的用例相关的代码所在行。在进行这样子的测试之前,我们当然得要明白我们的功能函数的功能及其预期输出,我们才能去进行测试用例的设计及进行测试。


以上就是关于Unity测试框架的使用分享,这只是这个测试框架的基本使用。有兴趣的、有用得上的朋友可以自己进行深入研究及使用。


相关书籍

第一本书:《软件单元测试入门与实践》周立功

这个Unity测试框架是我在周立功周工几个月前出版的新书《软件单元测试入门与实践》中看到的。之前刚出版的时候,他们有送书活动,我申请了一本纸质版书籍,没来得及看,最近仔细翻了一下,发现还实用,又学到了很多新东西。这不只是一本讲测试的书,也是一本教我们如何调高软件质量的书。书中有理论和实践大概各占一半,介绍了很多实用的工具和技巧。

======017

前面几章很详细地介绍了一些测试相关的知识,比如黑盒测试、白盒测试、灰盒测试、静态测试,动态测试等。介绍了静态测试工具:pc-lint 编码规则检查工具与 SourceMonitor 代码结构检查工具。其中pc-lint可以集成到keil中进行使用。从某种意义上说,PC-Lint 是一种更加严格的编译器,它除了可以检查出一般的语法错误外,还可以检查出那些虽然符合语法要求,但很可能是潜在的、不易发现的错误。

======018

后面几章分享一些实用工具的使用,比如Unity测试框架、cmake自动构建工具、持续集成系统 gitlab 等。


第二本书:《测试驱动的嵌入式C语言开发》尹哲翻译

这本是在周工那本书的参考文献里的其中一本。

======019

======020

这是老外写的书。看目录好像还不错,有空的时候可以当做课外书来读。

以上就是本次的笔记分享,希望各位喜欢!

关键字:STM32  测试框架 引用地址:STM32 | 分享几个开源的测试框架

上一篇:STM32 | hex文件、bin文件、axf文件的区别?
下一篇:STM32 | 学习STM32的一些经验分享

推荐阅读最新更新时间:2024-11-08 22:09

STM32高级定时器、通用定时器TIMx、基本定时器TIM6和TIM7的区别
TIM1和TIM8定时器的功能包括: ● 16位向上、向下、向上/下自动装载计数器 ● 16位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为1~65535之间的任意数值 ● 多达4个独立通道: ─ 输入捕获 ─ 输出比较 ─ PWM生成(边缘或中间对齐模式) ─ 单脉冲模式输出 ● 死区时间可编程的互补输出 ● 使用外部信号控制定时器和定时器互联的同步电路 ● 允许在指定数目的计数器周期之后更新定时器寄存器的重复计数器 ● 刹车输入信号可以将定时器输出信号置于复位状态或者一个已知状态 ● 如下事件发生时产生中断/DMA: ─ 更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发) ─ 触发事件(
[单片机]
USART(STM32
USART / USRT 串口模式实现有三种 阻塞模式 / 普通模式:在主函数中接收函数 非阻塞模式 / 中断模式:产生的不影响主程序运行 DMA模式:与主函数互不影响,独立运行 我的理解:阻塞就是死等,非阻塞就是中断 阻塞模式就像是一个延时函数,当这个函数没处理完那么,所有的按照流程需要执行的代码都不会被执行,要等到这个延时完成,类似 平时看书上写的LED灯闪烁,用的delay()一样… 而非阻塞模式就像他定义的那样,一般用的是中断,执行这条语句的时候,开启相应的中断达到一定的条件才进行处理,这样不会影响到流程的执行. STM32中的F0和F1的AF操作方式是不一样的。F0是复用,F1是备用。 据《STM32中文参考
[单片机]
USART(<font color='red'>STM32</font>)
解锁STM32 Printf新姿势!,用vsprintf吧!
解锁STM32 Printf新姿势!,用vsprintf吧! int my_printf(const char *fmt, …) { va_list args; int n; va_start(args, fmt);//初始化参数指针 n = vsprintf(sprint_buf, fmt, args);/函数放回已经处理的字符串长度/ va_end(args);//与va_start 配对出现,处理ap指针 shell_write((unsigned char *)sprint_buf, n); return n; 1 2 } 实现这个函数就行啦: int shell_write(unsigned c
[单片机]
STM32嵌入式FLASH擦除与写入
嵌入式Flash Flash具有以下主要特性: 1.对于STM32F40x和 STM32F41x,容量高达1 MB;对于STM32F42x和STM32F43x,容量高达2MB。128位宽数据读取---------意思就是128/8=16(字节) 2.字节、半字、字和双字数据写入----对应一个字节,两个字节,四个字节,八个字节。(推荐以字读取和写入,即四个字节,刚好32位) 3.扇区擦除与全部擦除 扇区擦除就像你删除电脑的C盘内容,不删除D-F盘内容一样。 扇区擦除完的数据都为0XFF 4.存储器组织结构Flash 结构如下: -主存储器块,分为4个16 KB扇区、1个64 KB扇区和7个128 KB扇区-系统存储器,
[单片机]
一步步写STM32 OS【二】环境搭建
一、安装IAR for ARM6.5 二、新建工程 1、选择处理器:STM32F407VG,暂不使用FPU 2、必要的路径配置和宏定义 3、使用SWO重定向IO输出 4、使用ST-LINK仿真器 5、下载配置 6、设置CPU频率,防止SWO输出乱码 三、代码调试
[单片机]
一步步写<font color='red'>STM32</font> OS【二】环境搭建
STM32 uCOS_II 实践 之 消息邮箱
所谓的消息邮箱并不是把数据进行传输,而是在合适的时间告诉任务去使用哪些变量或者当一些特殊的变量变化后可以及时并准确的使用变量,消息邮箱传递的是这些变量的指针,而这些变量本身就已经存在与内存中了,他们多以全局变量或者静态变量的形式存在。 首先介绍消息邮箱的一种使用方式,就是只传递一个非空指针,告诉等待消息的任务他等待的时间到了,但是这个指针里并没有有用的数据,而任务中也不应该对这个地址指向的变量进行任何的读取和写入操作,读写操作都是无意义的,从另外一个角度来看,虽然借用了别人的地址但是本身并没有对地址里的数据进行操作,所以地址里的数据也是安全的,说白了就是消息邮箱版信号量(非计数)。它的好处就是可以在系统里把信号量有关的代码给裁剪掉,
[单片机]
stm32_015_stm32工程设置程序下载到flash中
1.选择对应cpu型号 2.设置程序的存储地址和预留大小(不能超过总大小),还有设置RAM的地址和大小。 3.设置输出hex文件 4.安装好j-link驱动后,设置debug选项 5.设置Utilities选项 至此,变可以下载或者debug了。
[单片机]
stm32_015_stm32工程设置程序下载到flash中
stm32中的NVIC_Configuration(void)函数
用于映射中断的处理函数,就知道这么多,不求甚解呀, void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; #ifdef VECT_TAB_RAM /* Set the Vector Table base location at 0x20000000 */ NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); #else /* VECT_TAB_FLASH */ /* Set the Vector Table base location at 0x08000000 */ NVIC_SetVectorTable
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
  • 学习ARM开发(16)
    ARM有很多东西要学习,那么中断,就肯定是需要学习的东西。自从CPU引入中断以来,才真正地进入多任务系统工作,并且大大提高了工作效率。采 ...
  • 学习ARM开发(17)
    因为嵌入式系统里全部要使用中断的,那么我的S3C44B0怎么样中断流程呢?那我就需要了解整个流程了。要深入了解,最好的方法,就是去写程序 ...
  • 学习ARM开发(18)
    上一次已经了解ARM的中断处理过程,并且可以设置中断函数,那么它这样就可以工作了吗?答案是否定的。因为S3C44B0还有好几个寄存器是控制中 ...
  • 嵌入式系统调试仿真工具
    嵌入式硬件系统设计出来后就要进行调试,不管是硬件调试还是软件调试或者程序固化,都需要用到调试仿真工具。 随着处理器新品种、新 ...
  • 最近困扰在心中的一个小疑问终于解惑了~~
    最近在驱动方面一直在概念上不能很好的理解 有时候结合别人写的一点usb的例子能有点感觉,但是因为arm体系里面没有像单片机那样直接讲解引脚 ...
  • 学习ARM开发(1)
  • 学习ARM开发(2)
  • 学习ARM开发(4)
  • 学习ARM开发(6)
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved