<?xml version="1.0" encoding="gb2312"?>
<rss version="2.0">
<channel>
<title><![CDATA[I&#39;m learning,I&#39;m thinking]]></title>
        <image>
        <title>http://hi.baidu.com</title>
        <link>http://hi.baidu.com</link>
        <url>http://img.baidu.com/img/logo-hi.gif</url>
        </image>
<description><![CDATA[记录Daniel的学习过程和体验]]></description>
<link>http://hi.baidu.com/dearhwj</link>
<language>zh-cn</language>
<generator>www.baidu.com</generator>
<ttl>5</ttl>


<item>
        <title><![CDATA[博客搬家了]]></title>
        <link><![CDATA[http://hi.baidu.com/dearhwj/blog/item/65478d08e4ea0f9c0b7b8259.html]]></link>
        <description><![CDATA[
		
		博客搬新家了，网址是<a target="_blank" href="http://www.daniel-journey.com/">http://www.daniel-journey.com/</a>  RSS的地址是<a href="http://feed.feedsky.com/imlearningimthinking" target="_blank">http://feed.feedsky.com/imlearningimthinking</a><br>
欢迎大家在新空间中跟我交流 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/dearhwj/blog/category/%C4%AC%C8%CF%B7%D6%C0%E0">默认分类</a>&nbsp;<a href="http://hi.baidu.com/dearhwj/blog/item/65478d08e4ea0f9c0b7b8259.html#comment">查看评论</a>]]></description>
        <pubDate>2009-06-20  07:09</pubDate>
        <category><![CDATA[默认分类]]></category>
        <author><![CDATA[dearhwj]]></author>
		<guid>http://hi.baidu.com/dearhwj/blog/item/65478d08e4ea0f9c0b7b8259.html</guid>
</item>

<item>
        <title><![CDATA[何去何从想不清楚]]></title>
        <link><![CDATA[http://hi.baidu.com/dearhwj/blog/item/5464b30ebc88dac37bcbe1a8.html]]></link>
        <description><![CDATA[
		
		&nbsp;&nbsp;&nbsp;  最近一直都在思考应该说是迷茫自己的接下来3-4年要走的路，是留在目前的公司发展，保存一份稳定的收入呢，还是多冒一点的风险去一家小公司发展，代价就是这两年的工资都会被降很多。想离开现有公司的主要原因是自己搞了很长时间的企业软件开发做的都是一些类似CRM的东西，在目前的公司也是继续这样的工作，从自己心底愿望上讲看好中国互联网的发展，想有机会自己也建立和运营这样的一个网站。但目前无论技术上和管理上都没有相应的知识和经验的积累。去小公司就可以有这样的机会，而在现在的公司只能做一些技术方面的研究了,苦恼ing......。另外，下定决心购买自己的域名和blog空间，会在新空间上继续自己的blog。 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/dearhwj/blog/category/%C8%CB%C9%FA%D0%F5%D3%EF">人生絮语</a>&nbsp;<a href="http://hi.baidu.com/dearhwj/blog/item/5464b30ebc88dac37bcbe1a8.html#comment">查看评论</a>]]></description>
        <pubDate>2009-06-18  05:23</pubDate>
        <category><![CDATA[人生絮语]]></category>
        <author><![CDATA[dearhwj]]></author>
		<guid>http://hi.baidu.com/dearhwj/blog/item/5464b30ebc88dac37bcbe1a8.html</guid>
</item>

<item>
        <title><![CDATA[为什么要编写单元测试-单元测试的优势及优点]]></title>
        <link><![CDATA[http://hi.baidu.com/dearhwj/blog/item/5e1e1009998c658ad1581bc6.html]]></link>
        <description><![CDATA[
		
		  由于博客搬家到了<a href="http://www.daniel-journey.com/" target="_blank">http://www.daniel-journey.com/ </a>该文章页被搬到新的地址<a href="http://www.daniel-journey.com/archives/73    " target="_blank">http://www.daniel-journey.com/archives/73 &nbsp;&nbsp;      </a><br>
为什么要编写单元测试？原因是单元测试有不少的优点，能够给我们的工作带来很大的帮助。<br>
<strong>单元测试的优点</strong><br>
<br>
&nbsp;&nbsp;&nbsp;       <strong>1.帮助开发人员编写代码，提升质量、减少bug。</strong>如果大家分析一下我们bug原因的构成，我想有会有一部分bug的原因是开发人员在编写工作代码的时候没有考虑到某些case或者边际条件。造成这种问题的原因很多，其中很重要的一个原因是我们对工作代码所要完成的功能思考不足，而编写单元测试，特别是先写单元测试再写工作代码就可以帮助开发人员思考编写的代码到底要实现哪些功能。例如实现一个简单的用户注册功能的业务类方法，用单元测试再写工作代码的方式来工作的话<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;       开发人员就会先考虑各种场景相关，例如正常注册、用户名重复、没有满足必要的填写内容......等等，之后就会编写相关的测试用例<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;       public Class UserSerivceTest(){<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;       &nbsp;&nbsp;&nbsp;       public userRegister_Ok(){<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;       &nbsp;&nbsp;&nbsp;       &nbsp;&nbsp;&nbsp;       ......<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;       &nbsp;&nbsp;&nbsp;       }<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;       &nbsp;&nbsp;&nbsp;       public userRegister_nameDuplicated(){<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;       &nbsp;&nbsp;&nbsp;       &nbsp;&nbsp;&nbsp;       ......<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;       &nbsp;&nbsp;&nbsp;       }<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;       &nbsp;&nbsp;&nbsp;       public userRegister_emailEmpty(){<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;       &nbsp;&nbsp;&nbsp;       &nbsp;&nbsp;&nbsp;       ......<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;       &nbsp;&nbsp;&nbsp;       }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;       }<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;       编写单元测试代码的过程就是促使开发人员思考工作代码实现内容和逻辑的过程，之后实现工作代码的时候，开发人员思路会更清晰，实现代码的质量也会有相应的提升。<br>
<br>
&nbsp;&nbsp;&nbsp;       <strong>2. 提升反馈速度，减少重复工作，提高开发效率。</strong>开发人员实现某个功能或者修补了某个bug，如果有相应的单元测试支持的话，开发人员可以马上通过运行单元测试来验证之前完成的代码是否正确，而不需要反复通过发布war包、启动jboss、通过浏览器输入数据等繁琐的步骤来验证所完成的功能。用单元测试代码来验证代码和通过发布应用以人工的方式来验证代码这两者的效率差很多，看到很多开发人员每天要反复执行N次发布脚本（antx之类的工具）真是痛苦。<br>
&nbsp;&nbsp;&nbsp;<strong> 3.保证你最后的代码修改不会破坏之前代码的功能。</strong>项目越做越大，代码越来越多，特别涉及到一些公用接口之类的代码或是底层的基础库，谁也不敢保证这次修改的代码不会破坏之前的功能，所以与此相关的需求会被搁置或推迟，由于不敢改进代码，代码也变得越来越难以维护，质量也越来越差。而单元测试就是解决这种问题的很好方法（不敢说最好的）。由于代码的历史功能都有相应的单元测试保证，修改了某些代码以后，通过运行相关的单元测试就可以验证出新调整的功能是否有影响到之前的功能。当然要实现到这种程度需要很大的付出，不但要能够达到比较高的测试覆盖率，而且单元测试代码的编写质量也要有保证。<br>
<br>
&nbsp;&nbsp;&nbsp;       <strong>4. 让代码维护更容易。</strong>由于给代码写很多单元测试，相当于给代码加上了规格说明书，开发人员通过读单元测试代码也能够帮助开发人员理解现有代码。很有opensource的项目都有相当量的单元测试代码，通过读这些测试代码会有助于理解生产源代码。<br>
<br>
&nbsp;&nbsp;&nbsp;       <strong>5. 有助于改进代码质量和设计。</strong>除了那些大拿们编写的代码，我相信很多易于维护、设计良好的代码都是通过不断的重构才得到的。虽然说单元测试本身不能直接改进生产代码的质量，但它为生产代码提供了&quot;安全网&quot;，让开发人员可以勇敢地改进代码，从而让代码的clean和beautiful不再是梦想。<br>
<br>
<strong>单元测试的缺点</strong><br>
<br>
&nbsp;&nbsp;&nbsp;       <strong>1.单元测试的学习成本比较高</strong>。编写单元测试涉及的技术很多，如果只是单纯的使用Junit或是TestNG这样的基础单元测试框架往往很难应对各种复杂的单元测试情况，所以势必要借助很多第三方的框架和技术（easymock,jmock,dbunit等等），这些框架和技术的学习还是会增加学习的成本和难度。<br>
&nbsp;&nbsp;&nbsp;<strong> 2.编写单元测试会增加程序员工作量。</strong>单元测试跟生产代码是一样的，并不会应为是用来测试的就有所不同，开发人员同样要面对测试代码的编写、维护等工作，也同样要面对避免重复代码等一系列问题，能否写出好的测试代码还是取决于开发人员的设计和编码能力。<br>
&nbsp;&nbsp;&nbsp;       <strong>3. 推广和运用单元测试需要比较大的投入。</strong>只有在每个开发人员都编写了足够的、质量好的单元测试代码，大家才能真正享受到单元测试带给我们的好处。在达到这种层度以前，还需要不少实现和资源的投入。<br>
<br>
<strong>总结</strong><br>
<br>
&nbsp;&nbsp;       虽然单元测试也有一些缺点和负面的效应，但跟单元测试的优点比较起来，为了克服和解决这些缺点所在的付出是值得的。<br>
<br>
相关文章<br>
<a target="_blank" href="http://hi.baidu.com/dearhwj/blog/item/349a1000f3713519738b6544.html">单元测试的基本概念</a><br>
<a target="_blank" href="http://hi.baidu.com/dearhwj/blog/item/7c380b80664eeedf9123d9a2.html">推荐一个优秀的Java单元测试框架&mdash;&mdash;JTester</a><br>
<a href="http://hi.baidu.com/dearhwj/blog/item/b4b636361222c1390b55a956.html" target="_blank">关于《单元测试的七种境界》的自我总结</a> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/dearhwj/blog/category/tdd%28%B2%E2%CA%D4%C7%FD%B6%AF%29">tdd(测试驱动)</a>&nbsp;<a href="http://hi.baidu.com/dearhwj/blog/item/5e1e1009998c658ad1581bc6.html#comment">查看评论</a>]]></description>
        <pubDate>2009-06-10  13:13</pubDate>
        <category><![CDATA[tdd(测试驱动)]]></category>
        <author><![CDATA[dearhwj]]></author>
		<guid>http://hi.baidu.com/dearhwj/blog/item/5e1e1009998c658ad1581bc6.html</guid>
</item>

<item>
        <title><![CDATA[引用：单元测试的基本概念]]></title>
        <link><![CDATA[http://hi.baidu.com/dearhwj/blog/item/349a1000f3713519738b6544.html]]></link>
        <description><![CDATA[
		
		&nbsp;&nbsp;    这几天在准备一个给部门内部的单元测试的介绍，所以想说明一些单元测试的基本概念。google了一下，发现一篇整理了不错的文章<a href="http://tech.it168.com/softtest/2008-05-24/200805242235667.shtml" target="_blank">《单元测试的基本概念》</a>，所以直接转载了，原文内容如下。<br>
&nbsp;&nbsp;    <br>
&nbsp;&nbsp;&nbsp;    要减少软件中的错误数目，方法之一就是拥有一个专业的测试组，其工作就是尽一切可能使软件崩溃。不幸的是，如果拥有测试组，那么即使是经验丰富的开发人员，也会倾向于花费较少的时间来保证代码的可靠性。
<p>&nbsp;&nbsp;&nbsp;    软件界有一句俗语：&ldquo;开发人员不应该测试他们自己的代码&rdquo;。这是因为开发人员对自己的代码了如指掌，他们很清楚如何采用适当的方法对代码进行测试。尽管这 句俗语很有道理，但却忽略了非常重要的一点 - 如果开发人员不对自己的代码进行测试，又如何知道代码能否按照预期的方式运行？</p>
<p>&nbsp;&nbsp;&nbsp;    简单说来，他们根本无从得知。开发人员编写那种运行不正常或只在某些情况下运行正常的代码是一个严重的问题。他们通常只测试代码能否在很少的情况下正常运行，而不是验证代码能够在所有情况下均正常运行。</p>
<p>&nbsp;&nbsp;&nbsp;    发现软件错误的情况有很多：</p>
<p>&nbsp;&nbsp;&nbsp;    1.由首次编写代码的开发人员发现。 <br>
&nbsp;&nbsp;&nbsp;    2.由尝试运行代码的开发人员发现。 <br>
&nbsp;&nbsp;&nbsp;    3.由组中的其他开发人员或测试人员发现。 <br>
&nbsp;&nbsp;&nbsp;    4.作为产品大规模测试的一部分。 <br>
&nbsp;&nbsp;&nbsp;    5.由最终用户发现。</p>
<p>&nbsp;&nbsp;&nbsp;    如果在第一种情况下发现软件错误，则修复错误比较容易，成本也很低。情况越靠后，修复软件错误的成本就越高；修复一个由最终用户发现的软件错误可能要耗费 100 或 1000 倍的成本。更不用说用户通常因为软件错误导致工作无法继续，而一直等到下一个版本才能解决问题。<br>
&nbsp;&nbsp;&nbsp;    如果开发人员能够在编写代码期间发现所有的软件错误，那就再好不过了。为此，您必须编写能在编写代码时运行的测试。</p>
<p>&nbsp;&nbsp;&nbsp;    测试是软件开发的重要环节之一。按照软件开发的过程测试可分为：单元测试、功能测试、性能测试、性能测试、集成测试、系统测试、域测试（Field test）等。我们这里将主要研究的是面向程序员的单元测试。</p>
<p>&nbsp;&nbsp;&nbsp;    <strong>什么是单元测试  </strong></p>
<p>&nbsp;&nbsp;&nbsp;    单元测试是开发者编写的一小段代码，用于检验被测代码中的一个很明确的功能是否正确。通常而言，一个单元测试是用于判断某个特定条件（或者场景）下某个特 定函数的行为。例如，你可能把一个很大的值放入一个有序list 中去，然后确认该值出现在list 的尾部。或者，你可能会从字符串中删除匹配某种模式的字符，然后确认字符串确实不再包含这些字符了。</p>
<p>&nbsp;&nbsp;&nbsp;    单元测试是由程序员自己来完成，最终受益的也是程序员自己。可以这么说，程序员有责任编写功能代码，同时也就有责任为自己的代码编写单元测试。执行单元测试，就是为了证明这段代码的行为和我们期望的一致。</p>
<p>&nbsp;&nbsp;&nbsp;    <strong>为什么要使用单元测试</strong></p>
<p>&nbsp;&nbsp;&nbsp;    我们编写代码时，一定会反复调试保证它能够编译通过。如果是编译没有通过的代码，没有任何人会愿意交付给自己的客户。但代码通过编译，只是说明了它的语法正确；我们却无法保证它的语义也一定正确，没有任何人可以轻易承诺这段代码的行为一定是正确的。</p>
<p>&nbsp;&nbsp;&nbsp;    幸运，单元测试会为我们的承诺做保证。编写单元测试就是用来验证这段代码的行为是否与我们期望的一致。有了单元测试，我们可以自信的交付自己的代码，而没有任何的后顾之忧。</p>
<p>&nbsp;&nbsp;&nbsp;    单元测试有下面的这些优点：</p>
<p>&nbsp;&nbsp;&nbsp;    1、它是一种验证行为。</p>
<p>&nbsp;&nbsp;&nbsp;    程序中的每一项功能都是测试来验证它的正确性。它为以后的开发提供支缓。就算是开发后期，我们也可以轻松的增加功能或更改程序结构，而不用担心这个过程中会破坏重要的东西。而且它为代码的重构提供了保障。这样，我们就可以更自由的对程序进行改进。</p>
<p>&nbsp;&nbsp;&nbsp;    2、它是一种设计行为。</p>
<p>&nbsp;&nbsp;&nbsp;    编写单元测试将使我们从调用者观察、思考。特别是先写测试（test-first），迫使我们把程序设计成易于调用和可测试的，即迫使我们解除软件中的耦合。</p>
<p>&nbsp;&nbsp;&nbsp;    3、它是一种编写文档的行为。</p>
<p>&nbsp;&nbsp;&nbsp;    单元测试是一种无价的文档，它是展示函数或类如何使用的最佳文档。这份文档是可编译、可运行的，并且它保持最新，永远与代码同步。</p>
<p>&nbsp;&nbsp;&nbsp;    4、它具有回归性。</p>
&nbsp;&nbsp;&nbsp;    自动化的单元测试避免了代码出现回归，编写完成之后，可以随时随地的快速运行测试。<br>
<br>
&nbsp;&nbsp;&nbsp;    <strong>单元测试的范畴  </strong>
<p>&nbsp;&nbsp;&nbsp;    如果要给单元测试定义一个明确的范畴，指出哪些功能是属于单元测试，这似乎很难。但下面讨论的四个问题，基本上可以说明单元测试的范畴，单元测试所要做的工作。</p>
<p>&nbsp;&nbsp;&nbsp;    1、 它的行为和我期望的一致吗？</p>
<p>&nbsp;&nbsp;&nbsp;    这是单元测试最根本的目的，我们就是用单元测试的代码来证明它所做的就是我们所期望的。<br>
<br>
&nbsp;&nbsp;&nbsp;    2、 它的行为一直和我期望的一致吗？</p>
<p>&nbsp;&nbsp;&nbsp;    编写单元测试，如果只测试代码的一条正确路径，让它正确走一遍，并不算是真正的完成。软件开发是一个项复杂的工程，在测试某段代码的行为是否和你的期望一 致时，你需要确认：在任何情况下，这段代码是否都和你的期望一致；譬如参数很可疑、硬盘没有剩余空间、缓冲区溢出、网络掉线的时候。</p>
<p>&nbsp;&nbsp;&nbsp;    3、 我可以依赖单元测试吗？</p>
<p>&nbsp;&nbsp;&nbsp;    不能依赖的代码是没有多大用处的。既然单元测试是用来保证代码的正确性，那么单元测试也一定要值得依赖。</p>
<p>&nbsp;&nbsp;&nbsp;    4、 单元测试说明我的意图了吗？</p>
<p>&nbsp;&nbsp;&nbsp;    单元测试能够帮我们充分了解代码的用法，从效果上而言，单元测试就像是能执行的文档，说明了在你用各种条件调用代码时，你所能期望这段代码完成的功能。</p>
<p>&nbsp;&nbsp;&nbsp;    <strong>不写测试的借口</strong></p>
<p>&nbsp;&nbsp;&nbsp;    到这里，我们已经知道了使用单元测试的种种理由。但目前的实际情况是大多数程序员不进行单元测试，或只进行简单的单元测试。下面是一些他们常用的接口：</p>
<p>&nbsp;&nbsp;&nbsp;    1、 编写单元测试太花时间了。</p>
<p>&nbsp;&nbsp;&nbsp;    我们知道，在开发时越早发现BUG，就能节省更多的时间，降低更多的风险。如果你仍然认为在编写产品代码的时候，还是没有时间编写测试代码，那么请先考虑下面这些问题：</p>
<p>&nbsp;&nbsp;&nbsp;    1）、对于所编写的代码，你在调试上面花了多少时间。<br>
&nbsp;&nbsp;&nbsp;    2）、对于以前你自认为正确的代码，而实际上这些代码却存在重大的bug，你花了多少时间在重新确认这些代码上面。<br>
&nbsp;&nbsp;&nbsp;    3）、对于一个别人报告的bug，你花了多少时间才找出导致这个bug 的源码位置。<br>
&nbsp;&nbsp;&nbsp;    回答完这些问题，你一定不再以&ldquo;太花时间&rdquo;作为拒绝单元测试的借口。</p>
<p>&nbsp;&nbsp;&nbsp;    2、 运行测试的时间太长了。</p>
<p>&nbsp;&nbsp;&nbsp;    合适的测试是不会让这种情况发生的。实际上，大多数测试的执行都是非常快的，因此你在几秒之内就可以运行成千上万个测试。但是有时某些测试会花费很长的时间。这时，需要把这些耗时的测试和其他测试分开。通常可以每天运行这种测试一次，或者几天一次。</p>
<p>&nbsp;&nbsp;&nbsp;    3、 测试代码并不是我的工作。</p>
<p>&nbsp;&nbsp;&nbsp;    你的工作就是保证代码能够正确的完成你的行为，恰恰相反，测试代码正是你不可缺少的工作。</p>
<p>&nbsp;&nbsp;&nbsp;    4、 我并不清楚代码的行为，所以也就无从测试。</p>
<p>&nbsp;&nbsp;&nbsp;    如果你实在不清楚代码的行为，那么估计现在并不是编码的时候。如果你并不知道代码的行为，那么你又如何知道你编写的代码是正确的呢?</p>
<p>&nbsp;&nbsp;&nbsp;    5、 但是这些代码都能够编译通过。</p>
<p>&nbsp;&nbsp;&nbsp;    我们前面已经说过，代码通过编译只是验证它的语法通过。但并不能保证它的行为就一定正确。</p>
<p>&nbsp;&nbsp;&nbsp;    6、 公司请我来是为了写代码，而不是写测试。</p>
<p>&nbsp;&nbsp;&nbsp;    公司付给你薪水是为了让你编写产品代码，而单元测试大体上是一个工具，是一个和编辑器、开发环境、编译器等处于同一位置的工具。</p>
<p>&nbsp;&nbsp;&nbsp;    7、 如果我让测试员或者QA（Quality Assurance）人员没有工作，那么我会觉得很内疚。</p>
<p>&nbsp;&nbsp;&nbsp;    你并不需要担心这些。请记住，我们在此只是谈论单元测试，而它只是一种针对源码的、低层次的，为程序员而设计的测试。在整个项目中，还有其他的很多测试需要这些人来完成，如：功能测试、验收测试、性能测试、环境测试、有效性测试、正确性测试、正规分析等等。</p>
<p>&nbsp;&nbsp;&nbsp;    8、 我的公司并不会让我在真实系统中运行单元测试。</p>
<p>&nbsp;&nbsp;&nbsp;    我们所讨论的只是针对开发者的单元测试。也就是说，如果你可以在其他的环境下（例如在正式的产品系统中）运行这些测试的话，那么它们就不再是单元测试，而是其他类型的测试了。实际上，你可以在你的本机运行单元测试，使用你自己的数据库。</p>
<p>&nbsp;&nbsp;&nbsp;    总而言之，单元测试会让我们的开发工作变得更加轻松，让我们对自己的代码更加自信。无论是大型项目还是小型项目，无论是时间紧迫的项目还是时间宽裕的项目，只要代码不是一次写完永不改动，编写单元测试就一定超值，它已成为我们编码不可缺少的一部分。</p>
<p> </p>
<p>其他相关资料</p>
<p><a href="http://en.wikipedia.org/wiki/Unit_testing" target="_blank">Unit testing</a></p> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/dearhwj/blog/category/tdd%28%B2%E2%CA%D4%C7%FD%B6%AF%29">tdd(测试驱动)</a>&nbsp;<a href="http://hi.baidu.com/dearhwj/blog/item/349a1000f3713519738b6544.html#comment">查看评论</a>]]></description>
        <pubDate>2009-06-10  09:42</pubDate>
        <category><![CDATA[tdd(测试驱动)]]></category>
        <author><![CDATA[dearhwj]]></author>
		<guid>http://hi.baidu.com/dearhwj/blog/item/349a1000f3713519738b6544.html</guid>
</item>

<item>
        <title><![CDATA[申请了Ubuntu9.04的光盘]]></title>
        <link><![CDATA[http://hi.baidu.com/dearhwj/blog/item/fdeb0aef7d83ad3eacafd5be.html]]></link>
        <description><![CDATA[
		
		&nbsp;&nbsp;    依照<a href="http://wiki.ubuntu.org.cn/" target="_blank">wiki.ubuntu.org.cn</a>上的<a href="http://wiki.ubuntu.org.cn/%E7%94%B3%E8%AF%B7Ubuntu%E5%85%8D%E8%B4%B9%E5%85%89%E7%9B%98%E7%9A%84%E5%85%A8%E7%A8%8B%E6%8C%87%E5%AF%BC" target="_blank">申请Ubuntu免费光盘的全程指导</a> 申请了Ubuntu9.04的光盘。接下来就是等待光盘了，说是要4-6周才能送到。另外Ubuntu9.04硬盘安装的方法网上也有，地址如下 <a target="_blank" href="http://tech.ccidnet.com/art/302/20090424/1750209_1.html">http://tech.ccidnet.com/art/302/20090424/1750209_1.html</a> 这个安装方法我试过OK的！<br>
&nbsp;&nbsp; 
<div forimg="1"><img border="0" class="blogimg" small="0" src="http://hiphotos.baidu.com/dearhwj/pic/item/0a1ad138cd30bad7b211c784.jpg"></div> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/dearhwj/blog/category/Linux">Linux</a>&nbsp;<a href="http://hi.baidu.com/dearhwj/blog/item/fdeb0aef7d83ad3eacafd5be.html#comment">查看评论</a>]]></description>
        <pubDate>2009-06-03  12:49</pubDate>
        <category><![CDATA[Linux]]></category>
        <author><![CDATA[dearhwj]]></author>
		<guid>http://hi.baidu.com/dearhwj/blog/item/fdeb0aef7d83ad3eacafd5be.html</guid>
</item>

<item>
        <title><![CDATA[免费的google短信天气预报]]></title>
        <link><![CDATA[http://hi.baidu.com/dearhwj/blog/item/fdeb0aef789ba83eacafd586.html]]></link>
        <description><![CDATA[
		
		&nbsp;&nbsp;  google真是个有钱的主，通过google可以免费订阅短信天气预报。订阅网址为<a href="http://www.google.com/sms/alerts" target="_blank">http://www.google.com/sms/alerts</a>。不爽的地方这个短信天气预报服务需要每个月底去激活下个月的订阅，比较麻烦。<br>
&nbsp;&nbsp; 
<div forimg="1"><img border="0" src="http://hiphotos.baidu.com/dearhwj/pic/item/8ee11833fc3be266ac4b5f7e.jpg" small="0" class="blogimg"></div> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/dearhwj/blog/category/Google">Google</a>&nbsp;<a href="http://hi.baidu.com/dearhwj/blog/item/fdeb0aef789ba83eacafd586.html#comment">查看评论</a>]]></description>
        <pubDate>2009-06-02  09:03</pubDate>
        <category><![CDATA[Google]]></category>
        <author><![CDATA[dearhwj]]></author>
		<guid>http://hi.baidu.com/dearhwj/blog/item/fdeb0aef789ba83eacafd586.html</guid>
</item>

<item>
        <title><![CDATA[推荐一个优秀的Java单元测试框架——JTester]]></title>
        <link><![CDATA[http://hi.baidu.com/dearhwj/blog/item/7c380b80664eeedf9123d9a2.html]]></link>
        <description><![CDATA[
		
		<strong><font size="4">JTester</font><font size="4">简介</font></strong><br>
1、在unitils的基础，集成了jmock功能。<br>
2、在hamcrest断言的基础上，实现了fluent interface断言。<br>
3、改造了jmock expectation参数断言为fluent interface形式<br>
4、提供了将普通的pojo对象序列化到文件，然后再从文件中反序列化回来的功能，用于在对象复杂的情况下，直接录制接口（远程接口）调用返回的对象，以供下次测试或调试使用。<br>
5、使用wiki代替xml来准备测试数据。<br>
6、实现了更加丰富的断言。<br>
7、提供了hibernate annotation环境下，直接使用内存数据库进行db测试。<br>
8、提供了hibernate annotation环境下，Open Test in Session的实现。<br>
<br>
&nbsp;&nbsp;  熟悉Java单元测试的同学应该能体会到对Java程序如果只是单纯的使用Junit或是TestNG这样的基础单元测试框架往往很难应对各种复杂的单元测试情况，所以势必要借助很多第三方的框架和技术（easymock,jmock,dbunit等等）。而这些框架和技术的学习又会增加学习的成本和难度，所以有人在这些java基础单元测试的工具基础上开发一些测试框架(如unitils)将多种Java单元测试技术整合在一起，提高开发效率。JTester的目的也是一样，在作者精心的开发和维护的基础上，已经拥有了强大的功能和稳定的质量。希望对Java的单元测试技术感兴趣的同学能加以使用，对JTester有功能需求的同学可以跟作者    Darui.wu 或者我联系<br>
<br>
<strong><font size="4">相关资料</font></strong><br>
项目主页http://code.google.com/p/java-tester/ 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/dearhwj/blog/category/tdd%28%B2%E2%CA%D4%C7%FD%B6%AF%29">tdd(测试驱动)</a>&nbsp;<a href="http://hi.baidu.com/dearhwj/blog/item/7c380b80664eeedf9123d9a2.html#comment">查看评论</a>]]></description>
        <pubDate>2009-06-01  18:29</pubDate>
        <category><![CDATA[tdd(测试驱动)]]></category>
        <author><![CDATA[dearhwj]]></author>
		<guid>http://hi.baidu.com/dearhwj/blog/item/7c380b80664eeedf9123d9a2.html</guid>
</item>

<item>
        <title><![CDATA[Firefox保存、打开mht-单一网页文件]]></title>
        <link><![CDATA[http://hi.baidu.com/dearhwj/blog/item/ba8066efff93441efdfa3cbc.html]]></link>
        <description><![CDATA[
		
		&nbsp;&nbsp;&nbsp;     平时习惯用mht保存在网上找到的一些网页资料（都是借助IE），最近把操作系统更换成了Ubuntu, 需要用Firefox来保存和打开mht，原生的firefox不支持mht,可已经有热心的同学开发了相应的插件使firefox也可以支持mht.<br>
<strong><font size="3">什么是mh</font><font size="3">t</font></strong><br>
&nbsp;&nbsp;      mht又叫&ldquo;web单一文件&rdquo;也就是将网页中包含的图片，CSS文件以及HTML文件全部放到一个MHT文件里面。mht就是mono html，就是独立的HTML文件，在浏览器特别是IE在save as时将页面中所有可以收集的元素全部存放在一个页面里。<br>
<br>
<strong><font size="3">Firefox支持mht吗</font><font size="3">？</font></strong><br>
&nbsp;&nbsp;      微软的IE6＋原生就可以很好的支持mht，而firefox必须要借助    UnMHT 扩展才能处理mht，&nbsp;&nbsp;      UnMHT <a target="_blank" href="http://www.unmht.org/en_index.html">项目主页。 </a><br>
  安装完毕以后，firefox就会出现以下的内容,OK搞定<br>
 
<div forimg="1"><img border="0" src="http://hiphotos.baidu.com/dearhwj/pic/item/68498afbcb4aeb41024f5677.jpg" small="0" class="blogimg"></div>
<br> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/dearhwj/blog/category/%D3%A6%D3%C3%B3%CC%D0%F2">应用程序</a>&nbsp;<a href="http://hi.baidu.com/dearhwj/blog/item/ba8066efff93441efdfa3cbc.html#comment">查看评论</a>]]></description>
        <pubDate>2009-05-29  08:07</pubDate>
        <category><![CDATA[应用程序]]></category>
        <author><![CDATA[dearhwj]]></author>
		<guid>http://hi.baidu.com/dearhwj/blog/item/ba8066efff93441efdfa3cbc.html</guid>
</item>

<item>
        <title><![CDATA[Eclipse的Java单元测试小工具moreunit]]></title>
        <link><![CDATA[http://hi.baidu.com/dearhwj/blog/item/37ab6a6499f1a0f8f636546a.html]]></link>
        <description><![CDATA[
		
		文章内容迁移到了 <a href="http://www.daniel-journey.com/archives/182" target="_blank">http://www.daniel-journey.com/archives/182</a><br>
<a target="_blank" href="http://moreunit.sourceforge.net/"> moreUnit</a>是一个Eclipse的插件，为编写Java的单元测试提供了很多辅助的功能，提高了编写和管理Java单元测试(Junit或者TestNG)的效率。主要的功能有以下几点<br>
1.标志出哪些类是有单元测试支持的。<br>
2.标志出那些方法是有单元测试支持的。<br>
3.对类或者方法的名称进行重命名的时候会相应的重命名单元测试中的名称。<br>
4.移动类的时候moreUnit会相应的移动单元测试类。<br>
5.在工作类和测试类之间通过快捷方式实现(Ctrl+J)快速跳转，这个功能真是很方便<img src="http://img.baidu.com/hi/jx/j_0043.gif">。<br>
<br>
moreUnit的安装、配置和使用都很简单，moreUnit的文档也都配有截图，这里就不在做特别的说明了。提供链接，大家直接到项目网站上去看吧，<a target="_blank" href="http://moreunit.sourceforge.net/docu.html">moreUnit文档链接</a>。<br>
<br>
<br>
<strong><font size="3">相关资源</font></strong><br>
<a target="_blank" href="http://moreunit.sourceforge.net/">moreUnit<br>
</a> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/dearhwj/blog/category/tdd%28%B2%E2%CA%D4%C7%FD%B6%AF%29">tdd(测试驱动)</a>&nbsp;<a href="http://hi.baidu.com/dearhwj/blog/item/37ab6a6499f1a0f8f636546a.html#comment">查看评论</a>]]></description>
        <pubDate>2009-05-28  21:03</pubDate>
        <category><![CDATA[tdd(测试驱动)]]></category>
        <author><![CDATA[dearhwj]]></author>
		<guid>http://hi.baidu.com/dearhwj/blog/item/37ab6a6499f1a0f8f636546a.html</guid>
</item>

<item>
        <title><![CDATA[祝大家端午快乐]]></title>
        <link><![CDATA[http://hi.baidu.com/dearhwj/blog/item/1c50c8242e954023d40742b9.html]]></link>
        <description><![CDATA[
		
		&nbsp;&nbsp;  小时候端午的活动比较多，记忆最深的就是要吃粽子、<span class="dectext">佩香囊和</span>额上点雄黄。随着时代的发展传统的风俗在一点点的消失，而且&ldquo;端午&rdquo;这个传统的中国节日居然被某个小国申请成了自己的世界遗产，国人真是要认真思考如何保存、发展我们的优秀历史和文化。<br>
<strong><font size="4"> 吃粽子</font></strong><br>
 
<div forimg="1"><img border="0" src="http://hiphotos.baidu.com/dearhwj/pic/item/7f5d715164206a3c367abec2.jpg" small="0" class="blogimg"></div>
<br>
&nbsp;&nbsp;    <br>
&nbsp;&nbsp;  <strong><font size="4">点雄黄</font></strong><br>
&nbsp;&nbsp; 
<div forimg="1"><img border="0" src="http://hiphotos.baidu.com/dearhwj/pic/item/118290daebf6d5ffb6fd48cd.jpg" small="0" class="blogimg"></div>
<strong><font size="4">配香囊</font></strong><br>
<div forimg="1"><img border="0" src="http://hiphotos.baidu.com/dearhwj/pic/item/4d8df8dbdabbbe42d0164ed6.jpg" small="0" class="blogimg"></div> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/dearhwj/blog/category/%C8%CF%D5%E6%C9%FA%BB%EE">认真生活</a>&nbsp;<a href="http://hi.baidu.com/dearhwj/blog/item/1c50c8242e954023d40742b9.html#comment">查看评论</a>]]></description>
        <pubDate>2009-05-28  13:22</pubDate>
        <category><![CDATA[认真生活]]></category>
        <author><![CDATA[dearhwj]]></author>
		<guid>http://hi.baidu.com/dearhwj/blog/item/1c50c8242e954023d40742b9.html</guid>
</item>

<item>
        <title><![CDATA[鄙视PLSQL Developer的重构(refactoring)功能]]></title>
        <link><![CDATA[http://hi.baidu.com/dearhwj/blog/item/4655a227b6c2220b918f9d07.html]]></link>
        <description><![CDATA[
		
		<div forimg="1">&nbsp;&nbsp;   很多开发Oracle数据库应用的同学都喜欢使用PLSQL Developer，今天在开发存储过程的时候试用了一下PLSQL Developer的重构(refactoring)功能，修改的代码没有仔细check就提交QA MM测试了。谁知简单的Extract global constant功能都会失败，不知道这个功能是怎么通过QA的测试从而交付的。<br>
&nbsp;&nbsp;  注：我使用的PLSQL Developer的版本是7.1.0。<br>
<img border="0" class="blogimg" small="0" src="http://hiphotos.baidu.com/dearhwj/pic/item/f59d77fd2e920d3208244d04.jpg"></div> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/dearhwj/blog/category/Oracle">Oracle</a>&nbsp;<a href="http://hi.baidu.com/dearhwj/blog/item/4655a227b6c2220b918f9d07.html#comment">查看评论</a>]]></description>
        <pubDate>2009-05-27  15:17</pubDate>
        <category><![CDATA[Oracle]]></category>
        <author><![CDATA[dearhwj]]></author>
		<guid>http://hi.baidu.com/dearhwj/blog/item/4655a227b6c2220b918f9d07.html</guid>
</item>

<item>
        <title><![CDATA[Oracle的取整和四舍五入函数——floor,round,ceil,trunc使用说明]]></title>
        <link><![CDATA[http://hi.baidu.com/dearhwj/blog/item/fa951439b018e8fb3a87ce0c.html]]></link>
        <description><![CDATA[
		
		&nbsp;&nbsp;   看了<a target="_blank" href="http://www.electrictoolbox.com/">electrictoolbox</a>上对PHP，MYSQL，Javascript几种语言关于取整数的专题，也就依样画葫芦整理了Oracle的取整函数说明，这就是本文的由来。<br>
<br>
<strong><font size="4">FLOOR&mdash;&mdash;对给定的数字取整数位</font></strong><br>
SQL&gt; select floor(2345.67) from dual;<br>
<br>
FLOOR(2345.67)<br>
--------------<br>
2345<br>
<br>
<strong><font size="4">CEIL-- 返回大于或等于给出数字的最小整数</font></strong><br>
SQL&gt; select ceil(3.1415927) from dual;<br>
<br>
CEIL(3.1415927)<br>
---------------<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;     4<br>
<br>
<strong><font size="4">ROUND&mdash;&mdash;按照指定的精度进行<font color="#ff0000">四舍五入</font></font></strong><br>
SQL&gt; select round(3.1415926,4) from dual;<br>
<br>
ROUND(3.1415926,4)<br>
------------------<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;     3.1416<br>
<br>
<font size="4">TRUNC&mdash;&mdash;<strong>按照指定的精度进行<font color="#ff0000">截取</font>一个数</strong></font><br>
SQL&gt; select trunc(3.1415926,4) from dual;<br>
<br>
ROUND(3.1415926,4)<br>
------------------<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;     3.1415<br>
相关资源<br>
<a target="_blank" href="http://www.electrictoolbox.com/php-round-numbers/">Rounding numbers with PHP</a><br>
<a target="_blank" href="http://www.electrictoolbox.com/mysql-round-numbers/">Rounding numbers with MySQL</a><br>
<a target="_blank" href="http://www.electrictoolbox.com/ -round-numbers/">Rounding numbers with Javascript</a> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/dearhwj/blog/category/Oracle">Oracle</a>&nbsp;<a href="http://hi.baidu.com/dearhwj/blog/item/fa951439b018e8fb3a87ce0c.html#comment">查看评论</a>]]></description>
        <pubDate>2009-05-26  11:02</pubDate>
        <category><![CDATA[Oracle]]></category>
        <author><![CDATA[dearhwj]]></author>
		<guid>http://hi.baidu.com/dearhwj/blog/item/fa951439b018e8fb3a87ce0c.html</guid>
</item>

<item>
        <title><![CDATA[BeanUtils的copyProperties，populate实现方式分析以及容易引发的Bug]]></title>
        <link><![CDATA[http://hi.baidu.com/dearhwj/blog/item/7c1739193e05e772dab4bd0a.html]]></link>
        <description><![CDATA[
		
		<p style="text-indent: 21pt;" class="MsoNormal">该博客以及搬迁至<a target="_blank" href="http://www.daniel-journey.com/%20">http://www.daniel-journey.com/</a> 该文的新地址为<a href="http://www.daniel-journey.com/archives/72" target="_blank">http://www.daniel-journey.com/archives/72</a></p>
<p style="text-indent: 21pt;" class="MsoNormal"><strong>BeanUtils的copyProperties</strong>方法用来<span class="wenzhang_con" style="width: 740px;"><font color="#565656"><span>将<font color="#000000">orig中的成员变量的值复制给dest,即将已经存在的dest变为orig的副本</font></span></font></span>。<br>
&nbsp;&nbsp;&nbsp;     <font color="#0000ff">public void copyProperties(Object dest, Object orig) {<br>
&nbsp;&nbsp;             .......<br>
&nbsp;&nbsp;             } </font><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;           <strong>BeanUtils的populate方法</strong>用来将Map&lt;Key,value&gt;中的以值（String或String[]）转换到目标bean对应的属性中，Map中的Key是目标bean的属性名。  <br>
&nbsp;&nbsp;     <font color="#0000ff">        public static void populate(Object bean, Map properties){<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;             ......<br>
&nbsp;&nbsp;&nbsp;                  }</font><span><br>
</span></p>
<p style="text-indent: 21pt;" class="MsoNormal">copyProperties同样支持了populate中的功能（<font color="#ff0000">注</font><span class="wenzhang_con" style="width: 740px;"><font color="#565656"><span><font color="#ff0000">a</font><font color="#ff0000">pache的javadoc中,明确指明这个方法是为解析http请求参数特别定义和使用的,在正常的使用中不推荐使用.他们推荐使用BeanUtils.copyProperties方法</font><font color="#000000">）。</font></span></font></span></p>
<p style="text-indent: 21pt;" class="MsoNormal"><span>BeanUtils.</span>copyProperties和<span>populate</span><span>的实现方法是将源bean（也可以是</span><span>Map)</span><span>中的每个</span><span>element</span><span>在转换器（</span><span>Converter</span><span>）的帮助下</span><span>，将转换的结果设置到目标bean对应的属性中。例如在</span>HTTP应用中需要从http request中抽取数据,http request传递过来的都是String 或是String数组类型的变量而目标类型可能是各种各样的，例如http request会有一个name=visitDate，value='2009-05-13'的参数，而目标bean 的visitDate属性的类型是java.util.Date。<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;        <span>BeanUtils的</span>copyProperties和populate需要在转换器(converter)的配合下实现源和目标对象之间的数据类型的转换。在<span>BeanUtils.</span>copyProperties的javadoc中说明的（Copy property values from the origin bean to the destination bean for all cases where the property names are the same&mdash;&mdash; 只要属性名相同就可以从源bean中拷贝值到目标bean中）这句话提供到功能就是要通过转换器才能实现的。在<span>BeanUtils的</span>copyProperties<span>和populate</span><span>的使用过程中Converter是一个非常重要的概念，它</span><span>提供了强大的扩展能力。</span><font color="#0000ff">&nbsp;&nbsp;      <br>
&nbsp;&nbsp;&nbsp;      /****************************************************************/<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;      public interface Converter {<br>
&nbsp;&nbsp;&nbsp;&nbsp;        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                public Object convert(Class type, Object value);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;      }<br>
&nbsp;&nbsp;&nbsp;&nbsp;      /****************************************************************/</font><font color="#0000ff">&nbsp;&nbsp;&nbsp;&nbsp;      </font><br>
&nbsp;&nbsp;&nbsp;     convert方法的参数type是目标转换的类型，参数value是被转换的值，返回值就是转换以后的结果。当有需要自定义或扩展的Converter 的时候可以通过注册自定义的转换器来实现，例如Beanutil自带的DateConverter不支持String到java.util.Date的转换，通过扩展DateConverter就可以实现支持。需要特别注意的是Converter 是注册在classloader一级的，也就是说在一个class loader中同一时间只能有一个转换器起作用（<span>BeanUtils的</span>copyProperties<span>和populate会依据目标bean属性的类型来决定启用那个转换器</span>），我之前的项目中就有因为其他模块中在特定的时候会重新注册了某个类型的转换器，而新注册的转换器又没有支持我所需要的转换，从而导致在我的模块中出现NPE。 所以在使用<span>BeanUtils.populate</span><span>和copyProperties的时候要注意以下几点：</span></p>
<p style="text-indent: 21pt;" class="MsoNormal"><span>1. 只在系统初始化的时候注册一个转换器，而不要在某个功能的执行过程中注册转换器。<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;               2. 转换器要能够支持项目各个模块的使用需求<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;               3. 谨慎使用或者思考一下</span><span>BeanUtils.populate</span><span>和copyProperties是你想要的方法吗？</span></p>
<p style="text-indent: 21pt;" class="MsoNormal"><span>在我使用</span><span>BeanUtils.populate</span><span>的模块中本意是实现bean和Map的属性拷贝并不需要类型和值的转换。至于说为什么会使用</span><span>BeanUtils.populate</span><span>完全是被它支持Map所误导，其实</span><span>PropertyUtilsBean</span><span>.copyProperties和</span>     <span>BeanUtils.</span>copyProperties同样支持Map。<span>就我想要实现的功能而言通过PropertyUtilsBean</span><span>.copyProperties方法能更好地满足。</span><span>PropertyUtilsBean</span><span>.copyProperties方法不会有类型转换的逻辑，所以需要程序员自己保证目标和源Bean属性间的兼容性，也正因为如此</span><span>PropertyUtilsBean</span><span>.copyProperties的执行效率更高。</span></p>
<p style="text-indent: 21pt;" class="MsoNormal"><span><strong><font size="3">参考资料</font></strong><br>
</span></p>
<p style="text-indent: 21pt;" class="MsoNormal"><a href="BeanUtils.copyProperties与PropertyUtils.copyProperties用法及区别" target="_blank">BeanUtils.copyProperties与PropertyUtils.copyProperties用法及区别</a><span><a href="BeanUtils.copyProperties与PropertyUtils.copyProperties用法及区别" target="_blank">l</a><br>
</span></p>
<p style="text-indent: 21pt;" class="MsoNormal"><span><a href="http://commons.apache.org/beanutils/v1.8.0/apidocs/org/apache/commons/beanutils/PropertyUtilsBean.html" target="_blank">http://commons.apache.org/beanutils/v1.8.0/apidocs/org/apache/commons/beanutils/PropertyUtilsBean.html</a></span></p>
<p style="text-indent: 21pt;" class="MsoNormal"><span><a href="http://commons.apache.org/beanutils/v1.8.0/apidocs/org/apache/commons/beanutils/BeanUtils.html" target="_blank">http://commons.apache.org/beanutils/v1.8.0/apidocs/org/apache/commons/beanutils/BeanUtils.html</a></span></p>
<p style="text-indent: 21pt;" class="MsoNormal"><a href="http://www.360doc.com/content/051227/17/3343_50561.html" target="_blank">初用apache.commons.beanutils.BeanUtils</a></p>
<p style="text-indent: 21pt;" class="MsoNormal"> </p>
<p class="MsoNormal"><span> </span></p> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/dearhwj/blog/category/Java">Java</a>&nbsp;<a href="http://hi.baidu.com/dearhwj/blog/item/7c1739193e05e772dab4bd0a.html#comment">查看评论</a>]]></description>
        <pubDate>2009-05-25  21:11</pubDate>
        <category><![CDATA[Java]]></category>
        <author><![CDATA[dearhwj]]></author>
		<guid>http://hi.baidu.com/dearhwj/blog/item/7c1739193e05e772dab4bd0a.html</guid>
</item>

<item>
        <title><![CDATA[JUnit4的参数化测试]]></title>
        <link><![CDATA[http://hi.baidu.com/dearhwj/blog/item/30455345ab861a378794733a.html]]></link>
        <description><![CDATA[
		
		&nbsp;&nbsp;     一直以为<a target="_blank" href="http://testng.org/">TestNG</a>才有参数化测试解决方案，不想在看了<a href="http://jee-bpel-soa.blogspot.com/2009/05/parameterising-junit-tests.html">Parameterising JUnit tests</a> 的文章以才知道JUnit4中也提供了参数化测试的功能，于是简单的学习了一下。<br>
&nbsp;&nbsp;    <strong><font size="4">什么是参数化测试？</font></strong><br>
&nbsp;&nbsp;    很多时候一个方法的实现需要支持多种Case或者说从测试的角度来看需要测试多种边际条件。例如一个字符串大小写转换的函数需要实现把employee_info这样以&ldquo;_&rdquo;分隔的字符串转换成相应的大写字母开头的字符串EmployeeInfo。针对这样的实现方法进行单元测试就需要考虑支持测试多种情况：<br>
&nbsp;&nbsp;&nbsp;   1.测试空字符串<br>
&nbsp;&nbsp;&nbsp;   2.测试一般处理情况<br>
&nbsp;&nbsp;&nbsp;   3.测试尾字母大写的情况.......<br>
&nbsp;&nbsp;&nbsp;   4.处理Null<br>
&nbsp;&nbsp;&nbsp;  5......<br>
&nbsp;&nbsp;&nbsp;   在不使用参数化测试方法的情况下，我们需要针对各种情况编写assert:<br>
&nbsp;&nbsp;&nbsp;  1. assertEquals（&ldquo;&rdquo;,&ldquo;&rdquo;）;<br>
&nbsp;&nbsp;&nbsp;  2.assertEquals(&quot;EmployeeInfo&quot;,&quot;employee_info&quot;);<br>
    3. assertEquals(&quot;EmployeeInfoA&quot;,&quot;employee_info_a&quot;）;        <br>
&nbsp;&nbsp;&nbsp;  4.assertEquals(null,null）;<br>
&nbsp;&nbsp;&nbsp;  5......<br>
&nbsp;&nbsp;  这种解决方式是不是感到有很多重复，而参数化测试就是解决这种情况的绝好方法。<br>
&nbsp;&nbsp;  下面来介绍一下参数化测试的开发方式<br>
&nbsp;&nbsp;  <strong><font size="4">参数化测试实例</font></strong><br>
&nbsp;&nbsp;  1.  为准备使用参数化测试的测试类指定特殊的运行器 org.junit.runners.Parameterized。<br>
&nbsp;&nbsp;  2. 为测试类声明几个变量，分别用于存放期望值和测试所用数据。<br>
&nbsp;&nbsp;  3. 为测试类声明一个使用注解 org.junit.runners.Parameterized.Parameters 修饰的，返回值为 java.util.Collection 的公共静态方法，并在此方法中初始化所有需要测试的参数对。<br>
&nbsp;&nbsp;  4. 为测试类声明一个带有参数的公共构造函数，并在其中为第二个环节中声明的几个变量赋值。<br>
&nbsp;&nbsp;  5. 编写测试方法，使用定义的变量作为参数进行测试。<br>
/*********************************************************************************************/<br>
  @RunWith(Parameterized.class)<br>
public class StringTransformerTest {<br>
&nbsp;&nbsp;&nbsp;  private String testData;<br>
&nbsp;&nbsp;&nbsp;  private String expectedData;<br>
<br>
&nbsp;&nbsp;&nbsp;  public StringTransformerTest(String testData, String expectedData) {<br>
&nbsp;&nbsp;&nbsp;  &nbsp;&nbsp;&nbsp;  this.testData = testData;<br>
&nbsp;&nbsp;&nbsp;  &nbsp;&nbsp;&nbsp;  this.expectedData = expectedData;<br>
&nbsp;&nbsp;&nbsp;  }<br>
<br>
&nbsp;&nbsp;&nbsp;  @Test<br>
&nbsp;&nbsp;&nbsp;  public void testTransfer() {<br>
&nbsp;&nbsp;&nbsp;  &nbsp;&nbsp;&nbsp;  assertEquals(expectedData, StringTransformer.transfer(testData));<br>
&nbsp;&nbsp;&nbsp;  }<br>
<br>
&nbsp;&nbsp;&nbsp;  @Parameters<br>
&nbsp;&nbsp;&nbsp;  public static Collection getParameters() throws Exception {<br>
&nbsp;&nbsp;&nbsp;  &nbsp;&nbsp;&nbsp;  return Arrays.asList(new Object[][] {<br>
&nbsp;&nbsp;&nbsp;  &nbsp;&nbsp;&nbsp;  &nbsp;&nbsp;&nbsp;  &nbsp;&nbsp;&nbsp;  { &quot;employee_info&quot;, &quot;employeeInfo&quot; }, // 测试一般的处理情况<br>
&nbsp;&nbsp;&nbsp;  &nbsp;&nbsp;&nbsp;  &nbsp;&nbsp;&nbsp;  &nbsp;&nbsp;&nbsp;  { null, null }, // 测试 null 时的处理情况<br>
&nbsp;&nbsp;&nbsp;  &nbsp;&nbsp;&nbsp;  &nbsp;&nbsp;&nbsp;  &nbsp;&nbsp;&nbsp;  { &quot;&quot;, &quot;&quot; }, // 测试空字符串 时的处理情况<br>
&nbsp;&nbsp;&nbsp;  &nbsp;&nbsp;&nbsp;  &nbsp;&nbsp;&nbsp;  &nbsp;&nbsp;&nbsp;  { &quot;employee_info&quot;, &quot;EmployeeInfo&quot; }, // 测试当首字母大写时的情况<br>
&nbsp;&nbsp;&nbsp;  &nbsp;&nbsp;&nbsp;  &nbsp;&nbsp;&nbsp;  &nbsp;&nbsp;&nbsp;  { &quot;employee_info_a&quot;, &quot;employeeInfoA&quot; }, // 测试当尾字母为大写时的情况<br>
&nbsp;&nbsp;&nbsp;  &nbsp;&nbsp;&nbsp;  &nbsp;&nbsp;&nbsp;  &nbsp;&nbsp;&nbsp;  { &quot;employee_a_info&quot;, &quot;employeeAInfo&quot; } // 测试多个相连字母大写时的情况<br>
&nbsp;&nbsp;&nbsp;  &nbsp;&nbsp;&nbsp;  &nbsp;&nbsp;&nbsp;  &nbsp;&nbsp;&nbsp;  });<br>
<br>
&nbsp;&nbsp;&nbsp;  }<br>
}<br>
/*********************************************************************************************/<br>
<br>
&nbsp;&nbsp;  运行效果如下图<br>
 
<div forimg="1"><img border="0" src="http://hiphotos.baidu.com/dearhwj/pic/item/57168ec293ba3811e4dd3b20.jpg" small="0" class="blogimg"></div>
<br>
<br>
参考资料<br>
<a href="http://jee-bpel-soa.blogspot.com/2009/05/parameterising-junit-tests.html">Parameterising JUnit tests</a><br>
<a target="_blank" href="http://www.ibm.com/developerworks/cn/java/j-lo-junit4/">单元测试利器 JUnit 4</a> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/dearhwj/blog/category/tdd%28%B2%E2%CA%D4%C7%FD%B6%AF%29">tdd(测试驱动)</a>&nbsp;<a href="http://hi.baidu.com/dearhwj/blog/item/30455345ab861a378794733a.html#comment">查看评论</a>]]></description>
        <pubDate>2009-05-24  16:48</pubDate>
        <category><![CDATA[tdd(测试驱动)]]></category>
        <author><![CDATA[dearhwj]]></author>
		<guid>http://hi.baidu.com/dearhwj/blog/item/30455345ab861a378794733a.html</guid>
</item>

<item>
        <title><![CDATA[用UltraEdit查看、分析日志很方便]]></title>
        <link><![CDATA[http://hi.baidu.com/dearhwj/blog/item/1ace153f036e6dca7c1e712e.html]]></link>
        <description><![CDATA[
		
		&nbsp;&nbsp;&nbsp;  UltraEdit是一个非常棒的编辑器，对于程序员可以支持很多种语言。除了开发意外，用它来分析日志也是方便的。日志文件往往都很庞大，几百兆也是很平常的，而UltraEdit可以支持4G的文件。UltraEdit有一个很有用的查询功能&ldquo;列出包含字符串的行&rdquo;，这个选项是UltraEdit的【查找】功能中的【高级】配置。
<div forimg="1"><img border="0" src="http://hiphotos.baidu.com/dearhwj/pic/item/b158131bbe00baf1ac6e7504.jpg" small="0" class="blogimg"><br>
<br>
由于日志文件包含的东西很多，所以用这个方法可以很快的找出自己感兴趣的内容<br>
<div forimg="1"><img border="0" src="http://hiphotos.baidu.com/dearhwj/pic/item/8ee118330e627067ac4b5f07.jpg" small="0" class="blogimg"></div>
</div>
再通过【查找结果窗口】剪贴板的剪贴板功能，将查询结果复制到windows剪贴板中，然后用Ultraedit再新建一个文件，粘贴内容到该文件。通过这种方式，就可以不断的缩小日志查找的范围，避免了其他内容的干扰。有时候也会需要分析某条日志的上下文，也可以先利用以上的方法定位到了某条日志，再以该条日志的内容为查询条件到完整的日志文件中查找，马上就可以定位了:-)。 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/dearhwj/blog/category/%C8%ED%BC%FE%BF%AA%B7%A2">软件开发</a>&nbsp;<a href="http://hi.baidu.com/dearhwj/blog/item/1ace153f036e6dca7c1e712e.html#comment">查看评论</a>]]></description>
        <pubDate>2009-05-23  06:49</pubDate>
        <category><![CDATA[软件开发]]></category>
        <author><![CDATA[dearhwj]]></author>
		<guid>http://hi.baidu.com/dearhwj/blog/item/1ace153f036e6dca7c1e712e.html</guid>
</item>


</channel>
</rss>