Python unittest –单元测试示例

时间:2020-02-23 14:43:39  来源:igfitidea点击:

今天,我们将学习python unittest并浏览python unittest示例程序。

Python单元测试

Python unittest模块用于测试一个源代码单元。
假设您需要测试您的项目。
您知道函数将返回哪种数据。
编写大量代码后,您需要检查其输出是否正确。

通常,我们要做的是打印输出并将其与参考输出文件匹配,或者手动检查输出。

为了减轻这种痛苦,Python引入了unittest模块。
使用此模块,您可以通过一些简单的代码来检查函数的输出。
在本教程中,我们将讨论Python unittest模块的基本用法,并编写一些python单元测试用例来测试类函数。

Python单元测试示例源

首先,我们必须编写一些代码以对其进行单元测试。
我们将有一个Python类。

该程序的主要目的是存储和检索人的名字。
因此,我们编写了" set_name()"函数来存储数据,并编写了" get_name()"函数来从类中检索名称。

class Person:
  name = []

  def set_name(self, user_name):
      self.name.append(user_name)
      return len(self.name) - 1

  def get_name(self, user_id):
      if user_id >= len(self.name):
          return 'There is no such user'
      else:
          return self.name[user_id]

if __name__ == '__main__':
  person = Person()
  print('User Abbas has been added with id ', person.set_name('Abbas'))
  print('User associated with id 0 is ', person.get_name(0))

我们将类文件命名为Person.py
以上代码的输出将如下所示。

$python3.6 Person.py 
User Abbas has been added with id  0
User associated with id 0 is  Abbas
$

Python单元测试结构

现在,让我们学习如何为单元测试编写代码。
通过子类化unittest.TestCase创建一个单独的测试用例。
通过覆盖或者添加适当的功能,我们可以添加逻辑进行测试。
如果a等于b,则以下代码将成功。

import unittest

class Testing(unittest.TestCase):
  def test_string(self):
      a = 'some'
      b = 'some'
      self.assertEqual(a, b)

  def test_boolean(self):
      a = True
      b = True
      self.assertEqual(a, b)

if __name__ == '__main__':
  unittest.main()

如何运行python unittest模块

如果您使用的是PyCharm IDE,则只需按ctrl + shift + F10即可运行unittest模块。
否则,您可以使用命令提示符运行此模块。
例如,我们将用于单元测试的文件命名为Basic_Test.py
因此,运行python unittest的命令将是:

$python3.6 -m unittest Basic_Test.Testing

如果要查看详细信息,则命令为;

$python3.6 -m unittest -v Basic_Test.Testing

通过使用PyCharm,我们得到以下输出。

Python单元测试结果和基本功能

该单元测试有3种可能的结果。
它们在下面提到:

  • OK:如果所有测试用例都通过,则输出显示OK。

  • 失败:如果任何测试用例失败并引发AssertionError异常
    Error: If any exception other than AssertionError exception is raised.

unittest模块下有几个功能。
它们在下面列出。

MethodChecks that
assertEqual(a,b)a==b
assertNotEqual(a,b)a != b
assertTrue(x)bool(x) is True
assertFalse(x)bool(x) is False
assertIs(a,b)a is b
assertIs(a,b)a is b
assertIsNot(a, b)a is not b
assertIsNone(x)x is None
assertIsNotNone(x)x is not None
assertIn(a, b)a in b
assertNotIn(a, b)a not in b
assertIsInstance(a, b)isinstance(a, b)
assertNotIsInstance(a, b)not isinstance(a, b)

Python单元测试示例

现在该为我们的源类" Person"编写单元测试了。
在这个类中,我们实现了两个函数– get_name()和set_name()。

现在,我们将使用" unittest"来测试这些功能。
因此,我们针对这两个功能设计了两个测试用例。
看看下面的代码,您将很容易理解。

import unittest

# This is the class we want to test. So, we need to import it
import Person as PersonClass

class Test(unittest.TestCase):
  """
  The basic class that inherits unittest.TestCase
  """
  person = PersonClass.Person()  # instantiate the Person Class
  user_id = []  # variable that stores obtained user_id
  user_name = []  # variable that stores person name

  # test case function to check the Person.set_name function
  def test_0_set_name(self):
      print("Start set_name test\n")
      """
      Any method which starts with ``test_`` will considered as a test case.
      """
      for i in range(4):
          # initialize a name
          name = 'name' + str(i)
          # store the name into the list variable
          self.user_name.append(name)
          # get the user id obtained from the function
          user_id = self.person.set_name(name)
          # check if the obtained user id is null or not
          self.assertIsNotNone(user_id)  # null user id will fail the test
          # store the user id to the list
          self.user_id.append(user_id)
      print("user_id length = ", len(self.user_id))
      print(self.user_id)
      print("user_name length = ", len(self.user_name))
      print(self.user_name)
      print("\nFinish set_name test\n")

  # test case function to check the Person.get_name function
  def test_1_get_name(self):
      print("\nStart get_name test\n")
      """
      Any method that starts with ``test_`` will be considered as a test case.
      """
      length = len(self.user_id)  # total number of stored user information
      print("user_id length = ", length)
      print("user_name length = ", len(self.user_name))
      for i in range(6):
          # if i not exceed total length then verify the returned name
          if i < length:
              # if the two name not matches it will fail the test case
              self.assertEqual(self.user_name[i], self.person.get_name(self.user_id[i]))
          else:
              print("Testing for get_name no user test")
              # if length exceeds then check the 'no such user' type message
              self.assertEqual('There is no such user', self.person.get_name(i))
      print("\nFinish get_name test\n")

if __name__ == '__main__':
  # begin the unittest.main()
  unittest.main()

请注意,unittest模块按其名称的顺序而不是按其定义的顺序执行测试功能。
并且由于我们希望先执行set_name测试,因此我们将测试用例函数命名为test_0_set_nametest_1_get_name

Python单元测试示例输出

下图显示了我们的单元测试程序在正常模式和详细模式下产生的输出。

$python3.6 -m unittest -v PersonTest.Test
test_0_set_name (PersonTest.Test) ... Start set_name test

user_id length =  4
[0, 1, 2, 3]
user_name length =  4
['name0', 'name1', 'name2', 'name3']

Finish set_name test

ok
test_1_get_name (PersonTest.Test) ... 
Start get_name test

user_id length =  4
user_name length =  4
Testing for get_name no user test
Testing for get_name no user test

Finish get_name test

ok

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

OK
$