分类: tech

  • 界面自动测试工具UI auto test tool

    与unit test不同,我们项目特点决定了,一个可以录制回放键盘鼠标动作的自动化界面测试工具更为有用。基于这种想法,我们组里某个新人的training项目就是完成这个小工具。

    C#可以使用这个工程打底 http://www.codeproject.com/Articles/28064/Global-Mouse-and-Keyboard-Library 加入一些定制代码,就可以录制键盘和鼠标了,我还要求加入定时抓屏,重复回放的功能,在我们最近的项目开发中非常有用,比如测试某个动作300次,看内存消耗,不用这个工具就崩溃了。

    Python也可以达到类似效果,比如这个项目autopy https://github.com/msanders/autopy/ 或者是Pywinauto http://code.google.com/p/pywinauto/  也可以通过PyWin32直接访问windows api达到效果。还有一种办法就是 http://sikuli.org/ 这个sikuli的问题是录制起来稍微麻烦了些,不是那么直接。

  • 大连开发组开发流程及注意事项说明

    1,开发过程中注意要遵守以下流程:

    需求分析(邮件或者文档);设计(设计文档,小组设计评审,任务分派,截止时间确认);编码(daily report, daily check in, daily code review);收尾阶段小组代码评审;需求验证;测试完成(测试计划及结果);签收;项目总结。

    2,如果感觉任务比较复杂,问题比较棘手,自己研究了一会没有很好的解决方案。请马上联系我或者咨询组里其他同事;如果组内同事也解决不了,再求助国外同事。先发邮件说明问题,紧急的任务马上搭建电话会议保证及时沟通。

    3,尽量避免同时做三个及三个以上的任务。确保自己有足够的时间完成任务。

    4,项目流程方面,如果觉得需要有例外,比如不写什么文档,不做什么评审,请事先与我讨论。

    5,在开始阶段对最后整体实现效果有大致理解,可以预估技术难点所在,并且实现进行研究和求助(这一点我们做得很不好)。对于项目可能有的需求变化有一定的预估和计划。

    6,细致,仔细,认真;多思考,多学习,多沟通。

    7,允许犯错,但是要确保同样错误不要再次出现,从问题中吸取经验教训。

    8,及时回复邮件。到办公室后第一时间检查邮件和calendar当天会议安排。对于重要邮件,应该记录在本上作为TODO

    9,离开公司前,检查当天TODO任务,是否有邮件没有回复,是否有重要任务没有完成。

    10,对我或者任务负责人的具体分派有疑问,可以讨论提出。如果已经拍板决定,就必须遵守决定,而不是按照自己想法我行我素。

    11,随身带一个笔记本,随时记录问题,心得体会,TODO,解决方案等等。

    12,每天的工作都应该有结果产出。学习应该有文档总结汇报,项目应该有流程设计文档/代码/测试文档,项目进度有每日进度报告。

     

    避免以下情况发生:

    1)  将就,马马虎虎,不求完美。

    2)  需求不清楚,也不与onshore沟通澄清。

    3)  任务不清楚,就开始动手编码;时间管理不好,没有缓冲,截止时间定于最后一秒。

    4)  没有设计讨论,自己觉得没有问题,直接开发。

    5)  有问题,不做优先级分派,先开发了再说。

    6)  代码一直没有check in,累积三五天再提交;需要check in的时候,一次加入大量的代码修改。代码check in没有评审,也不做说明。

    7)  代码不注释,命名不规范,不关注静态分析/debug exception。

    8)  “我觉得没问题,但是没有check”

    9)  代码写完了,就认为是项目完成了;也只写了代码,没有设计没有文档没有测试

    10) 只有最后阶段才有问题,在开始时不考虑如何技术实现或者觉得不会有问题,不做风险评估

    11) “代码为什么好用?不知道;出问题的root cause?不知道”

    12) “这段代码干什么用?别人就这么写,我不知道,没研究过”

    13) “这个问题好像是,也许是,我猜”

    14) (讨论决定使用方案A,开发一段时间后)“我觉得这样更好,所以我就用自己这个方案,方案A有问题,如何如何”

  • Lua的好和不同 part1

    翻译自 http://notebook.kulchenko.com/programming/lua-good-different-bad-and-ugly-parts

    我已经用Lua编程了9个月,应该是时候停下来想想这段经历了。过去几年用过不少编程语言, perl, C, Javascript, MATLAB还有其他的,从TurboPascal到F#。Lua和这些语言做个比较是件很有意思的事情。我已经用Lua完成了一些不同类型的项目:一个远程调试器MobDebug https://github.com/pkulchenko/MobDebug ,扩展一个Lua IDE https://github.com/pkulchenko/ZeroBraneStudio ,一个mobile应用https://github.com/pkulchenko/LuaRemote ,还有几个教育性质的脚本https://github.com/pkulchenko/ZeroBraneEduPack ,以及一个在浏览器canvas上使用Lua画图的demo http://notebook.kulchenko.com/programming/drawing-on-browser-canvas-with-lua 。

    我已经看到有比较Lua好坏的文章,比如(http://lua-users.org/lists/lua-l/2007-11/msg00248.html http://blog.datamules.com/blog/2012/01/30/why-lua/ http://lua-users.org/lists/lua-l/2012-01/msg00731.html http://stackoverflow.com/questions/564665/advantages-of-lua http://gergely.imreh.net/blog/2011/07/language-of-the-month-lua-part-2/ http://stackoverflow.com/questions/1022560/subtle-differences-between-javascript-and-lua http://www.luafaq.org/gotchas.html ),但是我发现一些影响或者比较关注的特性没有在列表上。所以我写一个自己的列表。这篇文章不够广泛,Lua语言的某些方面也没有覆盖到(比如math和string库),但是它已经包含了我用Lua语言的要点。

    Good

    小:20000行源代码https://github.com/LuaDist/lua 在Linux下编译后就是182K左右的可执行解释器。

    可适性:任何有ANSI C编译器的平台都可以编译。可以看到在http://www.eluaproject.net/ 以及Lego Minstorms NXT上 http://hempeldesigngroup.com/lego/pblua/ ,mobile平台https://github.com/divineprog/mobilelua 游戏主机 http://blog.brokenfunction.com/2011/11/how-to-make-a-massively-cross-platform-game/ 到浏览器中(翻译到Javascript)http://notebook.kulchenko.com/programming/drawing-on-browser-canvas-with-lua

    容易嵌入和扩展:http://www.lua.org/pil/24.html 提供了简洁易用的接口与C/C++进行互通。

    快:http://shootout.alioth.debian.org/ 相比其他编程语言性能非常不错,还有一个JIT编译器 http://luajit.org/performance.html 对某些任务下的性能有显著提升;如果这还不能满足某些人,可以使用C语言实现性能瓶颈部分,与C的集成很容易,还可以继续从其它有用的部分收益。

    文档不错:语言手册 http://www.lua.org/manual/ ,书籍http://lua.org/pil/ 还有wiki http://lua-users.org/wiki/ 另外有http://www.capgo.com/Resources/SoftwareDev/LuaShortRef51.pdf

    友好热心的社区 http://lua-users.org/ ,通过文档,wiki还有邮件列表http://www.lua.org/lua-l.html 和SO http://stackoverflow.com/questions/tagged/lua ,任何问题都可以解决。

    干净和简单的参数适合初学者,对于非程序员也容易理解。Lua从Pascal的后继Modula http://en.wikipedia.org/wiki/Modula 借鉴了大部分控制语法,我仍然记得Philippe Kahn快速优雅的Turbo Pascal IDE http://en.wikipedia.org/wiki/Turbo_Pascal

    集成解释器:只要命令行运行lua就行了

    协程http://www.lua.org/pil/9.html 的内在支持,到实现iterators http://www.lua.org/pil/9.3.html 和非抢占性多线程 http://www.lua.org/pil/9.4.html

    增量垃圾收集器http://www.lua.org/manual/5.1/manual.html#2.10 有很低的延迟,没有额外的内存开销,很少的实现复杂度,支持弱表http://www.lua.org/pil/17.html

    强力的混杂式tables http://www.lua.org/pil/2.5.html 可以存储任意类型(除了nil),可以通过任何值索引(除了nil),比如 [1, 2, 5, foo = “bar”, [func] = “something”, [“some spaces”] = value()]

    词法定界(Lexical scoping)

    函数式编程http://www.lua.org/pil/6.html 通过一级(first class function)函数http://www.lua.org/pil/5.html 和闭包实现http://www.lua.org/pil/6.1.html

    尾调用http://www.lua.org/pil/6.3.html : return functioncall()

    递归函数不需要事先声明 local function foo() … foo() … end ,注意这样是不行的local foo = function() … foo() … end

    函数可以返回多值。调用者可以要求任意数量的返回值,如果比实际返回数量少,剩余的被抛弃,如果要求的多于实际返回的,用nil填充。

    函数允许可变函数参数个数 function foo(…) local args = {…}; bar(param, …) end

    Tables可以解开成一个参数列表,通过unpack(或者Lua5.2的table.unpack)实现 print(unpack({1, 2, 3})) prints 1 2 3

    可以操作环境变量(Lua5.1中的getfenv和setfenv,Lua5.2中的_ENV),这允许Lua建立沙箱机制 http://lua-users.org/wiki/SandBoxes

    变量列表赋值local a, b, c = 1, 2, x, y = y, x, or a, b = foo()

    使用[[…]] 做多行字符串,可以用[[…[=[…]=]…]]嵌套,注释如–[[…]]

    分号作为语句分隔符是可选的

    通过metatables重载 http://www.lua.org/manual/5.1/manual.html#2.8

    元编程http://metalua.luaforge.net/ 可以做到获取、修改一个抽象语法树来建立新的DSL

    for语句有两种方式,泛型式和数字式,数字型不光支持整数

    函数调用(function call)语法糖 f’string’, f”string” f[[string]]和 f{table},以及方法调用(method call) obj:m()

    简单但是很有用的调试库 http://www.lua.org/pil/23.html

     

    不同之处

    表和字符串索引从1开始,而不是0

    在table中给一个元素赋值nil,就把这个元素删除了。

    没有整型这个数据类型;number表现为浮点数

    没有类,面向对象机制通过表和函数实现;继承通过元表机制实现 http://www.lua.org/manual/5.1/manual.html#2.8

    方法调用通过object:method(args)实现,这和object.method(object, args)一样,but with object evaluated only once

    nil和false是唯二的假值,0,0.0,”0″和其他的都是真。

    ~=不等符号

    not, or, and关键字用做逻辑运算符

    赋值是语句http://www.lua.org/pil/4.1.html,这意味着不能a=b=1或者 if (a=1) then … end

    没有 a+=1 a++或者近似的方式

    没有continue语句,尽管有一个解释 http://www.luafaq.org/#T1.26 和一些变体,像是repeat break until true在循环内部打断,或者Lua5.2中的goto语句

    没有switch语句

    括号在某些情况下有必要,for example, a = {}; a.field works, but {}.field doesn’t; the latter needs to be specified as ({}).field.

    循环中控制变量默认本地化,loop外边就用不了了

    数值型for中的限制和步进值是被缓存的http://www.lua.org/pil/4.3.4.html  in for i = init(), limit(), step() do ... end all three functions initlimit, andstep are called once before the loop is executed.

    条件语句和其他控制结构不需要括号

    字符串和数字自动转换,但是在等于和不等于比较中不能自动转换。 0 == "0" is false{} ~= 1 is true . foo[“0”]和foo[0]在表中指向不同的值; other relational operators generate errors on comparing values of different types.

    逗号和分号可以用在table语法中;都可以放在最后的大括号前面作为可选操作符a = {a = 1, b = 2, }。

    一些组件额外提供;一些人认为这是“没有电池”。这是紧凑和可适内核的结果,也可以通过Luarocks和Penlight解决 http://luarocks.org/ http://stevedonovan.github.com/Penlight/

  • 如何称量代码复杂度(C++/C#)

    微博上的蛙蛙王子提出三个设想,发送给微博上一些知名程序员,惊悚的是,这三个问题我以前也考虑过还动手做过。这是巧合呢?还是巧合涅?

    蛙蛙王子的问题是:是否有个工具可以检测出函数的长度?检测出函数中嵌套的层次?是否可以检测出重复代码?

    基于我在罗克韦尔时写的一个Lua脚本经验来看,第一第二个问题非常容易。第三个问题稍有麻烦,有工具或者开源项目能做到,但是效果一般。

    回到标题上的问题,称量代码复杂度,可以通过实现某个工具检测长度或者嵌套层次来完成,还有另外更简单的办法。

    通常情况下,复杂代码所在文件大小也会比其他文件大出不少,所以不用编写什么工具,只要逐个察看项目中个头比较大的文件,就可以找到代码味道不好的地方了。

    另外一个办法是通过版本控制工具,什么样的文件需要重构?基本上修改check in 次数多的文件,你要考虑重构了,即使代码味道不错,也肯定是责任过重,这个办法也很简单,把history导出统计一下就可以了。

    如果通过判断函数长度和嵌套层次,建议大家可以这样实现,我考虑过C++的实现,算是比较完整,不需要什么编译原理知识。

    函数长度和嵌套层次可以这样判断。前提1,我们可以确定C++中的{}成对出现;前提2,class可以通过关键字定位,而struct可以假定其中没有函数体,不需要判断;前提3,函数中的{}也一定是成对出现。至于其他的复杂问题,我觉得没必要考虑太多,除非你想做一个商用级别的软件,否则一个Python脚本就能搞定。

    基于这些前提我们可以这样实现,先清理注释部分,C++注释分成// /*,另外对于/*要考虑单行和多行,基本上就是按行处理就行了。之所以这样,是为了防止注释部分包含{}或者特定关键字。

    如果能找到class,判断类名,然后查找{。对于{}匹配,可以定义一个树形结构,函数或者类作为根,发现一个{,加入一层嵌套,发现一个},减去一层嵌套。如果嵌套层次为零(不在class定义体中),或者为一(在class定义体中,假定class的{}级别为0),那就是函数,稍微处理一下(),就能拿到参数,然后前面就是函数名字了。

    这样按照文件处理逐个处理完,就能判断出那些函数,函数体多长,嵌套层次如何了。

    针对C#,也可以这样处理,但是我猜测如果用Roslyn有更好的办法,可是没找到例子。

    ————-

    另外一个问题是重复代码。有一些链接,比如 http://en.wikipedia.org/wiki/Duplicate_code http://pmd.sourceforge.net/cpd.html http://checkstyle.sourceforge.net/config_duplicates.html http://patterninsight.com/products/clone-detection/ http://stackoverflow.com/questions/546487/tools-to-identify-code-duplications

    但是我感觉最好用的办法,是通过peer code review来检查,因为这一块对于算法而言,应该是实现难度挺大的,而且结果也不理想,review的方式基本上可以杜绝类似问题。我们之所以不用review方式解决代码长度和嵌套层次,是因为的确有办法实现。

     

  • MFC在VisualC++中依然活的好好的

    http://blogs.msdn.com/b/vcblog/archive/2012/03/05/10278210.aspx

    Pat在这篇文章中介绍了VS11里面的Visual C++部分对MFC的修改,包括bug fix, 静态链接文件大小。

    最值得一提的是MFC对Metro Style的支持。

    总有人不做研究便大放厥词:MFC老旧了,已经过时了,已经死了,不要学了。结果,拿出来比的QT不醒醒了,设计优秀的Borland葛屁了,只有MFC依然好好的活着,照现在的势头,这笔财富还能用上五年十年的依然没有问题。

    所以说,设计好不好,优雅不优雅,这都不是问题,只要能活的比较持久,那就是成功。我一直建议Windows平台的C++程序员学MFC,对于争议,哥是一笑而过啊,不争论用事实说话。