首页 > 其他分享 >11 第十一章 测试代码

11 第十一章 测试代码

时间:2023-04-21 21:15:53浏览次数:39  
标签:11 name 第十一章 self formatted survey 测试代码 response first

测试函数

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

# name_function.py
def get_formatted_name(first, last):
    """Generate a neatly formatted full name."""
    full_name = first + ' ' + last
    return full_name.title()
# names.py
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)
    print("\tNeatly formatted name: " + formatted_name + '.')
# 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()

使用了unittest 类最有用的功能之一:一个断言 方法;
断言方法用来核实得到的结果是否与期望的结果一致

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

OK

第1行的句点表明有一个测试通过了;
接下来的一行指出Python运行了一个测试,消耗的时间不到0.001秒;
最后的OK 表明该测试用例中的所有单元测试都通过了

# name_function.py
# 运行test_name_function.py
def get_formatted_name(first, last):
    """Generate a neatly formatted full name."""
    full_name = first + ' ' + middle + ' ' + last
    return full_name.title()
E
======================================================================
ERROR: test_first_last_name (__main__.NamesTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test_name_function.py", line 8, 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.000s
FAILED (errors=1)

第1行输出只有一个字母E,它指出测试用例中有一个单元测试导致了错误;
接下来,我们看到NamesTestCase 中的test_first_last_name() 导致了错误;
测试用例包含众多单元测试时,知道哪个测试未通过至关重要;
我们看到了一个标准的traceback,它指出函数调用get_formatted_name('janis', 'joplin') 有问题,因为它缺少一个必不可少的位置实参;
我们还看到运行了一个单元测试;
最后,还看到了一条消息,它指出整个测试用例都未通过,因为运行该测试用例时发生了一个错误;
这条消息位于输出末尾,让你一眼就能看到——你可不希望为获悉有多少测试未通过而翻阅长长的输出

# name_function.py
def get_formatted_name(first, last, middle=''):
    """生成整洁的姓名"""
    if middle:
        full_name = first + ' ' + middle + ' ' + last
    else:
        full_name = first + ' ' + last
    return full_name.title()
# 运行test_name_function.py
.   
----------------------------------------------------------------------
Ran 1 test in 0.000s  

OK
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')

    def test_first_last_middle_name(self):
        """能够正确地处理像Wolfgang Amadeus Mozart这样的姓名吗?"""
        formatted_name = get_formatted_name(
        'wolfgang', 'mozart', 'amadeus')
        self.assertEqual(formatted_name, 'Wolfgang Amadeus Mozart')

unittest.main()

在TestCase 类中使用很长的方法名是可以的;
这些方法的名称必须是描述性的,这才能让你明白测试未通过时的输出

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

OK

测试类

img

# 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 results:")
        for response in responses:
            print('- ' + response)
# language_survey.py
from survey import AnonymousSurvey

#定义一个问题,并创建一个表示调查的AnonymousSurvey对象
question = "What language did you first learn to speak?"
my_survey = AnonymousSurvey(question)

#显示问题并存储答案
my_survey.show_question()
print("Enter 'q' at any time to quit.\n")
    while True:
    response = input("Language: ")
    if response == 'q':
       break
    my_survey.store_response(response)

# 显示调查结果
print("\nThank you to everyone who participated in the survey!")
my_survey.show_results()
# test_survey.py
import unittest
from survey import AnonymousSurvey

class TestAnonmyousSurvey(unittest.TestCase):
    """针对AnonymousSurvey类的测试"""

    def test_store_single_response(self):
        """测试单个答案会被妥善地存储"""
        question = "What language did you first learn to speak?"
        my_survey = AnonymousSurvey(question)
        my_survey.store_response('English')
        self.assertIn('English', my_survey.responses)

unittest.main()
.   
----------------------------------------------------------------------
Ran 1 test in 0.001s  

OK
import unittest
from survey import AnonymousSurvey

class TestAnonymousSurvey(unittest.TestCase):
    """针对AnonymousSurvey类的测试"""

    def test_store_single_response(self):
        """测试单个答案会被妥善地存储"""
        question = "What language did you first learn to speak?"
        my_survey = AnonymousSurvey(question)
        my_survey.store_response('English')
        self.assertIn('English', my_survey.responses)

    def test_store_three_responses(self):
        """测试三个答案会被妥善地存储"""
        question = "What language did you first learn to speak?"
        my_survey = AnonymousSurvey(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()
..  
----------------------------------------------------------------------
Ran 2 tests in 0.000s  

OK

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

import unittest
from survey import AnonymousSurvey

class TestAnonymousSurvey(unittest.TestCase):
    """针对AnonymousSurvey类的测试"""

    def setUp(self):
        """
        创建一个调查对象和一组答案,供使用的测试方法使用
        """
        question = "What language did you first learn to speak?"
        self.my_survey = AnonymousSurvey(question)
        self.responses = ['English', 'Spanish', 'Mandarin']

    def test_store_single_response(self):
        """测试单个答案会被妥善地存储"""
        self.my_survey.store_response(self.responses[0])
        self.assertIn(self.responses[0], self.my_survey.responses)

    def test_store_three_responses(self):
        """测试三个答案会被妥善地存储"""
        for response in self.responses:
            self.my_survey.store_response(response)
        for response in self.responses:
            self.assertIn(response, self.my_survey.responses)

unittest.main()

可在setUp() 方法中创建一系列实例并设置它们的属性,再在测试方法中直接使用这些实例;
相比于在每个测试方法中都创建实例并设置其属性,这要容易得多

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

小结

如何使用模块unittest 中的工具来为函数和类编写测试;
如何编写继承unittest.TestCase 的类,以及如何编写测试方法,以核实函数和类的行为符合预期;
如何使用方法setUp() 来根据类高效地创建实例并设置其属性,以便在类的所有测试方法中都可使用它们;
参与工作量较大的项目时,你应对自己编写的函数和类的重要行为进行测试;
这样你就能够更加确定自己所做的工作不会破坏项目的其他部分,你就能够随心所欲地改进既有代码了;
如果不小心破坏了原来的功能,你马上就会知道,从而能够轻松地修复问题;
相比于等到不满意的用户报告bug后再采取措施,在测试未通过时采取措施要容易得多;
如果你在项目中包含了初步测试,其他程序员将更敬佩你,他们将能够更得心应手地尝试使用你编写的代码,也更愿意与你合作开发项目;
如果你要跟其他程序员开发的项目共享代码,就必须证明你编写的代码通过了既有测试,通常还需要为你添加的新行为编写测试;
请通过多开展测试来熟悉代码测试过程;
对于自己编写的函数和类,请编写针对其重要行为的测试,但在项目早期,不要试图去编写全覆盖的测试用例,除非有充分的理由这样做

标签:11,name,第十一章,self,formatted,survey,测试代码,response,first
From: https://www.cnblogs.com/artwalker/p/17341546.html

相关文章

  • 【LeetCode动态规划#11】打家劫舍系列题(涉及环结构和树形DP的讨论)
    打家劫舍力扣题目链接(opensnewwindow)你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。给定一个代表每个房屋存放金额的非负整数数组......
  • 1110 完全二叉树
    给定一个树,请你判断它是否是完全二叉树。输入格式第一行包含整数 N,表示树的结点个数。树的结点编号为 0∼N−1。接下来 N 行,每行对应一个结点,并给出该结点的左右子结点的编号,如果某个子结点不存在,则用 - 代替。输出格式如果是完全二叉树,则输出 YES 以及最后一个结点......
  • 1115 二叉搜索树最后两层结点数量
    二叉搜索树(BST)递归定义为具有以下属性的二叉树:若它的左子树不空,则左子树上所有结点的值均小于或等于它的根结点的值若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值它的左、右子树也分别为二叉搜索树将一系列数字按顺序插入到一个空的二叉搜索树中,然后,请你......
  • 1119 前序和后序遍历
    假设一个二叉树上所有结点的权值都互不相同。我们可以通过后序遍历和中序遍历来确定唯一二叉树。也可以通过前序遍历和中序遍历来确定唯一二叉树。但是,如果只通过前序遍历和后序遍历,则有可能无法确定唯一二叉树。现在,给定一组前序遍历和后序遍历,请你输出对应二叉树的中序遍历......
  • 1102 反转二叉树
    以下是来自 MaxHowell@twitter 的内容:谷歌:我们的百分之九十的工程师都使用你编写的软件,但是你连在白板上反转二叉树都做不到,还是滚吧。现在,请你证明你会反转二叉树。输入格式第一行包含一个整数 N,表示树的结点数量。所有结点编号从 0 到 N−1。接下来 N 行,每行对......
  • 1106
    供应链是由零售商,经销商和供应商构成的销售网络,每个人都参与将产品从供应商转移到客户的过程。整个销售网络可以看作一个树形结构,从根部的供应商往下,每个人从上一级供应商中买入商品后,假定买入价格为 P,则会以高出买入价 r% 的价格向下出售。只有零售商(即叶节点)可以直接将产品......
  • Oracle:fedora-server-38:安装oracle11g
    基本过程不再赘述。关键点:问题1:解决1: 问题2:解决2:  问题3: 解决3: ......
  • 11、集群外部、内部的jenkins如何在k8s集群上创建动态pod agent
    Kubernetes插件能够让JenkinsMaster在Kubernetes集群上运行基于Pod的动态Agent◼它会为启动的每个Agent创建一个Pod,并在运行完成后停止它◼各PodAgent以InboundAgent形式运行,inbound-agent容器会自动连接到JenkinsMaster◆这意味着在每个PodAgent中,始终有一......
  • 类的memory以及抽象类继承学习(含测试代码)
    #include<iostream>#include<cstdio>#include<queue>#include<vector>#definelllonglongusingnamespacestd;/*注意:输出不同可能对齐参数或者编译器不同有关。*///模板类输出方法template<classT>intsize(Tlim){returnsizeof(lim);}/*......
  • Java8更新Java11, 修复使java11环境生效
     原因:jenkins安装新版本时发现不支持java8了,需要手动删除旧的8更新到11,再配置环境变量.报错:jenkins:invalidJavaversion:openjdkversion"1.8.0_312" 1.先卸载旧的java8dnfremovejava 2.安装装版本java11yuminstall-yfontconfigjava-11-openjdkjava-1......