Skip to content


失业,我们为谁买单!

经济危机果然不是盖的,至少从目前掌握的情况来看,很多行业都不景气,失业率狂飙。中国的脆弱经济结构在单纯的依赖出口带动的增长下,已经逐渐丧失了活力。这么多年未能深化的政治改革,以及严重的贪污已经严重的制约了经济,特别是民营经济。而目前看来,吸纳中国大量劳动力的恰恰就是外贸型出口制造企业和小型的民营企业。当这两者都受到重创的时候,中国的失业率急剧膨胀就在情理之中了。加上越来越多的大学生步入劳动力市场,形式更加艰巨。如果中国的经济结构和发展方式不做大的调整,中国的政治结构和贪污腐败不做彻底治理,中国的经济不会有太大的起色。

前人种树后人乘凉,前人不种树呢?我们的情况真的很糟,对每个失业的人来说,都在为中国政治经济的决策者的失误和纰漏买单。

[理论研讨]中国通胀

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • LinkedIn
  • description
  • TwitThis
  • MySpace
  • StumbleUpon
  • Google
  • FriendFeed
  • Mixx
  • Reddit

Posted in 全部, 读书笔记.

使用syntaxhighlighter在WordPress上张贴java代码

地址如下:

http://wordpress.org/extend/plugins/syntaxhighlighter/

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • LinkedIn
  • description
  • TwitThis
  • MySpace
  • StumbleUpon
  • Google
  • FriendFeed
  • Mixx
  • Reddit

Posted in 网络生活. Tagged with .

试试gmail的offline和联系人同步功能

  • offline

image

 

image

虽然现在还不太成熟,不过离线访问邮件还是很有必要的市场的,现在无网络连接时仍然可以寻找邮件中信息,对于喜欢GMail界面而不希望pop方式下载邮件到本地的用户来说,确实很有必有。

诺基亚s60第三版的手机可以通过如下步骤实现与google gmail中的联系人实现同步:

     

    1. 手机中打开“联系人”;
    2. 选择“同步” “设置”.;

      Sync application

    3. 在“选项”中选择“新情景模式” 

      New sync profile

    4. 设置情景模式名称
      Sync profile name
    5. 选择“应用程序”。
    6. 选择“名片夹” 
      • 确保是否同步的值为“是”;
      • 设置远程数据库为“contacts”,大小写敏感,请注意。

        Remote database

      • 选择返回并保存设置;
      • 确保其他内容类型为 “未设置”; 

        Settings defined

    7. 选择返回并保存设置;
    8. 选择连接设置
    9. 输入如下值: 
      • 服务器版本: 1.2
      • 服务器识别码: Google (大写G)
      • 数据承载方式: Internet
      • 接入点: 手机的接入点,移动的可以输入cmnet。

        Server version, server ID, data bearer, access point

      • 主机地址: https://m.google.com/syncml (注意https )
      • 端口: 443
      • 用户名: google帐户

      you@googlemail.com

      • 密码: 密码
      • 其他值保留默认值; 

        Host address, port, user name, password

    10. 返回并保存设置
    11. 返回情景模式设置;
    12. 一切设置好了就可以通过“同步”来同步gmail和s60手机中的联系人了。 

      Synchronise

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • LinkedIn
  • description
  • TwitThis
  • MySpace
  • StumbleUpon
  • Google
  • FriendFeed
  • Mixx
  • Reddit

Posted in 网络生活. Tagged with , , .

测试驱动开发 重构 Mock 单元测试

今天看了很多关于测试驱动开发TDD和单元测试相关的文章和帖子。把所学总结和整理一下,方便自己以后复习。

  • 测试驱动开发和重构是极限编程的核心部分;
  • 什么是测试驱动开发?
    测试驱动开发是一种开发方式:
    1) 你要维护一套详尽的程序员测试集。除非存在其目的是为了让产品代码通过的测试,否则就不存在任何产品代码。
    2) 除非存在相关测试,否则不编写任何产品代码。这样做的原因是系统中的一切都必须是可测试的。
    3) 首先编写测试。先编写少量的测试,随后编写足够使测试通过的代码,然后再多编写一些测试,接着再编一些代码,编写测试……
    4) 由测试来决定需要编写怎样的代码。编写足够让测试通过的代码,仅此而已。
  • 两顶帽子:
    编码:在你带上这顶帽子的时候,你向系统中增添新的功能但不进行重构。
    重构:在你带上这顶帽子的时候,你进行重构但不增加新的功能。

    在你要让某个测试通过的时候,带上编码的帽子。一旦测试通过,你就换顶帽子执行重构来进行清理。
  • 为什么要重构?
    1、改进软件设计。重构就是要让所有代码回到应该在的位置。重构还可以消除重复代码。
    2、使软件更容易理解。修改代码,让代码反映我的意图。重构可以帮助你看到你以前看不到的设计层面的东西。重构带你到更高的理解层次上。
    3、帮助你debug。弄清楚程序结构的同时,也很清楚地看到自己所做的一些假设。
    4、助你提高编程速度。良好设计才是快速开发软件的根本。
  • 单元测试并不是可以无条件实行的,良好的设计,清晰的层次是必须的。对一团乱麻搞单元测试,人基本要累死。
  • 关于单元测试是噩梦的讨论:
    • 项目进展到一定程度,也会产生出大量的单元测试代码。而且这些单元测试代码也被不断的增加、修改和删除。渐渐单元测试代码也变得难以维护了,里边夹杂了太多的业务逻辑。创建一个新的测试要做很多初始化的工作,很难在ide里直接运行所有测试,很难单独运行某项测试,运行所有的单元测试要比较长的时间……
      造成这种现象的原因有以下几种:

      • 1.未及时对单元测试进行重构,删除不必要的测试,合并类似的测试
        2.单元测试粒度过大,造成测试类过于臃肿。应该把大粒度的测试抽出来单独作为功能测试运行。
        3.大量依赖外界环境,如数据库。应使用mock object解除依赖关系。
    • 首先问自己几个问题
      • 1. 测试是不是程序员自己写的
        2. 是不是用的Test First
        3. 如果是unit test, 是不是 method by method写的
        4. 有没有区分什么是unit, integration test, 什么是functional test.
    • 单元测试的目的是为了让我们今后维护时能更快的定位BUG,所以简单独立测试代码更易读、更利于这个目的。
      (1)“创建一个新的测试要做很多初始化的工作”,其根本原因是在于单元测试做法有误,”单元测试粒度过大,造成测试类过于臃肿”,“大量依赖外界环境,如数据库”。
      只针对最复杂和最核心的逻辑来写单元测试,减少了单元测试代码的数量,也就减少了对测试代码本身的维护量。有一些不应该由单元测试来做的工作,还是留到集成测试和测试员的beta版测试吧。
      (2)单元测试要尽量做到环境无关性。比如测试EJB的单元测试,运行它并不需要启动Weblogic等EJB容器才能测试的。
  • 关于《不要把Mock当作你的设计利器》的讨论
    • 我倒觉得这本身就是不是问题的问题. Mock本身就是假设某种行为是正确的,从而保证单元的独立性,又何来行为依赖呢? 什么地方都去用Mock自然是带来重构也好,测试跟踪也好的麻烦了.
      我们总是谈单元测试,谈测试驱动, 才发现并不是大家对于单元的概念有比较统一的理解.自然而然,由此引申的相关Mock也就变得问题多多了.
    • Mock有自己的价值,但滥用Mock除了文里列出的种种弊端外还会使TDD失去一些很重要的意义。TDD能够优化设计的原因之一是你必须要仔细思考设计以使你的代码能够被自动测试,从而降低设计的耦合性。Mock的出现使得这种必要性明显降低。
      我认为Mock的价值主要在于模拟网络连接,消息队列,对象序列化服务之类依赖于环境的地方。
    • Mock还有一个更有用处的地方, 在一个多模块的商业项目中,  简单讲, 甲负责完成A, 乙负责完成B, 而A需要通过接口调用B实现, 这个时候, 因为项目的时间安排的关系, 甲完成了自己的代码, 而乙并没有完成B实现, 在这个时候,难道甲的单元测试不做了么? 使用Mock的目的就在这里了. 作为单元测试本身的概念, A是独立的单元, 它的单元测试只需要测试A本身的(如果连同B也考虑进去, 那只能是集成测试了).所以在这个时候需要做的就是假定B已经完成,并且正确, 基于此对A进行单元测试.
    • Mock用烂绝对不是Mock的错, 而是使用Mock的人根本就没有理解Mock的真正目的和使用范围.
    • mock的问题在于,你实际上不是在检查一个对象的接口,而是深入到了实现过程中。
      stub和mock的使用是有很大区别的,stub的用法是:假设一个对象是正确的,在这个基础上检查其他对象的接口。比如:我们假设A类肯定是对的,在此基础上检查B对不对,于是就制造一个A-stub。而mock是用来检查A的实现过程到底是不是对的。
      mock实际上是和面向对象的设计原则相违背的,他是在深入一个过程,去检查实现细节。因此mock用的多不多,体现了这个程序设计的内聚性好不好。如果程序中到处都需要用mock来测试,说明程序的内聚性不高。
      比如说有这样的需要:A向数据库里面写一个数据,然后B从数据库里面读这个数据。这样的设计从道理上来说就是不合理 的,既然是同一段逻辑,就应该封装在同一段代码中,外界只应该关注他的接口,而不应该知道这个数据的定义。对这段代码进行测试,也只需要测试他的接口。如 果需要知道实现过程对不对,数据在表里面到底保存了没有,这时候就可以使用mock。即使是这段代码里面错翻天了,也不应该对其他代码造成损害,至少接口 是对的。这就把mock的使用范围和影响力减到最小了。
  • 关于不要全程使用Mock对象的讨论:
    • 测试代码是功能代码的两三倍都是很正常的事情。不能因为测试代码量大就拒绝进行完备的单元测试编写。因为越是项目后期,有一个完备的单元测试集,你就对项目代码的信心越足。
    • 不同的测试目标决定了你选择什么样的测试方案
  • 单元测试vs集成测试
      在单元测试时,我们尽量在屏蔽模块间相互干扰的情况下,重点关注模块内部逻辑的正确性。而集成测试则是在将模块整合在一起后进行的测试,它的目的在于发现 一些模块间整合的问题。有些功能很难通过模拟对象进行模拟,相反它们往往只能在真实模块整合后,才能真正运行起来,如事务管理就是其中比较典型的例子。
      按照Spring的推荐(原话:You should not normally use the Spring container for unit tests: simply populate your POJOs in plain JUnit tests!),在单元测试时,你不应该依赖于Spring容器。换言之,你不应该在单元测试时启动ApplicatonContext并从中获取 Bean,相反你应该通过模拟对象完成单元测试。而集成测试的前提则是事先装配好模块和模块之间的关联类,如将DAO层真实的UserDao和 LoginLogDao装配到UserServiceImpl再进行测试。具体装配工作是在Spring配置文件中完成的,因此在一般情况下,集成测试需 要启动Spring容器,你可以在测试类中简单地从Spring容器中取出目标Bean进行测试。
Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • LinkedIn
  • description
  • TwitThis
  • MySpace
  • StumbleUpon
  • Google
  • FriendFeed
  • Mixx
  • Reddit

Posted in 全部, 读书笔记. Tagged with , , .

JUnit in action

JUnit Design Goals
The JUnit team has defined three discrete goals for the framework:
  The framework must help us write useful tests.
  The framework must help us create tests that retain their value over time.
  The framework must help us lower the cost of writing tests by reusing code.

When it is easy to reuse a fixture between tests, you can write tests more
quickly. Each time you reuse the fixture, you decrease the initial investment
made when the fixture was created. The TestCase fixtures speak to JUnit’s
third design goal:
The framework must lower the cost of writing tests by reusing code.

The simple but effective combination of a TestRunner with a TestSuite
makes it easy to run all your tests every day. At the same time, you can select a
subset of tests that relate to the current development effort. This speaks to
JUnit’s second design goal:
The framework must create tests that retain their value over time.
When you continue to run your tests, you minimize your investment in testing
and maximize your return on that investment.

Keeping tests independent
As you begin to write your own tests, remember the first rule: Each unit test must
run independently of all other unit tests. Unit tests must be able to be run in any order.
One test must not depend on some side effect caused by a previous test (for example,
a member variable being left in a certain state). If tests begin to depend on
one another, you are inviting trouble. Here are some of the problems with codependent
tests: 
     Not portable—By default, JUnit finds test methods by reflection. The reflection
API does not guarantee an order in which it returns the method names.
If your tests depend on an ordering, then your suite may work in one Java
Virtual Machine (JVM) but fail in another.
     Hard to maintain—When you modify one test, you may find that a number of
other tests are affected. If you need to change the other tests, you spend
time maintaining tests—time that could have been spent developing code.
     Not legible—To understand how co-dependent tests work, you must understand
how each one works in turn. Tests become more difficult to read and
harder to maintain. A good test must be easy to read and simple to maintain.

Three flavors of unit tests: logic, integration, and functional

  • Logic unit tests

Unit tests that focus on exercising the code logic. These tests are usually meant to exercise only a single method and no other. You can control the boundaries of a given method using mock objects or stubs.

  • Integration unit tests

Unit tests that focus on testing the interaction between components in their real
environment (or part of the real environment). For example, code that accesses a database has tests that effectively call the database, thus proving that the codedatabase interaction works.

  • Functional unit tests

Unit tests that extend the boundaries of integration unit testing to confirm a
stimulus-response. For example, imagine a web page that is protected and that
you can access only after being logged in. If you are not logged in, accessing the page results in a redirect to the login page. A functional unit test verifies that
behavior by sending an HTTP request to the page and verifying that the result is a 302 response code. It does not, however, verify that the full workflow leads to
the login page. Workflow is the domain of pure, software functional testing.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • LinkedIn
  • description
  • TwitThis
  • MySpace
  • StumbleUpon
  • Google
  • FriendFeed
  • Mixx
  • Reddit

Posted in 读书笔记. Tagged with , .

如何通过单元测试提高开发效率?

转载IT168

Kevlin Hnney是英国的一位独立顾问和培训师,其关注的范围主要包括软件架构、模式、开发过程和程序设计语言。在本文中他将谈谈如何通过单元测试提高开发效率。

    单元测试只会浪费时间吗?某些软件专家们确实是这么想的。最近在Software Quality Insights上看到一篇文章——《单元测试真的有用吗?》。那些认为单元测试无用的开发人员给出了如下理由:

    1. 他们不了解单元测试。

    2. 很难写出优秀的单元测试。

    3. 单元测试只会浪费时间、降低效率。

    4. 写单元测试需要太多时间(特别是频繁的迭代开发)。

    5. 回归测试更有效率。

    本文将重点讨论后面三个问题,即单元测试与开发效率的关系。

效率 vs 人员安排

    单元测试会降低效率、造成时间上的浪费吗?这取决于所说的效率是什么,以及所说的时间对象是谁。在一个纯粹编写新代码的周期里,写单元测试的程序员所写代码可能会比不写单元测试的少。如果所说的效率是指这个,那么单元测试确实会降低程序员的效率。

    但是,我们很容易发现这种牵强的效率定义的问题所在。代码行并不是衡量效率的标准,它只是所写代码的行数。从单个类到整个系统,我们可以发现很多代码行数已经远超出了实际所需。

    我们需要的并不是更多的代码,而是准确的代码。单元测试可以让我们随时进行代码层次上的真实性检查,它可以告诉我们是否在开发正确的东西。所以越多的测试就意味着越少的代码。这并不是什么坏事。开发速率(development velocity)与开发速度(development speed)的区别就在于方向。向正确的方向前进即使几步也要好于在错误的方向上飞奔。

    另一个错误的想法是开发人员大部分时间都在编写新代码。虽然开发人员也想专心于代码,但是现实却并非如此。会议(与团队、管理人员、客户、投资商等)、邮件、程序调试、会话、文档制作、安装、研究评估、帮助解决问题、跟进支持、合并版本、处理配置管理系统等都是需要考虑的。

    虽然各部分所占比例根据项目与公司的不同而有所变化,但是这些都是与代码无关的活动,而且所占时间总和要高于编写代码占用的时间。问题在于,如果我们把一部分编码时间用于单元测试,那么上面这些时间有多少可以转化为编码时间呢?

局部优化 vs 全局优化

    看清全局也很重要。下面Alfred Aho说所的关于开发AWK语言的故事颇有一些值得我们考虑的地方:

    “如果再有这样一次机会,我们在开发这种语言的时候肯定会增加严格的测试。我们当时是把AWK当作一种"临时性(throw-away)"语言进行开发,所以并没有考虑严格的质量控制……曾经有个人用AWK编写了一个CAD系统。他来找我,想告诉我AWK编译器的一个Bug。他很生气,说我浪费了他三个星期的生命,因为他用了三个星期查找他代码里的错误,结果却发现是编译器的问题!后来我和Brian Kernighan讨论过这个问题,我们觉得应该做一些质量控制方面的工作。然后,我们针对AWK所有功能做了一次严格的回归测试。从那以后,我们三人无论谁为这种语言增加新功能的时候,都要先写一份相应的测试。”

    这个故事的意义就在于它是比较早的拥护“测试先行”编程方式的实例——在实现某个功能之前先把测试写出来,而不是只在计划或者口头说说。另外,这个故事也说明了如何把短期、临时性或针对性代码转变为长期、稳定的方案。

不过对于我们而言,最重要的是帮助证实测试将降低效率这一谬论。这里所说不是代码编写人员的效率——而是用户的效率。或者更广泛地说,是这个开发链下一个环节的人的效率。

    所谓测试会“降低效率与浪费时间”,充其量也只是针对编程人员而言。而所有可能出现的问题则会堆积起来,直到下一个环节才被放大,浪费更多的时间和效率。当然,程序员可以继续解决任何后面出现的问题,不过你还会认为这属于“正常工作”范畴内吗?如果人们无法把编写单元测试看作他们正常工作的一部分,他们就可能把它当作是对正常工作的一种巨大干扰,而不是考虑如何在工作中取得一个和谐的平衡点。

解决应该解决的问题

    许多局部优化实际上是对全局的掌握不够,因为他们无法意识到更深层次的问题。这样,他们所做的许多解决性措施就只能解决表面问题,而无法触及问题的根本所在。如果迭代过于频繁而无法进行单元测试,这就意味着迭代的频率已经超出了这个团队或机构的产能。这个产能当然包括团队的单元测试能力。

    小周期迭代的目的并不是在短时间内进行迭代,迭代的目标是减少风险,以及通过持续发布功能性完整的增量版本来提高价值、改善工作流程。如果有达不到要求的地方,那么很可能是系统中的某一部分限制了迭代频率。如果无法解除这个限制,那么最好还是延长迭代的周期,使其更适合当前的环境,而不要“赌气”似的强制使用这个周期。

被动式的回归测试

    为什么有人说回归测试比单元测试更有效呢?虽然具体还要取决于回归测试指的是什么,不过这也暗示了他们对回归测试作用的误解。

    通过再运行一次同样的测试,回归测试保证了对代码所做的任何改动并没有影响到先前测试过的行为。但是新功能呢?按照定义,你不能用回归测试确定新功能的行为或者新功能可以实现预期的行为。所以关键就是要明白“回归”这个词。

    回归测试并不是一种仅仅与单元测试不同粒度的测试,它表示的是一种预期的测试结果。回归测试可以在单元、系统或者之间的任何层次上进行。它的意义在于保证不应改变的部分没有被改变。而新测试则是要保证发生改变的部分已经根据预期产生了相应的效果。

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • LinkedIn
  • description
  • TwitThis
  • MySpace
  • StumbleUpon
  • Google
  • FriendFeed
  • Mixx
  • Reddit

Posted in 全部, 职业生涯. Tagged with .