邮箱图标 5glive.com
  • 在公共会议做演讲,需要克服两大障碍:如何从会议主办方获得许可、如何在会议上做好演讲。

    对于第一个障碍,Jim Holmes的博客文章“编写优秀的演讲摘要”给出了几点建议:

    • 让你的演讲内容与活动目标相符合
    • 避免过于宽泛的演讲
    • 标题非常重要,真的
    • 说明听众能从你的演讲中得到哪些收获
    • 给出讨论的实际例子
    • 展示该演讲以前获得的反馈
    • 编写简洁的摘要
    • 编写内容紧凑的摘要
    • 一审再审,让人复审

    第二个障碍,可以参考Kathy Sierra(她是Head First系列书籍的作者之一)的博客文章:如何在技术会议上演讲

    • 坚决不要等待邀请!
    • 坚决不要指望别人提出建议议题邀请!
    • 知道会议的主题
    • 选择好的标题
    • 从听众的角度思考
    • 不要害羞,不要充斥市场宣传之词
    • 真正的工作实践远胜过抽象的思考
    • 回答该问题:我的演讲如何才能让听众解决实际问题?
    • 花时间研究会议手册,阅读每个摘要
    • 提供引人注目的个人介绍
    • 以前的演讲经验会有所帮助
    • 实际参加会议
    • 提交多个议题
    • 不要放弃,不管怎样,要是被拒绝了,不要将其视为个人恩怨
    • 寻求帮助

     

    P.S.:本文动机来自infoq新闻:《女士们:请递交你们的议题吧!》

  • 现在来看The Art of Unit Testing With Examples in .NET的第三章“Using Stubs to Break Dependencies”

    • 作者使用了三种定义来指向测试中的伪造关系:fakes, stubs 和 mocks。
    • “除了间接层次过多这样的问题之外,没有哪种面向对象的问题是不能通过添加间接层次解决的。”然而,单元测试的诸多精妙之处就在于:如何找到正确的地方添加或使用间接层次,以测试目标代码。
    • 加入间接层次的三个步骤:
      1. 找到待测试方法依赖的“接口”。这里的接口不单单是指面向对象中的接口,还包括与其他类协作需要调用的方法或类。
      2. 如果“接口”与待测方法有“直接关系”(比如直接调用等等),就可以通过向接口加入间接层次,使得待测方法可以被测试。
      3. 将交互接口的“潜在实现”用可以控制的东西替换。
    • 对于Seam(接缝)的定义:

    Seams are places in your code where you can plug in different functionality, such as stub classes. (可参考Michael Feathers的《修改代码的艺术》)

    • 打破依赖的5种方法:
      1. 抽离出接口,以替换潜在实现。
      2. 向待测类中注入stub实现。
      3. 在构造器中接收接口作为函数。
      4. 将接口作为属性,进行设置或读取。
      5. 在调用方法前得到stub。
  • The Art of Unit Testing With Examples in .NET的第二章“A first unit test”中,提出了一些unit test应该注意的初步细节,比如测试方法命名的基本规则:

    待测试对象:Project , 例如:项目名为Logan

    测试代码中的对应对象:创建项目名称为[ProjectUnderTest].Tests;上例对应项目名为:Logan.Tests

    待测试对象:Class,例如:类名为LogAnalyzer

    测试代码中的对应对象:对于每个class,至少创建一个对应class,命名为[ClassName]Tests;上例对应类名为:LogAnalyzerTests

    待测试对象:Method,例如:期待名为IsValidLogFileName的方法,输入合法的文件名,希望返回true

    测试代码中的对应对象:对于每个方法,创建至少一个测试方法,命名规则为[MethodName]_[StateUnderTest]_[ExpectedBehavior]. 上例对应方法名为:IsValidFileName_valideFile_ReturnsTrue()

    此外,还提到了针对状态的间接测试——state-based testing,其定义如下:

    State-based testing (also called state verification) determines whether the exercised method worked correctly by examining the state of the system under test and its collaborators (dependencies) after the method is exercised.
  • 什么是好的unit test?

    2009-09-02

    Tag:

    根据The Art of Unit Testing With Examples in .NET,好的unit test应该具备如下特点:

    • It should be automated and repeatable.
    • It should be easy to implement.
    • Once it’s written, it should remain for future use.
    • Anyone should be able to run it.
    • It should run at the push of a button.
    • It should run quickly.

    如果这还不够,请回答下列问题,足以判断一个测试是否是好的unit test:

    • Can I run and get results from a unit test I wrote two weeks or months or years ago?
    • Can any member of my team run and get the results from unit tests I wrote two months ago?
    • Can I run all the unit tests I’ve written in no more than a few minutes?
    • Can I run all the unit tests I’ve written at the push of a button?
    • Can I write a basic unit test in no more than a few minutes?

    有任何一个问题的回答是“no”,对不起,您的测试不是unit test,而是integration test,书中对于此类测试定义如下:

    Integration testing means testing two or more dependent software modules as a group.

    因此,unit test的定义如下:

    A unit test is an automated piece of code that invokes the method or class being tested and then checks some assumptions about the logical behavior of that method or class. A unit test is almost always written using a unit-testing framework. It can be written easily and runs quickly. It’s fully automated, trustworthy, readable, and maintainable.

  •  

    开始看这本书:The Art of Unit Testing With Examples in .NET。选择它,两个原因:

    1. 单元测试是保证代码质量的基石和安全网。
    2. 该书篇幅短小精湛,而且非常实用。非常期待看到Chapter 8中的Tough Questions and Answers,其中有对如下问题的回答。
      • How much time will this add to the current process?
      • Will my QA job be at risk because of this?
      • How do we know this is actually working?
      • Is there proof that unit testing helps?
      • Why is the QA department still finding bugs?
      • We have lots of code without tests: where do we start?
      • We work in several languages: is unit testing feasible?
      • What if we develop a combination of software and hardware?
      • How can we know we don’t have bugs in our tests?
      • My debugger shows that my code works: why do I need tests?
      • Must we do TDD-style coding?

    如果能够顺利回答这些问题,相信unit test的实施就不是问题了。

  • 我们希望系统解决的问题通过需求得以体现。GUI设计是要体现出GUI如何引导用户使用系统以解决他们的问题。很多项目都将GUI设计混同于需求的假面之下,这很让人讶异。如果你的项目总是陷于无尽的需求工作之中,看看问题是不是出在GUI设计上。

    GUI是设计,不是需求

    凯伦,程序经理

    我在一家新公司工作时,试图拯救一个陷入“需求地狱”的项目。需求文档已经达到300多页,而且远未完成。

    阅读这些文档后,我找到了原因。所有的GUI设计都被记录在需求文档中。GUI设计没有放在项目的设计阶段,业务分析人员和GUI设计人员试图将所有的GUI需求都放在需求文档中。他们使用了功能强大的图形设计工具,并在需求文档中定义GUI。

    我向他们询问原因,他们看着我,说道:“这些是GUI需求。”我建议他们认真看看GUI设计,并且考虑这些设计是否应该跟希望系统解决的问题放在一起。GUI设计不应放在需求文档中。

    最终,他们同意采纳我的建议,我们也可以逃离需求地狱了。而且,由于我按照逐个功能重新组织了项目,GUI设计也就跟各个功能结合在一起了。我们定期检查整个GUI的一致性,但是这与需求无关,这属于设计。

    人们很容易在项目开始阶段设计GUI,并称其为需求。如果要这么做,项目就永远无法找到自己的节奏。它会一直陷于需求的泥沼之中,直到最后,无法完成任何客户需要的功能,虽然到时候能够得到精美无比的GUI。

  • 要减少不必要的代码,有一个好方法:想想谁会使用系统,又该如何开发用户需要的系统。

    有很多项目都试图通过定义功能性和非功能性需求来确定需求。可是这些需求没有说明一个人如何使用系统,以及一个功能在何种场景下必须运行。需求收集的方法应该为项目团队提供上下文,这样才能深入理解需求。

    谁需要那个支票账户?

    克拉丽莎,资深经理

    我的项目团队陷入困境。他们实现了一堆只开发完一部分的功能,可是没有哪个能够真正运行。我召开了一个会议,以决定接下来该做什么。

    在会议上,我想知道:为了完成项目,哪些用户是他们的首要服务对象。他们看着我,脸上毫无表情。“你们看,我们是一家银行。我们希望年满18岁、将要进入大学的人们首先使用我们的服务。还有住在郊外的妈妈们,她们还有其他资产,75岁的老奶奶,以及年方15已经靠做家务挣得零花钱的孩子们。我们可以为他们提供不同的理财服务。如果他们走进来,我们希望他们成为我们的客户。对于这些不同类型的客户,我们真地想过要给他们提供什么样的产品么?”

    他们以前太过专注于系统的内部功能,忽视了系统真正要为之服务的用户。我们把期望捕获的用户重新进行了排序,项目团队因此得以完成需求定义,并完成系统的功能。

    人,总是人的因素,不是么? 

    只要大家了解需求的上下文,开发人员、测试人员和文案人员就能知道如何开发、测试、编写文案。如果他们不能了解,要是需求以功能性和非功能性需求的方式罗列,他们也可以问一些更好的问题,从而深入了解需求。

  • Google Translation Toolkit 是google刚刚发布的在线翻译平台,初步评测结果如下:

    说明:在settings里面有两个选择:

    第一种:让目的文档中填充它翻译的结果;

    第二种:在目的文档窗口中直接放置原文

    以下测试方式,选择第一种设置:

    已尝试如下三种方式:

    1、提供英文页面urll,直接让其翻译,

    结果:翻译质量不行,而且格式乱掉,它自己加了很多span

    2、将英文web页面另存到本地,再上传文件让其翻译,

    结果:同上;

    3、提取html标签内容,另存为word文件,再上传,让其翻译

    结果:格式同样乱掉,它自己很“智能”地处理了一些标签,结果更乱了。。..-_-|||||..

    当setting中选择显示原文时,上述第一和第二种方式生成的文件同样含有n多span,无法使用。

    第三种方案翻译起来相对比较方便,但是如果要调整html标签的位置相信比较麻烦(要调整,是因为语序上的变化),

    ===============

    如果在环境中选择show toolkit,屏幕下方会有工具箱出现,目前看来,

    • 字典比较方便,但是解释比较简单,
    • computer translation:如果你愿意,结果可以直接上到目的文档窗口。
    • glossary时间短, 还没有尝试。

    结论:

    一言以蔽之,这是一个初具雏形的翻译IDE。该平台最有用之处在于方便翻译的对照和审校,可以显著提高多人翻译写作效率,但是翻译质量,仍然不能恭维。简单说,就是给翻译提供了一个IDE。 如果能像Eclipse那样开放API或是开源,我相信很多做这个协作翻译平台的公司就要开始冒冷汗了~~~

     

    ps:

    另外,不知道大家有没有注意到,在选择要翻译的东西时,google提供的第四个选项:Knol

    http://knol.google.com/k

    这似乎是google自己做的知识平台……

    Google真得是强悍啊。。。

  •  

    邀请团队成员相互复查工作。复查的形式并不重要,结对编程(pair programming)、伙伴复查(buddy review)、同行复查(peer review)、走查(walk-through)、正式代码检查(formal code inspection)都可以。复查能够为项目方方面面带来好处。项目经理要为团队提供多种方法。这些方法以特定顺序介绍:从最不正式到最正式。以我的经验来看,这也可以从最有效和易于保持的,到最没有效果和难以维系的。

    结对编程。先不要假定“这里没人愿意这么做”,要允许大家这么做。(而且可以提醒大家,他们已经完成过结对调试了。)我会问大家谁自愿进行结对。我建议他们在开始之前,先去阅读一些相关资源,比如[WK02]和[SH06b],还有http://www.pairprogramming.com。

    不出意外的话,会有人愿意尝试结对的。相对独自工作来说,他们可以学到如何通过结对编程使工作变得更有效率。

    除了减少缺陷、加快开发速度外,结对编程还能带来很大的好处:有两个人完全熟悉并知道如何处理同一块代码。而且,如果人们经常切换不同的结对对象,他们就会深入了解目前团队正在开发的系统的各个部分。此外,对代码作者的反馈也没有延迟。

    用哪种生命周期都没有关系。结对这种技术总是可以用来让更多人了解代码。

    伙伴复查伙伴复查无法达到与结对编程同样的学习效果。没错,每个人都可以了解产品某个功能的代码,但是不会像作者那样深入。作者得到的反馈也会有一点点延迟——即完成复查所需的时间。

    同行复查。同行复查与伙伴复查的意思差不多(把你的代码给别人看看),但是很多人倾向于一次复查一个完整的模块,不管是一个文件还是几个文件。复查大量代码要更难,很难找出需要进行复查的大块时间,而且很难记住脑子里面所有的想法。

    同行复查很难达到与伙伴复查同样的学习效果。以我的经验来看,这样做经常只能复查代码风格,而不是内容。对于作者的反馈延迟可以长达一星期。

    走查。用走查的方式,一些人会集中在一个房间之内,由代码作者说明产品,过一遍文档。这里几乎没有团队学习的过程,而作者得到反馈的延迟时间也相当长——也就是用来组织会议需要的时间。

    正式检查。如果做得好,正式检查可以帮助团队通过讨论了解产品。不过我很少看到正式检查能够在组织内长久实施下去。即使是启动检查的人,也很难维持检查的动力。

    维持检查很困难,因为检查别人的代码会打乱每个人的节奏,还有项目的节奏。要想进行一次费根式(Fagan-style)的检查[1],人们必须离开自己的工作任务上下文,详细阅读产品代码,准备评论自己看到的东西。我发现,为了一次两小时的检查会议,要花上几小时甚至一天的时间去准备。


    [1] 费根式检查(Fagan inspection)是一种在开发文档中试图发现缺陷的结构化过程。这些文档可以包括代码、需求说明、设计文档以及其他软件开发过程涉及的文档。其命名来源于迈克尔·费根(Michael Fagan)——正式软件检查的发明人。详情可查看:http://en.wikipedia.org/wiki/Fagan_inspection。——译者注。


    文中图片来自:http://www.flickr.com/photos/pezz/

  •  

    逐个功能进行实现和测试

    哈威、维贾、道、兰迪、肯和梅布尔,负责提醒功能的团队

    我是哈威,团队的头儿。我们的开发人员包括维贾、道、兰迪和肯,梅布尔是测试人员。我们在GUI、平台、硬件集成以及几个方面都有专家,而梅布尔无所不知。(背景中传来笑声。)

    刚开始的时候,我们试图先把架构开发出来,再制订规范,告诉大家我们在做什么。我们每个人各自负责一块,最后再放到一起。可是一切都没有按计划进行。因为即使我们有规范,在开发各自的组件时,我们总会改变些什么。

    梅布尔曾经听过有关按功能实现的说法,并告诉了我。我问大家是否愿意组建一个基于功能的团队。嗯,其实是基于功能集合的团队。我们开发所有的提醒功能,一次完成一个,从前端到后台。梅布尔会负责测试。

    开始时有点儿困难,不过习惯之后,我们添加功能的速度让人惊喜不已。我们不再是每个人开发很多代码然后再集成到一起,而是只添加每个提醒功能需要的代码,再进行测试。梅布尔保证我们不要出现系统级别上的问题,我们保证每个提醒功能不要出问题。

    我们的开发速度如此之快,不久就有新的功能需要开发了。现在,有些其他组也在尝试我们的做法。整个项目的进度都加快了,而且客户也能知道我们在开发哪些功能,反馈也由此而来。

    很多项目团队都是按照架构进行组织的,比如基于Web的产品会分平台组、中间件组和GUI组。可是如果按架构进行实现,项目经理就很难知道开发完的功能是否可以正常运行,除非等到整个产品集成完毕。如果按架构实现,就很难进行持续集成了,因为无法构建和运行测试。在开发的开始阶段,没有哪个功能是完全实现的,都要等到快结束的时候才能做完。而且,项目经理也无法将任何功能视为完成。

    所有已经完成的开发工作都是在创建“浪费”[MP06],没有产生任何有价值的东西。一旦完成某些功能,就可以开始计算价值了。可是在此之前,这些价值无法衡量。

    按架构实现会打乱项目的节奏,因为得到的都是部分完成的功能。不到开发完成,项目经理看不到完整的功能,而这时得到的反馈对开发人员来说就太晚了。如果按功能实现,开发团队只要针对某个功能的要求利用架构进行实现就好了。假如要开发Web应用,项目经理可以组织一个小型的基于功能的跨职能团队,其中包括一些了解平台的人员、一些了解中间件的人员和了解GUI的人员,他们各自负责自己擅长的工作,并且只针对团队负责的一个特定功能。要是团队人员拥有不同的兴趣和技术技能,比如擅长GUI和固件方面的技术,这些人就可以按照功能逐个应用他们的技能。(项目经理应该帮助他们组织好各自在项目中的工作时间。)

    有些团队认为,应该在项目前期预先细化需求(Big Requirements Up Front,BRUF),并进行大量设计(Big Design Up Front,BDUF)。这样的团队要想切换到按功能实现的方式,就没那么顺利了。这时,可以跟他们说明一个功能应该是什么样子(它应该有多小),并让他们知道自己不应该做什么(参见5.3节),帮他们了解实现的功能要具备足够的架构完整性,从而在实现后续功能时也不会有问题。要提醒这些团队,他们在调试和测试的时候,都是按功能进行的,因此不会陌生。

    有些人可能仍持反对态度,说他们在考虑一个功能之前,仍需要知道整体架构没有问题。这种情况下,架构草稿会有所帮助(参见3.5节)。不过不要坚守其中的架构,除非团队已经实现过不少功能了。

    9.3.1. 首先实现具有最高价值的功能

    在按功能实现时,要先实现最有价值的功能。把风险最高的功能先往后放一放。如果运气足够好,也许根本不用开发这些高风险的功能。这样一来,测试人员和开发人员就能对整个系统有足够的了解,他们就可以保持自己的节奏了。

    有些团队不愿意按功能实现,因为他们不知道先开发哪个功能。团队中有些人会希望先开发风险最高的功能,有些人希望先开发最有价值的功能。如果没人愿意排定需求的优先级顺序,那就很难知道哪个功能最有价值了。

    如果没有客户或是客户代理的参与,你作为项目经理,就要在团队的辅助下,担起制订和发布产品待办事项列表的责任(参见16.6.1节)。项目经理要判断出各个功能的实现顺序。

    如果有人愿意判定各个功能的价值,那就按价值高低进行实现,即便会给架构带来风险也要这么做。

    如果功能的价值和完成度越高,项目经理就能在当前项目中为自己和团队带来更多灵活性。你也许可以尽早发布(如果高风险的功能无法使用当前架构),这对很多客户都是很有价值的。推迟开发高风险、低价值的功能,可以保持项目的节奏,并降低当前版本的风险。

    9.3.2. 按功能调试

    有些团队坚持按架构实现。到了测试的时候,测试人员却是逐个功能进行的。这么一来,团队在调试的时候也得按功能进行了,即使他们构建产品的方式与此不同。

    为了按功能调试,项目经理要构建跨架构团队(要么就得能够接触到所有团队成员)。如果从来没有组建过跨越架构的团队,项目的节奏会因此而扰乱。不过,要是没有跨越架构的团队,问题是无法解决的。

    要是到了项目尾声,发现团队在按功能调试,那还是考虑在一开始就按功能实现吧。这会减少项目的干扰,同时项目节奏也更平稳。

    9.3.3. 按功能测试

    测试人员会按照功能测试系统,有时是因为需求的编写方式,有时是因为这就是测试人员访问系统的工作方式。当测试人员报告问题时,他们很少会单独报告各个小架构组件上的问题。实际上,他们会在测试用例中提出问题,比如,“当我试图打开一个银行账号时,我可以看到数据穿过中间件进入到数据库中,但是我看不到返回的确认。”测试人员在这里报告了一个中间件的问题,但是没有明确指出是在哪里。

    开发人员已经习惯于看到这样的报告了(不管是与调试还是测试相关),也惯于回溯问题,以判断功能是如何与架构交互的,从而理解问题。按功能实现,开发人员就可以在设计和编写代码时看到潜在的问题,不至于到开发尾声才发现。