51Testing软件测试论坛

标题: 基于unittest框架的单元测试,还是挺简单的 [打印本页]

作者: lsekfe    时间: 2020-9-29 11:55
标题: 基于unittest框架的单元测试,还是挺简单的
 一、定义
  1)什么是单元测试?
  单元:函数或者是类
  单元测试:测试类或者函数
  2)为什么做单元测试?
  投入小、收益大,能够精准的、更早的发现问题
  3)单元测试和我有什么关系?
  python语言是很难测试java的单元,关键是单元测试一般是开发或者测开做的。
  自动化测试主要是做:集成测试、系统测试、验收测试 
  二、unittest-TestCase
  单元测试框架:
  Python内置的单元测试框架:unittest
[attach]130068[/attach]
unittest的注意事项:
  1.模块名称:test_开头
  2.类名:Test····
  3.测试用例方法名称:test·····开头
  4.TestLogin(unittest.TestCase),不要忘了继承unittest.TestCase
  1. #导入单元测试框架unittest

  2.   import unittest

  3.   """测试登录功能(函数)"""

  4.   def login(username = None,password = None):

  5.       if username != None and password != None:

  6.           if username == "zjx111" and password == "123456":

  7.               return {"code":0,"msg":"登录成功!"}

  8.           else:

  9.               return {"code":1,"msg":"登录失败,用户名或密码错误!"}

  10.       else:

  11.           return {"code":1,"msg":"登录失败,用户名或密码为空!"}

  12.   #设计登录测试用例类

  13.   class TestLogin(unittest.TestCase):#继承unittest.TestCase

  14.       def test_login_success(self):

  15.           '''登录成功'''

  16.           username = "zjx111"

  17.           password = "123456"

  18.           expected_reponse = {"code":0,"msg":"登录成功!"}

  19.           #实际结果:调用login函数

  20.           actual_reponse = login(username,password)

  21.           #判断预期结果跟实际结果是否一样   断言

  22.           self.assertTrue(expected_reponse == actual_reponse)

  23.       def test_login_error(self):

  24.           '''登录失败'''

  25.           username = ''

  26.           password = ''

  27.           expected_reponse = {"code":1,"msg":"登录失败,用户名或密码错误!"}

  28.           actual_reponse = login(username, password)

  29.           self.assertTrue(expected_reponse == actual_reponse) 
复制代码
三、unittest-Fixture:测试环境的搭建和销毁(前置、后置条件)
# 前置、后置条件是固定的名称,不改,执行一个用例执行一次前置后置条件
  def setUp(self):
     '''前置条件'''
     pass

  def tearDown(self):
     '''后置条件'''
     pass

在用例执行之前执行setUp(),在用例执行之后执行tearDown()
  有多少条用例,就执行多少遍setUp()和tearDown()

  1. #导入单元测试框架unittest

  2.   import unittest

  3.   """测试登录功能(函数)"""

  4.   def login(username = None,password = None):

  5.       if username != None and password != None:

  6.           if username == "zjx111" and password == "123456":

  7.               return {"code":0,"msg":"登录成功!"}

  8.           else:

  9.               return {"code":1,"msg":"登录失败,用户名或密码错误!"}

  10.       else:

  11.           return {"code":1,"msg":"登录失败,用户名或密码为空!"}

  12.   #设计登录测试用例类

  13.   class TestLogin(unittest.TestCase):#继承unittest.TestCase

  14.       def setUp(self):

  15.           '''前置条件'''

  16.           print('连接数据库')

  17.       def tearDown(self):

  18.           '''后置条件'''

  19.           print('断开数据库')

  20.       def test_login_success(self):

  21.           '''登录成功'''

  22.           username = "zjx111"

  23.           password = "123456"

  24.           expected_reponse = {"code":0,"msg":"登录成功!"}

  25.           #实际结果:调用login函数

  26.           actual_reponse = login(username,password)

  27.           #判断预期结果跟实际结果是否一样   断言

  28.           self.assertTrue(expected_reponse == actual_reponse)

  29.       def test_login_error(self):

  30.           '''登录失败'''

  31.           username = ''

  32.           password = ''

  33.           expected_reponse = {"code":1,"msg":"登录失败,用户名或密码错误!"}

  34.           actual_reponse = login(username, password)

  35.           self.assertTrue(expected_reponse == actual_reponse)

  36.   '''

  37.   结果:

  38.   连接数据库

  39.   断开数据库

  40.   连接数据库

  41.   断开数据库

  42.   '''
复制代码
如果想在一个测试类当中,只执行一次的话前置和后置,需要用到类方法:setUpClass(cls)和tearDownClass(cls)
  1.  #导入单元测试框架unittest

  2.   import unittest

  3.   """测试登录功能(函数)"""

  4.   def login(username = None,password = None):

  5.       if username != None and password != None:

  6.           if username == "zjx111" and password == "123456":

  7.               return {"code":0,"msg":"登录成功!"}

  8.           else:

  9.               return {"code":1,"msg":"登录失败,用户名或密码错误!"}

  10.       else:

  11.           return {"code":1,"msg":"登录失败,用户名或密码为空!"}

  12.   #设计登录测试用例类

  13.   class TestLogin(unittest.TestCase):#继承unittest.TestCase

  14.       @classmethod

  15.       def setUpClass(cls):

  16.           print('一个测试类中只会执行一次的前置条件')

  17.       @classmethod

  18.       def tearDownClass(cls):

  19.           print('一个测试类中只会执行一次的后置条件')

  20.       def setUp(self):

  21.           '''前置条件'''

  22.           print('连接数据库')

  23.       def tearDown(self):

  24.           '''后置条件'''

  25.           print('断开数据库')

  26.       def test_login_success(self):

  27.           '''登录成功'''

  28.           username = "zjx111"

  29.           password = "123456"

  30.           expected_reponse = {"code":0,"msg":"登录成功!"}

  31.           #实际结果:调用login函数

  32.           actual_reponse = login(username,password)

  33.           #判断预期结果跟实际结果是否一样   断言

  34.           self.assertTrue(expected_reponse == actual_reponse)

  35.       def test_login_error(self):

  36.           '''登录失败'''

  37.           username = ''

  38.           password = ''

  39.           expected_reponse = {"code":1,"msg":"登录失败,用户名或密码错误!"}

  40.           actual_reponse = login(username, password)

  41.           self.assertTrue(expected_reponse == actual_reponse)

  42.   '''

  43.   结果:

  44.   一个测试类中只会执行一次的前置条件

  45.   连接数据库

  46.   断开数据库

  47.   连接数据库

  48.   断开数据库

  49.   一个测试类中只会执行一次的后置条件

  50.   '''     
复制代码
 四、unittest-TestSuite/TextTestRunner:测试套件/运行测试用例
  unittest测试用例的执行顺序:
  不是从上到下
  根据测试用例的名称:ASCII码
  如果想自己调整测试用例的顺序,就可以在测试用例的方法名称上加数字,比如:test_login_01_success(self)
  我们会把测试用例的代码放到一个统一的文件夹当中,目录当中:tests/testcases

  1. if __name__=='__main__':

  2.       #使用Python运行这个模块里面的测试用例

  3.       unittest.main()
复制代码
测试用例收集步骤:
  1)将所有待测的测试用例放在,项目目录下new 一个directory,命名为tests / testcases里
  2)在run_test.py中,运行收集用例的代码
  a). import unittest
  b).初始化一个加载器    loader = unittest.TestLoader()
  c).加载器去收集所有的测试用例(testcases里的所有用例),放在testsuite里面  test_suite = loader.discover(case_path)

  1. import unittest

  2.   import os

  3.   #初始化一个加载器 test_loadder

  4.   loader = unittest.TestLoader()

  5.   #获取测试用例目录的路径,测试用例都放在tesetcases文件夹里

  6.   dir_path  = os.path.dirname(os.path.abspath(__file__))

  7.   case_path = os.path.join(dir_path,'testcases')

  8.   #使用loader获取所有的测试用例

  9.   test_suite = loader.discover(case_path)  #在case_path里面发现所有的测试用例

  10.   print(test_suite)#就是返回一个testSuite对象,列表存储的
复制代码
执行测试用例:
    1).初始化一个执行器runner
    2).runner.run(test_suite)

  1.  import os

  2.   import unittest

  3.   #初始化一个加载器 test_loadder

  4.   loader = unittest.TestLoader()

  5.   #获取测试用例目录的路径,测试用例都放在tesetcases文件夹里

  6.   dir_path  = os.path.dirname(os.path.abspath(__file__))

  7.   case_path = os.path.join(dir_path,'testcases')

  8.   #使用loader获取所有的测试用例

  9.   test_suite = loader.discover(case_path)  #在case_path里面发现所有的测试用例

  10.   print(test_suite)#就是返回一个testSuite对象,列表存储的

  11.   #执行测试用例

  12.   #先初始化一个执行器runner

  13.   runner = unittest.TextTestRunner()

  14.   runner.run(test_suite)
复制代码




作者: lsekfe    时间: 2020-9-29 11:56
五、生成测试报告
  1)生成txt报告
  但是在实际中,不会使用txt形式的报告,比较low,会换用HTML的报告.
  1. import unittest

  2.   import os

  3.   #初始化一个加载器 test_loadder

  4.   loader = unittest.TestLoader()

  5.   #获取测试用例目录的路径,测试用例都放在tesetcases文件夹里

  6.   dir_path  = os.path.dirname(os.path.abspath(__file__))

  7.   case_path = os.path.join(dir_path,'testcases')

  8.   #使用loader获取所有的测试用例

  9.   test_suite = loader.discover(case_path)  #在case_path里面发现所有的测试用例

  10.   print(test_suite)#就是返回一个testSuite对象,列表存储的

  11.   #执行 并生成text测试报告

  12.   with open('test_report.txt','a',encoding='utf-8') as f:

  13.       runner  = unittest.TextTestRunner(f) #f作为参数传入

  14.       runner.run(test_suite)
复制代码
2)生成HTML测试报告
  HTML报告不是内置的,需要自己去下载HTML的测试报告的运行器和模板(HTMLTestRunnerNew.py),导入到pycharm的seite_package 或者直接导入项目目录下

  1. #执行 并生成html测试报告

  2.   with open('test_report.html','wb') as f:

  3.       runner = HTMLTestRunner(

  4.           f,

  5.           title='自动化测试报告',

  6.           description='测试报告的描述',

  7.           tester='zjx'

  8.       )

  9.       runner.run(test_suite) 
复制代码
六、断点调试
  1)断点
  调试的时候使用debug模式,
  打断点 在可能出错的地方打断点,如果不知道哪行会出错,就打在最开始的位置,一行一行调试
  2)打断点如何运行?
  step over:单步执行,运行到下一行
  step into:执行到函数的内部
  step into my code:进入自己写的代码,别人写的进不去
  step out:退出函数
  run to cursor:运行到指定的行
  evaluate:查找值并可对查找到的值进行其他运算
  rerun:重新运行
  resume program:运行到下一个断点
  stop:停止
  view breakpoints:显示所有的断点
  mute breakpoints:关闭所有的断点







欢迎光临 51Testing软件测试论坛 (http://bbs.51testing.com/) Powered by Discuz! X3.2