Skip to content

Commit 28bb163

Browse files
committed
Pylons 升级为 0.9.7,修改了 WebHelpers 以及 routing 相关内容
1 parent 5ee683c commit 28bb163

File tree

4 files changed

+206
-129
lines changed

4 files changed

+206
-129
lines changed

ch01-preface.xml

+14-14
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
项目首页:<ulink url="http://pySvnManager.sf.net"/>。该项目从一开始,
1414
就采用了测试驱动开发(TDD)技术,通过一系列的迭代最终敏捷的实现了预期的需求。</para>
1515

16-
<para>在该项目中采用了Python最新流行的MVC框架:Pylons。并在 Web 页面中大量使用了
16+
<para>在该项目中采用了 Python 最新流行的 MVC 框架:Pylons。并在 Web 页面中大量使用了
1717
AJAX 技术。本文涉及到的技术术语有:敏捷, TDD, MVC, 单元测试, 代码覆盖测试,
1818
AJAX, 重构, i18n, 开放源代码。</para>
1919

@@ -86,8 +86,8 @@ user1 =
8686

8787
<para>其中1和2的错误会造成Subversion服务中断故障!3和4的问题如果不经过测试很难发现!
8888
在我们为客户实施Subversion技术支持服务过程中,发现了用户迫切需要容错性强的
89-
授权管理工具,于是便有了开发图形化管理界面的打算。选择Python是因为Python语言的魅力
90-
以及Python开发过程的高效。</para>
89+
授权管理工具,于是便有了开发图形化管理界面的打算。选择 Python 是因为 Python
90+
语言的魅力以及 Python 开发过程的高效。</para>
9191

9292
</sect2>
9393

@@ -113,16 +113,16 @@ Reading https://sourceforge.net/projects/pysvnmanager
113113

114114
<para>理论上很简单的东西,却奈何不了复杂的现实:</para>
115115

116-
<para>在项目刚刚开发完成,就出现了相当长一段时间的 SourceForge.net 无法访问!
116+
<para>在项目刚刚开发完成,就出现了相当长一段时间的 <uri>SourceForge.net</uri> 无法访问!
117117
导致 <command>easy_install</command> 为了搜索最新版本,在连接到
118-
<ulink url="http://SourceForge.net"/> 时发生了死锁而阻塞。
119-
虽然我打算把项目移到别处,但发现一些依赖的包如: python-ldap
120-
也是要访问 SourceForge.net网站。因此我取消了搬家的打算,耐心且无助的等待解封。
118+
<ulink url="http://pysvnmanager.sourceforge.net"/> 时发生了死锁而阻塞。
119+
虽然我打算把项目移到别处,但发现一些依赖的包如: <package>python-ldap</package>
120+
也是要访问 <uri>SourceForge.net</uri> 网站。因此我取消了搬家的打算,耐心且无助的等待解封。
121121
同时将代码镜像在网址:<ulink url="http://svn.worldhello.net/svn/pysvnmanager"/>
122-
上,供不能访问 <ulink url="http://SourceForge.net"/> 的用户参考。</para>
122+
上,供不能访问 <ulink url="http://pysvnmanager.sourceforge.net"/> 的用户参考。</para>
123123

124124
<para>如果遇到阻塞,则需要花费更多的时间,手工下载软件包。<command>easy_install</command>
125-
也可以安装下载到本地的软件包。</para>
125+
也可以安装已经下载到本地的软件包。</para>
126126

127127
<screen>
128128
$ <emphasis>wget http://pypi.python.org/packages/source/p/pySvnManager/pySvnManager... </emphasis>
@@ -169,25 +169,25 @@ Running setup_config() from pysvnmanager.websetup
169169

170170
<itemizedlist>
171171
<listitem>
172-
<para><emphasis>config.ini :</emphasis>
172+
<para><emphasis><filename>config.ini</filename> :</emphasis>
173173

174174
应用默认运行于5000端口,可以在此文件中定制</para>
175175
</listitem>
176176

177177
<listitem>
178-
<para><emphasis>config/localconfig.py :</emphasis>
178+
<para><emphasis><filename>config/localconfig.py</filename> :</emphasis>
179179

180-
设置应用缺省的认证方式,缺省用config/svn.passwd口令认证</para>
180+
设置应用缺省的认证方式,缺省用 <quote><filename>config/svn.passwd</filename></quote> 口令认证</para>
181181
</listitem>
182182

183183
<listitem>
184-
<para><emphasis>config/svn.passwd :</emphasis>
184+
<para><emphasis><filename>config/svn.passwd</filename> :</emphasis>
185185

186186
缺省该口令文件内所有用户的口令均为 "guess"</para>
187187
</listitem>
188188

189189
<listitem>
190-
<para><emphasis>config/svn.access :</emphasis>
190+
<para><emphasis><filename>config/svn.access</filename> :</emphasis>
191191

192192
svn路径授权文件,本应用要处理的文件。注意该文件开头的注释是版本号和版本库管理员帐号设置,
193193
不要随意删除!</para>

ch02-model-tdd.xml

+45-32
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
<para><emphasis>忘记Web吧:</emphasis></para>
1212

1313
<para>我们要开发出一套Web应用,但首先要忘掉Web。这看似矛盾,却正是MVC的要求和精髓。
14-
即对核心算法进行抽象,先实现Model,之后再去考虑Controller(控制器)和View(Web展现)。</para>
14+
即对核心算法进行抽象,先实现 <literal>Model</literal>,之后再去考虑
15+
<literal>Controller</literal>(控制器)和
16+
<literal>View</literal>(Web展现)。</para>
1517

1618
<para><emphasis>忘记详细设计吧:</emphasis></para>
1719

@@ -36,10 +38,12 @@
3638

3739
<para>Subversion路径授权中,用户对象(用户/别名/组)显然是最重要的基本单位,
3840
每一条授权策略都包含一个用户对象。那么我们第一个迭代就实现用户对象:
39-
User类,Alias类,Group类。</para>
41+
<classname>User</classname> 类,<classname>Alias</classname> 类,
42+
<classname>Group</classname> 类。</para>
4043

41-
<para>假设svnauthz的 User, Alias, Group 类已经完成,我们期望他们实现的功能是什么呢?
42-
于是在纸上写下假想任务目标(模拟python交互式命令行):</para>
44+
<para>假设 <package>svnauthz</package> 的 <classname>User</classname>,
45+
<classname>Alias</classname>, <classname>Group</classname> 类已经完成,
46+
我们期望他们实现的功能是什么呢?于是在纸上写下假想任务目标(模拟python交互式命令行):</para>
4347

4448
<programlisting>
4549
&gt;&gt;&gt; <emphasis>from svnauthz import User, Group, Alias</emphasis>
@@ -125,7 +129,7 @@ ImportError: No module named svnauthz
125129
<sect3 id="psm.tdd.iter1.unittest.pass">
126130
<title>编写模组,使测试用例通过</title>
127131

128-
<para>之前执行测试用例失败,报告:找不到 svnauthz 模组。因为模组还没有创建,当然找不到了。
132+
<para>之前执行测试用例失败,报告:找不到 <classname>svnauthz</classname> 模组。因为模组还没有创建,当然找不到了。
129133
于是创建一个空的模组文件 <filename>svnauthz.py</filename>。</para>
130134

131135
<screen>
@@ -147,10 +151,11 @@ NameError: global name 'User' is not defined
147151
...
148152
</screen>
149153

150-
<para>太棒了,我们前进了一步,因为失败的原因已经不同了。错误报告说:User类未定义。
151-
于是我们写一些代码,让测试用例通过。</para>
154+
<para>太棒了,我们前进了一步,因为失败的原因已经不同了。错误报告说:
155+
<classname>User</classname>类未定义。于是我们写一些代码,
156+
让测试用例通过。</para>
152157

153-
<para>svnauthz.py第一个版本的代码如下:</para>
158+
<para><filename>svnauthz.py</filename> 第一个版本的代码如下:</para>
154159

155160
<programlisting><![CDATA[
156161
1 #!/usr/bin/env python
@@ -193,25 +198,25 @@ NameError: global name 'Alias' is not defined
193198
...
194199
</screen>
195200

196-
<para>好的,我们已经有一个测试用例(testUser)通过了!其他的测试用例呢?
197-
先把他们注释掉,以便提前感受一下完全通过测试的滋味。</para>
201+
<para>好的,我们已经有一个测试用例(<classname>testUser</classname>)通过了!
202+
其他的测试用例呢?先把他们注释掉,以便提前感受一下完全通过测试的滋味。</para>
198203

199204
<para>注意:我所说的注释掉不是删除代码,也不是把每一行变为注释,
200205
而是非常简单的将暂不考虑的测试用例改名。</para>
201206

202207
<itemizedlist>
203208
<listitem>
204-
<para>将 def testAlias(self) 改为 def _testAlias(self)</para>
209+
<para>将 <code>def testAlias(self)</code> 改为 <code>def _testAlias(self)</code></para>
205210
</listitem>
206211

207212
<listitem>
208-
<para>将 def testGroup(self) 改为 def _testGroup(self)</para>
213+
<para>将 <code>def testGroup(self)</code> 改为 <code>def _testGroup(self)</code></para>
209214
</listitem>
210215

211216
</itemizedlist>
212217

213218
<note>
214-
<para>注:只要不是以 test 开头都好。</para>
219+
<para>注:只要不是以 <literal>test</literal> 开头都好。</para>
215220
</note>
216221

217222
<para>再次执行测试用例,太棒了完全通过!</para>
@@ -232,8 +237,9 @@ OK
232237
<sect3 id="psm.tdd.iter1.code.coverage">
233238
<title>完善测试用例</title>
234239

235-
<para>检查代码覆盖度,在Python下有coverage包可用。用easy_install安装之后,
236-
就可以使用coverage命令了。</para>
240+
<para>检查代码覆盖度,在 Python 下有 <package>coverage</package> 包可用。
241+
用 <command>easy_install</command> 安装之后,
242+
就可以使用 <command>coverage</command> 命令了。</para>
237243

238244
<screen>
239245
$ <emphasis>coverage -x test_svnauthz.py</emphasis>
@@ -250,18 +256,19 @@ Name Stmts Exec Cover Missing
250256
svnauthz 8 7 87% 15
251257
</screen>
252258

253-
<para>哦,看来我们离完美还是差了一点。从coverage的输出中可以看出,
254-
我们的测试用例并没有对svnauthz.py的代码测试完全:第15行没有测试到。
255-
也就是用空的用户名创建User对象,应该抛出异常。</para>
259+
<para>哦,看来我们离完美还是差了一点。从 <command>coverage</command>
260+
的输出中可以看出,我们的测试用例并没有对 <filename>svnauthz.py</filename>
261+
的代码测试完全:第15行没有测试到。也就是用<emphasis>空的用户名</emphasis>创建
262+
<classname>User</classname> 对象,应该抛出异常。</para>
256263

257-
<para>我们在testUser用例的最后补充一条断言:</para>
264+
<para>我们在 <methodname>testUser</methodname> 用例的最后补充一条断言:</para>
258265

259266
<programlisting>
260267
def testUser(self):
261268
user1 = User('Tom')
262269
self.assert_(str(user1) == 'Tom')
263-
self.assertRaises(Exception, User, " ")
264-
</programlisting>
270+
<emphasis>self.assertRaises(Exception, User, " ")</emphasis>
271+
</programlisting>
265272

266273
<para>再次检查一下测试用例对代码的覆盖度。哇,100% 通过!</para>
267274

@@ -282,10 +289,11 @@ svnauthz 8 8 100%
282289

283290
<!-- =============================================================== -->
284291
<sect3 id="psm.tdd.iter1.nosetests">
285-
<title>用例管理和nosetests</title>
292+
<title>用例管理和 nosetests</title>
286293

287294
<para>目前来讲,代码和测试用例共存于同一个目录。我们重构一下,将模组代码放在
288-
src目录,将测试用例放在 tests 目录。</para>
295+
<filename>src</filename> 目录,将测试用例放在 <filename>tests</filename>
296+
目录。</para>
289297

290298
<para>执行测试用例:</para>
291299

@@ -297,7 +305,8 @@ Traceback (most recent call last):
297305
ImportError: No module named svnauthz
298306
</screen>
299307

300-
<para>在 test_svnauthz.py 文件头增加如下语句,设置Python模组查询路径:</para>
308+
<para>在 <filename>test_svnauthz.py</filename> 文件头增加如下语句,
309+
设置 Python 模组查询路径:</para>
301310

302311
<programlisting>
303312
import sys
@@ -306,12 +315,13 @@ sys.path.insert(0,'src')
306315

307316
<para>测试用例又可以成功执行了。</para>
308317

309-
<para>tests目录下如果有多个测试用例文件,难道要一个一个去调用么?或者用
310-
unittest.TestSuite去组织测试用例?其实不用这么麻烦,nosetests
318+
<para>目录 <filename>tests</filename> 下如果有多个测试用例文件,
319+
难道要一个一个去调用么?或者用 <classname>unittest.TestSuite</classname>
320+
去组织测试用例?其实不用这么麻烦,<application>nosetests</application>
311321
可以自动发现目录下的测试用例,并执行。</para>
312322

313-
<para>鼻子测试(nosetests)是一个主动发现测试用例的unittest扩展。
314-
可以用easy_install 来安装:</para>
323+
<para>鼻子测试(<application>nosetests</application>)是一个主动发现测试用例的
324+
unittest 扩展。可以用 <command>easy_install</command> 来安装:</para>
315325

316326
<screen>
317327
$ <emphasis>easy_install nose</emphasis>
@@ -346,15 +356,18 @@ OK
346356
<sect2 id="psm.tdd.continued">
347357
<title>持续迭代</title>
348358

349-
<para>持续迭代,完成User, Group, Alias, Rules, Module, Repos, SvnAuthz等模组。</para>
359+
<para>持续迭代,完成 <classname>User</classname>, <classname>Group</classname>,
360+
<classname>Alias</classname>, <classname>Rules</classname>,
361+
<classname>Module</classname>, <classname>Repos</classname>,
362+
<classname>SvnAuthz</classname> 等模组。</para>
350363

351364
</sect2>
352365

353366
<!-- ================================================================= -->
354367
<sect2 id="psm.tdd.final">
355-
<title>最终完成的svnauthz</title>
368+
<title>最终完成的 svnauthz</title>
356369

357-
<para>在Python交互模式下测试svnauthz模组:</para>
370+
<para>在 Python 交互模式下测试 <classname>svnauthz</classname> 模组:</para>
358371

359372
<screen>
360373
&gt;&gt;&gt; <emphasis>buff = '''# admin: / = administrator</emphasis>
@@ -395,7 +408,7 @@ True
395408
['@group1 = r', 'user3 = rw', '$authenticated = ', '&amp;admin = rw']
396409
</screen>
397410

398-
<para>现在是时候给 svnauthz 套上一个华丽一点的外衣了。</para>
411+
<para>现在是时候给 <classname>svnauthz</classname> 套上一个华丽一点的外衣了。</para>
399412

400413
</sect2>
401414

0 commit comments

Comments
 (0)