python学习笔记(十九)测试类

python学习笔记(十九)测试类

在上一篇文章中,我们主要了解了针对单个函数的测试,而在这一篇中,我们将要具体学习一下针对类的测试。

1、断言方法
上一篇我曾经提到过断言方法是unittest类最有用的功能之一,主要用来核实得到的结果是否与期望值一致,这里我们来简单看一下几个常用的。

方法用途
a s s e r t E q u a l ( a , b ) assertEqual(a, b) assertEqual(a,b)核实 a = = b a==b a==b
a s s e r t N o t E q u a l ( a , b ) assertNotEqual(a, b) assertNotEqual(a,b)核实 a a a ! = != != b b b
a s s e r t T r u e ( x ) assertTrue(x) assertTrue(x)核实 x x x T r u e True True
a s s e r t F a l s e ( x ) assertFalse(x) assertFalse(x)核实 x x x F a l s e False False
a s s e r t I n ( i t e m , l i s t ) assertIn(item, list) assertIn(item,list)核实 i t e m item item l i s t list list
a s s e r t N o t I n ( i t e m , l i s t ) assertNotIn(item,list) assertNotIn(item,list)核实 i t e m item item 不在 l i s t list list

注意,我们只能在继承unittest.TestCase的类中使用这些方法。
实际上,类的测试与函数的测试很相似,测试代码的主要功能还是测试类中方法的行为,下面我们主要例子来了解测试类。

2、编写待测试的类
首先,创建一个空文件夹day_19。
在这里插入图片描述

在文件 question.py 中编写待测试类 Question(),并将其存放在文件夹day_19中。

class Question():
	"""调查问卷"""

	def __init__(self, question):
		"""初始化问题和答案"""
		self.question = question
		self.answers = []

	def give_question(self):
		"""提供问题"""
		print(self.question)

	def get_answer(self, answer):
		"""收集答案"""
		self.answers.append(answer)

	def show_answer(self):
		"""打印收集到的答案"""
		print("Results:")
		for answer in self.answers:
			print("- " + answer)

上述类只是一个空模型,我们可以将其实例化来调查大家最喜欢的编程语言。另创建 favorite_language.py 文件,并保存在 day_19 文件夹中。

from question import Question

question = "Please tell me your favorite programming language?"
answer_got = Question(question)

answer_got.give_question()
print("Please enter 'e' if you want to end.\n")
while True:
    response = input("Language: ")
    if response == 'e':
        break
    else:
        answer_got.get_answer(response)
answer_got.show_answer()

接下来我们运行一下 favorite_language.py 文件,简单看一下待测试类的基本功能。运行结果为:

Please tell me your favorite programming language?
Please enter 'e' if you want to end.

Language: python
Language: java
Language: ruby
Language: c
Language: e
Results:
- python
- java
- ruby
- c

但是,Question 类是否有什么隐藏问题呢,这时候我们就需要借助测试代码来确定一下。

3、编写测试代码
创建 test_question.py 文件,并存放在 day_19 文件夹中。

import unittest
from question import Question

class TestQuestion(unittest.TestCase):
    """针对Question类的测试代码"""

    def test_store_single_answer(self):
        """测试单个答案是否会被存储起来"""
        question = "Please tell me your favorite programming language?"
        answer_got = Question(question)
        answer_got.get_answer('python')

        self.assertIn('python', answer_got.answers)

unittest.main()

上述代码只是简单的测试了类存储单个答案的行为,我们来看看测试代码的编写,实际上,与函数的测试代码十分相似:导入 unittest 模块,导入待测类,创建继承TestCase类的测试类,编写以 _test 开头的测试方法,最后一行 unittest.main() 使python自动运行以 _test 开头的方法,稍微有点不同的是我们必须在测试类的方法之前先完成类的实例化。下面我们再来看看运行结果有什么不同:

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

OK

测试通过,一样。接下来我们核实一下用户传入三个答案时,答案能否被正常存储,改写 test_question.py 文件。

import unittest
from question import Question

class TestQuestion(unittest.TestCase):
    """针对Question类的测试代码"""

    def test_store_single_answer(self):
        """测试单个答案是否会被存储起来"""
        question = "Please tell me your favorite programming language?"
        answer_got = Question(question)
        answer_got.get_answer('python')

        self.assertIn('python', answer_got.answers)

    def test_store_three_answers(self):
    	"""测试三个答案能否被正常存储"""
    	question = "Please tell me your favorite programming language?"
    	answer_got = Question(question)
    	answers = ['python', 'java', 'c']

    	for answer in answers:
    		answer_got.get_answer(answer)

    	for answer in answers:
    		self.assertIn(answer, answer_got.answers)
        
unittest.main()

运行结果为:

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

OK

测试通过,但实际上新增的方法与之前的重复性很高,因为他只是设置了列表,再用for循环完成测试,这样代码效率会变低,但是,unittest模块的另一项功能可以帮助我们完美解决这一问题。

4、方法setUp()
在上一篇文章中我曾经提到过,python会自动运行测试类中以 test_ 开头的方法,但是当unittest.TestCase 类中包含 setUp()
方法,python将先运行它,在运行各个以 test_ 开头的方法,我们可以根据这一特性来提高测试类中代码的效率。接下来我们再次改写 test_question.py 文件。

import unittest
from question import Question

class TestQuestion(unittest.TestCase):
    """针对Question类的测试代码"""

    def setUp(self):
    	"""创建一个Question对象和一组答案"""
    	question = "Please tell me your favorite programming language?"
    	self.answer_got = Question(question)
    	self.answers = ['python', 'java', 'c']

    def test_store_single_answer(self):
        """测试单个答案是否会被存储起来"""
        self.answer_got.get_answer(self.answers[0])
        self.assertIn(self.answers[0], self.answer_got.answers)

    def test_store_three_answers(self):
    	"""测试三个答案能否被正常存储"""
    	for answer in self.answers:
    		self.answer_got.get_answer(answer)
    	for answer in self.answers:
    		self.assertIn(answer, self.answer_got.answers)

unittest.main()

运行结果为:

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

OK

实际上,setUp() 方法就是将其他测试方法中高度重复的部分想办法集中起来,从而提高代码的效率。

5、注意
运行测试用例时,每当完成单元测试,python都打印一个字符:
. . . :测试通过
E E E :测试引发错误
F F F :测试导致断言失败
如果测试用例包含很多单元测试,就需要运行很长时间,我们可以直接根据符号判断测试情况,再结合错误报告被测试的函数或者类。

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值