python之测试代码

简介: 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"这样的姓名了。

相关文章
|
1月前
|
安全 测试技术 网络安全
如何在Python Web开发中进行安全测试?
如何在Python Web开发中进行安全测试?
|
19天前
|
开发框架 数据建模 中间件
Python中的装饰器:简化代码,增强功能
在Python的世界里,装饰器是那些静悄悄的幕后英雄。它们不张扬,却能默默地为函数或类增添强大的功能。本文将带你了解装饰器的魅力所在,从基础概念到实际应用,我们一步步揭开装饰器的神秘面纱。准备好了吗?让我们开始这段简洁而富有启发性的旅程吧!
26 6
|
1月前
|
存储 缓存 测试技术
Python中的装饰器:功能增强与代码复用的利器
在Python编程中,装饰器是一种强大而灵活的工具,它允许开发者以简洁优雅的方式增强函数或方法的功能。本文将深入探讨装饰器的定义、工作原理、应用场景以及如何自定义装饰器。通过实例演示,我们将展示装饰器如何在不修改原有代码的基础上添加新的行为,从而提高代码的可读性、可维护性和复用性。此外,我们还将讨论装饰器在实际应用中的一些最佳实践和潜在陷阱。
|
1月前
|
安全 关系型数据库 测试技术
学习Python Web开发的安全测试需要具备哪些知识?
学习Python Web开发的安全测试需要具备哪些知识?
33 4
|
1月前
|
人工智能 数据挖掘 Python
Python编程基础:从零开始的代码旅程
【10月更文挑战第41天】在这篇文章中,我们将一起探索Python编程的世界。无论你是编程新手还是希望复习基础知识,本文都将是你的理想之选。我们将从最基础的语法讲起,逐步深入到更复杂的主题。文章将通过实例和练习,让你在实践中学习和理解Python编程。让我们一起开启这段代码之旅吧!
|
12天前
|
数据可视化 Python
以下是一些常用的图表类型及其Python代码示例,使用Matplotlib和Seaborn库。
通过这些思维导图和分析说明表,您可以更直观地理解和选择适合的数据可视化图表类型,帮助更有效地展示和分析数据。
55 8
|
19天前
|
API Python
【Azure Developer】分享一段Python代码调用Graph API创建用户的示例
分享一段Python代码调用Graph API创建用户的示例
42 11
|
21天前
|
测试技术 Python
探索Python中的装饰器:简化代码,增强功能
在Python的世界中,装饰器是那些能够为我们的代码增添魔力的小精灵。它们不仅让代码看起来更加优雅,还能在不改变原有函数定义的情况下,增加额外的功能。本文将通过生动的例子和易于理解的语言,带你领略装饰器的奥秘,从基础概念到实际应用,一起开启Python装饰器的奇妙旅程。
34 11
|
17天前
|
Python
探索Python中的装饰器:简化代码,增强功能
在Python的世界里,装饰器就像是给函数穿上了一件神奇的外套,让它们拥有了超能力。本文将通过浅显易懂的语言和生动的比喻,带你了解装饰器的基本概念、使用方法以及它们如何让你的代码变得更加简洁高效。让我们一起揭开装饰器的神秘面纱,看看它是如何在不改变函数核心逻辑的情况下,为函数增添新功能的吧!
|
18天前
|
程序员 测试技术 数据安全/隐私保护
深入理解Python装饰器:提升代码重用与可读性
本文旨在为中高级Python开发者提供一份关于装饰器的深度解析。通过探讨装饰器的基本原理、类型以及在实际项目中的应用案例,帮助读者更好地理解并运用这一强大的语言特性。不同于常规摘要,本文将以一个实际的软件开发场景引入,逐步揭示装饰器如何优化代码结构,提高开发效率和代码质量。
43 6