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

综合编程 简书

前言

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

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

一提到怪物,人们就会想到 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程序。

有请我的好兄弟浒天洛

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

简书稿源:简书 (源链) | 关于 | 阅读提示

本站遵循[CC BY-NC-SA 4.0]。如您有版权、意见投诉等问题,请通过eMail联系我们处理。
酷辣虫 » 综合编程 » python|渣渣辉喊你玩贪玩改错啦!

喜欢 (0)or分享给?

专业 x 专注 x 聚合 x 分享 CC BY-NC-SA 4.0

使用声明 | 英豪名录