我平常使用Gvim来写代码,所以先配置Vim的python开发环境。
为了在vim中能够自动建立测试文件框架,需要建立模版文件,假设我在 ~/.vim/skeleton
目录下建立需要的模版文件,目录结构如下:
/home/bl/.vim/skeleton
|---test.py
|---skeleton_top.py
|---alltests.py
|---skeleton_bottom.py
alltest.py 模版文件
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 模版文件
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 , [email protected]
"""docstring
"""
__revision__ = '0.1'
skeleton_bottom.py
# 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 , [email protected]
"""
试验 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 , [email protected]
"""
测试单元测试案例
"""
__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: