我日常使用Gvim來寫代碼,因此先配置Vim的python開發環境。html
爲了在vim中可以自動創建測試文件框架,須要創建模版文件,假設我在 ~/.vim/skeleton
目錄下創建須要的模版文件,目錄結構以下:python
/home/bl/.vim/skeleton |---test.py |---skeleton_top.py |---alltests.py |---skeleton_bottom.py
alltest.py 模版文件vim
import unittest import sys import os CUR_DIR = os.path.abspath(os.path.dirname(__file__)) PAR_DIR = os.path.abspath(os.path.join(CUR_DIR, os.path.pardir)) sys.path.append(os.path.abspath(PAR_DIR)) sys.path.append(os.path.abspath(CUR_DIR)) sys.path.append(os.path.join(CUR_DIR, 'tests')) tests = os.listdir(os.curdir) tests = [n[:-3] for n in tests if n.startswith('test') and n.endswith('.py')] teststests = os.path.join(os.curdir, 'tests') if os.path.isdir(teststests): teststests = os.listdir(teststests) teststests = [n[:-3] for n in teststests if n.startswith('test') and n.endswith('.py')] modules_to_test = tests + teststests else: modules_to_test = tests def suite(): alltests = unittest.TestSuite() for module in map(__import__, modules_to_test): alltests.addTest(unittest.findTestCases(module)) return alltests if __name__ == '__main__': unittest.main(defaultTest='suite')
test.py 模版文件app
import sys import os CUR_DIR = os.path.abspath(os.path.dirname(__file__)) PAR_DIR = os.path.abspath(os.path.join(CUR_DIR, os.path.pardir)) sys.path.append(os.path.abspath(PAR_DIR)) sys.path.append(os.path.abspath(CUR_DIR)) from unittest import TestCase class simpleTest(TestCase): def setUp(self): pass def tearDown(self): pass def testExample(self): self.assertEqual(1, 1) def testOther(self): self.assertNotEqual(0, 1) if '__main__' == __name__: import unittest unittest.main()
skeleton_top.py框架
#!/usr/bin/env python # -*- coding: UTF-8 -*- # FileName : # Last Change: # AUTHOR : User , user@mail.com """docstring """ __revision__ = '0.1'
skeleton_bottom.pycurl
# vim:ts=4:sw=4:ft=python:expandtab:set fdm=indent:
設置自動使用模版生成文件函數
" 自動使用新文件模板 autocmd BufNewFile *.py 0r ~/.vim/skeleton/skeleton_bottom.py autocmd BufNewFile test*.py 0r ~/.vim/skeleton/test.py autocmd BufNewFile alltests.py 0r ~/.vim/skeleton/alltests.py autocmd BufNewFile *.py 0r ~/.vim/skeleton/skeleton_top.py
設置在vim中執行單元測試工具
" Python Unittest 的一些設置 " 可讓咱們在編寫 Python 代碼及 unittest 測試時不須要離開 vim " 鍵入 :make 或者點擊 gvim 工具條上的 make 按鈕就自動執行測試用例 autocmd FileType python compiler pyunit autocmd FileType python setlocal makeprg=python\ ./alltests.py autocmd BufNewFile,BufRead test*.py setlocal makeprg=python\ % " 設置make的快捷鍵,m map <C-F8> :make<cr> " 設置run的快捷鍵,r map <leader>r :w<cr>:!python %<cr>
自動刪除行尾空格單元測試
" 保存時自動刪除行尾空格 function! RemoveTrailingWhitespace() if &ft != "diff" let b:curcol = col(".") let b:curline = line(".") silent! %s/\s\+$// silent! %s/\(\s*\n\)\+\%$// call cursor(b:curline, b:curcol) endif endfunction autocmd BufWritePre *.py call RemoveTrailingWhitespace()
自動保存文件名測試
" 自動保存文件名 function! Filename_Save() " let pattern = '^#\s*FileName\s*:' let row = search(pattern, 'n') if row != 0 && row <10 let curstr = getline(row) let col = match( curstr , 'FileName\s*:') let spacestr = repeat(' ',col-1) let buffilename = bufname("%") let buffilename = strpart(buffilename,strridx(buffilename,"/")+1) "echo strpart(bufname("%"),strridx(bufname("%"),"/")) let newline = '#' . spacestr . 'FileName : ' . buffilename call setline(row, newline) endif endfunction " au BufWritePre *.py call Filename_Save()
自動修改最後修改日期
"Last change用到的函數,返回時間,可以自動調整位置 function! TimeStamp(...)" let sbegin = '' let send = '' if a:0 >= 1 let sbegin = a:1.'\s*' if a:1 == '*' let sbegin = '\' . sbegin endif endif if a:0 >= 2 let send = ' '.a:2 endif let pattern = 'Last Change:.*' \. send let pattern = '^\s*' . sbegin . pattern . '\s*$' "let now = strftime('%Y年%m月%d日 %H時%M分%S秒', let now = strftime('%Y年%m月%d日',localtime()) let row = search(pattern, 'n') if row != 0 let curstr = getline(row) let col = match( curstr , 'Last') let leftcol = match(curstr,sbegin) let spacestr = repeat(' ',col - len(a:1)-leftcol) let leftspacestr = repeat(' ',leftcol) let now = leftspacestr . a:1 . spacestr . 'Last Change: ' \. now . send call setline(row, now) endif endfunction" # 保存時自動 修改更改時間 au BufWritePre *.py call TimeStamp('#')
vim-flake8 插件
可以自動檢查python代碼是否符合 pep8 風格,默認快捷鍵是 F7
我本身並不使用 pytest , 可是簡單看了一下,挺方便的,須要安裝。
pip install -U pytest
vim 有一個 pytest的插件能夠配合使用,感興趣能夠試一下。
完成上面的準備以後,開始搭建一個演示用的測試框架項目 TDDtest 。
$ mkdir -p TDDtest/tests/
如今目錄結構是
/home/bl/TDDtest |--- |---tests
創建測試整個項目的文件 alltests.py
$ cd TDDtest $ vim alltests.py vim會使用模版自動生成一個 alltests.py 文件,保存關閉。 $ python alltests.py 返回 -------------------- Ran 0 tests in 0.000s OK 證實 alltests.py 運行正常,但沒有找到單元測試用例。
在 tests 目錄下創建單元測試文件
$ cd tests $ vim test1.py 只要是test開頭的.py文件,vim都會用單元測試模版填充新文件。保存後運行 $ python test1.py -v testExample (__main__.simpleTest) ... ok testOther (__main__.simpleTest) ... ok -------------------- Ran 2 tests in 0.000s OK
測試導入模塊進行測試
$ cd .. $ vim a.py 添加一個實驗性的函數 def func_a(): pass 在 tests/test1.py 中增長 import a class simpleTest(TestCase): def setUp(self): ... def testImportFunc(self): res = a.func_a() self.assertIsNone(res) $ python alltests.py -v testExample (test1.simpleTest) ... ok testOther (test1.simpleTest) ... ok testImportFunc (test1.simpleTest) ... ok ---------------------------------------------------------------------- Ran 3 tests in 0.002s OK
測試整個項目
$ python alltests.py
測試單個文件
$ python tests/test1.py
增長測試文件
使用 vim 在tests目錄中創建以 test 開頭的.py文件。
vim中快捷測試test ,r 執行當前編輯的測試文件 ctrl+F8 執行 alltests.py
/home/bl/TDDtest |--- |---alltests.py |---a.py |---tests | |---test1.py
#!/usr/bin/env python # -*- coding: UTF-8 -*- # FileName : a.py # Last Change: 2014年07月08日 # AUTHOR : BaiLiang , bailiangcn@gmail.com """ 試驗 unittest """ def func_a(): pass # vim:ts=4:sw=4:ft=python:expandtab:set fdm=indent:
#!/usr/bin/env python # -*- coding: UTF-8 -*- # FileName : test1.py # Last Change: 2014年07月08日 # AUTHOR : BaiLiang , bailiangcn@gmail.com """ 測試單元測試案例 """ __revision__ = '0.1' import sys import os CUR_DIR = os.path.abspath(os.path.dirname(__file__)) PAR_DIR = os.path.abspath(os.path.join(CUR_DIR, os.path.pardir)) sys.path.append(os.path.abspath(PAR_DIR)) sys.path.append(os.path.abspath(CUR_DIR)) from unittest import TestCase import a class simpleTest(TestCase): def setUp(self): pass def tearDown(self): pass def testExample(self): self.assertEqual(1, 1) def testOther(self): self.assertNotEqual(0, 1) def testImportFunc(self): res = a.func_a() self.assertIsNone(res) if '__main__' == __name__: import unittest unittest.main() # vim:ts=4:sw=4:ft=python:expandtab:set fdm=indent: