Python学习笔记9—测试代码

Python标准库中的模块unittest提供了测试代码工具。单位测试用于核实函数的某个方面没有问题;测试用例是一组单元测试,这些单元测试一起核实函数在各种情形下的行为都符合要求。良好的测试用例考虑到了函数可能收到的各种输入,包含针对所有这些情形的测试。全覆盖式测试用例包含一整套单元测试,涵盖了各种可能的函数使用方法。对于大型项目,要实现全覆盖式可能很难。通常,最初要求针对代码的重要行为编写测试即可,等项目被广泛使用时再考虑全覆盖。

一、单元测试

1、测试函数

name_function.py

def get_formatted_name(first,last):
    """Generate a neatly formatted full name."""
    full_name = first + ' ' + last
    return full_name.tiltle()

test_name_function.py

import unittest
from name_function import get_formatted_name

class NamesTestCase(unittest.TestCase):
    """测试name_function.py."""
    
    def test_first_last_name(self):
        ""能够正确地处理像Janis Joplin这样的姓名吗?"""
        formatted_name = get_formatted_name('Janis','Joplin')
        self.assertEqual(formatted_name,'Janis Joplin')

unittest.main()

注:

  • 首先导入uinttest模块和要测试的函数
  • 创建测试类NamesTestCase,这个可随便给这个类命名,但最好让它看起来与要测试的函数相关,并包含字样Test。这个类必须继承unittest.TestCase类,这样Python才知道如何运行你编写的测试。
  • 运行test_name_function.py时,所有以test_打头的方法都将自动运行。
  • 断言方法

2、测试未通过时要怎么办

测试未通过,不要修改测试,应修复导致测试不能通过的代码:检查刚对函数所做的修改,找出导致函数行为不符合预期的修改。

二、测试类

1、各种断言方法

方法 用途
assertEqaul(a,b) 核实 a == b
assertNotEqaul(a,b) 核实 a != b
assertTrue(x) 核实 x 为True
assertFalse(x) 核实 x 为False
assertIn(item,list) 核实 item在list中
assertNotIn(item,list) 核实 item不在list中

2、一个要测试的类

类的测试与函数的测试相似,你所做的大部分工作都是测试类中的方法,但存在一些不同之处。
survey.py

class AnonymousSurvey():
    """收集匿名调查文件的答案"""
    def __init__(self,question):
        """存储一个问题,并未存储答案做准备"""
        self.question = question
        self.responses = []

    def show_question(self):
        """显示调查问卷"""
        print(question)

    def store_response(self,new_response):
        """存储单位调查问卷"""
        self.responses.append(new_response)

   def show_results(self):
        """显示收集到的所有答案"""
        print("Survey Result: ")
        for response in responses:
            print(' - ' + response)

3、测试类

test_survey.py

import unittest
from survey import AnnoymousSurvey

class TestAnnoymouseSurvey(unittest.TestCase):
    """创建AnnoymousSurvey类的测试"""
    
    def test_store_single_response(self):
        """测试单个答案会被妥善地存储"""
        question = "What langeuage did you first learn to speak?"
        my_survey = AnnoymousSurvey(question) 
        my_survey.store.response('English')

        self.assertIn('English',my_survey.responses)

    def test_store_three_response(self):
        """测试单个答案会被妥善地存储"""
        question = "What langeuage did you first learn to speak?"
        my_survey = AnnoymousSurvey(question) 
        responses = ['English','Spanish','Mandarin']
        for response in responses:
            my_survey.store.response(response)

        for response in responses:
            self.assertIn(response,my_survey.responses)
unittest.main()

4、方法setUp()

在前面的test_survey.py中,我们在每个测试方法中都创建了一个AnnoymousSurvey实例,并在每个方法中都创建了答案。unittest.TestCase 类包含方法setUp(),让我们只需创建这些对象一次,并在每个测试方法中使用它们。如果你在TestCase类中包含了方法setUp(),Python将先运行它,再运行各个以test_打头的方法。这样,在编写的每个测试方法总都可以使用在方法setUp()中创建的对象了。

import unittest
from survey import AnnoymousSurvey

class TestAnnoymouseSurvey(unittest.TestCase):
    """创建AnnoymousSurvey类的测试"""

    def setUp(self):
        """创建一个调查对象和一组答案,供使用的测试方法使用"""
        question = "What langeuage did you first learn to speak?"
        my_survey = AnnoymousSurvey(question) 
        responses = ['English','Spanish','Mandarin']
        
    
    def test_store_single_response(self):
        """测试单个答案会被妥善地存储"""
        self.my_survey.store_responsse(self.responses[0])
        self.assertEqaul(self.responses[0],my_survey.store_responses)

    def test_store_three_response(self):
        """测试单个答案会被妥善地存储"""

        for response in self.responses:
            self.my_survey.store_response(response)

        for response in responses:
            self.assertIn(response,self.my_survey.responses)
unittest.main()

5、运行结果

运行测试用例时,每完成一个单元测试,Python都打印一个字符:测试通过时打印一个句点;测试引发错误时打印一个E;测试导致断言失败时打印一个F。

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

推荐阅读更多精彩内容

  • Startup 单元测试的核心价值在于两点: 更加精确地定义某段代码的作用,从而使代码的耦合性更低 避免程序员写出...
    wuwenxiang阅读 10,097评论 1 27
  • 编写函数或类时,还可为其编写测试。通过测试,可确定代码面对各种输入都能够按要求的那样工作。在程序中添加新代码时,你...
    Darren_Lin阅读 5,248评论 1 5
  • 用Python搭建自动化测试框架,我们需要组织用例以及测试执行,这里博主推荐Python的标准库——unittes...
    灰蓝蓝蓝蓝蓝蓝阅读 9,617评论 3 56
  • unittest作为一个python中的基本模块,是其他框架和工具的基础,官方文档神马的最实用了:https://...
    cheneydc阅读 8,133评论 0 3
  • 有时候会突然感到孤独,哪怕身边有很多人围绕着,哪怕上一秒还在开怀大笑。突如其来的孤独感总是让人难以适应,也无...
    赖床的蜗牛阅读 95评论 0 0