关闭

自动化代码生成在UI可测试性提升中的应用

130人阅读 评论(0) 收藏 举报
分类:

 

【摘要】

本文阐述了在基于测试总线构建UI端到端可测试性架构的过程中,如何采用自动代码生成机制生成接口-实现的代码框架。自动化代码生成大大减轻了基于测试总线架构的代码因接口隔离造成的重复语句编写的负担。自动化手段使得UI可测试性方案的推广更方便。本文的代码自动生成仅限于C++Builder编译环境中的C++代码生成。

【关键词】

UI可测试性,自动化代码生成,C++,python

1     背景

在笔者撰写的《基于TDD的UI端到端可测试性改进最佳实践》,详细阐述了UI端到端可测试性的框架。见下图。


在实际的C++ Builder环境中,由于Form本身不支持多继承,所以在实际实现时,往往还需要在UI API和实际的Form之间增加一个间接层,此间接层实现在UIAPI所有接口,但在接口实现中无任何逻辑,仅仅是调用Form的具体实现。见下图。

 

这仅仅是由于CB本身的VCL局限导致的。这个间接层的引入,使得代码层次变深,而且基本都是机械式拷贝和粘贴,完全可以采用自动化手段来实现代码的生成,避免浪费宝贵的程序员时间。

2     解决思路

我们以某项目为例,看一下我们即将面对的问题。

1)View API如下:

2)ViewImpl的头文件如下:

3)ViewImpl的源文件如下(摘取片段):

4)Form头文件如下(摘取片段):

5)Form源文件如下(摘取片段):

从实际代码来看,雷同的地方比较多。如果项目中涉及到界面的部分全部采用TestBus方式来编码,很多的工作量都浪费在无谓的拷贝和粘贴上。

通过对代码模式进行分析,我们可以看出,其具备高度的一致性。模型抽象如下:

假设模块名称为XXX,

1) XXXView.h需要开发人员自己编写,文件内容可以抽象为:

    ….

struct XXXView

{

    virtual ~XXXView(){};

    一组形如“virtual 返回值 函数名(参数列表) = 0;”的函数

} ;

….

2) XXXImp.h文件自动生成,规则为:

#ifndef XXXViewImpH

#define XXXViewImpH

//---------------------------------------------------------------------------

#include "XXXView.h"

class TfrmXXX;

struct XXXViewImp :public XXXView

{

public:

    XXXViewImp(TfrmXXX *form);

    virtual ~XXXViewImp();

    一组XXXView.h中的函数,需要去掉末尾的“= 0;”

private:

    TXXXPlay *form;

};

 

#endif

 

3) XXXImp.cpp文件自动生成,规则如下:

 

#pragma hdrstop

 

#include "XXXViewImp.h"

#include "XXXForm.h"

 

//---------------------------------------------------------------------------

 

#pragmapackage(smart_init)

 

XXXViewImp:: XXXViewImp(TfrmXXX*form) : form(form)

{

}

XXXViewImp::~ XXXViewImp()

{

}

 

返回值 XXXViewImp::函数名(参数表)

{

    form->函数名(参数名);

}

返回值、函数名、参数表、参数名和XXXView.h中的一致。

4) XXXForm.h中的和XXXView接口相关的函数,自动生成,规则如下:

BEGIN_MVP

    一组和XXXVIew.h一致的“返回值 函数名(参数列表);”

END_MVP

5) XXXForm.cpp中的和XXXView接口相关的实现函数,自动生成,规则如下:

如果XXXForm.h中不含有宏BEGIN_MVP,说明是第一次生成,则cpp文件末尾增加实现函数,规则如下:

返回值 TfrmXXX::函数名(参数表)

{

}

如果XXXForm.h中含有宏BEGIN_MVP,说明不是第一次生成,可能已经含有用户真正实现代码,不能简单覆盖。由于逻辑比较复杂,因此在此不做处理。需要用户手工保持一致。

从以上分析过程可知,只要从XXXView.h文件中,得到以下变量,即可生成相应文件:

1) 模块名。模块名从API文件中的类名中截取,即从字符串XXXView中获取到XXX。

2) 函数返回值。函数返回值为virtual之后到左括号之前,去掉最后一个单词即可。

3) 函数名。函数名为左括号之前的最后一个单词。

4) 函数参数列表。参数列表为左括号和右括号直接的所有字符,含换行符。

5) 函数参数名。参数名为参数列表中逗号之前的最后一个单词,以及右括号之前的最后一个单词。

这样,通过对文本的简单解析,即可以生成得到上述变量,再根据上述的文件规则,生成出所需要的XXXViewImp的头文件和实现文件,以及XXXForm中的所有和API接口相关的头文件和实现文件的代码片段。

3    实践情况

在具体实现时,采用了编码效率比较高的python来完成代码编写。代码片段如下:

解析函数名和返回值代码:

执行时,只需要把python脚本放置在模块目录下,双击即可自动生成所需文件。

在网优工具部某项目的客户端代码中,有两个模块具体采用此种手段进行了验证,生成的代码一次性编译通过,运行正常。

4     效果评价

采用本方法后,解决了采用TestBus技术实现UI端到端可测试性提升带来的接口及实现中的重复劳动问题,使得开发人员只需关心具体的业务实现,从而可以较大提升工作效率。而且,在UI API接口变动时,只需要在Form实现文件中简单修改,然后运行脚本即可保证文件间的一致性。



0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:25225次
    • 积分:649
    • 等级:
    • 排名:千里之外
    • 原创:35篇
    • 转载:8篇
    • 译文:4篇
    • 评论:8条
    最新评论