Python3 测试代码

逆流者 2020年11月06日 145次浏览

测试函数

先看下测试代码

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()

测试代码:

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 + '.')

结果:

Enter 'q' at any time to quit.

Please give me a first name: wu
Please give me a last name: shanghui
	Neatly formatted name: Wu Shanghui.

Please give me a first name: wu
Please give me a last name: chengen
	Neatly formatted name: Wu Chengen.

Please give me a first name: q

Process finished with exit code 0

单元测试和测试用例

Python标准库中的模块unittest提供了代码测试工具.
测试用例是一组单元测试

可通过的测试

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()

运行它

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

OK

分析:

  • self.assertEqual(formatted_name, 'Janis Joplin') 断言
  • 结果第一行句号表示测试通过了
  • 最后OK表示测试用例中的所有单元测试都通过了

不能通过的测试

我们故意断言一个错误的结果试试看

def test_first_last_name(self):
    """能够正确地处理像Janis Joplin这样的姓名吗?"""
    formatted_name = get_formatted_name('janis', 'joplin')
    self.assertEqual(formatted_name, 'Janis Joplin1')
F
======================================================================
FAIL: test_first_last_name (__main__.NamesTestCase)
能够正确地处理像Janis Joplin这样的姓名吗?
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_name_function.py", line 10, in test_first_last_name
    self.assertEqual(formatted_name, 'Janis Joplin1')
AssertionError: 'Janis Joplin' != 'Janis Joplin1'
- Janis Joplin
+ Janis Joplin1
?             +


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

FAILED (failures=1)

添加新的测试

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

测试类

各种断言方法

Python在unittest.TestCase类中提供了很多断言方法.

unittest Module中的断言方法

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

一个要测试的类

一个帮助管理匿名调查的类
survey.py

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 results: ')
        for response in self.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()

测试结果:

What language did you first learn to speak?
Enter 'q' at any time to quit.

language: English
language: Spanish
language: Mandarin
language: q

Thank you to everyone who participated in the survey!
Survey results: 
- English
- Spanish
- Mandarin

测试AnonymousSurvey类

test_survey.py

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)


unittest.main()

运行它:

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

OK

再测试一个新方法

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)

通过上面的两个函数可以看到, 在方法里面都有相同的代码, 比如创建AnonymousSurvey类, 怎么能复用呢?

方法setUp()


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.TestCase类包含方法setUp(), 可以用来创建好其他函数都用到的部分
  • 其他函数需要以test_打头

测试结果:

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

OK


Python3 目录

  1. Python3 教程
  2. Python3 变量和简单数据类型
  3. Python3 列表
  4. Python3 操作列表
  5. Python3 if 语句
  6. Python3 if 字典
  7. Python3 用户输入和while循环
  8. Python3 函数
  9. Python3 类
  10. Python3 文件和异常
  11. Python3 测试代码
  12. Python3 使用matplotlib绘制图表
  13. Python3 使用Pygal生成矢量图形文件
  14. Python3 使用csv模块处理CSV(逗号分割的值)格式存储的天气数据
  15. Python3 处理JSON格式数据(制作交易收盘价走势图)
  16. Python3 使用API