python 驱动开发环境实践

余生长醉 提交于 2019-12-17 15:58:25

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

我平常使用Gvim来写代码,所以先配置Vim的python开发环境。

一、配置Vim环境

模版文件准备

为了在vim中能够自动建立测试文件框架,需要建立模版文件,假设我在 ~/.vim/skeleton 目录下建立需要的模版文件,目录结构如下:

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

     # 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的插件可以配合使用,感兴趣可以试一下。

二、测试框架建立

完成上面的准备之后,开始搭建一个演示用的测试框架项目 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

完整的样例文件

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:
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!