因目前业务还跑在Pylons上,因此就拿Pylons来做这个例子吧。其他Python环境应该也是大同小异的。
CI系统环境:
OS: Ubuntu
CI 工具: Hudson 1.396
单元测试工具: nosetests
Hudson 本身的安装使用就不细写了,网上现在已经有很多了。直接下载war包,用java -jar运行即可。
启动之后,在管理界面中安装 Hudson Cobertura plugin、Python Plugin、Hudson Violations plugin、Subversion Plugin等插件即可。
一、建立虚拟环境
为了使Hudson同时支持多个python项目的持续集成,建议为每一个项目建立独立的虚拟环境,以便更清楚与项目相关联的包的情况,方便今后的部署。
下面几个步骤即可建立一个基本的虚拟环境。
1. 找到virtualenv包,取出其中的virtualenv.py
2. 运行python virtualenv.py --no-site-packages pylons-0.9.7 建立一个名字叫pylons-0.9.7的虚拟环境。这里 --no-site-packages参数是为了排除linux系统自带的python包对项目的影响,加了这个参数即可建立比较干净的Python虚拟环境。
3. 启动刚才建立的虚拟环境 source pylons-0.9.7/bin/activate
4. 运行easy_install nose 安装nosetests单元测试工具
5. 运行easy_install fudge 安装fudge Mock工具
6. 运行easy_install nosexcover 安装覆盖率生成工具,这个工具可以生成hudson中需要的xml格式的报表。仅仅安装coverage包不能生成类似报表。
二、建立项目运行环境
现在一个基本的环境已经基本建立完成了。下面在安装一些该项目特定的包
1. 安装mysql python包、sqlalchemy包
sudo apt-get install libmysqlclient-dev (MySQL-python编译安装需要mysql client开发环境)
easy_install MySQL-python
easy_install "sqlalchemy==0.5.8"
2. 安装pylons
easy_install -Z "pylons==0.9.7"
在pylons-0.9.7/lib/python26/site-packages/WebOb-1.1beta1-py2.6.egg/webob/__init__.py中加入一行from webob.multidict import UnicodeMultiDict
(pylons下载了最新的webob,里面有些改动,pylons 0.9.7不支持,需要改下)
3. 再按装写杂七杂八的项目用到的包
easy_install pycrypto
easy_install recaptcha_client
easy_install python-memcached
好了,一个pylons虚拟环境基本完成了,可以先直接下载项目代码运行nosetests看看有没有什么问题,如果运行都正常,即可进行以下步骤
三、建立Hudsong项目
1. 在Hudson中新建一个任务,选择“构建一个自由风格的软件项目“
2. 输入代码地址(SVN/CVS...)
3. 按照crontab规则建立build规律
4. 选择shell脚本作为build命令,在里面输入如下内容:
. /home/mm/pylons-0.9.7/bin/activate
cd ${WORKSPACE}
nosetests --cover-package=包名 --cover-tests --with-xcoverage --with-xunit --verbose
注:这里报名替换成需要测试覆盖率的包名
5. 设置输出报表
Publish JUnit test result report
xml文件直接输入 nosetests.xml
Publish Cobertura Coverage Report
xml文件直接输入 coverage.xml
Wednesday, August 10, 2011
Sunday, August 7, 2011
code review 之我见
近期code review的讨论貌似很多,也来凑下热闹,说说自己的一些认识和想法。
一、常见误区
1. 在我经历过的很多团队中,貌似不少人员都认为code review是一种上级的管理手段。毕竟翻译成中文叫“代码评审
”,这又评又审的,很多人就已经开始心里打鼓了,这嘴上不说,心底里早就开始抵触上了。这种情绪下还能指望即时
的review么?
2. code review不能算是考核工具,很多管理者都会有review出一个问题,扣多少多少类似的想法,把review简简单单
的当成了抓虫子,从而造成了更多的开发人员的抵触。一review就变味成了给开发挑刺,然后升级成双方攻防战,搞得
面红耳赤,你死我活的,最后一拍两散。
3. code review也不是个人技术挑战赛,这在很多年轻气盛的开发人员中很常见,“凭什么给他看”,“他又看不懂”
是这类人经常会说的话。其实从来没有人规定过review一定要找更厉害的人,一定要找出问题来的。
4. review是每一个团队成员的事,而不仅仅是经理或者架构师的事。这在传统的开发团队里面很常见,代码开发完了
一丢,就没自己啥事了。在敏捷开发中,review应该是每一个成员自发的行为。
二、一点想法
1. 整个团队必须保持一个开放的心态,能够虚心听取他人意见,战斗的团队是指对外战斗,不是内斗。
2. 必须建立一个前提认识:代码共享,团队中每个人都能随时浏览他人最新代码。代码不是私人物品,不能敝帚自珍。
3. 明确一个观点:任何review都不是挑错,是一种相互探讨,追求更高质量,更优代码的过程,是团队共同进步的一种手段。
4. review中每个人都是平等的,没有谁服从谁的概念。每个参与review的人要有包容的心态,不是只有你的解决办法是最优的
5. 得有一个公认的代码标准,最好能持续维护一个知识库,将一些优秀的代码、历史的review经验积累起来。
6. review要经常化,每次review的量要小,最好完成一个功能就review它。一次review一整个项目任谁都会烦。
7. 提交代码的时候要写清楚,也要有点必要的注释或文档,不要让别人去猜,浪费大家时间。
一、常见误区
1. 在我经历过的很多团队中,貌似不少人员都认为code review是一种上级的管理手段。毕竟翻译成中文叫“代码评审
”,这又评又审的,很多人就已经开始心里打鼓了,这嘴上不说,心底里早就开始抵触上了。这种情绪下还能指望即时
的review么?
2. code review不能算是考核工具,很多管理者都会有review出一个问题,扣多少多少类似的想法,把review简简单单
的当成了抓虫子,从而造成了更多的开发人员的抵触。一review就变味成了给开发挑刺,然后升级成双方攻防战,搞得
面红耳赤,你死我活的,最后一拍两散。
3. code review也不是个人技术挑战赛,这在很多年轻气盛的开发人员中很常见,“凭什么给他看”,“他又看不懂”
是这类人经常会说的话。其实从来没有人规定过review一定要找更厉害的人,一定要找出问题来的。
4. review是每一个团队成员的事,而不仅仅是经理或者架构师的事。这在传统的开发团队里面很常见,代码开发完了
一丢,就没自己啥事了。在敏捷开发中,review应该是每一个成员自发的行为。
二、一点想法
1. 整个团队必须保持一个开放的心态,能够虚心听取他人意见,战斗的团队是指对外战斗,不是内斗。
2. 必须建立一个前提认识:代码共享,团队中每个人都能随时浏览他人最新代码。代码不是私人物品,不能敝帚自珍。
3. 明确一个观点:任何review都不是挑错,是一种相互探讨,追求更高质量,更优代码的过程,是团队共同进步的一种手段。
4. review中每个人都是平等的,没有谁服从谁的概念。每个参与review的人要有包容的心态,不是只有你的解决办法是最优的
5. 得有一个公认的代码标准,最好能持续维护一个知识库,将一些优秀的代码、历史的review经验积累起来。
6. review要经常化,每次review的量要小,最好完成一个功能就review它。一次review一整个项目任谁都会烦。
7. 提交代码的时候要写清楚,也要有点必要的注释或文档,不要让别人去猜,浪费大家时间。
Tuesday, August 2, 2011
Pyramid 学习笔记:创建Pyramid项目(下)
除了在项目根目录生成了一系列项目配置性文件之外,Pyramid还生成了一个简单的项目框架结构以方便开发人员编写代码。这些文件统一放在了myproject这个目录下面。
一、__init__.py文件
该文件主要定义了项目入口方法。主要代码如下:
这个main函数是Pyramid自动生成的本项目的入口,这里global_config, settings两个参数分别对应于development.ini(或production.ini)中的DEFAULT段和app:myproject段的内容。本函数主要功能就是完成了使用traversal机制进行URL映射的配置过程。traversal机制是受zope启发而来的一种URL映射机制,可以构建比较复杂的URL结构。如果URL结构比较简单的化,可以使用ROUTE机制,比较直观一点。
该函数最后返回一个WSGI应用以启动本应用。
二、view.py文件
Pyramid应用中的大部分实现都是在view中实现的,这个可以看作pylons中的controller。在我们生成的项目中,view.py只有一个简单的函数:
def my_view(request):
return {'project':'myproject'}
在前面提到的__init__.py中,我们通过add_view函数注册到了系统中。因此运行这个应用之后,直接浏览 / 看到的就是调用了这个函数而返回的结果(经模板渲染之后)。
三、resources.py文件
这个文件就是用于traversal机制来映射URL时提供站点结构等资源的文件。我们通常用一个Root类来表示这些资源的根。每次接到WEB请求的时候,Pyramid Router通过这个类来找到本项目资源树的根。
四、静态文件目录
主要包含CSS、图片等静态文件
五、模板目录
存放项目开发用的模板文件。这也是在__init__.py中被add_view注册到系统中,并且与一个view关联。
六、test.py
这就是单元测试文件。
Pyramid生成的这个项目框架其实是很简单的一个结构,基本上是无法满足我们项目开发的需要的,一般我们都会修修改改再在项目中使用,也可以修改后生成一套scaffold以便今后重复利用。
一般情况下,我们都会做如下修改:
* view包,以及多层的包结构,如果应用比较复杂的话。
* 单元测试包结构
* URL映射如果复杂的化最好也能独立出来
* lib包,如果需要的话
* model包,如果有数据库支持的话
总体感觉,Pyramid生成的代码在项目代码结构的指导意义上不如pylons,也没Pylons那么严谨周全,要动的东西很多,需要抽个时间好好整理一个能用的东西出来。
本文提到的示例材料均源于Pyramid官方网站
一、__init__.py文件
该文件主要定义了项目入口方法。主要代码如下:
def main(global_config, **settings): """ This function returns a Pyramid WSGI application. """ config = Configurator(root_factory=Root, settings=settings) config.add_view(’myproject.views.my_view’, context=’myproject.resources.Root’, renderer=’myproject:templates/mytemplate.pt’) config.add_static_view(’static’, ’myproject:static’) return config.make_wsgi_app()
这个main函数是Pyramid自动生成的本项目的入口,这里global_config, settings两个参数分别对应于development.ini(或production.ini)中的DEFAULT段和app:myproject段的内容。本函数主要功能就是完成了使用traversal机制进行URL映射的配置过程。traversal机制是受zope启发而来的一种URL映射机制,可以构建比较复杂的URL结构。如果URL结构比较简单的化,可以使用ROUTE机制,比较直观一点。
该函数最后返回一个WSGI应用以启动本应用。
二、view.py文件
Pyramid应用中的大部分实现都是在view中实现的,这个可以看作pylons中的controller。在我们生成的项目中,view.py只有一个简单的函数:
def my_view(request):
return {'project':'myproject'}
在前面提到的__init__.py中,我们通过add_view函数注册到了系统中。因此运行这个应用之后,直接浏览 / 看到的就是调用了这个函数而返回的结果(经模板渲染之后)。
三、resources.py文件
这个文件就是用于traversal机制来映射URL时提供站点结构等资源的文件。我们通常用一个Root类来表示这些资源的根。每次接到WEB请求的时候,Pyramid Router通过这个类来找到本项目资源树的根。
四、静态文件目录
主要包含CSS、图片等静态文件
五、模板目录
存放项目开发用的模板文件。这也是在__init__.py中被add_view注册到系统中,并且与一个view关联。
六、test.py
这就是单元测试文件。
Pyramid生成的这个项目框架其实是很简单的一个结构,基本上是无法满足我们项目开发的需要的,一般我们都会修修改改再在项目中使用,也可以修改后生成一套scaffold以便今后重复利用。
一般情况下,我们都会做如下修改:
* view包,以及多层的包结构,如果应用比较复杂的话。
* 单元测试包结构
* URL映射如果复杂的化最好也能独立出来
* lib包,如果需要的话
* model包,如果有数据库支持的话
总体感觉,Pyramid生成的代码在项目代码结构的指导意义上不如pylons,也没Pylons那么严谨周全,要动的东西很多,需要抽个时间好好整理一个能用的东西出来。
本文提到的示例材料均源于Pyramid官方网站
Subscribe to:
Posts (Atom)