<pre id="vvttv"><mark id="vvttv"><progress id="vvttv"></progress></mark></pre>
    <pre id="vvttv"></pre>

      <p id="vvttv"></p>

          <p id="vvttv"></p>

                <p id="vvttv"></p>

                <pre id="vvttv"><cite id="vvttv"><progress id="vvttv"></progress></cite></pre>

                  <output id="vvttv"><dfn id="vvttv"><th id="vvttv"></th></dfn></output>

                    <p id="vvttv"></p>

                    16.7. 全部放在一起

                    你已經學習了足夠的知識,現在來分析本章樣例代碼的前七行:讀取一個目錄并從中導入選定的模塊。

                    例 16.16. regressionTest 函數

                    
                    def regressionTest():
                        path = os.path.abspath(os.path.dirname(sys.argv[0]))   
                        files = os.listdir(path)                               
                        test = re.compile("test\.py$", re.IGNORECASE)          
                        files = filter(test.search, files)                     
                        filenameToModuleName = lambda f: os.path.splitext(f)[0]
                        moduleNames = map(filenameToModuleName, files)         
                        modules = map(__import__, moduleNames)                 
                    load = unittest.defaultTestLoader.loadTestsFromModule  
                    return unittest.TestSuite(map(load, modules))          
                    

                    讓我們一行行交互地看。假定當前目錄是 c:\diveintopython\py,其中有包含本章腳本在內的本書眾多樣例。正如在 第 16.2 節 “找到路徑” 中所見,腳本目錄將存于 path 變量,因此讓我們從這里開始以實打實的代碼起步。

                    例 16.17. 步驟 1:獲得所有文件

                    >>> import sys, os, re, unittest
                    >>> path = r'c:\diveintopython\py'
                    >>> files = os.listdir(path)                               
                    >>> files 1
                    ['BaseHTMLProcessor.py', 'LICENSE.txt', 'apihelper.py', 'apihelpertest.py',
                    'argecho.py', 'autosize.py', 'builddialectexamples.py', 'dialect.py',
                    'fileinfo.py', 'fullpath.py', 'kgptest.py', 'makerealworddoc.py',
                    'odbchelper.py', 'odbchelpertest.py', 'parsephone.py', 'piglatin.py',
                    'plural.py', 'pluraltest.py', 'pyfontify.py', 'regression.py', 'roman.py', 'romantest.py',
                    'uncurly.py', 'unicode2koi8r.py', 'urllister.py', 'kgp', 'plural', 'roman',
                    'colorize.py']
                    
                    1 files 是由腳本所在目錄的所有文件和目錄構成的列表。(如果你已經運行了其中的一些樣例,可能還會看到一些 .pyc 文件。)

                    例 16.18. 步驟 2:找到你關注的多個文件

                    >>> test = re.compile("test\.py$", re.IGNORECASE)           1
                    >>> files = filter(test.search, files)                      2
                    >>> files                                                   3
                    ['apihelpertest.py', 'kgptest.py', 'odbchelpertest.py', 'pluraltest.py', 'romantest.py']
                    
                    1 這個正則表達式將匹配以 test.py 結尾的任意字符串。注意,你必須轉義這個點號,因為正則表達式中的點號通常意味著 “匹配任意單字符”,但是你實際上想匹配的事一個真正的點號。
                    2 被編譯的正則表達式就像一個函數,因此你可以用它來過濾文件和目錄構成的大列表,找尋符合正則表達式的所有元素。
                    3 剩下的是一個單元測試腳本列表,因為只有它們是形如 SOMETHINGtest.py 的文件。

                    例 16.19. 步驟 3:映射文件名到模塊名

                    >>> filenameToModuleName = lambda f: os.path.splitext(f)[0] 1
                    >>> filenameToModuleName('romantest.py')                    2
                    'romantest'
                    >>> filenameToModuleName('odchelpertest.py')
                    'odbchelpertest'
                    >>> moduleNames = map(filenameToModuleName, files)          3
                    >>> moduleNames                                             4
                    ['apihelpertest', 'kgptest', 'odbchelpertest', 'pluraltest', 'romantest']
                    
                    1 正如你在 第 4.7 節 “使用 lambda 函數” 中所見,lambda 快餐式地創建內聯單行函數。這里應用你在 例 6.17 “分割路徑名” 中已經見過的,標準庫的 os.path.splitext 將一個帶有擴展名的文件名返回成只包含文件名稱的那部分。
                    2 filenameToModuleName 是一個函數。lambda 函數并不比你以 def 語句定義的普通函數神奇。你可以如其他函數一樣地調用 filenameToModuleName,它也將如你所愿:從參數中剔除擴展名。
                    3 現在你可以通過 map 把這個函數應用于單元測試文件列表中的每一個文件。
                    4 結果當然如你所愿:以指代模塊的字符串構成的一個列表。

                    例 16.20. 步驟 4:映射模塊名到模塊

                    >>> modules = map(__import__, moduleNames)                  1
                    >>> modules                                                 2
                    [<module 'apihelpertest' from 'apihelpertest.py'>,
                    <module 'kgptest' from 'kgptest.py'>,
                    <module 'odbchelpertest' from 'odbchelpertest.py'>,
                    <module 'pluraltest' from 'pluraltest.py'>,
                    <module 'romantest' from 'romantest.py'>]
                    >>> modules[-1]                                             3
                    <module 'romantest' from 'romantest.py'>
                    
                    1 正如你在 第 16.6 節 “動態導入模塊” 中所見,你可以通過 map__import__ 的協同工作,將模塊名 (字符串) 映射到實際的模塊 (像其他模塊一樣可以被調用和使用)。
                    2 modules 現在是一個模塊列表,其中的模塊和其他模塊一樣。
                    3 該列表的最后一個模塊 romantest 模塊,和通過 import romantest 導入的模塊完全等價。

                    例 16.21. 步驟 5:將模塊載入測試套件

                    >>> load = unittest.defaultTestLoader.loadTestsFromModule  
                    >>> map(load, modules)                     1
                    [<unittest.TestSuite tests=[
                      <unittest.TestSuite tests=[<apihelpertest.BadInput testMethod=testNoObject>]>,
                      <unittest.TestSuite tests=[<apihelpertest.KnownValues testMethod=testApiHelper>]>,
                      <unittest.TestSuite tests=[
                        <apihelpertest.ParamChecks testMethod=testCollapse>, 
                        <apihelpertest.ParamChecks testMethod=testSpacing>]>, 
                        ...
                      ]
                    ]
                    >>> unittest.TestSuite(map(load, modules)) 2
                    
                    1 模塊對象的存在,使你不但可以像其他模塊一樣地使用它們;通過類的實例化和函數的調用,你還可以內省模塊,從而弄清楚已經有了那些類和函數。這正是 loadTestsFromModule 方法的工作:內省每一個模塊并為每個模塊返回一個 unittest.TestSuite 對象。每個 TestSuite (測試套件) 對象都包含一個 TestCase 對象的列表,每個對象對應著你的模塊中的一個測試方法。
                    2 最后,你將TestSuite列表封裝成一個更大的測試套件。unittest 模塊會很自如地遍歷嵌套于測試套件中的樹狀結構,最后深入到獨立測試方法,一個個加以運行并判斷通過或是失敗。

                    自省過程是 unittest 模塊經常為我們做的一項工作。還記得我們的獨立測試模塊僅僅調用了看似神奇的 unittest.main() 函數就大刀闊斧地完成了全部工作嗎?unittest.main() 實際上創建了一個 unittest.TestProgram 的實例,而這個實例實際上創建了一個 unittest.defaultTestLoader 的實例并以調用它的模塊啟動它。 (如果你不給出,如何知道調用它的模塊是哪一個?通過使用同樣神奇的 __import__('__main__') 命令,動態導入正在運行的模塊。我可以就 unittest 模塊中使用的所有技巧和技術寫一本書,但那樣我就沒法寫完這本了。)

                    例 16.22. 步驟 6:告知 unittest 使用你的測試套件

                    
                    if __name__ == "__main__":                   
                        unittest.main(defaultTest="regressionTest") 1
                    
                    1 在不使用 unittest 模塊來為我們做這一切的神奇工作的情況下,你實際上已自己做到了。你已經創建了一個自己就能導入模塊、調用 unittest.defaultTestLoader 并封裝于一個測試套件的 regressionTest 函數。現在你所要做的不是去尋找測試并以通用的方法構建一個測試套件,而是告訴 unittest 前面那些,它將調用 regressionTest 函數,而它會返回可以直接使用的 TestSuite

                      <pre id="vvttv"><mark id="vvttv"><progress id="vvttv"></progress></mark></pre>
                      <pre id="vvttv"></pre>

                        <p id="vvttv"></p>

                            <p id="vvttv"></p>

                                  <p id="vvttv"></p>

                                  <pre id="vvttv"><cite id="vvttv"><progress id="vvttv"></progress></cite></pre>

                                    <output id="vvttv"><dfn id="vvttv"><th id="vvttv"></th></dfn></output>

                                      <p id="vvttv"></p>

                                      这里只有精品视频