美文网首页程序员大学生世界
python|渣渣辉喊你玩贪玩改错啦!

python|渣渣辉喊你玩贪玩改错啦!

作者: turbotx | 来源:发表于2018-02-13 18:34 被阅读0次
    前言

           大家好,我系渣渣辉, 给大家推荐一款超好玩的游戏——贪玩改错。


    【一】大怪出现 (异常处理)

           一提到怪物,人们就会想到bug,可是这只是其中一类。其实还有两类:一个是用户输入错误,我们会提醒用户让他们检查;另一类就是完全无法预测的错误了,像python这种高级语言都贴心地内置了一套异常处理机制,比如:

    try……except……else……语句   try-finally 语句

    看一下可能出现小怪的模样:

    示例(单个异常) 使用raise语句自己触发异常

    所以啊,世上虽然有像我这么完美的玩家,却没有一个顺畅的成功之路。游戏能一次通关并正常运行的概率微乎其微。但我渣渣辉岂能败给这些小小的错误?!于是我集齐了一整套神器来修复bug,开始了打怪调试之路(就是我再写一段代码去检查错误)……

    开始打怪!

    【二】打怪从小开始(单元调试)

    一屋不扫何以扫天下?打怪也要从小抓起、从一个模块、一个函数或一个类开始进行!

    比如函数abs()吧,我们就写出几个测试用的例子:输入正数,期待返回值与输入相同;输入负数,期待返回值与输入相反;输入0,期待返回0;输入非数值类型,比如None、[]、{},期待抛出TypeError。 把上面的测试用例放到一个测试模块里,就是一个完整的单元测试。那我用什么方法呢?

    (1)Python单元测试必杀技之unittest

    了解xUnit系列框架的小伙伴对这个肯定很熟悉,因为这就是其中一员。(可惜我没学过呜呜!

    命令行接口、测试案例自动搜索、创建测试代码、构建测试套件方法等内容,需要的朋友可以参考下

    ①它主要包括:

    1.测试脚手架(test fixture)——准备工作和扫尾工作.包括setUp()和tearDown().

    2.测试案例(test case)——最小的测试单元.

    3.测试套件(test suite)——测试案例的集合.

    4.测试运行器(test runner)——测试执行的组件.

    ②自动击杀(测试案例自动搜索)

    unittest支持简单的test discovery. 命令行传入discovery后,框架会自动在当前目录搜索要测试的案例并执行.搜索目录必须是包或者模块.基本使用如下:

    cd project_directory

    python -m unittest discover

    技能选择如下: 

    -v, –verbose 输出信息的详细级别;

    -s, –start-directory directory 开始搜索目录 (默认为当前目录);

    -p, –pattern pattern 匹配的文件名 (默认为test*.py);

    -t, –top-level-directory directory 搜索的顶层目录 (默认为start directory)。

    ③创建测试代码

    方式一:创建子类继承unittest.TestCase

    class WidgestTestCase(unittest.TestCase):

        def setup(self):

             pass

        def runTest(self):

              pass

         def tearDown(self):

              pass

    方式二:编写以test开头的方法

    class WidgetTestCase(unittest.TestCase):

        def setUp(self):

            pass

        def test_xx1(self)

        def test_xx2(self)

        ...

        def test_xxN(self)

        def tearDown(self):

            pass

    ④构建测试套件

    def suite():

        suite = unittest.TestSuite()

        suite.addTest(WidgetTestCase('test_default_size')) 

        suite.addTest(WidgetTestCase('test_resize'))

        return suite

    def suite():

        tests = ['test_default_size', 'test_resize']

        return unittest.TestSuite(map(WidgetTestCase, tests))

    (2) Python单元测试必杀技之pytest

    这个必杀技与python自带的unittest类似,但是比unittest使用起来更简单,打怪效率也更高。而且它能够支持简单的单元测试和复杂的功能测试;支持参数化;具有很多第三方插件,并且可以自定义扩展;方便的和持续集成工具集成。

    听起来就好牛逼的样子是不是?实际上也真的很牛逼!

    ①安装

    像安装python的其它软件一样,直接用pip安装。

    pip install -U pytest 

    py.test --version # 安装完成后,验证安装的版本

    ②实战

    # content of test_sample.py

    def func(x):                     # 定义一个被测试函数func

          return x+1                 # 该函数将传递进来的参数加1后返回

    def test_func():               # 再定义一个测试函数test_func用来对func进行测试

          assert func(3) == 5    #用断言语句assert来对结果进行验证

    当打多个怪(需要编写多个测试样例)时,我们可以将其放到一个测试类当中:

    # content of test_class.py

        class TestClass:

          def test_one(self):

              x = "this"

              assert 'h' in x

           def test_two(self):

              x = "hello"

              assert hasattr(x, 'check')  

    ③如何召唤技能(如何编写pytest测试样例

    通过上面2个实例,我们发现编写pytest测试样例非常简单,只需要按照下面的规则:

    测试文件以test_开头(以_test结尾也可以);测试类以Test开头,并且不能带有 __init__ 方法;测试函数以test_开头;断言使用基本的assert即可。

    ④如何使用技能(如何执行pytest测试样例)

    方法很多种,上面第一个实例是直接执行py.test,第二个实例是传递了测试文件给py.test。其实py.test有好多种方法执行测试:

    1. py.test                       # run all tests below current dir  

    2. py.test test_mod.py   # run tests in module  

    3. py.test somepath      # run all tests below somepath  

    4. py.test -k stringexpr # only run tests with names that match the  

                                        # the "string expression", e.g. "MyClass and not method"  

                                        # will select TestMyClass.test_something  

                                        # but not TestMyClass.test_method_simple  

    8. py.test test_mod.py::test_func # only run tests that match the "node ID",                                                                            # e.g "test_mod.py::test_func" will select                                                                            # only test_func in test_mod.py  

    ⑤所获成就(测试报告)

    pytest可以方便的生成测试报告,即可以生成HTML的测试报告,也可以生成XML格式的测试报告用来与持续集成工具集成。

    生成HTML格式报告: py.test --resultlog=path  

    生成XML格式的报告: py.test --junitxml=path  

    ⑥游戏提示(获取帮助信息)

    1. py.test --version       # shows where pytest was imported from  

    2. py.test --fixtures       # show available builtin function arguments  

    3. py.test -h | --help      # show help on command line and config file options  

    ⑦最佳作战环境

    其实对于测试而言,特别是在持续集成环境中,我们的所有测试最好是在虚拟环境中。这样不同的虚拟环境中的测试不会相互干扰的。由于我们的实际工作中,在同一个Jekins中,运行了好多种不同项目册的测试,因此,各个测试项目运行在各自的虚拟环境中。

    将pytest安装在虚拟环境中:

    1、将当前目录创建为虚拟环境virtualenv .        # create a virtualenv directory in the current directory source bin/activate # on unix  

    2、在虚拟环境中安装pytest:

    pip install pytest  �

    【三】全杀(调试)

    (1)技能一:print

    这一技能简单直接粗暴有效,就是正面刚,不服就把你打……印出来:

    # error.py

    def foo(s):

         n = int(s)

         print '>>> n = %d' % n

         return 10 / n

    def main():

          foo('0')

    main()

    执行后在输出中查找打印的变量值就行。

    由于这一技能过于残暴,所以用过场面一度混乱,会产生很多垃圾信息。

    (2) 技能二:assert

    这一技能不仅可替代print(凡是用print来辅助查看的地方,都可以用断言(assert)来替代),而且不会场面会整齐一些(因为启动Python解释器时可以用-O参数来关闭assert,关闭后,所有的assert语句都当成pass来看)。

    # error.py

    def foo(s):

         n = int(s)

         assert n != 0, 'n is zero!' # 表达式n != 0应该是True,否则后面的代码就会出错。

         return 10 / n

    def main():

          foo('0')                # 如果断言失败,assert语句本身就会抛出AssertionError

    (3) 技能三:logging(必杀技!!)

    这一绝妙技能不仅不会抛出错误,而且可以输出到文件:

    # error.py

    import logging

    logging.basicConfig(level=logging.INFO)

    s = '0'

    n = int(s)

    logging.info('n = %d' % n)

    print 10 / n

    logging允许你指定记录信息的级别,有debug,info,warning,error等几个级别,当我们指定level=INFO时,logging.debug就不起作用了。同理,指定level=WARNING后,debug和info就不起作用了。这样一来,你可以放心地输出不同级别的信息,也不用删除,最后统一控制输出哪个级别的信息

    logging的另一个迷人之处是通过简单的配置,一条语句可以同时输出到不同的地方,比如console和文件。

    (4) 技能四:pbd

    启动Python的调试器pdb,让程序以单步方式运行,可以随时查看运行状态。然而,这种通过pdb在命令行调试的方法理论上是万能的,但实在是太麻烦了,如果有一千行代码,要运行到第999行得敲多少命令啊。还好,我们还有另一种调试方法——pdb.set_trace()

    这个方法也是用pdb,但是不需要单步执行,我们只需要import pdb,然后,在可能出错的地方放一个pdb.set_trace(),就可以设置一个断点:

    # error.py

    import pdb

    s = '0'

    n = int(s)

    pdb.set_trace()

    # 运行到这里会暂停并进入pdb调试环境,可以用命令p查看变量,或用命令c继续运行

    print 10 / n

    (5) 技能五:IDE

    如果要比较爽地设置断点、单步执行,就需要一个支持调试功能的IDE。目前比较好的Python IDE有PyCharm。另外,eclipse加上pvdev插件也可以调试Python程序。


    有请我的好兄弟浒天洛

    探挽改错,介四里没有挽过的船新版本,挤需体验三番钟,里造会干我一样,爱像借款游戏。

    相关文章

      网友评论

        本文标题:python|渣渣辉喊你玩贪玩改错啦!

        本文链接:https://www.haomeiwen.com/subject/nmvoaxtx.html