首页 > 代码库 > 让hg版本库自动化测试
让hg版本库自动化测试
前言
在嵌入式开发中,测试是很重要的一个环节,但是开发人员往往会忽视它。所以把自动化测试与代码紧密结合在一起是这篇文章的主题。
我们开发人员平时维护代码的时候使用最多的是版本库工具,很多时候代码修改完了,本地一编译,通过就提交了。但是却忽视了一个问题:程序编译通过就一定能正常运行了?显然是不对的。
前期准备
这里需要准备以下工具:
1,linux -- 这里我使用了ubuntu
2,gcc -- ubuntu是默认自带的
3,hg -- 版本库管理工具
4,unity -- 测试夹具
5,scons -- 一个自动化编译工具(你也可以使用makefile)
创建测试工程
首先我们需要在服务器端搭建一个版本库,
>>mkdir hg_hook >>cd hg_hook >>hg init >>touch main.c >>touch Sconstruct
然后我们修改main.c,代码如下:
#include <stdio.h> int main(void) { printf("hello world!\r\n"); return 0; }
修改Sconstruct文件,代码如下:
import os import sys BUILD = 'debug' # toolchains CC = 'gcc' if BUILD == 'debug': CFLAGS = ' -Wall -g -O0' else: CFLAGS = ' -O2' CFLAGS += ' -I'+os.getcwd() + '/' TARGET = 'main.out' env = Environment(CC=CC, CCFLAGS=CFLAGS) env.Program(TARGET, 'main.c') env.Command('-r', TARGET, './'+TARGET)Scons是一个类似于makefile的自动编译工具,大家如果有什么以后可以网上google一下,很多Scons的使用介绍。
这里我主要介绍最后一行:
env.Command('-r', TARGET, './'+TARGET)这是自定义一个命令,在我们编译好以后自动执行我们生成的可执行文件。便于我们测试程序运行结果。
我们在终端输入:scons -r,可以看到输出结果。
提交版本库
上面的工作完成以后,我们可以把源文件进行一次提交。
>>hg add . >>hg commit -m "packed init"这样我们就有了一个版本库。
修改版本库配置
因为我们需要用到的是hg的hook功能,所以我们需要修改hg的配置文件。
>>thg
是hg的自带图形界面,进入File->Setting;
点击编辑文件,输入:
[hooks] changegroup = update update = scons -r第一行表示当有用户提交代码的时候,自动调用update。
第二行表示执行hg update的时候执行scons -r。
点击ok。然后输入:
点击ok。然后输入:
>>hg serve启动版本库服务器。
用户提交代码
首先我们从服务器端clone代码,然后本地修改main.c代码:
#include <stdio.h> int main(void) { printf("hello world!\r\n"); x=6; // 添加的错误代码 return 0; }本地commit一下,然后pull到服务器,在log窗口可以看到如下信息:
我们可以看到remote返回了很多信息,其中把编译结果也返回了回来。就可以看出我们提交的代码首先是编译不正确的。
到了这里,我们基本上可以通过版本库的hook自动编译代码,来检测程序的编译阶段的错误。
添加unity测试夹具
添加unity源代码到hg-hook目录下,并在unity目录下添加Sconscript文件,内容如下:
objs = Object(Glob('*.c')) Return('objs')修改hg-hook目录下的Sconstruct文件,添加几行代码:
import os import sys BUILD = 'debug' # toolchains CC = 'gcc' if BUILD == 'debug': CFLAGS = ' -Wall -g -O0' else: CFLAGS = ' -O2' CFLAGS += ' -I'+os.getcwd() + <span style="font-family: Arial, Helvetica, sans-serif;">' -I'+os.getcwd() + ‘/unity’</span> MY_ROOT = os.path.normpath(os.getcwd()) # 添加的代码:获取当前根目录 TARGET = 'main.out' env = Environment(CC=CC, CCFLAGS=CFLAGS) objs = env.Object(Glob("*.c")) # 获取当前的源文件对象 objs += SConscript(['unity/Sconscript']) # 获取unity文件夹内的所有源文件对象 env.Program(TARGET, objs) env.Command('-r', TARGET, './'+TARGET)
移动源程序
我们把hello world代码从main里面移除出去,单独创建hello-world.c,hello-world.h2个源文件;也就是我们需要测试的程序
hello-world.c
#include <hello-world.h> #include <stdio.h> void hello_world(void) { printf("hello world\r\n"); }hello-world.h
#ifndef __HELLO_WORLD_H__ #define __HELLO_WORLD_H__ void hello_world(void); #endif然后我们修改main.c为:
#include <unity_fixture.h> static void run_all_test(void) { RUN_TEST_GROUP(hello_world); } static char *arg_string[] = { "main", "-v", }; int main(int argc, char *argv[]) { argc = sizeof(arg_string)/sizeof(char *); argv = arg_string; return UnityMain(argc, argv, run_all_test); }这个是我们测试夹具的框架。下面添加测试用例。
添加测试用例
我们添加hello-world-test.c文件,用于我们测试hello-world的函数。
#include "unity_fixture.h" #include "hello-world.h" TEST_GROUP(hello_world); TEST_SETUP(hello_world) { printf("\r\nstart\r\n"); } TEST_TEAR_DOWN(hello_world) { printf("end\r\n"); } TEST(hello_world, test1) { hello_world(); }添加hello-world-runner.c文件,用于测试夹具的启动:
#include "unity_fixture.h" TEST_GROUP_RUNNER(hello_world) { RUN_TEST_CASE(hello_world, test1); }接着我们运行hg commit,hg push,我们可以看到:
unity测试夹具对hello-world的测试通过了。
让hg版本库自动化测试
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。