Fit: Framework for Integrated Test 优秀的软件需要协作和沟通,在开发过程中,客户如何才能知道他们的程序员如何正确处理了事情呢?而程序员又如何知道客户究竟想的是什么呢?测试人员如何才能知道什么是正确的而什么又是错误的?让这些小组能有效和精确地交流应该是团队创建伟大软件的一个目标。 FIT就是一个用于增强交流和协作的工具。FIT创建了一个在客户和程序员之间的反馈循环。FIT让客户和测试人员可以使用诸如Microsoft Office之类的工具来给出程序应当如何表现的例子——而无需成为直接编码的程序员。FIT自动针对实际的程序检测那些例子,这样就在业务世界和软件工程世界之间建立了一个简单而且有效的桥梁。 有了FIT,客户可以通过将他们的主题相关的专业知识和想象引入实际的工作中,给开发过程直接提供更多的指导。客户所获得的更多关于目前产品开发中正在发生的东西的可见性,能让他们随时控制项目避免偏离目标。 ==FIT如何工作== FIT通过读取由类似MicrosoftWord之类的工具生成的HTML文件中的表格来进行工作。每一个表格通过一个程序员写的“装置”来进行解释。装置将通过运行实际的程序来检测表格中的例子。 在这个例子中,团队要建立一个产品用于计算职工的薪水。团队已经一起创建了一个包含一些如何计算小时薪水例子的FIT文档。 表格包含了例子。第一行告诉了FIT如何读取表格。第二行给出了例子的头,剩下的行给出了例子。例如,在第一个表格中的例子说:“如果某人工作了40个工时同时没有休息时,那么就付给$20每小时的薪水,然后他的总薪水是$800。” (虽然这个例子只使用了一个简单的表格格式来展示计算的结果,其实还有很多不同的表格格式可以使用。) FIT自动针对软件检验表格中的例子。在我们这个例子中,对前两个测试案例,软件给出了正确的解,所以FIT把表格单元标示为绿色。在最后一个测试案例中,软件给出了错误的解,所以FIT把这个表格单元标记为红色。这个软件说职员的总薪酬是$1,040,而期望的值是$1,360。 为了能让FIT能使用这个表格工作,团队的程序员创建了一个“装置”来告诉FIT如何和他们的软件交流。情况类似下面: 程序员使用了一个ColumnFixture来将表格中的列映射到装置中的变量和方法上。前三列,提供了信息,对应于装置中的变量。最后一列,包含期望的值,对应于装置中的Pay()方法。要计算答案,程序员使用他们程序中的WeeklyTimesheet类。 ==总结== FIT给予了客户和程序员一个关于软件的精确交流的方法。客户所给的具体的例子让程序员能深刻理解将要构建的产品。程序员的对于装置的工作和软件可以让客户给出不同的例子进行试验来获取对于软件如何真正工作更深入的了解。这样通过一起工作,整个团队可以学会更多关于产品的内容并产生更好的结果。
原文:为什么Flickr不进行自动化测试? — Carlos Villela @ 8:00 pm 翻译:ShiningRay Sam Newman 惊讶于(中文版) Flickr没有使用很多自动化测试,因为“作为一个姿态鲜明和成功的应用,我只能假设自动化测试还存在一个更加成熟的途径”。 事实上,当看到的时候我也有点惊讶,不过我想我知道他们为什么不真正十分关心测试的原因,我的反应是他们不仅仅只是一群过时.COM时代的普通牛仔,在一边把代码仍在墙上一边看看堵住了什么——这些人常常被一般的敏捷人(agilist,还和拳击手pugilist押韵?)在会议和论文上批评他们没有测试自己的代码并被告知这样做更好。也许有某些原因可以不去麻烦测试,我在这里要尝试在这里解释他们,当然我明白这篇贴子可能有点过激。首先,让我们提出在一个新的项目阶段开始后,两种不同的场景,其中数字代表某种在给定的期间内的想象的成本单元: 场景 A B 开发 10 10 自动化测试 8 0 维护 2 10 假设其他条件均相同,同时代码是由合格的开发者——当然Flickr的家伙们肯定都是——很好地书写的,这样的表格看起来似乎可信:其中A使用了自动化测试来发现错误,节省了维护的时间,而B单独把时间花费在维护上,产生了同样的结果(至少在这个阶段)。 在A中,公司需要预付钱来建立可用的测试套件并运行,这样他们就不用对未来的维护多花费这笔钱。现在飞过来了叉子和火把,并且要置我于死地,但是这是一个糟糕的财政决定,除非写自动测试的成本比进行所有的维护的成本要低,但后者的成本可能会扩散。然而这个成本不低的风险,至少在我的经验里,看起来比大多数公司所愿意接受的要高的多,因此我们从多数——如果不是全部的——敏捷人那里听到关于这个方式的好的结果。 现在再把这小段话引用一下:我是一个自动化测试的爱好者因为我见过维护软件有多烦人 ,在几个月都不停做这事,消耗尽了我最后一点出现在我可怜精神中的愉快感。我则更偏好写全新的代码,即使代码没有在最终的产品环境中用到,就像测试代码一样,而不是经历另一个令人沮丧的一天不停地在调试器上一步步移动。 我确定Sam和大多数正在阅读本文的人都是同一条船上的。 而B,在我的理论中,就是Flickr所正在做的:较少的预期投入和随着时间流逝的更多的维护成本。 作为一个开始阶段(嗯,不管怎样,在他们被Yahoo收购之前),这很有意义:整个启动阶段就是让你可以去做更有风险的事情,同时某种程度上他们臆测自动地测试任何东西除了小部分重要的(冒烟测试?)并不如立刻把代码颁布出门,且快速,并强制听取用户的反馈并作出反应来得更加重要。这也许要求对对细节和承诺的关注保持一种疯狂的关注程度,这是很稀罕的,不过我要补充一点,这却是我所总结他们成功的原因的一个重要的部分。 正如Joel Spolsky所写的,大概三年前,针对一个类似的情况: 你需要某种经济模型来决定如何花费你有限的资源。你不可能通过说 “压力测试是一个没脑子的东西”或者“服务器也许还可以撑一下。”之类的话来作出可靠的理智的决定。这些都是感情用事的脑子的大便,而非分析。同时在长期的运行中,我们科学家将会获胜。 所以,我不确定谁是正确的,这里:我知道我所参与的大部分项目,在没有经过自动化测试和大量的测试覆盖率保持工作的情况下,本应该完全失败的(某些事实上就是)。但是再说,我从来没有进行过任何像Flickr这样的起始工作。
原文: Web 2.0 needs testing 作者:Sam Newman 翻译:ShiningRay @ Nirvana Studio 我带着很多怀疑,耐着性子看完了Cal Henderson的高度富有娱乐性的(而且推荐大家观看) 《构建Flickr作坊》, 从中听说自动化测试在他们的优先级列表中并不是特别地高 (有趣的旁白——Cal还认为面向对象编程是“神经错乱的”,所有的“健全”的代码则在“一超大函数”编程和OO之间的空间中存在)。 “测试Web应用”Cal说,“很困难”。其实这是一个普遍的误解。像任何其他应用的类型一样,只要你针对测试性设计了结构,测试是很容易的。然而,同时如果你采用了针对Web应用的测试而制作的测试工具(FIT 、 FITnesse, 以及Selenium都是很好的例子),那么即使那些没有带着测试的概念写的应用都没有借口说不利用他们进行开发。 但是现在放在我们面前的是Flickr这样一个姿态鲜明和成功的应用,我只能假设自动化测试还存在一个更加成熟的途径。这种对自动化测试的放任自由的方式是不是很普遍呢? 让我们看看这另一条道路。如果你没有自动化测试,你要么手工进行测试(这意味着更长的发布时间)要么干脆不测试。如果你要着眼于交付有质量的产品,这也许意味着你最终还是要做很多手工测试,而这些测试本来可以自动化地更快完成的,甚至只要你想,可以在 在每一次的代码提交中完成。 Web的架构产生了一个及早的快速发布、同时有一个经常发布的过程这样的想法。有了Web,你所有要关心的最终目标环境仅仅是你的服务器和客户端的浏览器。推出一个发行版真的可以像Flickr使用的“一点部署”(One-click Deployment)。有了一个成熟的测试框架,如果有必要的话,还可以办到一天之内多次直接给你的用户发布。 测试也许看起来不怎么好玩——但是一旦你明白了它意味着你可以更频繁地对你的用户发布更酷的功能,同时你可以在修复Bug上花费更少的时间,那么我们都可以去更加喜欢书写测试了。
原文:http://www.cincomsmalltalk.com/blog/blogView?showComments=true&entry=3295067130 by James Robertson 翻译:ShiningRay 我收到了一封邮件,看到了一个语言趋势的帖子的链接——这个帖子说大约在1995年,Smalltalk有一个很好的及正派的用途,但是在2005却被大家扔进了墙角。他问到: 那么为什么会导致这种情况呢?这个更大的故事的背后:对于Smalltalk的否定。我很感兴趣的是,为什么Smalltalk会从他的顶点——1995年OO语言的首选落到到它现在作为一个强大却没人用的平台的地步。这是否也是Java的未来呢?如果我能更好的理解Smalltalk的衰落(更不用提Objective C了),我可以更好地预期Java和其他语言的未来。 好吧,有两件事情影响了Smalltalk的使用——ParcPlace-Digitalk(也就是后来的ObjectShare)的行为和IBM的行为。先让我说一下PPD/OBJS。ParcPlace在1995年是一个快速成长的公司,但那在与Digitalk合并之前。之后这个公司就逐渐显现出一些组织上的劳损——管理小组充其量只是次好的(他们所做的与Digitalk合并的决定就很好的说明了这个问题)。 那次合并消耗了接下去的18个月和大量资金。公司不仅仅花了18个月尝试将VisualWorks和VSE合并,他还: 烧掉了很多钱却带来了几个没有效果的新东西 在尝试代码合并的过程中没有发布任何VW或者是VSE的新版本 由于没有去管理合并本身的事宜,结果导致了在工程和咨询小组之间致命的冲突。 不用说了,这种事情根本不能给客户群带来任何信息。这已经够坏了——然后财政问题的谣言就传开了,然后再1997年的动态年管理层发布了VSE的EOL(不包括任何迁移策略)的声明,VW/VSE的代码合并终止,以及一个新的Java策略。然后VSE的客户群就乱套了,已经对不存在的新发布很紧张,质问在新的Java的关注下,到底这个产品还能获得多少关注。 一切就这样进行直到新的管理团队进入并把公司名称更改为了ObjectShare(在原来管理层的疯狂的收购行为中一个被培养出来的公司)。事情一团糟,Java产品砰一下砸了出来,VW也爬了出来。新的管理层尝试扶持股票价格但是未能成功,情况又继续下滑(这一次又没有对顾客和前景带来任何信心)。最后,Cincom在1999年收购了Smalltalk业务(从此事情在我们这边开始有了转机)。 。下面,你要看一下Java的介绍和IBM的举动。在90年代中期的时候,IBM有一个很成功的Smalltalk产品,而且他们所有的开发环境都是基于它的——从VisualAge Smalltalk产生了一个C++、Cobol、同时最后,一个Java工具集。IBM的这些东西做的都很好,并且已经设法(由于PPD刚刚抛弃了他们)。然而,Java得到了很多绯闻,而且IBM对于构建VA架构基础花了很多他们自己的钱。提醒一下,这部分是我的推测,不过我认为发生了这些事情: IBM发现Java在快速流行起来。 他们认识到直接骑在Sun的Java上要比维护他们自己的一套基于VAST的开发工具要便宜得多 后一个观点最后因为Sun免费发布Java而成真。同时这两个举动都帮助了Java惊人地增长,我一点也不确定他们是否帮助了Sun一点点。这是另外一个故事了——在Smalltalk的世界中,IBM逐渐降低了他们对Smalltalk的投资(最后以他们把这个技术推给Instantiations而告终,今年),同时开始快速书写他们的Java故事。这也没有给Smalltalk用户或者是对Smalltalk的期望带来任何信息——特别是当IBM的销售人员们开始干劲十足地推进他们的Java生产线和驳倒Smalltalk的时候。 总之——ParcPlace(以及他后来的公司,PPD/OBJS)自己把自己玩完了,破坏了它原有的客户群,并让潜在的用户对Smalltalk的信息也降低了。同时,IBM开始从Smalltalk转移至Java上——也产生了同样的效果。在90年代中期其他的Smalltalk提供商还过于微小无法影响这种不断成长的观点病毒——Smalltalk正在消亡。 而现在不同了——从1999末开始,Cincom勤奋地研究Smalltalk,我们也拥有一个快速增长的、并且盈利的业务。同时还有很多其他的Smalltalk方言,包括现在要称为VA Smalltalk的。Smalltalk在当前并不是主流,但是它还是被很多期望一个有生产力的候选工具的公司所使用。
作者: Denys Duchier 翻译: Shining Ray @ Nirvana Studio 写本文旨在回应comp.lang.python新闻组中关于延续的讨论。 对于call/cc(call with current continuation)的情结和关于他的操作解释粗糙的细节内容,至今一直掩盖了延续的简洁和优雅。在本文中,我想用两个方式来纠正这个问题: 首先用一个简单且直观的方式展示延续的概念。 第二通过提供_可运行的_Python代码,来描述如何使用延续而不用call/cc来实现搜索引擎。 我将展示: 一个针对命题公式确定性检查工具。 一个基本的带回溯和裁剪的prolog引擎。 我希望这能帮助那些对于这个论题有些迷惑的人搞清这个问题。我还想指出上面讲到的两个程序是我在今天晚上花了几个小时写的,他们应该可以给你关于下面将要讲述的技术的能力的一些衡量尺度。 1. 简化延续 习惯上一般来说,一个函数返回一个值是这样的: def foo(x): return x+1 这隐含了它的值返回的地方。而延续的想法是通过添加一个延续参数来明确要返回的地方。函数不“返回”值,而是通过把值作为一个参数传递给延续“继续”处理值。在基于延续的程序中,以上函数foo变成了: def foo(x,c): c(x+1) 从这个角度看,函数从不使用返回“return”。取代的是它“继续”。正因为这个原因,延续有时候会被描述为“带参数的goto”。 上面描述的想法是。更精确地说,它是CPS(Continuation Passing Style,延续传送风格)的一个初步代码转换。基本的想法是给每个函数添加一个额外的“延续”参数,并进一步转化函数体以便不用返回他的值,而是把值传送给这个额外的延续参数。 在foo函数的例子中已经大体描述了这个概念。然而,更确切的,要注意CPS转换同时展开了所有的非lambda算子的嵌套表达式(换句话说,就是他显式地连接了所有子表达式的计算)。让我们看一个例子: def baz(x,y): return 2*x+y 在延续传送的观点中,甚至像*和+之类的基本操作符都要带一个额外的延续参数。我们通过以下定义进行模拟: def add(x,y,c): c(x+y) def mul(x,y,c): c(x*y) 现在,CPS可以把上面的baz函数转换成: def baz(x,y,c): mul(2,x,lambda v,y=y,c=c: add(v,y,c)) 换句话说,2*x的计算现在使用了一个延续来接收结果v并使用它来计算 v+y并最终把这个结果传给总的延续c。 [...]
“动态语言”现在是一个很时髦的术语,常用来表示那些编程语言十分地具有弹性而且很合适“敏捷”开发环境。在这种趋势背后有一些很有趣和很强大的语言,Io就是其中一个十分重要的语言。 Io最早发布在2002年,它混合了Lua、Lisp、Smalltalk和其他一些语言的某些方面的一个小语言。而起初的大想法是要把Io作为一个完整的可视化编程语言的基础,就像Self一样。 概览 Io属于“解释型”语言家族(像Perl、Python等等),这种语言的代码并不是通过编译而至直接解释并运行的。和很多“解释型”语言一样,Io也是高度动态的:一个程序可以迅速地生成并解释新的代码。同时,Io通过采用了Lisp的“代码即数据”的模型让这个特性向前迈进了一步,它可以让任何Io程序访问和处理它自身在内存中的对象模型。毫无疑问,这也让Io成为一个自省的语言。 并发编程在很多应用中都是一个新兴的被关注的方面,尤其是大多数用户界面和Web应用。Io从Act1中获得了灵感并使用了“参与者”(Actor)的概念。参与者介于线程和延续之间,它可以让你更容易编写你的并发应用,而原有的基于线程或者是进程编程的负担则不复存在。 简介清晰在Io的语法和他的对象模型中是显而易见的。语法可读性很好,而且看上去很好地结合了Lisp和Smalltalk。Io的对象模型是基于原型的。一个基于原型的对象模型不使用类来表示泛化和特化,取代的是创建特定的对象来用作“模型”或是“原型”并通过他们来创建新的对象。在这种编程范型中,对象是从原型中克隆出来的而不是从一个类实例化得来的。 对象模型是基于消息的,这表示方法调用甚至是变量访问都是通过发送动态的消息来完成的,而不是“硬布线”的(像C++和Java那样)。同时,Io对象响应消息的方式可以在运行时进行改变,这也是一个很典型的“动态”特性。 Io的足迹很小可以很方便地嵌入C或者是C++应用中。这方面它最有趣的特点之一是他的Objective-C的桥接器,这在集成上达到了一个令人惊奇的程度,在Io中使用你的Objective-C对象几乎不要写任何粘合代码。 Io分析 长处 Io的主要的优点来自他简洁的设计:它是一个可以很快学会的语言因为他有一个简单而且一致的语法、语义和API。由于Io的足迹小,所以它十分合适嵌入式编程。Io的另一个长处是它的速度。它能在性能上胜过很多其他解释型语言,这让他成为密集工作的一个理想选择。 Io的另一个长处——从一个嵌入的角度来看是很有意思的——是你可以重新定义几乎任何运行机制。Io语法中的任何东西都已经转化成了消息,而消息是可以在运行时重新定义的。从这方面来看,实际上你就可以改变里面任何东西来满足你的需求。 同时,Io对于并发编程的解决方案对于Web应用和GUI脚本编程也极具吸引力。 弱点 尽管Io有很多有趣和先进的特性,然而它还是十分年轻。到目前为止它还没有什么值得称赞的开发工具诸如文档生成器或者是代码检查器等等,而且在解释其上面仍然有一些问题。尽管如此,随着Io社群的不断壮大,更多的代码被制作共享,这个“青少年问题”会最终消失。 范例程序 BaseObject := Object clone do( demo := method(“Inheritance Demo”)) Parser := BaseObject clone do( parse := method(line, words := line split(” “) words foreach(word, writeln(word)) words count )) filename := args at(0) if (args count < 1) then ( [...]
作者:Chris翻译:ShiningRay @ Nirvana Studio 0. 前言 在Trails的首页上有一段Trails的指导视频,它比本文说得更为详细。你可以看看它,另外根据Firebird设置一节中的内容,设置一下和Firebird相关的东西。 1. 什么是Trails? Trails是一个领域驱动开发框架,它使用了Hibernate、Spring和Tapestry。其中,Hibernate 被用作数据访问层,Tapestry用来给用户显示数据。而Spring 则是把Hibernate和Tapestry连接在一起。 Trails自带了几乎所以必需的jar文件——你只需要安装一下Firebird的数据库驱动,它可以在 http://firebirdsql.sf.net上下载。 1.1 Hibernate Hibernate是一个O/RM工具。O/RM的意思是:对象关系映射。O/RM可以让你把 java 对象映射到后台数据库中。Hibernate使用了XDoclet来指明映射信息所需的信息,以便在数据库中存储复杂的对象。而XDoclet使用了javadoc注释来告诉Hibernate如何映射对象。例如: [code lang="java"]/** * @hibernate.class table="PERSON" */ public class Person { } [/code] 这段代码会告诉Hibernate要将一个指定的对象(在这里是Person)映射到PERSON表。 Hibernate 的主页是:www.hibernate.org. 1.2 Tapestry Tapestry 是(简而言之)一个Web框架。更确切地说,Taspetry是一个基于组件的Web框架,它将表示和逻辑清晰地分离开来了。 在Tapestry中,一个页面和一个.html文件相关,这个文件负责这个页面的外观,和一个Java类,它负责对.html文件提供数据,还有一个. page或者是一个.jwc文件(这由你是要作为一个真正的页面还是一个单独的组件),这两个负责把前两个层次连接起来。 组件是通过ognl语言来访问的,形式如: <a href=”#” jwcid=”@PageLink” page=”myPage”>Goto MyPage</a> jwcid 指明了使用的组件——这里是一个PageLink,它是一个HTML表现中的<a></a>标签的一个组件。page属性指明了你要链接的页面的名称。 Tapestry 的主页在jakarta.apache.org/tapestry 2. 安装Trails。 首先从trails.dev.java.net下载Trails. 当前的版本是0.5.1。先把下载的文件解压缩(在https://trails.dev.java.net上有一个很棒的演示,教你如何利用Trails来写应用程序)。 解压缩trails,并进入新建的文件夹。更改build.properties文件以匹配你的tomcat路径, [...]