??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲国产精品成人综合久久久 ,亚洲日韩精品国产一区二区三区,亚洲国产AV无码一区二区三区 http://www.tkk7.com/iamtin/archive/2007/09/17/java_web_architecture_and_performance_turnning.htmlTinTinMon, 17 Sep 2007 14:48:00 GMThttp://www.tkk7.com/iamtin/archive/2007/09/17/java_web_architecture_and_performance_turnning.htmlhttp://www.tkk7.com/iamtin/comments/146003.htmlhttp://www.tkk7.com/iamtin/archive/2007/09/17/java_web_architecture_and_performance_turnning.html#Feedback4http://www.tkk7.com/iamtin/comments/commentRss/146003.htmlhttp://www.tkk7.com/iamtin/services/trackbacks/146003.html 本文已经发表于InfoQ中文站,Q?a >大型Java Web目的架构和部v问题Q?br />

一位ID是jackson1225的网友在javaeye询问?a title="一个大型Webpȝ的架构和部v选型问题" target="_blank">一个大型Webpȝ的架构和部v选型问题Q希望能提高现有的基于Java的Web应用的服务能力。由于架构模式和部v调优一直是JavaC֌的热门话题,q个问题引发了很多热心网友的讨论Q其中一些意见对其它大型Web目也有很好的指导意义。在讨论之初jackson1225q样描述了当前的应用的架构和部vҎQ?/p>

目前pȝ架构如下:

  1. web层采用struts+tomcat实现Q整个系l采?0多台web服务器,其负载均衡采用硬件F5来实玎ͼ
  2. 中间层采用无状态会话Bean+DAO+helpercL实现Q共3台weblogic服务器,部v有多个EJBQ其负蝲均衡也采用F5来实玎ͼ
  3. 数据库层的操作是自己写的通用cd现的Q两台ORACLE数据库服务器Q分别存攄户信息和业务数据Q一台SQL SERVER数据库,是第三方的业务数据信息;

web层调用EJBq程接口来访问中间g层。web层首先通过一个XML配置文g中配|的EJB接口信息来调用相应的EJBq程接口Q?/p>

该系l中一ơ操作涉及到两个ORACLE库以及一个SQL SERVER库的讉K和操作,x三个数据库连接,在一个事务中完成?/p>

q样的架构其实很多公叔R在用,因ؓStruts和Tomcat分别是最行的Java Web MVC框架和Servlet容器Q而F5公司的负载均衡是横向扩展常见的解x案(例如配置session stickyҎQ。由于这个系l中有跨数据源的事务Q所以用Weblogic Server EJB容器和支持两阶段提交的数据库驱动可以保证跨数据源的事物完整性(当然Q容器管理的分布式事务ƈ非是唯一和最优的解决ҎQ?/p>

但是随着Rod Johnson重量U的著作《J2EE Development without EJB》和其中的Spring框架的流行,轻量U框架和轻量U容器的概念已经深入人心。所以对于jackson1225提出的这个场景,大多数网友都提出了置疑,认ؓq个pȝ滥用了技术,完全是在费钱。网友们大都认ؓSLSBQ无状态会话BeanQ完全没有必要出现在q个场景中,认ؓSLSB通过q程接口讉K本地资源会有很大的性能开销Q这U观点也是Rod johnson在without EJB中批判EJB 2.x中的一大反模式?/p>

׃JavaEE是一个以模式见长的解x案,模式和架构在JavaEE中占有很重要的地位,所以很多业内专家也都警?#8220;反模式(Anti-patternsQ?#8221;的出现。对于上面所q的Ҏ是否是反模式Qjackson1225马上站出来申辩:

我们目是把EJB作ؓ一个FacadeQ只是提供给WEB层调用的q程接口Q而且只用了无状态会话BeanQ所以性能上还可以的?/p>

q个解释很快得到了一些网友的认可Q但是大家很快意识到架构的好坏决定于是否能够满用户的需求,davexinQ可能是jackson1225的同事)描述了这个系l的用户和ƈ发情况:

现在有用?000万,马上要和另一个公司的会员pȝ合ƈQ加h一共有9000万用戗数据量单表中有一亿条以上的数据。这是基本的情况Q其实我觉得现在的架构还是可以的Q现在支持的q发大概5000q发用户左右Q接下来会进行系l改造,目标支持1万个q发用户?/p>

具体的ƈ发量公布后又有网友置疑这个数据,认ؓq个pȝ的Servlet容器支持的ƈ发数太小Q怀疑是否配|不够优化。davexin又补充了该项目的服务器配|:

pȝ前端tomcat都是用的刀片,配置?G内存Qcpu大概?.0GQ每台机器也支?50-400个ƈ发,再多的话Q就会相应时间非常的常,过20U,失去了意?Q所以我们才得出q样的结论的?/p>

一位ID是cauherk的网友提Z比较中肯的意见,他没有从Web容器单纯的ƈ发支持能力上提出改进ҎQ而是提出了对于类似的应用?a title="一些通用的改q提C? target="_blank">一些通用的改q提C?/a>Q这里摘要一下:

  1. 数据库压力问?

    可以按照业务、区域等{特性对数据库进行配|,可以考虑分库、用rac、分区、分表等{策略,保数据库能正常的进行交易?/p>

  2. 事务问题

    要在两个数据库中操作Q那么必考虑到分布式事务。你应该仔细的设计你的系l,来避免用分布式事务Q以避免分布式事务带来更多的数据库压力和其它问题。推荐你采用延迟提交的策?q不保证数据的完?Q来避免分布式事务的问题Q毕竟commitp|的几率很低?/p>

  3. web的优?

    静态、图片独立用不同的服务器,对于常态的静态文Ӟ采用E-TAG或者客L~存Q?google很多是q样q的。对于热点的功能Q考虑使用完全装蝲到内存,保证l对的响应速度Q对于需要频J访问的热点数据Q采用集中缓?多个可以采用负蝲均衡)Q减L据库的压力?/p>

    对于几乎除二q制文gQ都应该在L4上配|基于硬件的压羃ҎQ减网l的量。提高用户用的感知?/p>

  4. |络问题

    可以考虑采用镜像、多路网l接入、基于DNS的负载均衡。如果有_的投资,可以采用CDN(内容分发|?Q减M的服务器压力?/p>

cauherk的这个分析比较到位,其中ETags的方案是最q的一个热点,InfoQ?#8220;使用ETags减少Web应用带宽和负?/a>”里面对这U方案有很详l的介绍。一般以数据库ؓ中心的Web应用的性能瓉都在数据库上Q所以cauherk把数据库和事务问题放C前两位来讨论。但是davexin解释在所讨论的这个项目中数据库ƈ非瓶颈:

我们的压力不在数据库层,在web层和F5?当高峰的时?QF5也被Ҏ了,是每秒点击过30万,web动态部分根本承受不了。根据我们程序记录,20台web最多承?000个ƈ发,如果再多Qtomcat׃响应了。就像死了一栗?/p>

q个回复让接下来的讨论都集中于Web容器的性能优化Q但?a title="JavaEye站长robbin发表了自q意见" target="_blank">JavaEye站长robbin发表了自q意见Q将话题引回了这个项目的架构本nQ?/p>

performance tuning最重要的就是定位瓶颈在哪里Q以及瓶颈是怎么产生的?/strong>

我的推测是瓶颈还是出在EJBq程Ҏ调用上!

tomcat上面的java应用要通过EJBq程Ҏ调用Q来讉Kweblogic上面的无状态SessionBeanQ这Lq程Ҏ调用一般都?00ms~500msU别Q或者更多。而如果没有远E方法调用,即大量采用spring的动态反,一ơ完整的webh处理在本地JVM内部的完成时间一般也不过20ms而已。一ơwebh需要过长的执行旉Q就会导致servletU程被占用更多的旉Q从而无法及时响应更多的后箋h?/p>

如果q个推测是成立的话,那么我的是既然你没有用到分布式事务Q那么就q脆LEJB。weblogic也可以全部撤掉,业务层用spring取代EJBQ不要搞分布式架构,在每个tomcat实例上面部v一个完整的分层l构?/p>

另外在高q发情况下,apache处理静态资源也很耗内存和CPUQ可以考虑用轻量web server如lighttpd/litespeed/nginx取代之?/p>

robbin的推断得C|友们的支持Qdavexin也认同robbin的看法,但是他解释说公司认ؓ攑ּSLSB存在风险Q所以公司們֐于通过Tomcat替换为Weblogic Server 10来提升系l的用户支撑能力?a title="robbin则马上批评了q种做法" target="_blank">robbin则马上批评了q种做法Q?/p>

坦白说我q从来没有听说过大规模互联网应用使用EJB的先例。ؓ什么大规模互联|应用不能用EJBQ其实就是因为EJB性能太差Q用了EJB几乎必然出现性能障碍?/p>

web容器的性能说到底无非就是ServletU程调度能力而已QTomcat不像WebLogic那样附加n多管理功能,跑得快很正常。对比测试一下WebLogic的数据库q接池和C3P0q接池的性能也会发现cM的结论,C3P0可要比WebLogic的连接池快好几倍了。这不是说WebLogic性能不好Q只不过weblogic要实现更多的功能Q所以在单一的速度斚w׃牺牲很多东西?/p>

以我的经验来判断Q用tomcat5.5以上的版本,配置apr支持Q进行必要的tuningQ用BEA JRockit JVM的话Q在你们目前的刀片上面,支撑500个ƈ发完全是可以做到的。结合你们目?0个刀片的gQ那么达?万ƈ发是没问题的。当然这样做的前提是必须扔掉EJBQƈ|web层和业务层在同一个JVM内部?/p>

接下来robbinq针对davexin对话题中的应用分别在tomcat和weblogic上的试数据q行了分析:

引用Q?

2?台weblogic10 ExpressQ相当于1台tomcatQ用于发布jsp应用Q加1台weblogic10Q发布ejb应用Q,能支?000个ƈ发用?.....
......
4?台tomcat4.1?台weblogic8Q只能支?50个ƈ发用Ptomcatpl超Ӟ说明此种l构瓉在tomcat?

q说明瓶颈还不在EJBq程调用上,但是问题已经逐渐清楚了。ؓ什么weblogic充当web容器发vq程EJB调用的时候可以支?000个ƈ发,但是tomcat只能?50个?只有两个可能的原因:

  1. 你的tomcat没有配置好,严重影响了性能表现
  2. tomcat和weblogic之间的接口出了问?

 

接着springside目发v者江南白衣也提出了一个M的优化指|

1.基础配置优化

tomcat 6Q?tomcat参数调优?
JRockit JVM? JVM参数调优Q?br /> Apache+Squid 处理静态内容?

2.业务层优?/p>

部分功能本地化,而不调remote session bean?
异步提交操作,JMSQ?br /> cache热点数据Q?

3.展示层优?/p>

动态页面发布ؓ静态页面?
Cache部分动态页面内容?

davexin在调整了Tomcat配置后应验了robbin对tomcat配置问题的质疑,davexinq样描述l过配置优化以后的测试结果:

l过试Qƈ发h数是可以辑ֈ像robbin所说的一P能够?00人左叻I如果压到q发700人,有15%左右的失败,虽然在调整上面参C后,q发人数上去了,但是在同L旉内所完成的事务数量下降了10%左右Qƈ且响应时间gq了1U左叻I但从整体上来_牺牲一点事务吞吐量和响应时_q发人数能够提高500Q觉得还是值得的?/p>

xq个话题有了一个比较好的结果。这个话题ƈ非完全针对一个具体的目才有意义Q更重要的是在分析和讨论问题的过E中|友们解决问题的思\Q尤其是cauherk、robbin、江南白衣等几位|友提出的意见可以让q大Java Web目开发者了解到中、大型项目所需要考虑的架构和部v所需要考虑的关键问题,也消除了很多人对轻量Servlet容器与EJB容器性能的一些误解?/p>

在讨Zq有一些小插曲Q如davexin和江南白衣讨ZJRocket的实ӞRealtimeQ版本是否可以提升Servlet容器的相应能?/a>Q答案是不可以。还有ID为mfc42d的网友从Servlet容器的ƈ发支持能力引甛_?a title="Java的线E调度能力和NIO对Servelet容器的意? target="_blank">Java的线E调度能力和NIO对Servelet容器的意?/a>Q他推荐了自q两篇不错的blog“java的线E实?/a>”?#8220;javaq程使用的最大内存的数?/a>”Qblog文章里面从JVM源码U别分析了Java的线E支持能力,面JVM性能调优问题的网友可以认真阅M下?/p>

Tin 2007-09-17 22:48 发表评论
]]>
与时p的轻量Web服务?/title><link>http://www.tkk7.com/iamtin/archive/2007/08/02/light-web-servers.html</link><dc:creator>Tin</dc:creator><author>Tin</author><pubDate>Thu, 02 Aug 2007 02:10:00 GMT</pubDate><guid>http://www.tkk7.com/iamtin/archive/2007/08/02/light-web-servers.html</guid><wfw:comment>http://www.tkk7.com/iamtin/comments/133926.html</wfw:comment><comments>http://www.tkk7.com/iamtin/archive/2007/08/02/light-web-servers.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/iamtin/comments/commentRss/133926.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/iamtin/services/trackbacks/133926.html</trackback:ping><description><![CDATA[本文已经发表于InfoQ中文站点Qhttp://www.infoq.com/cn/news/2007/07/light-web-serversQ?br><br> <p>IBM developerWorks|站上最q发布了一则Cameron Laird?a >关于轻量UWeb服务器的文章</a>Q? 里面列D了很多的d的Web服务器实现和它们的特点,Cameronq从自己的经验出发ȝ了评价Web服务器的一些指标。这文章目的在于扩展我们在 Web应用部v时的思\Q让我们重新思考Web应用的架构和部vҎ。众多的轻量UWeb服务器其实见证了动态脚本语a实现Web应用的火爆,l实? Web应用提供了更多解x案?/p> <p>轻量Web服务器这个概念关?#8220;dy?#8221;Q这意味着单、易于安装、流U化、要求低和健壮。这U?#8220;dy”主要是相对于目前市场占有率占优的 Apache和IIS而言的,轻量Web服务器应该更更单,q且它们臛_要有一些性能Q特性超q这两个产品Q这样它们才可能分得市场份额Q? Cameronq样Ҏ?#8220;轻量”相比“重量”?a >一些优?/a>Q?/p> <blockquote style="background: #eeeeee none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; font-style: italic;">轻量UWeb服务器可以适用于市场领头品和其他“重量U?#8221;服务器无法胜ȝ情况。例如,整个服务器可以打包在一个文件中。这? 味着开发h员可以方便地携带生环境所需的所有工兗即使在生服务器上q行的是 ApacheQ也仍然可以在宾馆的戉K里,借助只需数秒钟就可以安装完毕的轻量Web服务器以试新想法。而且Q由于轻量Web服务器要求很低,因此 可以在那些无法负担IIS的主Z畅地运行?/blockquote> <p>我们x一下目前的Web服务器占有率情况QNetcraft在它2007q?月的<a >Web服务器调?/a>中的服务器占有率数据如下Q?/p> <table border="1" cellspacing="0"> <tbody> <tr> <th>开发?/th> <th>2007q??/th> <th>癑ֈ?/th> <th>2007q??/th> <th>癑ֈ?/th> <th>变更?/th> </tr> <tr align="right"> <td align="left">Apache</td> <td>65588298</td> <td>53.76</td> <td>66144734</td> <td>52.65</td> <td>-1.11</td> </tr> <tr align="right"> <td align="left">Microsoft</td> <td>38836030</td> <td>31.83</td> <td>41257913</td> <td>32.84</td> <td>1.01</td> </tr> <tr align="right"> <td align="left">Google</td> <td>4872765</td> <td>3.99</td> <td>5465538</td> <td>4.35</td> <td>0.36</td> </tr> <tr align="right"> <td align="left">Sun</td> <td>2273173</td> <td>1.86</td> <td>2245493</td> <td>1.79</td> <td>-0.07</td> </tr> <tr align="right"> <td align="left">lighttpd</td> <td>1470930</td> <td>1.21</td> <td>1471779</td> <td>1.17</td> <td>-0.04</td> </tr> <tr align="right"> <td align="left">Zeus</td> <td>480698</td> <td>0.39</td> <td>463449</td> <td>0.37</td> <td>-0.02</td> </tr> </tbody> </table> <p>其中Apache占有率最高,它是公认的稳定、性能优良、开发者活跃的开源Y件品。而Microsoft则受益于Windowsq_内置的PWS 和IIS的优势及.NETq_的市场占优率Q占有第二的位置。Sun则是׃历史问题Q它的iPlanet、SunONE和一q计的Netscape- Communications产品q能跻n?。后面的lighttpd则是轻量型Web容器的代表,已经过了老牌的商业Web服务器Zeus QServerWatchl出了一?a >lighttpd市场占有率上升的分析</a>Q,主要因ؓ一些AJAX目和Ruby on RailsQ以下简URoRQ的行对它的广泛部|v了推波助澜的作用?/p> <p>轻量Web服务器除了lighttpdq有mongrel也经常被提及Q主要因为它们是RoR目的两U主要部|方案。JavaEye的创始h<a >Robbin Fan</a>曄在它的blog中对比过RoR的这<a >两种部vҎ</a>Q?/p> <blockquote style="background: #eeeeee none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; font-style: italic;">QRoR目Q用fcgi方式q是http方式Q我个h觉得区别不大Q关键还是看应用的场合,一般而言Q推荐的搭配是lighttpdQfcgi 或者nginxQmongrelQ而Apache因ؓ性能差距Q而不被推荐?/blockquote> <p>lighttpd+fcgi是大量用脚本语a~写的网站的首选部|方案,Robbin Fan在同一文章中阐述了他选择lighttp部vJavaEye的理由:</p> <blockquote style="background: #eeeeee none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; font-style: italic;"> JavaEyeZ么用lighttpdQfcgi呢?原因如下Q? <p>1) lighttpd发展了好几年了,市场占有率也相当高,是一个经q实跉|验的serverQ它的文档也很全Q?/p> <p>2) JavaEye的Rubyq程和Web Server在一台机器上面跑Q通过unix socket使用fcgi协议通讯可以避免tcp的网l开销Q其通讯速度比用tcp socket使用http协议通讯要快一些?/p> </blockquote> <p>Robbin选择lighttpd的主要原因是性能好于Apache。ƈ且Apache目前的fastcgi模块有些bugQ而对于像RoRq样的项目fastcgi是一U很好的部v方式Q所以Apache因此失Mq块份额。最qInfoQ报道q的<a >RubyWorks</a>? 供的RoR工作栈中选择了Haproxy+mongrel的方式,q也是前面引用的Robbin所说的另外一U部|方案。mongrel本n可以? Rubyq程Q同时也是一个http服务器,它可以兼֊态和静态Web服务Q配合Haproxy做负载均衡就可以支持大ƈ发量的Web应用Q所以它来 流行了?/p> 可见轻量UWeb服务器由于性能Q特性上的一些优势,开始逐渐瓜分Apache、IIS所没有照顾到的一些新兴的市场分额。那么如何去评h一个Web服务器呢QCameronl出了如下的<a >一些重要指?/a>Q? <blockquote style="background: #eeeeee none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; font-style: italic;"> <li><span style="font-weight: bold;">性能Q?/span>对请求作出响应的速度有多快?</li> <li><span style="font-weight: bold;">可׾~性:</span>当很多用户同时访问它Ӟ服务器还能l可靠地q行吗?</li> <li><span style="font-weight: bold;">安全性:</span>服务器是否只执行它应该执行的操作。它在认证用户和加密传输斚w提供了怎样的支持?它的使用是否佉Kq的应用E序或主机变得更易受dQ?/li> <li><span style="font-weight: bold;">可靠性:</span>服务器的失效模式和故障发生率如何Q?/li> <li><span style="font-weight: bold;">标准遵从性:</span>服务器遵从相关的 RFC 吗?</li> <li><span style="font-weight: bold;">灉|性:</span>是否可以Ҏ务器q行调优Q以支持较重的请求负载、需要计的动态页面或者代价不菲的认证{等Q?/li> <li><span style="font-weight: bold;">q_需求:</span>该服务器可用于哪些^収ͼ它是否有特定的硬仉求?</li> <li><span style="font-weight: bold;">易管理性:</span>服务器是否易于设|和l护Q它是否与日志记录、审计、成本计等l织标准兼容Q?/li> </blockquote> 目前来多的轻型Web服务器开始在上面的一个或着多个斚w向Apache和IIS提出了挑战,因ؓ很难有一个Web服务器可以做到面面俱到。我们可以从Cameron提供的一份列表里面看C些选用轻量UWeb服务器的<a >成功案例</a>Q? <blockquote style="background: #eeeeee none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; font-style: italic;"> <li>YouTube依靠lighttpd快速交付归档的内容Q例如视频;</li> <li>cdServeq行 “German Woodworking Machinery and Tools” CDQ?/li> <li>LiteSpeed宣扬它在 twitter、www.funnyoride.com、www.airliners.com、WordPress.com? fanfiction.com、SlashGear、www.forumactif.com 和其他著名Web 站点上担ȝ角色Q?/li> <li>OpenSUSE、RubyOnRails、MarkaBoo和其他一些著名站点依赖于MongrelQ?/li> <li>demon.net、bluelight.com、mtv.com、The Drudge Report、garfield.com{站点则使用thttpdQ?/li> </blockquote> <p>上面的例子中有一些用RoR的网站的例子QCameron指出不仅是网站可以用常规以外的其他~程语言?#8220;不常?#8221;语言q可以被用来实现轻量 Web服务器,例如Erlang、Java、Lisp、Lua、Perl、Python和Tcl。用q些语言实现的轻量Web服务器不一定只是在性能Q? Ҏ上过Apache和IISQ它们可以提供例如容易嵌入、体U轻这LҎ来吸引开发者的使用。Cameronl出了?#8220;不常?#8221;语言~写轻量U? Web服务器的原因Q?/p> <blockquote style="background: #eeeeee none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; font-style: italic;"> <li>教学Q用轻量Web服务器来制定一个重要、但是ƈ不太大的目标。这是获得用某U语a的经验的好方法?/li> <li>虽然用C~写的轻量Web服务器大ؓ10-50KBQ更高的语a?00KB到数MB的运行时Q但整个 Web 服务器的源文件可能只占几千个字节。这UWeb服务器占用的I间很小Q因此比Apache更易于与技术伙伴共享?/li> <li>更高U的语言可以使实验更吸引?—?例如Q添加一个新的HTTP/1.1Ҏ可能只需几行源代码。这些轻量服务器是非常方便的实验材料?/li> <li>HTTP服务器添加到已有的、用高语言~写的应用程序中只需增加几行源代码?/li> <p>如前所qͼ不同的轻量Web服务器有着不同的优点,它们或多或少独立于编E语a。所有轻量Web服务器都比Apache更小、更易于配置。与 Apache相比Q有些轻量 Web 服务器更快,有些则快得多。有些则安全性、重负蝲下的从容性、可扩展性或者内存占有量。在M情况下,都可以以一U不适用?Apache 的方式彻底地理解q些服务器?/p> </blockquote> <p>q些理由从另外一个方面说明了轻量UWeb服务器的优势QCameronq提供了一长串的轻量Web服务器的<a >列表和简?/a>Q感兴趣的读者可以认真阅读,从中L到您感兴的实现。轻量Web服务器不只是Apache、IIS的竞争者,也是很好的合作者(例如我们l常可以见到关于mongrel与Apache<a >配合使用的文?/a>Q,现在我们q可以看到很多服务器协作部v的例子,各取所长应该是最佳的选择Q所以我们更应该从现在就开始拓宽眼界,L我们所需要的?/p> <p>最后,推荐对Web服务器感兴趣的读者可以用Netcraft提供?a >Webserver Search</a>的服务器查询功能来探索你感兴的|站的服务器QWebserver Search可以报告搜烦的url对应的服务器的操作系l和Web服务器类型,是设计部|方案的一个很好参考?/p> <br><br><img src ="http://www.tkk7.com/iamtin/aggbug/133926.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/iamtin/" target="_blank">Tin</a> 2007-08-02 10:10 <a href="http://www.tkk7.com/iamtin/archive/2007/08/02/light-web-servers.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于InfoQ的“评论:C#正变得越来越臃肿”的感想http://www.tkk7.com/iamtin/archive/2007/07/31/133581.htmlTinTinTue, 31 Jul 2007 07:41:00 GMThttp://www.tkk7.com/iamtin/archive/2007/07/31/133581.htmlhttp://www.tkk7.com/iamtin/comments/133581.htmlhttp://www.tkk7.com/iamtin/archive/2007/07/31/133581.html#Feedback0http://www.tkk7.com/iamtin/comments/commentRss/133581.htmlhttp://www.tkk7.com/iamtin/services/trackbacks/133581.html“C#正变得越来越臃肿”
发表了一些感惻I

先进与成熟的是矛盾Q但是现在的新技术成熟的都比较快Q可能是人接受新事物的速度提高了吧?br>Haskellq样的语a是函数式~程的代表,更多的需要从头开始。所以国外学计算机理论首选HaskellQ很多老外抱怨过上学的时候这个东西学的头|但是后来他们也都表示L匪浅。我们的计算机教育是本末倒置Q所以我们这些程序员觉得他们晦ӆ难懂。但是看到Erlangq样的语aQ在未来多核环境下的前途,我们q是会动摇的?br>LINQ的确不错Q但是又是M$一a堂。统一数据讉K模型是非常好的想法,MS总能后发制hQ但是闭门造R很容易被人家过。现在我们看到LINQ很先q,但是{MS的讲师把它推到实늚W一U的时候,别的开发^C会有cM的品出C。而且Q根据标准,查询XML用JQueryQ在各种语言里面查询关系数据库也都有众多ORM实现。所以LINQ的想法虽然很好,但是对于其他语言Q^台来说却没有非常q切的需求去实现cM的技术?br>
关于修改Java JVM的话题不是最紧才有的Q下一步会怎样很难说。CLSq个技术不ؓ奇,其实虚拟机本w就是^収ͼ语言无关的东西,我们已经看到了JRuby、XRuby、Jython和现在的Java Script Engineq样的东西,Java已经在^台化了,q个大家都不会放慢脚步?br>
关于C#和Java的痼疾,我推荐Bruce Tate的《超Java》,里面的观点同样适用于C#?br>
他的原文引用如下Q?br>

C# 2.0发布的时候,我们回头看JavaQ总认个语a怎么发展得这么慢Q但当C#发展?.0的时候,它也开始显C出臃肿之?/a>了,q是否会也会带来什么连锁效应呢Q?/p>

6q前Q我是个Java的拥护者,当时C#q是1.0版,我经常和师傅争论Java如何比C#好,于是他给我一个回{:“我们的COM比Java? 了近5q_所以我们更成熟Q我们的.NET比Java晚了5q_所以更先进”。虽然这么比较有“h概念”的感觉,但现在想惛_实有另一层意思—?#8220;成熟 与先q?#8221;的矛盾?/p>

Lisp、Haskell、Schemeq些语言也都可以被称之ؓ“伟大”Q但Z么很有人去学呢Q因为需要用太多的东?#8220;充斥”我们的大脑后? 可以使用。Java和C#之所以可以快速地被普遍接受,一个很重要的原因就是因为它们的单与清爽。但当明q春天C# 3.0发布的时候会怎么样呢Q虽然你可以WCF、WF、WCS和WPF视ؓ.NET的外挂,不予理会Q但LINQ是个不好回避的内容,因ؓ它在处理数据 讉KQ关pd的、非关系型的Q方面有比较明显的优势,所以即便你个h排斥它,其他q是会有很多人用。最后很可能成ؓq样一U局面:参与C个项目组Q自? 只能从事一些表层业务开发,因ؓ下层的公共封装机刉是用LINQ~写的,况且q有Enterprise Libraryq个“h工程”在后面催着?/p>

可以q么_C#来臃肿是个必然的势Q作?NET语言?#8220;d”Q随着新的开发架构的出现QC#的复杂性还会增加,同时很可能导致革新特性越慢,毕竟牉|的内容多了,作ؓ“d”除了要考虑语言Ҏ间的协作外Q还要充分考虑处理效率?/p>

不过比v“一条道跑到?#8221;的Java而言Q?NETq_有个优势——CLSQCommon Language SpecificationQ公pa规范Q。相信Java的设计者不太愿意,也不敢随便ؓ了一?#8220;快速走U?#8221;但还没有2q时间市验的技术趋势就M 改Java~译器;.NET不同Q?#8220;C#U旗不倒的同时Q?NETq_可以彩旗飘飘”Q比如Spec#是个例子,Z避免null对于软g的媄响,. NET家族诞生?a >Spec#Q目的就是通过非nullq个前提Q提高数据验证、异常处理、堆栈管理的能力Q利于开发者提供更高质量的软gQ?a >F#也是Q虽然C#是强cd的,但动态语a式的开发一样可以基于这?#8220;兄?#8221;开发,加上它和其他.NET语言前辈Z同一个CLR环境Q所以功能毫不逊色?/p>

lg所qͼC#臃肿是不可避免的Q而且很可能会像Visual C++一P因ؓ语言的复杂性,DC#开发h员技术能力的两极分化。但同时Q借助试验?NET语言的支持,即便需要集成新的特性,也不会像某些语言一 样从头开始。依靠试验性语a的积累,怿从MSDN中查看C#q些新语法的时候,可以见一些标着“[Obsolete]”的内宏V?/p>  



Tin 2007-07-31 15:41 发表评论
]]>
Java交互理工具——SecureJSH发布http://www.tkk7.com/iamtin/archive/2007/07/27/java-securejsh-publish.htmlTinTinFri, 27 Jul 2007 01:56:00 GMThttp://www.tkk7.com/iamtin/archive/2007/07/27/java-securejsh-publish.htmlhttp://www.tkk7.com/iamtin/comments/132698.htmlhttp://www.tkk7.com/iamtin/archive/2007/07/27/java-securejsh-publish.html#Feedback1http://www.tkk7.com/iamtin/comments/commentRss/132698.htmlhttp://www.tkk7.com/iamtin/services/trackbacks/132698.html本文已经发布于InfoQ中文站(http://www.infoq.com/cn/news/2007/07/java-securejsh-publishQ,感谢Complystill为我们A献了SJSHq个目?br>

JavaEye上活跃的开发者ComplystillQ歆渊)最q发布了自己的开?a >SecureJSH目Q提供了一个通过SSH交互q行Java应用开发或者管理的工具?/p>

在项目的介绍中可以得知,SecureJSH与Ptyhon里面的ipython或者Ruby里面的irb非常怼。它们都允许交互式运行语a的代 码,以方便跟t或者调试应用。但是,Java与Ruby、Python不同Q后者是动态脚本语aQ它们天生具有解释执行的特点Q注意:当然Python? 持预~译QRuby也将在YARV中开始支持,q里指它们的解释执行状态)。我们常见的Python和Ruby发行版本基本上都包括自己的解释器Q这也是 它们的核心组ӞQ但是Java是一U需要中间编译过E的语言Q默认情况下它无法直接解释运行,也没有相应的解释器?/p>

那么SecureJSH是如何实现的呢?读者首先会惛_JSR-223Q这个API可以自己扩展脚本语言支持Q比如rhino? Javascript解释引擎。但是用它难以实现交互操作Q因为它必须输入一个相对完整的脚本才可以运行,q样会׃部分交互性。SecureJSH 实际上是使用了JDK 6.0的新ҎJava Compiler APIQJSR-199Q,它提供了一lAPI来让E序可以动态地讉KJava~译器的接口Q这样就可以使用Java~译器动态检查代码语法或者动态根? Java源码生成可以执行的字节码。这U方式与ASM的编E直接生成字节码不同Q它能直接将Java源码转换为字节码QXRuby的主力开发者郑晔(|名 dreamheadQ在他的Blog?a dreamhead.blogbus.com="" logs="">q样Ҏ了两U方?/a>Q?/p>

之前Q刚?a >在Blog中提到ASMQ? 里面的代码生成工作是通过直接?字节码完成的。现在有了Compiler APIQ可以考虑生成代码以Java源码的Ş式完成,然后Q通过调用Compiler APIҎ码进行动态编译,q样Q可以达到同直接写字节码cM的作用。用Compiler APIQ肯定不如直接生成字节码来得高效Q但对于不了解JVM指o的h来说q也许是一U解x案?/blockquote>

可见JSR-199不是最高效的字节码生成ҎQ但是更方便使用。Java Compiler API不是Z取代ASMq样的方案的Q它的本意是以编E的方式实现实时~译及信息反馈。Java目前的主要架构师之一Peter von der Ahé曄在他的Blog对谁需要用Java Compiler APIq个问题做了如下解释Q?/p>

99%的Java开发者都不需要了解Java Compiler API。只有少数的开发者会直接应用q个API。但是IDE、Java EE应用E序服务器、Maven或者Antq有试框架的开发者却不一P他们有一个共同点Q就死需要调用编译器Java源码转换为类文gQ他们是q个 API的潜在用P?/blockquote>

可见JSR-199的生主要是面向热部|或者增量编译这L场合Q但是SecureJSH的生扩展了Java Compiler API的应用场景,同时也增ZJava和JVM的交互性。Complystillq样介绍?a >SecureJSH的应用场景和需?/a>Q?/p>

SecureJSH允许Java~写的服务器端应用程序ؓ理员、客戗开发者和客户端服务提供一个安全shellQ这里可以交互性地让Java语言逐句q行。SecureJSH需要JDK 6.0或者JRE 6.0加JAVACQ在classpath中)来运行?/blockquote> SecureJSH的官斚w?/a>q样描述了它的主要特性:
  • 安全Q?/strong>SecureJSH在服务器端实CRFC-4251QSSH 2.0协议Q支持公钥认证,q种方式方便安全Q不需要每ơ输入密码)?/li>
  • 交互式执行:? l的方式下,在运行Java源代码之前你必须它们编译ؓ字节码。但是用SecureJSHQ编译的q程是透明完成的,所以你只需要随意输入一? Java表达式(可以运行)。这意味着你可以用你书写应用E序时完全相同的语法Q与最新的Java语言规范同步。你可以在你的Java目源码? SecureJSHl端里面拯Q粘贴Q何代码,都没有问题?/li>
  • 命o识别QUNIX Shell风格Q?/strong>? 像JSR-223QJava Scripting EnginQJava脚本引擎Q对Java语言的脚本的支持Q在QJava脚本引擎Q里面你必须Javacȝ全部代码输入后才可以执行Q? secureJSH更加和h性化Q如果你输入了不完整的Java表达式,它会自动提示你进行多行的输入Q然后将q些表达式包装到一个预先定义的cȝ? 中来执行。它是一个真正的Shell?/li>
  • 没有怺q扰Q最化资源消耗:SecureJSH没有需要储存在JVM范围的静态资源,每一个实例只消耗很量的资源(ZNIO实现Q所有的SSH通讯都由一个线E处理)。你可以按照你的x在一个JVM里面q行L多个shell服务Q包括Java应用E序服务器的JVM?/li>

作ؓ一个开源项目,SecureJSH使用了ganymed的纯Java实现的SSH 2.0库,q用Java NIO~写了网l服务,代码质量很高。据Comply Still介绍QSecureJSH最初是为内存数据库TOB设计的,个面向对象数据库提供交互讉K的接口,但是后来作者发现它可以被应用在很多? 合,所以单独开源发布。作为Java开发者,您可以从q里下蝲源码从中学习SSH 2.0、NIO|络服务、Java Compiler API的用方法,怿一定会有所收获?/p>

Tin 2007-07-27 09:56 发表评论
]]>争论又vQRIA的未来在哪里Q?/title><link>http://www.tkk7.com/iamtin/archive/2007/07/18/dhh-debates-ria-future.html</link><dc:creator>Tin</dc:creator><author>Tin</author><pubDate>Wed, 18 Jul 2007 06:28:00 GMT</pubDate><guid>http://www.tkk7.com/iamtin/archive/2007/07/18/dhh-debates-ria-future.html</guid><wfw:comment>http://www.tkk7.com/iamtin/comments/131063.html</wfw:comment><comments>http://www.tkk7.com/iamtin/archive/2007/07/18/dhh-debates-ria-future.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/iamtin/comments/commentRss/131063.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/iamtin/services/trackbacks/131063.html</trackback:ping><description><![CDATA[<p>本文已经发表于InfoQQ?a title=争论又vQRIA的未来在哪里Q?>http://www.infoq.com/cn/news/2007/07/dhh-debates-ria-future</a>Q?br><br>David Heinemeier HanssonQ以下简UDHHQRuby on Rails作者)在最q的一Blog“<a ><u><font color=#0000ff>如果我真的喜ƢHTML、CSS和JavascriptQ那又怎么了?</font></u></a>”QWhat if I actually like HTML, CSS, and JavaScript?Q中阐述了他对RIA未来的一U看法。他认ؓ目前在三大Web标准规范下的HTML、CSS和Javascript是一套够强大的工具,q些技术提供给开发h员的功能q没有媄响到Web应用的发展,q且随着?a ><u><font color=#0000ff>Firebug</font></u></a>和其他优UJavascript库的支持下,WebE序员的日常开发工作已l非常惬意了。DHH表示Q?/p> <blockquote><span style="BACKGROUND-COLOR: #c0c0c0">从用户体验的角度来说Q我们甚臌没有发挥出HTML的全部潜力?/span></blockquote> <p>本篇Blog引v了众多网友的评论Q大部分人都认同DHH的观炏V大部分开发者认为基于标准的Web开发还大有潜力可挖Q通过加强设计者与开发者的联系Q品的用户体验可以得到很大的提升。目前大部分Web应用q不能o人满意,但是q个问题q不完全归咎于浏览器的非标准实现Q更多的是因计和开发者本w对技术的掌握q不C。DHH认ؓ不能假设用新的(Z插g的)RIA技术开发出了非o人惊奇的应用Q就认ؓq些?#8220;先进”?#8220;?#8221;的技术会取代我们正在使用的HTML、CSS和Javascript{。相反,DHH认ؓ对这些技术的q度鼓吹都是废话。但回复的网友中也有一些h认ؓq是DHH对于RIA技术革命的不友好表玎ͼ例如Flexible Rails的作者Peter Armstrongp为Flexl合Rails可以带来更好的用户体验。而后QDHH也很快出来澄清说他只是向那些无视HTML、CSS和Javascript的技术狂热者表C反对,而Rails是非常欢q其它RIA技术作充的?/p> <p>在国内技术社区,Ajax斚w的专Ӟ<a ><u><font color=#0000ff>Ajaxcn|站</font></u></a>站长Q李锟针对DHH的这博客也发v?a ><u><font color=#0000ff>讨论</font></u></a>。讨Z李锟认ؓZ标准的HTML、CSS和Javascript在RIA的未来发展中q将扮演d的地位,引出许多针锋相对的观点讨论。最后大家基本上一致认为基于标准和模式q行ZHTML、CSS和Javascript的开发在目前q没有成为技术瓶颈,q些技术在未来q有很多潜力。李锟很好地ȝ了开发者目前面临的问题Q现在看C技术局限是因ؓ对它的了解,而其它新兴RIA技术是否会成ؓLq要{它们充分暴露问题以后再说?/p> <blockquote style="BACKGROUND-COLOR: #c0c0c0">Apple的iPhone也将Mobile Ajax作ؓ他们首先支持的一U开发技术,q也不是偶然的。我觉得我们应该看到技术本w的局限,也应该看到技术未来发展的势。我们之所以对ZWeb标准的技术局限看的这么清楚,也是因ؓ对这些技术我们已l有了大量的实践。而其他的RIA技术目前尚未得到大量的实践Q它们描l的好蓝图能否实现q未可知Q它们存在哪些局限还没有充分暴露出来?/blockquote> <p>q里李锟引用发布?a ><u><font color=#0000ff>InfoQ中文站上的这条新?/font></u></a>Q其实表明了Z标准的Ajax有可能被作ؓ另外一U可行的技术手D,在以前被认ؓ是插件型RIA天下的受限环境中被重新认可。这是说现在的新兴RIA技术(?a ><u><font color=#0000ff>Apollo</font></u></a>?a ><u><font color=#0000ff>Silverlight</font></u></a>{)q不一定会以Ajax杀手的形式出现Q而是作ؓAjax的补充,所以RIA的未来似乎更加扑朔迷R而作为Ajax开发者,q是一条好消息Q证明现在正在用的HTML、CSS和Javascript工具ƈ没有q时Q不需要在恐慌中去学习新的RIA技术,而应该坦然地喜爱你正在用的技术,像DHH和李锟这些Web开发者一栗?/p> <p>最后,关于最q在RIA界非常火的离U存储技术(?a ><u><font color=#0000ff>Google Gears</font></u></a>?a ><u><font color=#0000ff>Dojo Offline</font></u></a>{)QDHH也写了一有的<a ><u><font color=#0000ff>Blog</font></u></a>Q有兴趣的读者也可以一q诅R?/p> <img src ="http://www.tkk7.com/iamtin/aggbug/131063.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/iamtin/" target="_blank">Tin</a> 2007-07-18 14:28 <a href="http://www.tkk7.com/iamtin/archive/2007/07/18/dhh-debates-ria-future.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[译]使用试分类(test categorization)q行敏捷构徏http://www.tkk7.com/iamtin/archive/2006/12/01/84700.htmlTinTinThu, 30 Nov 2006 16:30:00 GMThttp://www.tkk7.com/iamtin/archive/2006/12/01/84700.htmlhttp://www.tkk7.com/iamtin/comments/84700.htmlhttp://www.tkk7.com/iamtin/archive/2006/12/01/84700.html#Feedback0http://www.tkk7.com/iamtin/comments/commentRss/84700.htmlhttp://www.tkk7.com/iamtin/services/trackbacks/84700.html 本文译自IBM DeveloperWorks上的一文章,该文讲述了测试分c?test categorization)的概念,本nq个概念很简单,但是却实际的解决我们常见的问题,在我们的试庞大C定地步的时候,试的运行时间过长,l护成本很高Q我们如何能够保证持l集?CI)的正常运行?那就是通过试分类。所以我译了这片文章,希望对大家有所帮助?br />
原文Q?a target="_blank">In pursuit of code quality: Use test categorization for agile builds
原文作者:Andrew Glover is president of Stelligent Incorporated, which helps companies address software quality with effective developer testing strategies and continuous integration techniques that enable teams to monitor code quality early and often. Check out Andy's blog for a list of his publications.

大家都同意开发h员的试很重要,但是Z么要p么长的时间运行测试呢Q这个月QAndrew Glover给我们讲述对于pȝ来说需要保证运行的三类试Qƈ且告诉你如何Ҏ分类整理和运行测试。结果将会奇q般的减build的时_即是面对当今庞大的试集?br />
如果不太难过的话Q假想一下你是一?002q初刚刚建立的公司的开发h员。在淘金热潮中,你和你的同事已经军_使用最行最强大的Java API来开发一个庞大的数据驱动的Web应用E序。你可你的管理团队坚定的信Ԓ敏捷q程。从W一天开始,׃用JUnit~写试Qƈ且通过Ant build脚本可能频J的q行它们。最后,你们q会使用cronQ?nix下的一个定时运行脚本的dQ来q行nightly build。再然后Q某些h可能会下在CruiseControl然后把测试写成套Ӟ然后在每ơcheck-in时执行(持箋集成Q?br /> 现在回到今天?br /> l过了前几年的磨l,你的公司已经开发了数量巨大的代码,当然也有同样庞大的JUnit试。一q前所有的事情都运转良好,当你的测试套件有过2000个测试,Z开始注意到buildq程可能要执行三个小时以上。几个月以前Q你停止通过代码提交来处|持l集成(CIQ运行单元测试,因ؓCI服务器会因此q渡J忙。你改ؓq行nightly试Q每日测试)Q第二天早上开发h员可能会头疼试Zp|?br /> 最q,试套gg很难在晚上运行一ơ以上了——这是ؓ什么呢Q它们永q运行不完!没有Z用几个小时的旉来等待确认代码运行是正常的(或不正常Q。所以,整个的测试会在晚上运行,对么Q?br /> 因ؓ你如此频J的q行试Q他们L充满了问题。(译者注Q你会开始怀疑是不是试也出了问题,是否x试你的测试?Q从而,你和你的团队开始怀疑单元测试的价|如果代码质量q不那么重要Qؓ什么我们要承受q种痛苦Q假如你可以用敏LҎq行它们的话Q你们完全同意这是单元测试的基本价倹{?/font>

试试分类Qtest categorizationQ?/strong>

你需要的是一个让你的build转变到更敏捷状态的{略。你需要一U解x案来允许你在一天内多次q行试Q让那些已经需要三个小时完成的试回到原先的状态?br /> 在你试使用q个{略让你的测试套件恢复原形之前,思考一下“单元测试”的基本概念可能会有所帮助。“我家有一只动物”和“我喜欢汽R”这L陈述不是非常明确Q所以,不幸的是Q“我们编写单元测试”也不明。现在,但愿试泛指一切?br /> 思考前面的两个关于动物和汽车的陈述Q它们生了很多疑问。例如,你家里有什么动物?是猫、蜥蜴还是熊Q“我家有一只熊”与“我家有一只猫”完全不同。同LQ“我喜欢汽R”对于与汽R销售商交谈时没有帮助。你喜欢哪种车:q动车、卡车或者大货RQ不同的{案会将你引入不同的路径?br /> 同样Q对于开发h员进行测试,根绝试cd分类是有所帮助的。这样做更加_Q能够允怽的团队以不同的频度运行不同类型的试。分cL避免gh的运行所有“单元测试”的三小时build的关键方法?br />



三种分类

形象的将你的试套g整理Z层,每一层代表开发h员进行的不同cd的测试,它们是根据运行时间的长短划分的。如?所C,每一层将p更多的总build旉Q无论是q行旉q是~写它们所需的时间?/font>

? 试分类的三?br />

最下面一层测试运行时间最短,如你所惻I他们也是最Ҏ写的。他们也覆盖最量的代码。顶层是有高层次的测试组成,它们应用程序的很大一部分。这些测试相寚w写,同时也需要更多时间来执行。中间一层测试介于两个极端之间?br />q三个分cd下:

  • 单元试
  • lg试
  • pȝ试
让我们分别的考察它们?/font>

1、单元测?/font>

单元试隔离的确认一个或者多个对象。单元测试不处理数据库、文件系l或者Q何可能带来测试不能保证长期可q行的因素;序上,试可以从(目Q第一天就开始写。事实上Q这是JUnit的设计目标。单元测试的隔离概念是在很多mock对象库隔ȝ定对象的外在依赖的基上的。进一步说Q单元测试可以在实际代码~写前就开始写——也是试先行开发TDD的概c?br /> 单元试一般容易编写,因ؓ他们不依靠于pȝ依赖Qƈ且他们运行迅速。不好的斚w是,单独的单元测试只能提供有限的代码覆盖度。单元测试的价值在于允许开发者在最低的依赖E度下保证对象的质量?br /> 因ؓ单元试q行q速容易编写,一个代码库应该有很多单元测试且量频繁的运行它们。你应该在每ơbuild的时候运行它们,不管是在你的机器或者一个CI环境Q以你应该在每次向SCMpȝchech in之前q行它们Q?/font>

2、组件测?/strong>

lg试保证多个对象的交互,但是它们H破了代码隔ȝ概念。因为组件测试处理多层架构,他们l常要处理数据库、文件系l、网l元素等。而且lg试一般很隑֜Q项目)前编写,所以将它们加入C个实际的试先行/试驱动的场景中是个很大的挑战?br /> lg试~写要花多一些时_因ؓ他们比单元测试要手。从另一个方面来看,他们能够提供比单元测试更高的代码覆盖率因为它们的宽工作范围。它们运行耗时更多Q所以它们会极大地拖长你们的L试耗时?br /> 一个宿L架可能减测试庞大架构组建的挑战隑ֺ。DbUnit是一个这U框架的完美例子。DbUnit是编写依赖于数据库的试ҎQ它能够处理复杂的数据库状态准备工作?br /> 当测试引起build旉廉Q你基本上可以确定那是大组的组件测试造成的。因些测试比单元试q行旉更长Q你可能发现你不能Lq行它们。因此,它让CI环境臛_以小时ؓ间隔执行它们。你一应该要求每个开发者在check in前在本机环境q行q些代码?/font>

3、系l测?/strong>

pȝ试从端到端保证软g应用。因此,他们提出了高度的架构复杂性:整个应用必须在进行系l测试时q行。如果是一个Web应用E序Q你需要访问数据库Q从Web服务器、(应用E序Q容器、Q何相关的配置都要配合pȝ试的运行。系l测试L在Y件开发周期的最后阶D|写的?br /> pȝ试对于~写人员是个挑战Qƈ且实际往往p比较长的旉。另一斚wQ他们提供更好的催款理由Q也是_他们提供了系l架构的代码覆盖率?br /> pȝ试与功能测试非常相q。区别在于它们不是一个假扮用P用户是虚拟的。就像组件测试一P很多框架都是来帮助这cL试的。例如,jWebUnit通过模拟一个浏览器提供了测试Web应用E序的基设施?br />

什么是接受试Q?/b>
接受试与功能测试类|不同点在于,理想情况下,客户或者最l用h~写接受试。与功能试cMQ接受测试按照最l用L行ؓ试。一个备受关注的接受试框架是SeleniumQ它使用览器来试Web应用E序。Selenium可以在buildq程中自动运行,像JUnit试一栗但是Selenium是一个新的^収ͼ他不一定用JUnitQ方式也不太一栗(Selenium RC没有这个问题了Q?/p>

我应该用jWebUnit或者SeleniumQ?/b>
jWebUnit是一个JUnit扩展框架Q设计用来进行系l测试;所以,它需要你自己写这些测试。Selenium是一个优U的接受测试和功能试工具Q不同于jWebUnitQ它允许非程序员~写试。理想状态下Q你的团队可以同时用两U工h认应用E序的功能?/p>

使用TestNGq行试分类
使用TestNG实现试分类非常Ҏ。用TestNG的group注释Q逻辑上将试分类是q行合适的group注释Q这非常单。运行某一分类的测试只需要将group名称传给test runner可以了Q例如通过Ant?/p>

实现试分类

所以,你的单元试套g实际上是单元试、组件测试和pȝ试的套件。甚臻I在你查所有的试后发现build需要这么长旉是因为大部分试都是lg试。下一个问题是Q如何通过JUnit实现试分类Q?br />
你有很多选择Q但是让我们先试验一下最单的两个Q?

  • Ҏ需要的分类创徏不同的JUnit套gQsuiteQ文?
  • 对于不同cd的测试创Z同的目录

创徏不同的套?/strong>

你可以用JUnit的TestSuitec(它也是一UTestQ定义一l同cL试的集合。你要创Z个TestSuite的实例ƈd相关的测试类到testҎ中。你可以在TestSuite实例中通过定义一个叫做suite()的public staticҎ告诉JUnitq个套g包括哪些试。所有包括的试会一ơ全部执行。因此你可以通过创徏TestSuite来实现测试分c,一个单元测试的TestSuite、一个组件测试的TestSuiteQ有一个系l测试的TestSuite?br />例如清单1的类中的suite()Ҏ创徏了一个包含所有组建测试的TestSuite。注意这个类不是非常W合JUnit规范。他既没有承TestCaseQ也没有M试的定义。但是JUnit会自动发现suite()Ҏq且q行它返回的所有测试类?/font>

清单1 单元试的TestSuite

package test.org.acme.widget;

import junit.framework.Test;
import junit.framework.TestSuite;
import test.org.acme.widget.*;

public class ComponentTestSuite {

 
public static void main(String[] args) {
  junit.textui.TestRunner.run(ComponentTestSuite.suite());
 }

 
public static Test suite(){
  TestSuite suite 
= new TestSuite();
  suite.addTestSuite(DefaultSpringWidgetDAOImplTest.
class);
  suite.addTestSuite(WidgetDAOImplLoadTest.
class);
  
  suite.addTestSuite(WidgetReportTest.
class);
  
return suite;
 }
}


定义TestSuite的过E需要你察看你当前的所有测试ƈ它们加入到相应的类里面Q例如,所有的单元试加入到UnitTestSuiteQ。这也就意味着你在相应的分c里面创Z新的试Q你必须~程式的它们添加到合适的TestSuite中,当然q需要重新编译它们?br /> q行单独的TestSuite需要单独的Antd来运行正的试l。你可以定义一个component-testd来执行ComponentTtestSuiteQ就像清?中的样子Q?/font>

清单2 q行l徏试的一个Antd

< target  name ="component-test"  
           if
="Junit.present"  
           depends
="junit-present,compile-tests" >
 
< mkdir  dir ="${testreportdir}" />    
 
< junit  dir ="./"  failureproperty ="test.failure"  
             printSummary
="yes"  
             fork
="true"  haltonerror ="true" >
   
< sysproperty  key ="basedir"  value ="." />      
   
< formatter  type ="xml" />       
   
< formatter  usefile ="false"  type ="plain" />      
   
< classpath >
    
< path  refid ="build.classpath" />        
    
< pathelement  path ="${testclassesdir}" />         
    
< pathelement  path ="${classesdir}" />       
   
</ classpath >
   
< batchtest  todir ="${testreportdir}" >
    
< fileset  dir ="test" >
     
< include  name ="**/ComponentTestSuite.java" />                  
    
</ fileset >
   
</ batchtest >
 
</ junit >
</ target >

理想情况下,你还需要一个触发单元测试的d和系l测试的d。最后,q有希望q行所有测试的情况Q你需要创建第四个d来运行其它三个Q务,像清单3里面那样Q?/font>

清单3 q行所有测试的d

< target  name ="test-all"  depends ="unit-test,component-test,system-test" />

创徏单独的TestSuite是一个迅速实现测试分cȝ解决Ҏ。缺Ҏq个Ҏ需要你创徏新的试Q你必须~成式的它们添加到合适的TestSuite里面Q这可能有点痛苦。给每个试cd创徏单独的目录可能是一U更加有Ҏ的ҎQ它允许你添加新的测试分cM无需重新~译?br />


创徏单独的目?/strong>

我发现最单的通过JUnit实现试分类的方法是逻辑上将不同cd的测试放C同的目录中。用这个方法,所有的单元试都放在unit目录Q所有的l徏试都放在component目录Q等{?br /> 例如Q在test目录中保存着所有未分类的测试,你可以创Z个新的子目录Q就像清?中那P

清单4 实现试分类的目录结?/strong>

acme-proj/
       test/
          unit/
          component/
          system/ 
          conf/

q行q些试Q你需要定义至四个AntdQ一个给单元试Q另外的l组建测试,q有pȝ试。第四个d是一个方便运行其它三个测试类型的dQ就像清?U展C的那种方式Q?br /> JUnitd像清单2中的形式。区别在哪里呢,只是在Q务的batchtestq个地方。这ơ,fileset指向的是一个指定的目录Q就像清?U的样子Q他指向了unit目录Q?br />
清单5 JUnitd中的batchtest斚wQ用来运行所有单元测?/strong>

< batchtest  todir ="${testreportdir}" >
 
< fileset  dir ="test/unit" >  
  
< include  name ="**/**Test.java" />        
 
</ fileset >
</ batchtest >

注意q个dq行test/unit目录下的所有测试,当创Z新的单元试Q或者其它分cȝ其它试Q,你只需要把它们攑ֈq个目录里面可以了Q这比添加一行到TestSuite中ƈ重新~译它要方便多了?br />


问题解决了!

回到最初的场景Q我认ؓ你和你的团队会决定用单独的目录q种Ҏ的解决Ҏ来解决你们的build旉q长的问题。这个Q务最隄一个方面是查和分清试cd。你重构你的Ant build文g创徏四个新的dQ三个单独的试分类q有一个运行它们三个)。甚臻I你修改CuiresControl只在check-in的时候运行单元测试,而组建测试按时q行。更q一步的查后Q系l测试也可以几个时q行一ơ,也许你会创徏一个新的Q务来同时q行l徏试和系l测试?/font>

最后的l果是每天测试运行很多次Q你的团队可以快速的发现集成错误——一般在几个时内?/font>

创徏敏捷构徏不是Z赶时髦,它实际上是保证代码质量的重要因素。测试运行的更加频繁Q开发h员的试的h值就能直接{化ؓ钱。ƈ且,希望你们的公司能够在2006取得q泛的成功!

资源
Learn

Get products and technologies

Discuss



Tin 2006-12-01 00:30 发表评论
]]>
在JUnit中多个testCase只执行一ơsetup和tearDown的方?/title><link>http://www.tkk7.com/iamtin/archive/2006/11/17/81802.html</link><dc:creator>Tin</dc:creator><author>Tin</author><pubDate>Fri, 17 Nov 2006 09:29:00 GMT</pubDate><guid>http://www.tkk7.com/iamtin/archive/2006/11/17/81802.html</guid><wfw:comment>http://www.tkk7.com/iamtin/comments/81802.html</wfw:comment><comments>http://www.tkk7.com/iamtin/archive/2006/11/17/81802.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.tkk7.com/iamtin/comments/commentRss/81802.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/iamtin/services/trackbacks/81802.html</trackback:ping><description><![CDATA[q个问题出现在这U情况,你的每个testCase都需要用某一U初始化比较耗时的对象(资源Q,举例如数据库q接、Spring Context。我们遇到的问题是Selenium试中开启和关闭览器,如果一个test启动关闭Q我们的E序q需要登录和注销Q,q样试的时间会拖的很长Q给持箋集成带来了困难?br />所以,我们需要在每组不会冲突的test中间׃n一个浏览器H口Q这样也需要一个全局的setUp和tearDown。问题是JUnit 3.8.1里面的setUp和tearDown是在每个test之前和之后运行的Q如果在里面初始化和关闭览器就会造成上面所说的问题。要解决它,׃生了如下3U思\Q?br />1、升U,使用JUnit4<br />JUnit4从TestNG里面吸取了两个注释:@BeforeClass和@AfterClass<br />用它们注释过的方法就会只初始化一ơ,完全W合我们的需求?br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id="Codehighlighter1_56_678_Open_Image" onclick="this.style.display='none'; Codehighlighter1_56_678_Open_Text.style.display='none'; Codehighlighter1_56_678_Closed_Image.style.display='inline'; Codehighlighter1_56_678_Closed_Text.style.display='inline';" src="http://www.tkk7.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_56_678_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_56_678_Closed_Text.style.display='none'; Codehighlighter1_56_678_Open_Image.style.display='inline'; Codehighlighter1_56_678_Open_Text.style.display='inline';" src="http://www.tkk7.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> SeleniumTestCase </span><span style="COLOR: #0000ff">extends</span><span style="COLOR: #000000"> SeleneseTestCase4 </span><span id="Codehighlighter1_56_678_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.tkk7.com/images/dot.gif" /></span><span id="Codehighlighter1_56_678_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">protected</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">final</span><span style="COLOR: #000000"> Log log </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> LogFactory.getLog(SeleniumTestCase.</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">);<br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">protected</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> Selenium selenium </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">;<br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img id="Codehighlighter1_191_267_Open_Image" onclick="this.style.display='none'; Codehighlighter1_191_267_Open_Text.style.display='none'; Codehighlighter1_191_267_Closed_Image.style.display='inline'; Codehighlighter1_191_267_Closed_Text.style.display='inline';" src="http://www.tkk7.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_191_267_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_191_267_Closed_Text.style.display='none'; Codehighlighter1_191_267_Open_Image.style.display='inline'; Codehighlighter1_191_267_Open_Text.style.display='inline';" src="http://www.tkk7.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span><span id="Codehighlighter1_191_267_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/** */</span><span id="Codehighlighter1_191_267_Open_Text"><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"><br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />     * 包含了登录的代码Q保证在一个测试内部只执行一ơ开启浏览器q登录操?br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />     * </span><span style="COLOR: #808080">@throws</span><span style="COLOR: #008000"> Exception<br /><img src="http://www.tkk7.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />     </span><span style="COLOR: #008000">*/</span></span><span style="COLOR: #000000"><br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />    @BeforeClass<br /><img id="Codehighlighter1_342_461_Open_Image" onclick="this.style.display='none'; Codehighlighter1_342_461_Open_Text.style.display='none'; Codehighlighter1_342_461_Closed_Image.style.display='inline'; Codehighlighter1_342_461_Closed_Text.style.display='inline';" src="http://www.tkk7.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_342_461_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_342_461_Closed_Text.style.display='none'; Codehighlighter1_342_461_Open_Image.style.display='inline'; Codehighlighter1_342_461_Open_Text.style.display='inline';" src="http://www.tkk7.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> startSelenium() </span><span style="COLOR: #0000ff">throws</span><span style="COLOR: #000000"> Exception </span><span id="Codehighlighter1_342_461_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.tkk7.com/images/dot.gif" /></span><span id="Codehighlighter1_342_461_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />        log.debug(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Starting Selenium<img src="http://www.tkk7.com/images/dot.gif" /></span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />        selenium </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> SeleniumSession.getCurrentSession().getSelenium();<br /><img src="http://www.tkk7.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span></span><span style="COLOR: #000000"><br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img id="Codehighlighter1_468_530_Open_Image" onclick="this.style.display='none'; Codehighlighter1_468_530_Open_Text.style.display='none'; Codehighlighter1_468_530_Closed_Image.style.display='inline'; Codehighlighter1_468_530_Closed_Text.style.display='inline';" src="http://www.tkk7.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_468_530_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_468_530_Closed_Text.style.display='none'; Codehighlighter1_468_530_Open_Image.style.display='inline'; Codehighlighter1_468_530_Open_Text.style.display='inline';" src="http://www.tkk7.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span><span id="Codehighlighter1_468_530_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/** */</span><span id="Codehighlighter1_468_530_Open_Text"><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"><br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />     * 在该cd含的所有测试结束之后关闭浏览器<br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />     * </span><span style="COLOR: #808080">@throws</span><span style="COLOR: #008000"> Exception<br /><img src="http://www.tkk7.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />     </span><span style="COLOR: #008000">*/</span></span><span style="COLOR: #000000"><br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />    @AfterClass<br /><img id="Codehighlighter1_603_676_Open_Image" onclick="this.style.display='none'; Codehighlighter1_603_676_Open_Text.style.display='none'; Codehighlighter1_603_676_Closed_Image.style.display='inline'; Codehighlighter1_603_676_Closed_Text.style.display='inline';" src="http://www.tkk7.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_603_676_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_603_676_Closed_Text.style.display='none'; Codehighlighter1_603_676_Open_Image.style.display='inline'; Codehighlighter1_603_676_Open_Text.style.display='inline';" src="http://www.tkk7.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> stopSelenium() </span><span style="COLOR: #0000ff">throws</span><span style="COLOR: #000000"> Exception </span><span id="Codehighlighter1_603_676_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.tkk7.com/images/dot.gif" /></span><span id="Codehighlighter1_603_676_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />        log.debug(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Stoping Selenium<img src="http://www.tkk7.com/images/dot.gif" /></span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />        selenium.stop();<br /><img src="http://www.tkk7.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span></span><span style="COLOR: #000000"><br /><img src="http://www.tkk7.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span></div>q个里面的selenium = SeleniumSession.getCurrentSession().getSelenium();其实是个singletonQ第一ơopen newQ后来就直接q回selenium的instanceQ具体参考其它文章)?br />q样做非常舒服,因ؓ完全不是TrickQ而是新的featureQ用ht实。这Pq个cȝ所有@Test׃公用一个selenium打开的浏览器了?br />那么~点是什么呢Q缺Ҏ攑ֈCI环境的时候如果用我们习惯的Ant写执行脚本的话必dAnt升?.7Beta3Q因为Ant 1.6.5的Junit task不支持JUnit4……当然升Uƈ不会带来代码的变化,但是问题在于Ant 1.7q是BetaQ而且JUnit4需要JDK5的AnnotationQ你的PM估计要撇嘴了<img height="19" src="http://www.tkk7.com/Emoticons/74_74.gif" width="19" border="0" /><br /><br />2、JVMU别钩子?br />因ؓJVM支持关闭时执行制定代码的钩子Q而static代码会在cd始化时执行,再加上Ant调用的是cM命o行的java命oQ实际上每一个测试运行在一个完整的JVM启动关闭周期里面Q所以也׃生了q种解决Ҏ?br />q个Ҏ来自<a target="_blank">taowen同学的两则Seleniuml验</a>?br />代码我恢复了一下,大概是这P<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">abstract</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> SomeTestCase </span><span style="COLOR: #0000ff">extends</span><span style="COLOR: #000000"> TestCase {<br /><br />  </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> {<br />    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> perform the "global" set up logic<br />    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">q里的代码会在类初始化时执行Q所以相当于BeforeClass</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">    log.debug(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Starting Selenium<img src="http://www.tkk7.com/images/dot.gif" /></span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br />        selenium </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> SeleniumSession.getCurrentSession().getSelenium();<br /><br />    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> and now register the shutdown hook for tear down logic<br />    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">一个匿名方法写到这里,q当于AfterClass</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">    Runtime.getRuntime().addShutdownHook(<br />       </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> Thread(){<br />           </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> run() {<br />             log.debug(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Stoping Selenium<img src="http://www.tkk7.com/images/dot.gif" /></span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br />             selenium.stop();<br />           }<br />       }<br />     );<br />  }<br /><br />}</span></div><br />q个Ҏ挺酷的,我认为完全可以被UC“奇技淫y”。缺点就是,有点不好看?br /><br />3、还有别的方法,q个来自Selenium|站Q似乎是不错的中庸方案?br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000"> junit.framework.</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">;<br /></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000"> junit.extensions.TestSetup;<br /><br /></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> AllTestsOneTimeSetup {<br /><br />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> Test suite() {<br /><br />        TestSuite suite </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> TestSuite();<br /><br />        suite.addTest(SomeTest.suite());<br />        suite.addTest(AnotherTest.suite());<br /><br />        TestSetup wrapper </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> TestSetup(suite) {<br /><br />            </span><span style="COLOR: #0000ff">protected</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> setUp() {<br />                oneTimeSetUp();<br />            }<br /><br />            </span><span style="COLOR: #0000ff">protected</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> tearDown() {<br />                oneTimeTearDown();<br />            }<br />        };<br /><br />        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> wrapper;<br />    }<br /><br />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> oneTimeSetUp() {<br />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> one-time initialization code</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">    }<br /><br />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> oneTimeTearDown() {<br />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> one-time cleanup code</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">    }<br />}<br /><br /></span></div><br /><p>q个好像是比较正l的ҎQ不好意思我q没有试验,但是看v来这的确可能是限定用JDK 1.4或JUnit 3.8.1的最佌x案。欢q尝试。相关的q接参考这里:<a >http://www.cs.wm.edu/~noonan/junit/doc/faq/faq.htm#organize_3</a> </p><img src ="http://www.tkk7.com/iamtin/aggbug/81802.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/iamtin/" target="_blank">Tin</a> 2006-11-17 17:29 <a href="http://www.tkk7.com/iamtin/archive/2006/11/17/81802.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Selenium Remote Control 0.9.0发布http://www.tkk7.com/iamtin/archive/2006/11/15/81284.htmlTinTinWed, 15 Nov 2006 07:57:00 GMThttp://www.tkk7.com/iamtin/archive/2006/11/15/81284.htmlhttp://www.tkk7.com/iamtin/comments/81284.htmlhttp://www.tkk7.com/iamtin/archive/2006/11/15/81284.html#Feedback3http://www.tkk7.com/iamtin/comments/commentRss/81284.htmlhttp://www.tkk7.com/iamtin/services/trackbacks/81284.html你可以在q里察看Q?br />http://www.openqa.org/selenium-rc/
也可以在q里下蝲Q?br />http://www.openqa.org/selenium-rc/download.action
0.9.0包括很多L意,包括frame支持Q多H口支持Q用来测试那些不能够在子frame中运行的应用Q,一个Konqueror览器launcherQ新的cookie理功能Q和Firefox 2.0与IE7的支持。还包括一个试验性的在Selenium代理中直接的SSL支持Q一个新的实验性的“代理注入(proxy injectionQ”模式允许我们通过修改HTTP代理来更好的控制我们试的应用程序?br />Have FunQ?img src ="http://www.tkk7.com/iamtin/aggbug/81284.html" width = "1" height = "1" />

Tin 2006-11-15 15:57 发表评论
]]>
Selenium相关资源中文化动?/title><link>http://www.tkk7.com/iamtin/archive/2006/11/13/selenium_chinese_translation_start.html</link><dc:creator>Tin</dc:creator><author>Tin</author><pubDate>Mon, 13 Nov 2006 07:31:00 GMT</pubDate><guid>http://www.tkk7.com/iamtin/archive/2006/11/13/selenium_chinese_translation_start.html</guid><wfw:comment>http://www.tkk7.com/iamtin/comments/80902.html</wfw:comment><comments>http://www.tkk7.com/iamtin/archive/2006/11/13/selenium_chinese_translation_start.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.tkk7.com/iamtin/comments/commentRss/80902.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/iamtin/services/trackbacks/80902.html</trackback:ping><description><![CDATA[ <h1> <a name="Home-Selenium%E7%9B%B8%E5%85%B3%E8%B5%84%E6%BA%90%E4%B8%AD%E6%96%87%E5%8C%96"> </a>Selenium相关资源中文?/h1> <h3> <a name="Home-1.%E5%8A%A8%E6%9C%BA"> </a>1. 动机</h3> <p>springside目的江南白衣、cac和徐昊、熊杰都多次推广非常Pragmatic的Seleniumq行功能试。而我们的目中也开始引入Selenium试Qƈl合持箋集成搭徏了一个测试环境,也尝试通过Seleniumq行一些浏览器兼容性的试。期间感觉到Selenium的强大,同时也发现这个项目还不是很成熟,q需要很多改q。但是,对于已经h的程序员Q我们觉得应该提供一个学习的场所Q所以决定依靠javascud提供的服务,q行Selenium相关资源的中文化?br />已经与Openqa的Wiki的负责hPatrick lightbodyq行了沟通,他非常支持我们翻译Selenium文档Q我们将一边翻译一边将译l果转移到OpenQAQ这样就能够方便所有用中文的Selenium用户了,希望大家共同努力Q?/p> <h3>2. 初步计划</h3> <p>我们准备从翻?<span id="eyyywac" class="nobr"><a title="Visit page outside Confluence" rel="nofollow">Selenium相关wiki <sup><img class="rendericon" height="7" alt="" src="http://wiki.javascud.org/images/icons/linkext7.gif" width="7" align="absMiddle" border="0" /></sup></a></span> 开始,译openqa下面的Selenium、Selenium RemoteControl、Selenium IDE下面的相x章。顺序应该是偏重SeleniumRemoteControl和Selenium Core部分?br />而openqa|站下面Selenium和RC的相xE我们也会选择性的q行译?br />Selenium On Rails如果哪位朋友感兴也可以负责Q目前还是空的:Q?br /><strong><font color="#006400">Ƣ迎所有对Selenium感兴的Q翻译的q程是很好的学习)或者已l用Selenium的同学积极参加,参加的方式可以是Q直接参与翻译,~写原创学习文章q添加到相关资源列表Q交心得ƈ心得添加到相关资源列表Q提供用的视频片断Q推荐好的Selenium文章q入译计划Q提Z自己的意见。以上方式都非常Ƣ迎Q可以发信给我进行沟通(iamtin AT gmail.comQ?br />目前我们使用JavaScud的Wikiq行译工作Q网址如下Q?br /></font></strong><a ><strong><font color="#006400">http://wiki.javascud.org/display/SEL/Home</font></strong></a><br /><strong><font color="#006400">需要帐可自行注册Q然后将注册后的帐号发给我带为申h者直接向scudQ飞云小侠)甌?/font></strong></p> <h3> <a name="Home-3.%E5%B7%A5%E4%BD%9C%E7%BA%BF%E8%B7%AF%E5%9B%BE%E5%B7%A5%E4%BD%9C%E7%BA%BF%E8%B7%AF%E5%9B%BE"> </a>3. <a title="工作U\? >工作U\?</a></h3> <p>按照官方|站的目录进行整理,首先译比较有意?实用的部分。本将作ؓ文档的烦引,同时也作ZQ务分配的面。如果某一늚内容被翻译者认领,请将自己的名字和文档的翻译状态注在烦引后面,方便l计。状态ؓQworking, complete, reviewdQ,认领后ؓworking状态,译好则completeQ其它h看过q审q以后ؓreviewd?br />我们首先译Selenium的几个About面Q然后开始翻译相应的Wiki部分Q然后再补全Documentation、Reference部分Q其余部分最后补齐?br />现在wiki和about的原文文档已l粘贴过来了Q请大家有工夫的时候开始翻译,q部分翻译完成后我们把阶段成果链接到openqa的translation部分厅R?/p> <ul> <li>Selenium Core <ul><li><a title="Selenium - 关于" >关于 </a></li><li>News </li><li>Documentation </li><li>Usage </li><li>Reference </li><li>FAQ </li><li>Demos </li><li>Wiki <ul><li><a title="我应该用哪USelenium工具Q? >我应该用哪USelenium工具Q?/a></li><li><a title="Selenium Core FAQ" >Selenium Core FAQ</a></li><li><a title="Getting Started with Selenium Core" >Getting Started with Selenium Core</a></li><li><a title="Selenium Core Examples" >Selenium Core Examples</a></li><li><a title="Help With XPath" >Help With XPath</a></li><li><a title="References and Citations" >What People are Saying About Selenium</a></li><li><a title="Publications and Presentations" >Publications and Presentations</a></li><li><a title="Translated Document" >Translated Document</a><font color="red">new!!</font></li><li><a title="Selenium Core API Documentation Standard" >Selenium Core API Documentation Standard</a></li><li><a title="Contributed User-Extensions" >Contributed User-Extensions</a></li></ul></li></ul></li> <li>Selenium IDE <ul><li><a title="Selenium IDE - 关于" >关于 </a></li><li>News </li><li>Recording a test (video) </li><li>Documentation </li><li>Wiki <ul><li><a title="Recording a Test" >Recording a Test</a></li><li><a title="FAQ" >FAQ</a></li><li><a title="Contributed Extensions and Formats" >Contributed Extensions and Formats</a></li><li><a title="Automating Selenium IDE tests" >Automating Selenium IDE tests</a></li><li><a title="Writing extensions" >Writing extensions</a></li><li><a title="Adding Custom Format" >Adding Custom Format</a></li><li><a title="Building Selenium IDE" >Building Selenium IDE</a></li></ul></li></ul></li> <li>Selenium RC <ul><li><a title="Selenium Remote Control - 关于" >关于 </a></li><li>News </li><li>Documentation </li><li>Tutorial </li><li>Troubleshooting/FAQ <ul><li>Java </li><li>.NET </li><li>Perl </li><li>Python </li><li>Ruby </li><li>Selenese </li></ul></li><li>Server Command Line Options </li><li>Developer's Guide </li><li><a title="Selenium Remote Control - Wiki" >Wiki</a><ul><li><a title="Possible Solution to HTTP AUTH Issues" >Possible Solution to HTTP AUTH Issues</a></li><li><a title="Release Process" >Release Process</a></li><li><a title="Selenium-RC and Continuous Integration" >Selenium-RC and Continuous Integration</a></li><li><a title="Specifications for Selenium Remote Control Client Driver Protocol" >Specifications for Selenium Remote Control Client Driver Protocol</a></li><li><a title="TODO for first Selenium Release" >TODO for first Selenium Release</a></li><li><a title="Windows Registry Support" >Windows Registry Support</a></li></ul></li></ul></li> <li>Selenium On Rails </li> </ul> <h3> <a name="Home-4.%E7%9B%B8%E5%85%B3%E8%B5%84%E6%BA%90%EF%BC%88%E9%83%A8%E5%88%86%EF%BC%89"> </a>4. 相关资源Q部分)</h3> <p> <span id="qkyukke" class="nobr"> <a title="Visit page outside Confluence" href="/raimundox/archive/2006/08/04/61860.html" rel="nofollow">徐昊(X)的:Selenium Better Pratice <sup><img class="rendericon" height="7" alt="" src="http://wiki.javascud.org/images/icons/linkext7.gif" width="7" align="absMiddle" border="0" /></sup></a> </span> <br /> <span id="mwmyiii" class="nobr"> <a title="Visit page outside Confluence" rel="nofollow">江南白衣的:Selenium--透明反复推介的集成测试工?Pragmaticpd) <sup><img class="rendericon" height="7" alt="" src="http://wiki.javascud.org/images/icons/linkext7.gif" width="7" align="absMiddle" border="0" /></sup></a> </span> <br /> <span id="qgscgeu" class="nobr"> <a title="Visit page outside Confluence" rel="nofollow">cac译的:selenium参考手?<sup><img class="rendericon" height="7" alt="" src="http://wiki.javascud.org/images/icons/linkext7.gif" width="7" align="absMiddle" border="0" /></sup></a> </span> <br /> <span id="uawumes" class="nobr"> <a title="Visit page outside Confluence" rel="nofollow">SpringSideTeam的Selenium指南 <sup><img class="rendericon" height="7" alt="" src="http://wiki.javascud.org/images/icons/linkext7.gif" width="7" align="absMiddle" border="0" /></sup></a> </span> <br /> <span id="uuewiiy" class="nobr"> <a title="Visit page outside Confluence" rel="nofollow">IBM的用 Selenium 自动化验收测?<sup><img class="rendericon" height="7" alt="" src="http://wiki.javascud.org/images/icons/linkext7.gif" width="7" align="absMiddle" border="0" /></sup></a> </span> <br /> <span id="ecwqcsi" class="nobr"> <a title="Visit page outside Confluence" rel="nofollow">Fit(table)+RC的方式用Selenium <sup><img class="rendericon" height="7" alt="" src="http://wiki.javascud.org/images/icons/linkext7.gif" width="7" align="absMiddle" border="0" /></sup></a> </span> <br /> <span id="muoakca" class="nobr"> <a title="Visit page outside Confluence" rel="nofollow">OpenQA的Selenium Remote Control Wiki <sup><img class="rendericon" height="7" alt="" src="http://wiki.javascud.org/images/icons/linkext7.gif" width="7" align="absMiddle" border="0" /></sup></a> </span> <br /> <span id="kueiuka" class="nobr"> <a title="Visit page outside Confluence" rel="nofollow">OpenQA的Selenium Core Wiki <sup><img class="rendericon" height="7" alt="" src="http://wiki.javascud.org/images/icons/linkext7.gif" width="7" align="absMiddle" border="0" /></sup></a> </span> <br /> <span id="wewissi" class="nobr"> <a title="Visit page outside Confluence" rel="nofollow">OpenQA的Selenium IDE Wiki <sup><img class="rendericon" height="7" alt="" src="http://wiki.javascud.org/images/icons/linkext7.gif" width="7" align="absMiddle" border="0" /></sup></a> </span> <br /> <span id="meqiwoe" class="nobr"> <a title="Visit page outside Confluence" rel="nofollow">OpenQA的Selenium Selenium on Rails Wiki <sup><img class="rendericon" height="7" alt="" src="http://wiki.javascud.org/images/icons/linkext7.gif" width="7" align="absMiddle" border="0" /></sup></a> </span> <br /> <span id="ksoqayo" class="nobr"> <a title="Visit page outside Confluence" href="/Nicholas/archive/2006/11/02/78725.html" rel="nofollow">Nicholas的用Seleniumq行功能试 <sup><img class="rendericon" height="7" alt="" src="http://wiki.javascud.org/images/icons/linkext7.gif" width="7" align="absMiddle" border="0" /></sup></a> </span> <br /> <span id="eeqswcc" class="nobr"> <a title="Visit page outside Confluence" href="/iamtin/archive/2006/10/30/78137.html" rel="nofollow">Tin的Selenium做功能测试的一点讨?/a> </span> </p> <img src ="http://www.tkk7.com/iamtin/aggbug/80902.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/iamtin/" target="_blank">Tin</a> 2006-11-13 15:31 <a href="http://www.tkk7.com/iamtin/archive/2006/11/13/selenium_chinese_translation_start.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Selenium做功能测试的一点讨?061102 update)http://www.tkk7.com/iamtin/archive/2006/10/30/78137.htmlTinTinMon, 30 Oct 2006 13:33:00 GMThttp://www.tkk7.com/iamtin/archive/2006/10/30/78137.htmlhttp://www.tkk7.com/iamtin/comments/78137.htmlhttp://www.tkk7.com/iamtin/archive/2006/10/30/78137.html#Feedback3http://www.tkk7.com/iamtin/comments/commentRss/78137.htmlhttp://www.tkk7.com/iamtin/services/trackbacks/78137.htmlselenium的Remote Control比较适合在需求阶D就撰写Q当然Fit方式也可以先于实现写Q,作ؓ验收的测试。好处是RC寚w构支持相对好一些,而且你可以换AgentQ也可以做浏览器兼容试。(但是׃RC的限Ӟ兼容侧试兼容性ƈ不好Q)
按照raimudox所说RC是更加Pragmatic的实践,更能体现敏捷软g开发的试先行的特性。功能测试可以说是沟通用户与开发者的最佛_U?br />Selenium IDE录制script适合作ؓ基线保留Q指先实现需求,后录制测试这L序Q,作ؓ某次重构之前的样本。或者说Q如果觉得手写测试脚本太ȝQ而喜Ƣ本末倒置Q没有贬义,U技术上Q的计的。更现实的说Q这很有用,比如一个项目从一半开始敏h造,引入功能试、单元测试,对以后的q代q行基线的衡量,l新引入的CIQ持l集成)一个更有实际意义的试保障Q用Selenium IDE帮助生成一下ScriptQ然后再使用RC或者直接用Core执行一下都是不错的实践。而Fit方式Q这里指先于应用实现写出来的基于html/table的Fit式测试)Q相对吸引力差一些,因ؓ工作量与RC总Q重构支持比较差Q而且没有DSL风格的封装,读v来相对费解一些?br />q有Q据Nicholas同学实践QSelenium IDE所录制的script在IDE中执行比RC方式兼容性要好,其对于跨域的情况,RC很有可能是无法工作的。还有一个问题,是Selenium实际上是ThoughtWorks和BEA牵头的项目,TW负责CoreQ目前Core的代码发展的必较快,而RC由BEA负责Q发展比较缓慢,所以,有些时候选择也就成ؓ无奈了?br />061102补充Q?br />1、Selenium目前有做不到的地方:例如<input type="file"/>的情况,׃安全问题Q浏览器是不允许通过javascript|里面的value的,所以selenium在此时会处于无能为力的情c比较郁闗虽然强行修改如Mozzila的安全属性可以办Q但那不是好办法?br />2、对于拥有复杂的Ajax widget的应用测试可能会非常ȝQ因为需要写很多javascript api在测试里面,寚w构支持差Q如api发生变化修改unit test很麻烦,而且可能出现需要对你的试q行试的尴情况)。当然对于大部分的ajax应用Selenium都是很好的选择?br />3、大安很看好的Remote Control方式发展比较慢,APIq不够友好(l常抛出奇怪的异常Q,Bugq是比较多。所以还需要耐心{待Q要多些像我们这L白?D
推荐大家看看我的同事nicholas的这:?Selenium q行功能试
羃一下:
1、何时、何目的来用Selenium选择不同。RC、Fit适合从需求阶D就开始写。而IDE录制则适合后补?br />2、重构支持。RC重构友好一些。Fit重构不友好?br />3、IDE目前限定于FFQ做跨浏览器RC比较好。但是IDE录制后的代码很方便{为RC方式?br />4、跨域兼Ҏ问题,IDE解决的比较好?/font>

Tin 2006-10-30 21:33 发表评论
]]>
վ֩ģ壺 ձѸƵ| ޳AVƬ| AVһ| ҹþþþƷӰԺ| aëƬȫ| պƷƵһ | պһ| ѹƵȫվ| ޸ľƷ26U| ѿƵ| þþþþþAv | eeussӰԺ| ëƬav߲һ| ޱٸ뼤| պӰ߹ۿƵ| ˬ AVˬ| hƵ߹ۿվ| ƵƷ߹ۿ| 999þþѾƷ| ػaaëƬƵ| www޾Ʒþþձ| þѵľƷV| ޹ۺרӰ| 2020ΪĻѹۿȫ| ޹ƷȾþ| ÿ߹ۿapp| ҹƵ | 1024ƷƵר| վ߹ۿ| ޳ҹӰ| Ů18ëƬaëƬ| ޹Ʒ99þþþþ| պߵӰ| ޾Ʒ鶼| Ʒ99Ʒþ| ٶ100%ڵѹۿ| wwww߹ۿ| Ƶһ| վɫƵ߹ۿaվ | պavþþƷ| hƵ߹ۿ|