Category Archives: Software Engineering

Scrum is good at time management

Scrum is good at time management because it puts every activity under track without any exceptions

All what you are doing should be tasks on the white board.  

Requirement analysis, tech design are now grooming sessions and spikes.  They are all scrum terms and will be handled in a formal way so time spent on them will always be calculated in your plan. 

You can have small grooming sessions instead of a big one

You don’t have to have a big grooming session to analyse all the user stories for next sprint.  That will be tiresome since it takes long, and people won’t like it.  

Instead you can break them into small ones, like a one-hour session everyday for a few days while you are still going on current sprint.  During every session, you still try to clarify the user story as in detail as possible and work out a design and task break down on spot if possible.  

一种健壮性测试的思路:用爬虫扫描全站,然后查看系统日志

以前一直有这样一个想法,今天终于付诸实践了。

为了查看web应用有后台错误日志,最基本的测试办法是手工点页面。

但要手工点全站,会比较慢。 最理想的办法是建立一套自动化测试脚本。

但如果没有一套这样的脚本,或者说没有这个脚本还不够完备时,就可以考虑使用爬虫了。 爬虫的好处是它可以递归地找出一个站点的所有链接并跟踪,也就是说能够完整遍历你的网站提供的服务。

所以,你可以一边用爬虫扫,一边盯着你后台的日志文件,看看有没有ERROR Log.

这里推荐一个轻巧的爬虫:skipfish. 它是一个命令行程序,主要用于安全性扫描,不过当然也可以用于健壮性测试:

./skipfish  -D my-friend.com -g 1 -m 1  -r 100  -o  ~/report-dir http://my.com/index  #这是linux版的,windows下也有skipfish.exe
#你还可以使用-C参数注入cookie, 方便扫描登录后的页面

    

扫完之后找出所有错误日志:

cat my.log|grep ERROR|awk '{for (i=5;i<=NF;i++ )printf( "%s ",$i); printf("\n")}' |sort|uniq  # 这里从第5列开始看日志,请按你的日志pattern来调整这个值

不过skipfish有个缺点,它对javascript的处理能力;如果你的网站有大量的ajax请求,那skipfish是不够用的,需要另找其它爬虫。

开发环境要不要和测试环境隔离?  

开发环境要不要和测试环境隔离?  要就是说,是不是要各用一套数据库等基础设施?

能隔离当然最好,开发人员和测试人员不会互相干扰。 但隔离是有代价的,它意味着你要多引一个数据库,如果你的系统是分布式的,你还要多维护一套MQ、RPC中间件等。

依我看,需不需要隔离要看系统是否满足下面的三个条件:

1. 两个环境的系统总是要接触到同一份数据

2. 数据被一个系统接触后,业务状态会改变;导致这份数据对另一个系统不再可用

3. 很难禁止两个系统在同一时刻接触到同一份数据

解释:

条件1. 如果两个环境共享数据库,但开发环境只处理北方数据,测试环境只处理南方的,那不用隔离

条件2. 即使两个环境都会处理北方数据,但如果这种处理是只读的,也就是开发环境用了,测试环境可以再用,那也无所谓

条件3. 即使数据被一个环境处理后,另一个不能用;但如果对数据的接触是人为触发的,也就是说开发环境被人触发数据改动时,不会干扰测试环境的测试,那也无所谓。

具体的场景:

1. 纯读的网站不必隔离,它不满足条件2

2. 有写、但所有操作都由用户触发的网站也不必隔离,因为它不满足条件3

3. 以全局数据为目标的自启应用需要隔离,比如 Quartz, Cron, MQ消费者等,因为它们不满足条件1。 以MQ应用为例,如果外部发来的某个数据被测试环境消费过了,开发环境就无法再消费了,这时你应该为开发和测试环境各配一个MQ

4. 对自启应用,如果实在不想隔离,就要在代码里做一些env-specific的东西,使得不同环境不会访问到相同的数据,比如开发环境只能访问数据库里flag=Dev的记录。不过,这种作法对程序和数据的侵入都很大,不值得提倡。 但这种做法可以应用到其他环境的隔离上,比如预发环境和正式环境,它们必须使用相同的数据库。

根据Module的特性决定单元测试的覆盖率要求

业务应用的单元测试覆盖率可以低一些,框架和工具箱的覆盖率必须要很高

 

单元测试的覆盖率高当然很好,但高的覆盖率意味着要写很多测试;而写测试本身是件费脑费时的事情,代价不低。 所以要在收益和代价之间取得平衡。

 

可以着眼现在,放眼未来,具体考量四个因素:

    1. 对代码正确性的要求。 要求越高,覆盖率就应该越高。

    2. 能否人肉测试。 如果用人肉可以做测试,则自动化运行的单元测试代码可以少一些

    3. 代码逻辑的易变性。    代码逻辑越易变,写的测试被浪费的概率越大,对低覆盖率的容忍度越大

    4. 发现bug时的易改性。 出现bug的代码越容易改,对低质量的容忍度越大,对低覆盖率的容忍度也越大

   

 

以互联网为例,在业务应用层面,可以为了迅速推出新产品而容忍一定的bug,可以用鼠标进行人肉测试,产品易变代码逻辑也易变,发现bug时也容易改,所以这一块的测试覆盖率可以低一些

 

而框架、工具箱等Module的代码正确性必须非常高,否则会影响很多上层模块和系统;没有界面因此不能人肉测试; 代码逻辑不怎么变,单元测试被浪费的概率不高;一旦出现bug,受牵连的上层模块和系统可能会非常多,因此不能轻易让bug出现。 所以,框架、工具箱等Module的测试覆盖率必须非常高。

MS Project项目跟踪:如果排在后面的任务被先做了怎么办?

分享MS Project项目跟踪的一个技巧:
如果排在后面的任务被先做了,你应该把这个任务挪到前面来,或者把做掉的那部分挪到前面来

问题:

如果排在后面的任务被先做了,你要怎么更改甘特图才能体现它对进度的影响?

举例来说,原计划是

A

B

C

结果你第一天没有做A,而是做C做了50%,这时甘特图应该怎么填?

不好的方案

直观的方案是给C填50%,其它不变。但实践证明,这样弄的话,A,B的计划开始时间并不会自动后移; 若查看“项目跟踪-差异"视图将新计划与基线比较,你也看不到A,B的拖延情况

有效的方案

我的办法是:“如实反映”。
如果你就是要把C做完,再做A,B,那就把C挪到最前面

C 100%

A

B

如果你想接下来做A,B,再做剩下的C的50%,那就把C切分掉,把完成的任务放到最前面

C1 50%

A

B

C

这时候你再检查一下“项目跟踪-差异"视图,它会给你一个让你可以接受的答案。

我这个办法未必是最佳实践。欢迎提出更好的方案

适合结对的工作和不适合结对的工作

Pair Programming的适用性不能盲目肯定,也不能一棍子打死

按我的体会,有的事情适合Pair,有些不适合

适合结对的工作:

   1. 列出所有XXX,以免遗漏。这种事情一个人做很容易遗漏,两个人会好很多。

不适合结对的工作:

   1. 创新、探索性工作,比如设计出一个完备的业务流程。这种事情需要集中精力、独立思考,两个人一起做,效率反而更低。

(待续)

版本号释义

抄自《Maven实战》

    版本号 1.3.4-beta-2 该怎么理解?

1 – 代表“主版本”,表示项目的重大架构变更

3 – 代表“次版本”,表示较大范围的功能增加和变化,但总体架构未变

4.- 代表“增量版本”,一般表示重大Bug的修复或功能的增强

beta-2 –  代表“里程碑版本”,表示当前的开发已经完成了某个里程牌,但还未稳定

Feature Branch的优缺点

Feature Branch指的是每开发一个新功能、每修一个bug,都打出一个新的分支,等测试通过后才合并到主干。它的反面是"对所有新功能,大家直接在主干上修改代码“

个人对Feature Branch的优缺点有一些体会:

优点

  1.
不同feature之间的开发可以彼此隔离,避免了“一损俱损”的风险。比如,如果大家都在主干上开发,一个人不小心提交了错误的代码变更导致了编译错误,会搞得所有人的code base都无法编译。亲身经验表明,这种事情非常浪费时间、损耗士气

  2.
隔离了的分支可以独立进行QA测试,时间上不会互相担误。如果大家都在主干上开发,那主干就用于QA测试,也就是说,张三和李四的改动会集成在一起测试,

    a. 如果张三的改动在测试时发现问题,修改后要重build、重启应用,则李四的改动也意味着要被重启,这会浪费测跟李四有关的测试人员的时间。为了避免这种影响,大家只好约定在每天一两个固定的时间点重build、重启。亲身经验表明,这种做法的效率比较低。

    b. 如果张三的改动没测通,李四的改动可能也不准发布,因为测试人员不敢确定张三的错误是否与李四的改动有关

 3.
确保未测通的改动不会跟别的改动混在一起或进入主干,避免发布时的“选择性代码合并”问题。如果大家都在主干上开发,在发布时只能选择已测通的改动发出去;由于测通了的改动和未测通的改动混杂在主干分支上,所以合并代码到发布分支时,你要小心翼翼,以保证只合并该合并的代码。虽然现在的版本控制工具很强大,但在处理这类事情时如果遇到复杂的情形,往往还是力不从心,仍须人力来辅助。亲身经验表明,用人力做这种事情比较无聊、费时,而且错误率很高。

(待续)

缺点

  1.每次开发都要新建分支、重建开发环境,比较浪费时间

  2.如果每个分支独立测试,则意味着每个分支要占一台测试机器,这要求公司的硬件比较充裕。

  3.持续集成的利用率不高。对Feature Branch一般不会持续监控,所以持续集成只能作用在主干上。既然健康的改动才会集成到主干上,所以主干基本上也是健康的,这时持续集成基本上是个摆设。

  4.一个分支的大改动要很晚才能集成到另一个分支,导致Big Scary Merge问题(Martine Fowler语)。假如张三的Feature改了很长时间,终于在今天归并到了主干; 而李四已有一个分支在改动,当他第二天把主干集成到自己的分支时(日常集成),由于主干的变动很大,他会发现自己可能会遇到非常多的代码冲突,即Big Scary Merge

(待续)