很cool的名字,極限編程(Extreme Programming,簡寫XP)是編程的一種流行趨勢:
(1)首先是對目標進行計劃;
(2)而後將測試用例集合編寫爲一種框架;
(3)以後才編寫實際的代碼。
在完成實際代碼後的任什麼時候候,均可以運行測試用例以查看接近設計目標的程度,該測試套件具體體現了這個設計目標,同時也在調式和測試軟件,很是的nice。
****************************************************************************************************
下面是一個實際的例子,完成一個和Unix中find和grep結合的工具
能夠指定 文件名 文件內容 擴展名 搜索目錄 進行搜索,返回合適的文件信息
----------------------------------------------------------------------
第一步是須要分析,對結果作初步規劃:
(1)返回形式:(path , filename , 擴展名 , 文件大小)的元組;
(2)輸入參數:搜索文件名的regex 和 內容地regex;
(3)其它搜索項:文件大小,存在時間,最近一次修改信息等(介個之後再說)
-----------------------------------------------------------------------
第二步是極限編程的特點,按照設計好的接口,完成測試代碼:
(這裏是個做弊的行爲,由於實踐中不可能一次性的將測試代碼所有完成)
1 #!/usr/bin/python
2 # -- coding: utf-8 --
3 #============================================
4 #FileName: test_find.py
5 #Date: 2013年 06月 04日 星期二 09:29:20 CST
6 #Author: chenhuan
7 #Usage: unittest test file of find.py
8 #============================================
9
10 import unittest
11 import find
12 import os , os.path
13 import shutil
14
15 #============================================================
16 class TestFind(unittest.TestCase) :
17 """
18 TestFind - test the find module. It has five parts to test
19 1. testSearchAll - search the .*
20 2. testSearchFile - search as the input filename
21 3. testSearchContent - search as the content
22 4. testSearchExtension - search as the extension name
23 5. testSearchLogic - search as the logic
24
25 find(fileName , content , start)
26 return ([path , fileName , extension , fileSize]...)
27 """
28
29 #--------------------------------------------------
30 def __getFileName(self , fileInfo) :
31 """
32 __getFileName - return the filename
33 fileInfo - the result return by find
34 """
35 return fileInfo[1]
36
37
38 #--------------------------------------------------
39 def setUp(self) :
40 """
41 setUp - build up the test files as follows
42 1. _test/file_1.txt "chenhuan"
43 1. _test/file_2.py "wuxiaoqin"
44 2. _test/dir_1/file_1.cpp "#include <stdio.h>"
45 3. _test/dir_2/file_1.py "wuxiaoqin"
46 """
47 try :
48 os.mkdir('./_test')
49 os.mkdir('./_test/dir_1')
50 os.mkdir('./_test/dir_2')
51 except :
52 pass
53
54 f = open('./_test/file_1.txt','w')
55 f.write('chenhuan')
56 f.close()
57
58 f = open('./_test/file_2.py','w')
59 f.write('wuxiaoqin')
60 f.close()
61
62 f = open('./_test/dir_1/file_1.cpp','w')
63 f.write('#include<stdio.h>')
64 f.close()
65
66 f = open('./_test/dir_1/file_1.py','w')
67 f.write('wuxiaoqin')
68 f.close()
69
70 #-------------------------------------------------
71 def tearDown(self) :
72 """
73 tearDown - remove all the test files
74 """
75 shutil.rmtree('./_test')
76
77 #-------------------------------------------------
78 def testSearchAll(self) :
79 """
80 testSearchAll - find all the files under pointed directory
81 """
82 filesInfo = find.find(fileName=r".*" , start="_test")
83 self.failUnless(map(self.__getFileName , filesInfo).sort() ==
84 ['file_1.txt','file_2.py','file_1.cpp','file_1.py'].sort(),
85 'Error in testSearchAll')
86
87 #----------------------------------------------------
88 def testSearchFile(self) :
89 """
90 testSearchFIle - find the pointed file
91 """
92 filesInfo = find.find(fileName=r"file_1.*" , start='_test')
93 self.failUnless(map(self.__getFileName , filesInfo).sort() ==
94 ['file_1.txt' , 'file_1.cpp' , 'file_1.py'].sort() ,
95 'Error in testSearchFile')
96
97
98 filesInfo = find.find(fileName=r"file_1.txt" , start='_test')
99 self.failUnless(map(self.__getFileName , filesInfo) ==
100 ['file_1.txt'] , 'Error in testSearchFile')
101
102 filesInfo = find.find(fileName=r"file_2.txt" , start='_test')
103 self.failUnless(map(self.__getFileName , filesInfo) ==
104 [] , 'Error in testSearchFile')
105
106 #----------------------------------------------------
107 def testSearchContent(self) :
108 """
109 testSearchContent - find the files which contains pointed content
110 """
111 filesInfo = find.find(content = 'wuxiaoqin' , start='_test')
112 self.failUnless(map(self.__getFileName , filesInfo).sort() ==
113 ['file_2.py' , 'file_1.py'].sort() ,
114 'Error in testSearchContent')
115
116 filesInfo = find.find(content = r'include' , start='_test')
117 self.failUnless(map(self.__getFileName , filesInfo) ==
118 ['file_1.cpp'] , 'Error in testSearchContent')
119
120 filesInfo = find.find(content = r'wu.*qin' , start='_test')
121 self.failUnless(map(self.__getFileName , filesInfo).sort() ==
122 ['file_1.py' , 'file_2.py'].sort() ,
123 'Error in testSearchContent')
124
125 #-------------------------------------------------------
126 def testSearchExtension(self) :
127 """
128 testSearchExtension - find the files by the extension name
129 """
130 filesInfo = find.find(extension='txt' ,start='_test')
131 self.failUnless(map(self.__getFileName , filesInfo).sort() ==
132 ['file_1.txt','file_2.txt'].sort() ,
133 'Error in testSearchExtension')
134
135 filesInfo = find.find(content='chenhuan' , extension='txt' ,
136 start='_test')
137 self.failUnless(map(self.__getFileName , filesInfo) ==
138 ['file_1.txt'] , 'Error in testSearchExtension')
139
140 #=====================================================
141 if name == 'main' :
142 unittest.main()python
第三步開始纔是真正的須要實現功能的代碼,實際上這一塊和測試代碼一道,是一個緩慢發展的過程:
1 #!/usr/bin/python
2 # -- coding: utf-8 --
3 #============================================
4 #FileName: find.py
5 #Date: 2013年 06月 04日 星期二 09:29:55 CST
6 #Author: chenhuan
7 #Usage: find to search the file as dir regex
8 #and content regex
9 #============================================
10
11 import os
12 import os.path
13 import re
14 from stat import
15
16 #---------------------------------------------------------
17 def find(fileName=r'.' , content=None , extension=None , start='.') :
18 """
19 find - find the file named 'fileName' which contains the
20 'content' under the 'start' path, 'extension' means the suffix
21 """
22 context = {}
23 context['fileName'] = fileName
24 context['content'] = content
25 context['extension'] = extension
26 context['return'] = []
27
28 os.path.walk(start , findFile , context)
29
30 return context['return']
31
32 #----------------------------------------------------------
33 def findFile(context , dirName , files) :
34 """
35 findFile - return the fileInfo which match the context
36 """
37 for file in files :
38 path = os.path.join(dirName,file)
39 path = os.path.normcase(path)
40
41 fileInfo = os.stat(path)
42 size = fileInfo.st_size
43
44 #ignore directorys
45 if S_ISDIR(fileInfo.st_mode) :
46 continue
47
48 try :
49 extension = os.path.splitext(file)[1][1:]
50 except :
51 extension = ''
52
53 #do filtration based on the fileName
54 fileNameP = re.compile(context['fileName'])
55 if not fileNameP.search(file):
56 continue
57
58 #do filtration based on extension
59 if context['extension'] :
60 extensionP = re.compile(context['extension'])
61 if not extensionP.search(extension) :
62 continue
63
64 #do filtration based on the contents
65 if context['content'] :
66 f = open(path , 'r')
67 fileContentP = re.compile(context['content'])
68 matchFlag = False
69 for line in f.readlines() :
70 if fileContentP.search(line) :
71 matchFlag = True
72 break
73 f.close()
74 if not matchFlag :
75 continue
76
77 #Build the return value
78 fileReturn = (path , file , extension ,size)
79 context['return'].append(fileReturn)編程
結果直接運行test_find.py就能夠了,調式了半天,固然是沒有啥錯誤:
Python:極限編程app
極限編程的優勢是在開始真正的coding以前,須要有一個清晰的需求分析和接口設計,這是個人大短板。感受從學習Python開始,愈來愈習慣於接受知識,而不是去思考本身的方案,有點像Matlab,過度的依賴於各類庫。thinking~~~thinking~~~thinking纔是王道,工具只是用來實現本身想法的,別捨本逐末~~~框架