2006/10 29
Test First Guidelines
Sean Shubin
01/25/2002
Sean Shubin has begun using Test-First development. He wanted to share these ideas and guidelines with us.

Contents:

This document is my attempt to filter out guidelines about Test First Design from the XP series of books. Thanks to Denise Phillips and Ron Jeffries for their input. It is not my intent to justify Test First Design, I just want summarize what martin Fowler's Refactoring and the XP texts have to say on the subject. If you see anything that you think contradicts these sources, please e-mail me with the book and page number. I am still working on samples for each of these guidelines. If you find any of them completely confusing, send me an e-mail to let me know which ones I need to work on. Send e-mail to Sean Shubin, (remove the "nospam" portion of the e-mail address).

The tests should drive you to write the code, the reason you write code is to get a test to succeed, and you should only write the minimal code to do so. Note that test-first-design is more than just unit testing. Unit testing by itself does not change the design of the code. In addition to documenting how code should be used, test-first-design helps you keep the design simple right from the start, and keeps the design easy to change.

As project complexity grows, you may notice that writing automated tests gets harder to do. This is your early warning system of overcomplicated design. Simplify the design until tests become easy to write again, and maintain this simplicity over the course of the project.
Guidelines for test first design:

* The name of the test should describe the requirement of the code
* There should be at least one test for each requirement of the code. Each possible path through of the code is a different requirement
* Only write the simplest possible code to get the test to pass, if you know this code to be incomplete, write another test that demonstrates what else the code needs to do
* A test should be similar to sample code, in that it should be clear to someone unfamiliar with the code as to how the code is intended to be used
* If a test seems too large, see if you can break it down into smaller tests
* If you seem to be writing a lot of code for one little test, see if there are other related tests you could write first, that would not require as much code
* Test the goal of the code, not the implementation
* One test/code/simplify cycle at a time. Do not write a bunch of tests, and try to get them working all at once
* Keep writing tests that could show if your code is broken, until you run out of things that could possibly break
* When choosing an implementation, be sure to choose the simplest implementation that could possibly work
* If you are unsure about a piece of code, add a test you think might break it
* A test is one specific case, for which there is a known answer
* If all of the tests succeed, but the program doesn't work, add a test
* Tests should be as small as possible, before testing a requirement that depends on multiple things working, write a test for each thing it depends
* Tests should not take longer than a day to get working, typical test/code/simplify cycles take around 10 minutes
* Don't test every single combination of inputs. Do test enough combinations of inputs to give you confidence that the any code that passes the test suite will work with every single combination of inputs
* Do not write a single line of code that doesn't help a failing test succeed. (Clarification for GUI's, some aspects of GUI's are impossible to test automatically, so it will have to be an acceptance test that drives you two write some GUI code. Use automated testing whenever possible)
* Do not fix a bug until you have written a test that demonstrates the bug

What is the simplest code? (Paraphrased from the "Extreme Programming" series of books)

* All of the tests run
* There is no duplicate code (any given code segment or structural pattern should appear "once and only once")
* Clarity. The code and tests communicate the intent as clearly as possible
* The code is minimal (no classes or methods unnecessary to get the tests to pass)

The Test-Code-Simplify cycle (Quoted verbatim from "Extreme Programming Applied", p159)

* Write a single test
* Compile it. It shouldn't compile, because you haven't written the implementation code it calls
* Implement just enough code to get the test to compile
* Run the test and see it fail
* Implement just enough code to get the test to pass
* Run the test and see it pass
* Refactor for clarity and "once and only once"
* Repeat

Online Examples of Test First Design:

Roman numeral converter example

http://www.differentpla.net/~roger/devel/xp/test_first/

Sample application that calculates bowling score

http://www.objectmentor.com/publications/xpepisode.htm

Books:

"Refactoring" and "Design Patterns" tell you how to maintain a simple design.

The "Extreme Programming" series explains test-first design in detail, and was the primary resource I used to put together this set of guidelines.

来源:http://xprogramming.com/xpmag/testFirstGuidelines.htm
最近感觉想翻译的东西太多了,有一些就纯粹转载了。有时间再翻译。
Defined tags for this entry: , , ,

Posted by rollenc

Not modified
2006/10 29
以前在学习《php设计模式》时,学习了一点点simple Test的知识,停留在单元测试的学习就停了。也写过一些测试代码,但觉得很烦,对于测试用例也没有研究,还有不知道如何来测试PHP的输出,如一些ECHO语句等。所以,没有坚持下来,一直简单的以var_dump来调试。
现在要重新拣拾起来,重新开始学,希望能够理解好测试驱动的开发思想和编写好的测试用例等。
参考网址:
http://www.lastcraft.com/simple_test.php
http://simpletest.org/
Defined tags for this entry: , , ,

Posted by rollenc

Not modified
2006/10 28
以下的代码适用于大量数据的情况,加载时并没有对所有数据全部加载,而是取相应级数的数据加载,同样也支持N级菜单。不过暂时没有时间来修改,使之使用AJAX加载。有时间再说。
来源:http://www.7880.com/info/Article-28836620.html



Horizontal Drop Down Menus




$menu_array[1]
"; my_menu($menu_content,$i,$temp1,$temp2); } else { $temp3[$menu_grade_temp+1]=""; $temp6=implode("/",$temp3); echo "$menu_array[1]
"; } } } } // 连接 MySql 数据库 $db_host="localhost"; $db_user="test"; $db_password="test"; $db_name="test"; mysql_connect($db_host,$db_user,$db_password); mysql_select_db($db_name); //从数据库中取得数据 $query_string="select * from menu order by menu_grade"; $db_data=mysql_query($query_string); $menu_grade_temp = @intval($_GET['menu_grade_temp']); $menu_superior_temp = @($_GET['menu_superior_temp']); //第一次执行初始化 if (! $menu_grade_temp) { $menu_superior_temp=0; } //将所有的信息读入数组,并统计数组个数 $i=0; while (list($menu_id,$menu,$menu_grade,$menu_superior)=mysql_fetch_row($db_data)) { $menu_content[$i]=$menu_id."/".$menu."/".$menu_grade."/".$menu_superior; $i++; } my_menu($menu_content,$i,1,$menu_superior_temp); /* 附数据库结构及模拟数据 # phpMyAdmin MySQL-Dump # # 主机: localhost 数据库 : test # -------------------------------------------------------- # # 数据表的结构 'menu' # CREATE TABLE menu ( menu_id int(11) NOT NULL auto_increment, menu varchar(20) NOT NULL, menu_grade int(11) NOT NULL, menu_superior int(11) NOT NULL, UNIQUE menu_id (menu_id) ); # # 导出下面的数据库内容 'menu' # INSERT INTO menu VALUES( '1', '计算机', '1', '0'); INSERT INTO menu VALUES( '2', '编程', '2', '1'); INSERT INTO menu VALUES( '3', '网络', '2', '1'); INSERT INTO menu VALUES( '4', 'PHP与MySql', '3', '2'); INSERT INTO menu VALUES( '5', 'C语言', '3', '2'); INSERT INTO menu VALUES( '6', '网页制作', '3', '3'); INSERT INTO menu VALUES( '7', 'TCP、IP协议', '3', '3'); INSERT INTO menu VALUES( '8', '数学', '1', '0'); INSERT INTO menu VALUES( '9', '高等数学', '2', '8'); INSERT INTO menu VALUES( '10', '线性代数', '3', '9'); INSERT INTO menu VALUES( '11', '离散数学', '3', '9'); INSERT INTO menu VALUES( '12', '初等数学', '2', '8'); INSERT INTO menu VALUES( '13', '文学', '1', '0'); INSERT INTO menu VALUES( '14', '中国文学', '2', '13'); INSERT INTO menu VALUES( '15', 'php', '4', '4'); INSERT INTO menu VALUES( '16', 'mysql', '4', '4'); */ ?>

点击察看示例
Defined tags for this entry: ,

Posted by rollenc

Last modified on 2007-03-20 16:21
2006/10 28
纯粹使用CSS来实现的二级菜单(IE下需要JS协助)。但是可扩展性不是很好,难以发展为多级菜单。每增加一级,CSS就要进行相应的修改和增加。不过,使用CSS来作二级菜单也已经很COOL了。
来源: http://www.marktip.com/blog/article.asp?id=81



Horizontal Drop Down Menus




 




点击察看示例
Defined tags for this entry: ,

Posted by rollenc

Last modified on 2009-11-20 12:06
2006/10 28
以下代码实现了一个很酷的动态树,从http://www.cnlei.org/codes/javascript/Dhtml-Tree-Menu-200/index.html的示例文件中截取出来的。里面的每一个变量带得便意义我没有去深究,知识简单的看了一下关于数据的那一部分,感觉可以拿来就用。
当然,如果你喜欢而且想要更多的动态菜单,你可以去买一个。
apycoms DHTML Tree MenuDHTML Tree Menu都是不错的产品。




apycoms_DHTML_TREE_MENU







点击察看示例
Defined tags for this entry: ,

Posted by rollenc

Last modified on 2007-03-20 16:23
2006/10 27
From: http://www.devshed.com/c/a/PHP/Unit-Testing/
Unit Testing
单元测试

Having a formalized unit testing infrastructure for your projects will save you time in the long run, especially when looking for bugs in code. This article introduces you to setting up a unit testing framework. It is excerpted from chapter 6 of the book Advanced PHP Programming, written by George Schlossnagle (Sams; ISBN: 0672325616).
在正式的单元测试编程的基础上,你可以给你的程序开发节省下不少时间,特别是查找和修复BUG时的时间。本文介绍了如何建立一个测试框架。本文引于《告急PHP编程》第六章,作者:George Schlossnagle (Sams; ISBN: 0672325616).

Testing and engineering are inextricably tied forever.
测试和开发紧密联系

All code is tested at some point—perhaps during its implementation, during a dedicated testing phase, or when it goes live. Any developer who has launched broken code live knows that it is easier to test and debug code during development than after it goes into production.
所有的代码都在同一时候被测试,很可能是在程序执行的时候,或者是在专门的测试阶段,或者在程序发布后。程序员们都知道,在开发阶段中,在开发阶段修复程序BUG比发布后再修复要容易。

Developers give many excuses for not testing code until it is too late. These are some of the popular ones:
程序员给没有经过测试的代码找了很多的理由,常见的有:
* The project is too rushed. 程序开发过于匆忙。
* My code always works the first time. 程序在开始是可以正常运行的。
* The code works on my machine. 这些代码在我的机器上是可以正常运行的。

Let's explore these excuses. First, projects are rushed because productivity lags. Productivity is directly proportional to the amount of debugging required to make code stable and working. Unfortunately, testing early and testing late are not equal cost operations. The problem is two-fold:
我们来研究这几个理由。首先,工程匆忙是因为效率不佳,对代码的稳定性和正确性的调试直接影响到开发效率。不幸的是。在不同时候对代码进行调试所需要的花费是不一样的。从下面几点来说明:

* In a large code base that does not have a formalized testing infrastructure, it is hard to find the root cause of a bug. It's a needle-in-a-haystack problem. Finding a bug in a 10-line program is easy. Finding a bug in 10,000 lines of included code is a tremendous effort.
* 项目中没有基于一个正式的测试基础,这导致很难查找到BUG的来源。在10行代码中找出错误是简单的,但是在10,000行代码中,而且包含很多文件包含关系的代码中找出一个错误则是一场噩梦。

* As the code base grows, so do the number of dependencies between components. Seemingly innocuous changes to a "core" library—whether adding additional features or simply fixing a bug—may unintentionally break other portions of the application. This is known as refactoring. As the size and complexity of software grow, it becomes increasingly difficult to make these sorts of changes without incurring time costs and introducing new bugs.
*
* All software has bugs. Any developer who claims that his or her software is always bug-free is living in a fantasy world.
* System setups are all slightly different, often in ways that are hard to anticipate. Differing versions of PHP, differing versions of libraries, and different file system layouts are just a few of the factors that can cause code that runs perfectly on one machine to inexplicably fail on another.
Defined tags for this entry: , ,

Posted by rollenc

Not modified
2006/10 27
今天去了药店,顺便去称台上一站,乖乖,54Kg。
不敢相信,把女友放上去,45Kg,称没错。
女友在问,你肉张在哪里了?我说不知道。
胖了点是真的,自己有点感觉,但不敢想像,现在有108斤了,要知道,大学期间我的体重一直就在100斤左右徘徊。
继续长胖吧,我还需要继续增肥。
Defined tags for this entry:

Posted by rollenc

Not modified
2006/10 27
九个知识框架:

核心知识框架:
Scope Mgt. 范围管理 需求,在多大范围内来作
Time Mgt. 时间管理
COst Mgt. 成本管理
Quality Mgt. 质量管理

支持性知识框架
HR Mgt. 人力资源管理,
Communication Mgt 交流管理。 成员理解,外界沟通
Risk Mgt 风险管理
Product Mgt. 采购管理 采购组件,外包,监控外包进度

project Integration mgt. 集成管理,组织上述行为

涉及知识
Generally Accepted Project management Knowledge and Practice 以上的知识框架
Generally management Knowledge and Practice 一般性管理知识:人员管理,时间管理。
Application Area Knowledge and Practice 应用领域知识的管理。软件知识(与程序员),与目标领域(与客户)。

项目阶段:
标志:交付品deliverable。(报告,原型等)
Initiate 初始准备
Plan 计划
Control 构造
Execute 运行
Close 结束

在风险允许的前提下,可以允许下一阶段提前进行。
Defined tags for this entry: ,

Posted by rollenc

Not modified
2006/10 27
现在在网上搜索和从一些开源软件中截取一些常用的代码出来,把他们封装成类,包。以备以后使用。不过这封装过程有些困难了,耦合性,内聚性等,不知道该如何去整。特别是堪虑一些可扩展性,通用性等。
软件工程方面的知识还得继续加强啊。
如果这一步走完,自己的级别也将升一级了:从砌墙工升级到组装工了。
Defined tags for this entry:

Posted by rollenc

Not modified
2006/10 20
2006年10月19日19点44分,接到妈的电话,外婆走了。我在前一个小时,18点30分还打了电话回家,问妈外婆的情况。
一个小时。就一个小时。。。
我明天早上一早出发,坐车回家,近24个小时的车程。
只求,能够送外婆走好,在那远方能够开开心心的生活。

Defined tags for this entry:

Posted by rollenc

Not modified
2006/10 16
很久没有试过使用gaim来登录QQ了,前阵子GAIM自动升级,出现了QQ的协议。用了下,居然可以登录:!
只是群和分组信息没了,显示不出来。基本也是等于不能用的。但我记得当时TENCENT把这个协议封闭了的,好像还和LUMAQQ打了官司。
什么时候TENCENT也开放起来了?

Defined tags for this entry:

Posted by rollenc

Not modified
2006/10 11
曾经一度被测试驱动开发的思想所吸引,使用了一些PHPUnit,SimpleTest这些东西来进行开发,不过最终因为没有体会到测试开发和模块的开发方法,在组合测试上卡的很死,简单只能做点单元测试。因而最终放弃了测试驱动的开发思想。
刚刚看到PHPUnit3.0beta放出消息,也许有可以去看一看了。有机会回过头在学习一下,测试驱动开发思想。

Defined tags for this entry: ,

Posted by rollenc

Not modified
2006/10 11
假设,现在的有两个类,句子(sentence),单词(word)。句子和单词都有一个语言的属性,比如:中文句子,中文单词,而实际上,句子的属性中文又是单词给赋予的。
问题:我现在要求一个中文句子,那么中文这个语言属性值是属于句子,还是属于单词?还是两者?
Defined tags for this entry:

Posted by rollenc

Not modified
2006/10 10
昨天不知道是吃了什么过敏的东西还是什么,下午身上慢慢的出现红斑,本来想用被子晤晤的,在公司不好办。晚上又等玲子下班,在门外吹了好长一阵的风。
晚上终于受不了,身上全红了。用被子穿着棉衣,盖着被子晤了好长时间都不好。
一晚上受罪。
今天买了点天价的药,6粒17块钱。碰碰运气,看看能不能见效。

Defined tags for this entry:

Posted by rollenc

Not modified
2006/10 9
七天的休息,好像也没做什么很有意义的事情,简简单单的过去了。
今天8号,上班开始,团队有一人离开,挺失落的。
慢慢来吧,我现在也没有什么很好的信仰,将自己觉得好的产品坚持下来,如果觉得迷茫,抽空研究一下自己真正想学的知识。
自己在前进,虽然,在一些方向上又一些偏离。
不管,努力就是了。
Defined tags for this entry:

Posted by rollenc

Not modified

(Page 1 of 2, totaling 20 entries)