python之测试代码

测试函数:

要学习测试,就必须要测试的代码,下面是一个简单的函数,他接受名和性并返回整洁的姓名:

举例:
name_function文件中的内容为:

#功能为返回以标题为形式的简洁的姓名
def get_formatted_name(first,last):
    full_name=f"{first}{last}"
    return full_name.title()
from name_function import get_formatted_name
print("Enter 'q' at any time to quit")
while True:
    first=input("\nplease give me a first name:")
    if first=='q':
        break
    last=input("please give me a last name:")
    if last=='q':
        break
    formatted_name=get_formatted_name(first,last)#调用name_function函数
    print(f"\tNeatly formatted name:{formatted_name}")

输出结果如下所示:

Enter 'q' at any time to quit

please give me a first name:jains
please give me a last name:joplin
	Neatly formatted name:Jainsjoplin#首字母大写,标题形式

please give me a first name:q

Process finished with exit code 0

现在假设要修改get_formatted_name,使其还能处理中间名,这样所时,要确保这个函数处理只含有名和姓的姓名的方式,为此,可在每次修改get_formatted_name后都进行测试,再运行程序,并输入像jains/joplin的姓名。

但是这样很繁琐,好在python提供了一种自动测试函数输出的高效方式,倘若对get_formatted_name()进行自动测试,就能始终确信当前提供测试过的姓名时,该函数都能正确工作。

单元测试和测试用例:

python标准库中的模块unittest提供了代码测试工具,但单元测试用于核实函数的某个方面没有问题。

测试用例是一组单元测试,它们一道核实函数在各种情形下的行为都符合要求,良好的测试用例考虑到了函数可能收到的各种输入,包含针对所有这些情形下的测试。

全覆盖的测试用例包含一整套单元测试,涵盖了各种可能的函数使用方式。对于大型项目,要进行全覆盖测试可能很难,通常,最初只要针对代码的重要行为编写测试即可,等到项目被广泛使用时在考虑全覆盖。

可通过的测试:

要为函数编写测试用例,可先导入模块unittest和要测试的函数,再创建一个继承unittest.TestCase的类,并编写一系列方法对函数行为的不同方面进行测试。

举例:
使用我们上述提到的实例,返回以标题为形式的简洁的姓名

test_name_function.py
运行该文件时,所有以test_打头的方法都将自动运行

import unittest
from name_function import get_formatted_name
class NameTestCase(unittest.TestCase):#创建名为NameTestCase的类,用于包含一系列针对get_formatted_name的单元测试
    #这个类的命名并不是唯一的,但是最好让他看起来与要测试的函数相关并包含Test的字样
    #这个类必须继承unittest.TesetCase类,这样python才知道如何运行编写的程序的运行
    def test_first_last_name(self):#NameTestCase类只包含test_first_last_name一个方法
        # 用于测试get_formatted_name的一个方面
        formatted_name=get_formatted_name("janis","joplin")
        self.assertEqual(formatted_name,"Janis Joplin")
        #断言方法:用来核实得到的结果与期望的结果一致
        #assertEqual(arg1,arg2,msg(期望值)),arg1==arg2通过, False返回msg
if __name__=='__main__':if代码块是用来检验特殊变量__name__,这个变量是在程序执行时设置的。
#如果这个文件作为主程序执行,变量__name__将被设置'__main__'
'''
在这里,调用 unittest.main()来运行测试用例,但他如果不是作为主程序运行,
则变量__name__的值将不是'__main__',因此不会调用unittest.main()
'''
    unittest.main()

name_function.py

def get_formatted_name(first,last):
    full_name=f"{first}{last}"
    return full_name.title()

输出结果如下所示:

.      #表明有一个测试通过了
----------------------------------------------------------------------
Ran 1 test in 0.000s  #指出python运行了一个测试,消耗时间不到0.001秒

OK    #表明该测试用例中的所有单元测试都通过了

未通过的测试:

现在我们给get_formatted_name指定一个新的版本,使其能够处理中间名,但同时故意让该函数无法正确处理像’janis joplin‘这种,只有姓和名的名字,看看会发生什么情况:

 def get_formatted_name(first, last):
    full_name=f"{first} {middle} {last}"
    return full_name.title()

输出结果:

E                   #测试用例中有一个单元测试导致了该错误
======================================================================
ERROR: test_first_last_name (__main__.NameTestCase)#test_first_last_name导致了该错误
----------------------------------------------------------------------
#下面的Traceback 指出调用get_formatted_name("janis","joplin")有问题,由于缺少一个必不可少的位置参数
Traceback (most recent call last):
  File "C:/Users/Lenovo/PycharmProjects/pythonProject4/test_name_function.py", line 19, in test_first_last_name
    formatted_name=get_formatted_name("janis","joplin")
TypeError: get_formatted_name() missing 1 required positional argument: 'last'

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (errors=1)#整个测试未通过,因为在运行该测试用例的时候发生了一个错误

测试未通过怎么办:

如果你检查的条件没错,测试通过意味着函数的行为是对的,而测试未通过意味着编写的新代码有错,因此,测试未通过时,不要修改测试,而应修复导致测试不能通过的代码,检查刚刚对函数所做的修改,找出导致函数行为不符合预期的修改。

在上述示例中,get_formatted_name()以前只需要名和姓两个实参,但是现在要求提供名,中间名,和姓,新增的中间名参数是必不可少的,这导致get_formatted_name()的行为不符合预期。就这里而言,最佳的选择是让中间名变为可选的,这样做后,使用只有姓和名而没有中间名的姓名进行测试时,测试也能顺利通过,而且也可以接受中间名。

下面我们就对get_formatted_name()进行修改,将中间名设置为可选的,然后再次运行这个测试用例。如果通过了,就接着确认该函数能够妥善处理中间名。

具体操作如下:

def get_formatted_name(first,last, middle=''):
    if middle:#存在即返回含有middle的姓名
        full_name=f"{first} {middle} {last}"
    else:#不存在即返回不含有middle的姓名
        full_name=f"{first} {last}"
    return full_name.title()

此时,测试顺利通过。

.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

添加新测试:

确定get_formatted_name()又能正确处理简单的姓名后,我们再编写一个测试,用于测试含中间名。为此,在NameTestCase类中再添加一个方法:

test_name_function.py中添加新的测试:

#该测试我们想测试的目的是正确处理像"Wolfgang Amadeus Mozart"这样的姓名
    def test_first_last_middle_name(self):#方法名必须以test_开头,这样我们在运行test_name_function.py时自动运行。
        formatted_name = get_formatted_name("wolfgang", 'mozart', "amadeus")
        self.assertEqual(formatted_name, "Wolfgang Amadeus Mozart")

可以在TestCase类中使用很长的方法名,而这些方法名必须是描述性的,这样你才能看懂测试未通过时的输出,而这些方法由python自动调用,因此,你根本不用编写调用它们的代码。

输出结果如下:

两个测试都通过了!

..
----------------------------------------------------------------------
Ran 2 tests in 0.000s

OK

现在我们能够无比信任get_formatted_name()不仅可以处理像’janis joplin‘这种,还可以处理像"Wolfgang Amadeus Mozart"这样的姓名了。

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
#模块导入 import pygame,sys from pygame.locals import* #初始化pygame pygame.init() #设置窗口大小,单位是像素 screen = pygame.display.set_mode((500,400)) #设置背景颜色 screen.fill((0,0,0)) #设置窗口标题 pygame.display.set_caption("你好,我的朋友") # 绘制一条线 pygame.draw.rect(screen, (0,0,0), [0,100,70,40]) #加载图片 img = pygame.image.load("panda.jpg") #初始化图片位置 imgx = 0 imgy = 10 #加载和播放音频 sound = pygame.mixer.Sound('Sound_Of_The_Sea.ogg') sound.play() #加载背景音乐 pygame.mixer.music.load('TEST1.mp3') #播放背景音乐,第一个参数为播放的次数(-1表示无限循环),第二个参数是设置播放的起点(单位为秒) pygame.mixer.music.play(-1, 30.0) #导入文字格式 fontt=pygame.font.Font(None,50) #配置文字 tex=fontt.render("It is boring!!!",True,(0,0,128),(0,255,0)) #显示文字及坐标 texr=tex.get_rect() texr.center=(10,250) #初始化方向 dire = "right" #设置循环 while 1: #绘制文字 screen.blit(tex,texr) screen.fill((0,0,0)) screen.blit(img,(imgx,imgy)) if dire == "right": imgx+=5 if imgx == 380: dire = 'down' elif dire == 'down': imgy += 5 if imgy == 300: dire = 'left' elif dire == 'left': imgx -= 5 if imgx == 10: dire = 'up' elif dire == 'up': imgy -= 5 if imgy == 10: dire = 'right' #获取事件 for ss in pygame.event.get(): #判断事件 if ss.type == QUIT: #退出Pygame pygame.quit() #退出系统 sys.exit() #绘制屏幕内容 pygame.display.update() #设置帧率 pygame.time.delay(10)

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

从未止步..

谢谢你的打赏,我会继续努力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值