python 驅動開發環境實踐

我日常使用Gvim來寫代碼,因此先配置Vim的python開發環境。html

1、配置Vim環境

模版文件準備

爲了在vim中可以自動創建測試文件框架,須要創建模版文件,假設我在 ~/.vim/skeleton 目錄下創建須要的模版文件,目錄結構以下:python

/home/bl/.vim/skeleton
|---test.py
|---skeleton_top.py
|---alltests.py
|---skeleton_bottom.py
  1. 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')
  2. 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()
  3. skeleton_top.py框架

    #!/usr/bin/env python
     # -*- coding: UTF-8 -*-
    
     #  FileName  :
     # Last Change:
     #   AUTHOR   :  User , user@mail.com
    
     """docstring
     """
    
     __revision__ = '0.1'
  4. skeleton_bottom.pycurl

    # vim:ts=4:sw=4:ft=python:expandtab:set fdm=indent:

vimrc測試相關設置

  1. 設置自動使用模版生成文件函數

    " 自動使用新文件模板
       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
  2. 設置在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>

vim其餘python設置

  1. 自動刪除行尾空格單元測試

    " 保存時自動刪除行尾空格
         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()
  2. 自動保存文件名測試

    " 自動保存文件名
     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()
  3. 自動修改最後修改日期

    "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('#')
  4. vim-flake8 插件

可以自動檢查python代碼是否符合 pep8 風格,默認快捷鍵是 F7

  1. pytest 插件(主頁

我本身並不使用 pytest , 可是簡單看了一下,挺方便的,須要安裝。

pip install -U pytest

vim 有一個 pytest的插件能夠配合使用,感興趣能夠試一下。

2、測試框架創建

完成上面的準備以後,開始搭建一個演示用的測試框架項目 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

3、基本使用

  • 測試整個項目

    $ python alltests.py
  • 測試單個文件

    $ python tests/test1.py
  • 增長測試文件

    使用 vim 在tests目錄中創建以 test 開頭的.py文件。
  • vim中快捷測試test ,r 執行當前編輯的測試文件 ctrl+F8 執行 alltests.py

完整的樣例文件

1.目錄結構

/home/bl/TDDtest
    |---
    |---alltests.py
    |---a.py
    |---tests
    |    |---test1.py

2. alltests.py (略,未改變模版)

3. a.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:

4. test1.py

#!/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:
相關文章
相關標籤/搜索