zoukankan      html  css  js  c++  java
  • Python测试代码unittest简单使用笔记。

    学习Python有段时间了,关于测试的部分基本没咋学过,初学的时候看不懂,现在都2018年了,回头再来学习下,要不然一点不了解说不过去。

    首先参考的是入门初级《Python编程从入门到实践》第11章,测试代码。

    Python标准库中的模块unittest提供了代码测试工具。单元测试用于何时函数的某个方法没有问题;

    测试用例是一组单元测试,这些单元测试一起核实函数在各种情况下的行为都符合要求。

    良好的测试用例考虑到了函数可能收到的各种输入,包含针对目标情形的测试。

    全覆盖测试用例包含一整套单元测试,涵盖了各种可能的函数使用方式。对于大型项目,要实现全覆盖很难。

    通常,最初只要针对代码的重要行为编写测试既可,等项目被广泛使用时再考虑全覆盖。

    首先编写一个测试函数

    def get_formatted_name(first, last):
        full_name = first + ' ' + last
        return full_name.title()
    

     然后编写一个测试该函数的类

    import unittest
    from name_function import get_formatted_name
    
    # 编写一个测时类继承unittest.TestCase
    class NamesTestCase(unittest.TestCase):
    
        # 定义一个测试的方法,方法名字要以test开头,这样在unittest.main()执行的时候会自动执行
        def test_first_last_name(self):
            # 调用被测试的函数,输入参数,并通过变量接收
            formatted_name = get_formatted_name('janis', 'joplin')
            # 通过assertEqual判断测试函数返回的,与实际正确的结果是否一致。
            self.assertEqual(formatted_name, 'Janis Joplin')
    
    if __name__ == '__main__':
        unittest.main()
    

     执行该脚本

    shijianzhongdeMacBook-Pro:Python从入门到实践 shijianzhong$ python3 test_name_function.py 
    .
    ----------------------------------------------------------------------
    Ran 1 test in 0.000s
    
    OK
    

     一个点表示一个测试方法通过了,第二个是花费的时间,第三个参数为所有的测试方法都通过了。

    故意搞错了试试。

    def get_formatted_name(first, middle, last):
        full_name = first + ' ' + middle + ' ' + last
        return full_name.title()
    

     把函数改成三个参数输入的。

    运行测试的输出

    shijianzhongdeMacBook-Pro:Python从入门到实践 shijianzhong$ python3 test_name_function.py 
    E
    ======================================================================
    ERROR: test_first_last_name (__main__.NamesTestCase)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "test_name_function.py", line 10, 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)
    

    测试没通过,就要新办法去修改你的函数,让其通过

    def get_formatted_name(first, last, middle=''):
    if middle:
    full_name = first + ' ' + middle + ' ' + last
    else:
    full_name = first + ' ' +last
    return full_name.title()

    改成这样就又可以通过了。

    因为这个函数可以接收三个参数,所以原来的测试类上面添加一个测试的方法。

    import unittest
    from name_function import get_formatted_name
    
    # 编写一个测时类继承unittest.TestCase
    class NamesTestCase(unittest.TestCase):
    
        # 定义一个测试的方法,方法名字要以test开头,这样在unittest.main()执行的时候会自动执行
        def test_first_last_name(self):
            # 调用被测试的函数,输入参数,并通过变量接收
            formatted_name = get_formatted_name('janis', 'joplin')
            # 通过assertEqual判断测试函数返回的,与实际正确的结果是否一致。
            self.assertEqual(formatted_name, 'Janis Joplin')
            
        def test_first_last_middle_name(self):
            formatted_name = get_formatted_name(
                'wolfgang', 'mozart', 'amadeus'
            )
            self.assertEqual(formatted_name, 'Wolfgang Amadeus Mozart')
    
    if __name__ == '__main__':
        unittest.main()
    

     返回的结果

    shijianzhongdeMacBook-Pro:Python从入门到实践 shijianzhong$ python3 test_name_function.py 
    ..
    ----------------------------------------------------------------------
    Ran 2 tests in 0.000s
    
    OK
    

    作业不写了,基本跟书上的一模一样,只不过把名字改成了城市。

    测试类。

    各种断言方法

    self.assertEqual(a,b)    核实 a == b

    self.assertNotEqual(a, b)    核实 a != b

    assertTrue(x)           核实x为True

    assertFalse(x)          核实x为False

    assertIn(item, list)    核实item在list中

    assertNotIn(item, list)  核实item不在list中

    看了一下,其实跟测试函数差不多。

    先些测试准备被测试的类

    class AnonymousSurvey:
    
        def __init__(self, question):
            self.question = question
            self.responses = []
    
        def show_question(self):
            print(self.question)
    
        def store_response(self, new_response):
            self.responses.append(new_response)
    
        def show_results(self):
            print('Survey result:')
            for response in self.responses:
                print('- ' + response)
    

     在写一个脚本使用这个类

    from survey import AnonymousSurvey
    
    question = "What language did you first learn to spaek?"
    my_survey = AnonymousSurvey(question)
    
    
    my_survey.show_question()
    print('Enter "q" at any time to quit.
    ')
    while True:
        response = input("Language: ")
        if response == 'q':
            break
        my_survey.store_response(response)
    
    print('
    Thank you to everyone who participated in the survey!')
    my_survey.show_results()
    

     运行脚本显示的情况

    /usr/local/bin/python3.7 /Users/shijianzhong/study/测试/Python从入门到实践/language_survey.py
    What language did you first learn to spaek?
    Enter "q" at any time to quit.
    
    Language: python
    Language: java
    Language: js
    Language: q
    
    Thank you to everyone who participated in the survey!
    Survey result:
    - python
    - java
    - js
    

    编写测试 AnonymousSurvey的类,因为每添加一门语言,在实例的responses属性里面都会多一门,所以测试的时候用了AssertIn()

    import unittest
    from survey import AnonymousSurvey
    
    # 创建测试类
    class TestAnonymousSurvey(unittest.TestCase):
    
        # 首先针对只输入了一门语言的情况
        def test_store_single_response(self):
            question = "What language did you first learn to spaek?"
            my_survey = AnonymousSurvey(question)
            # 保存一门语言
            my_survey.store_response('English')
    
            # 准备测试,这么语言是否在对象的responses属性里面
            self.assertIn('English', my_survey.responses)
    
    if __name__ == '__main__':
        unittest.main()
    
    shijianzhongdeMacBook-Pro:Python从入门到实践 shijianzhong$ python3 test_survey.py 
    .
    ----------------------------------------------------------------------
    Ran 1 test in 0.000s
    
    OK
    

    后面写测试三个答案时候,是否也能妥善保管

    import unittest
    from survey import AnonymousSurvey
    
    # 创建测试类
    class TestAnonymousSurvey(unittest.TestCase):
    
        # 首先针对只输入了一门语言的情况
        def test_store_single_response(self):
            question = "What language did you first learn to spaek?"
            my_survey = AnonymousSurvey(question)
            # 保存一门语言
            my_survey.store_response('English')
    
            # 准备测试,这么语言是否在对象的responses属性里面
            self.assertIn('English', my_survey.responses)
    
        def test_store_three_responses(self):
            question = "What language did you first learn to spaek?"
            my_survey = AnonymousSurvey(question)
            # 答案列表
            responses = ['English', 'Spanish', 'Mandarin']
            for response in responses:
                # 把答案先存起来
                my_survey.store_response(response)
    
            for response in responses:
                # 测试所有的答案到底在不在实例的responses里面
                self.assertIn(response, my_survey.responses)
    
    
    if __name__ == '__main__':
        unittest.main()
    
    shijianzhongdeMacBook-Pro:Python从入门到实践 shijianzhong$ python3 test_survey.py 
    ..
    ----------------------------------------------------------------------
    Ran 2 tests in 0.000s
    
    OK
    

    方法setUp()

    前面的测试,每次测试都要在测试方法中实例化对象,很蛮烦,所以有了setUp方法,就好比普通类里面的__init__,在每次执行的时候,该方法内的逻辑会先执行。

    import unittest
    from survey import AnonymousSurvey
    
    # 创建测试类
    class TestAnonymousSurvey(unittest.TestCase):
    
        def setUp(self) -> None:
            question = "What language did you first learn to spaek?"
            # 对象变成实例属性,后面大家可以用
            self.survey = AnonymousSurvey(question)
            # 答案列表
            self.responses = ['English', 'Spanish', 'Mandarin']
    
    
    
        # 首先针对只输入了一门语言的情况
        def test_store_single_response(self):
            # 从答案列表拿一个元素出来,进行存储操作
            self.survey.store_response(self.responses[0])
            # 准备测试,这么语言是否在对象的responses属性里面
            self.assertIn(self.responses[0], self.survey.responses)
    
        def test_store_three_responses(self):
            for response in self.responses:
                # 把答案先存起来
                self.survey.store_response(response)
    
            for response in self.responses:
                # 测试所有的答案到底在不在实例的responses里面
                self.assertIn(response, self.survey.responses)
    
    
    if __name__ == '__main__':
        unittest.main()
    

     运行结果是一样的。这本书中的学习结束,作业不做了,这个书中的作业太简单了。

    从另外一本书上看到,说写函数或者方法之前应该先写测试,这个感觉。。。。。。好苛刻啊。。。。。。

  • 相关阅读:
    leetcode 202 Happy Number
    【C++】函数缺省参数的作用
    【C++】类的两种实例化方法
    【C++】const 常引用的用法
    【Ubuntu】使用root账户登录ubuntu
    【Docker】基本命令使用介绍
    【Ajax】PHP中ajax的基本知识点
    【PHP】mysql基本操作整合
    一条命令搞定在VMware中的Ubuntu14.04 64 位安装Docker
    Java泛型初探
  • 原文地址:https://www.cnblogs.com/sidianok/p/12689050.html
Copyright © 2011-2022 走看看