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程序。


有请我的好兄弟浒天洛

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容

  • Python 四五事 介绍 Python 相关工具,工作流程和测试框架。 发布于 2014.1.19最后更新 20...
    hzyido阅读 65,010评论 0 4
  • Startup 单元测试的核心价值在于两点: 更加精确地定义某段代码的作用,从而使代码的耦合性更低 避免程序员写出...
    wuwenxiang阅读 10,083评论 1 27
  • 企管家:信息发布托管,获取询盘机会,节省人员成本,实现用户零操作。您只管做好产品,其他的交给企管家。 企管家——电...
    17034b15b301阅读 401评论 0 1
  • 孩子伸伸手 我的桶我的桶 其实想说手电筒 老奶奶举苍蝇拍 孙女围她转 白晃晃的阳光 挤满夏天的街道 梧桐树排排坐 ...
    赵象阅读 575评论 0 1
  • 这个世界上,文字是最公平的话语权,因为没有人能阻挡得了。 对于我这个资深网虫来说,很多的视频报道,评论都在说刚毕业...
    毕诗萌阅读 374评论 2 2