array(2) { ["docs"]=> array(10) { [0]=> array(10) { ["id"]=> string(3) "428" ["text"]=> string(77) "Visual Studio 2017 单独启动MSDN帮助(Microsoft Help Viewer)的方法" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(8) "DonetRen" ["tagsname"]=> string(55) "Visual Studio 2017|MSDN帮助|C#程序|.NET|Help Viewer" ["tagsid"]=> string(23) "[401,402,403,"300",404]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400964" ["_id"]=> string(3) "428" } [1]=> array(10) { ["id"]=> string(3) "427" ["text"]=> string(42) "npm -v;报错 cannot find module "wrapp"" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "zzty" ["tagsname"]=> string(50) "node.js|npm|cannot find module "wrapp“|node" ["tagsid"]=> string(19) "[398,"239",399,400]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400760" ["_id"]=> string(3) "427" } [2]=> array(10) { ["id"]=> string(3) "426" ["text"]=> string(54) "说说css中pt、px、em、rem都扮演了什么角色" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(12) "zhengqiaoyin" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400640" ["_id"]=> string(3) "426" } [3]=> array(10) { ["id"]=> string(3) "425" ["text"]=> string(83) "深入学习JS执行--创建执行上下文(变量对象,作用域链,this)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "Ry-yuan" ["tagsname"]=> string(33) "Javascript|Javascript执行过程" ["tagsid"]=> string(13) "["169","191"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511399901" ["_id"]=> string(3) "425" } [4]=> array(10) { ["id"]=> string(3) "424" ["text"]=> string(30) "C# 排序技术研究与对比" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "vveiliang" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(8) ".Net Dev" ["catesid"]=> string(5) "[199]" ["createtime"]=> string(10) "1511399150" ["_id"]=> string(3) "424" } [5]=> array(10) { ["id"]=> string(3) "423" ["text"]=> string(72) "【算法】小白的算法笔记:快速排序算法的编码和优化" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "penghuwan" ["tagsname"]=> string(6) "算法" ["tagsid"]=> string(7) "["344"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511398109" ["_id"]=> string(3) "423" } [6]=> array(10) { ["id"]=> string(3) "422" ["text"]=> string(64) "JavaScript数据可视化编程学习(二)Flotr2,雷达图" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "chengxs" ["tagsname"]=> string(28) "数据可视化|前端学习" ["tagsid"]=> string(9) "[396,397]" ["catesname"]=> string(18) "前端基本知识" ["catesid"]=> string(5) "[198]" ["createtime"]=> string(10) "1511397800" ["_id"]=> string(3) "422" } [7]=> array(10) { ["id"]=> string(3) "421" ["text"]=> string(36) "C#表达式目录树(Expression)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "wwym" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(4) ".NET" ["catesid"]=> string(7) "["119"]" ["createtime"]=> string(10) "1511397474" ["_id"]=> string(3) "421" } [8]=> array(10) { ["id"]=> string(3) "420" ["text"]=> string(47) "数据结构 队列_队列实例:事件处理" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "idreamo" ["tagsname"]=> string(40) "C语言|数据结构|队列|事件处理" ["tagsid"]=> string(23) "["246","247","248",395]" ["catesname"]=> string(12) "数据结构" ["catesid"]=> string(7) "["133"]" ["createtime"]=> string(10) "1511397279" ["_id"]=> string(3) "420" } [9]=> array(10) { ["id"]=> string(3) "419" ["text"]=> string(47) "久等了,博客园官方Android客户端发布" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(3) "cmt" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511396549" ["_id"]=> string(3) "419" } } ["count"]=> int(200) } 222 自动化测试框架:测试编程框架 - ohmyjava - 爱码网
ohmyjava

自动化测试框架:测试编程框架

做任何事,要牢记你的用户是谁!设计一个框架,要知道你的用户的使用需求是什么,这样,框架设计才可能容易被接受,离成功也就越进一步了。

框架的用户是测试人员。测试人员的特点是:

  1. 熟悉或精通业务
  2. 了解程序元素,但不了解程序结构
  3. 实现细节更是难以洞察

因此,在设计初期,就考虑将控件的访问封装起来。对于测试人员来说,所有的控件都已经封装好了,他们只需要调用就可以了。

这一点,应该已经初步解决问题了。但是我们并没有满足这一点。

对于测试来讲,他们了解的是业务元素,而我们常规做法,是把控件封装成编程元素。这是不一样的。举个例子:

我们在界面编程的时候,命名一个按钮控件,叫btnOk,标题是“确定”。对于程序员来说,btnOk可能是自然的标识名称,而对于测试来说,“确定”反而是更自然的选择。

我们考虑,测试最后编程的代码,应该接近DSL(domain-specific language领域描述语言)。可能有这样的几种方式:

  • 设置文本(标题编辑框, "新的标题")
  • 标题编辑框.设置文本("新的标题")

由于我采用了VCL的控件封装策略,所以倾向于使用接口的访问方式(使用.的方式),向测试人员开放接口。在这点上和同事有过争论。不过后来,对测试人员做过简单调查,发现第二种方式还是可以接受的。

下面的考虑问题是,这些控件的访问代码,怎么让测试写了?最直接想到的方法,就是通过遍历窗体,通过访问每一个控件,逐个封装成代码,这样测试就不需要关心这段复杂代码的编写了。

比如:

TMyFormTestCase=class
private
  FEdit1: IEdit;
public
  
property Edit: IEdit read FEdit1;
  procedure DoTestCase; override;
end;

其中DoTestCase是真正完成业务功能的虚拟函数。通过覆盖,完成实际业务代码。属性Edit直接封装给测试人员调用。但是,注意到业务代码和我们自动生成的代码混合在一起,这有两个坏处:

  1. 自动生成的代码,需要和编写的代码进行混合处理。降低了自动化的可能性。
  2. 两者混合,其实是增加了测试学习的成本。相反,如果隔离,可以使得应用变得简单。

这两个缺点,让我们决定,为每一个窗体都建立一个基类,在这个基类中,完成所有控件的定义和访问。并将所有这些控件封装类,集中在一个单元中。每一个类,一个单元也想过,但是感觉太复杂了。也没必要。

这里面还有另外一个易用性问题。这和第一篇中讲到的组件架构有关。如果我们的测试业务代码,都是和主程序混在一起,那么对于测试人员,

  1. 他们必须在有主程序代码的前提下,才可以调试业务测试代码
  2. 程序代码,也会成为他们的负担

另外,从程序代码的封装角度来看,也有可能遭受破坏的可能。所以,决定将所有业务代码都封装到一个独立的Dll中。另外,为了降低Dll对程序代码的依赖,所有对控件的访问,都通过对应的接口(如IEdit,IForm,IButton)来访问,而这些接口的对象实例的创建,都可以留在程序代码中(这是为了方便扩展)。

整个框架过程中,还有几个重要的问题。第一个就是控件名称的命名问题。本来可能通过控件的属性来生成,但后来发现,不一定有中文信息,比如Edit控件啊,Grid控件啊。所以支持了字典表的方式来做翻译。首先将控件Name按照骆驼命名法分离,然后将那些缩写或者单词,到对应表中,查找中文解释,最后组合称为名称。

还有就是业务流程的Log问题。这个实现,后来采用的是AOP模式。具体的实现思路,后面会有专门介绍。

当然了,实际应用中,还可能有很多其他问题。这些都需要细细解决。总之一句话,由于充分考虑了用户的感受,所以这部分的框架,改了又改,现在才稍微满意了。 

分类:

技术点:

相关文章: