51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 3858|回复: 0
打印 上一主题 下一主题

[转贴] 测试小白简单聊聊关于UnitTest(三)

[复制链接]
  • TA的每日心情
    擦汗
    7 天前
  • 签到天数: 1027 天

    连续签到: 2 天

    [LV.10]测试总司令

    跳转到指定楼层
    1#
    发表于 2021-6-8 10:10:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    六、数据驱动DDT(Data Driven Tests)
      在介绍数据驱动之前,我们先来看一下下面这个示例,代码的内容特别特别的简单,用来模拟自动化测试时输入用户名和密码(哈哈,我知道这样模拟有点勉强!!!):
      1、打开百度;
      2、第一次在输入框中输入java,然后清除,再输入123456,关闭浏览器
      3、第二次在输入框中输入selenium,然后清除,输入abcdef,关闭浏览器。
    1. import unittest
    2. from selenium import webdriver
    3. import time


    4. class UnitForTestddt(unittest.TestCase):

    5.     def setUp(self) -> None:
    6.         self.driver = webdriver.Chrome()
    7.         self.driver.get('http://www.baidu.com')

    8.     def test_ddt1(self):
    9.         self.driver.find_element_by_id('kw').send_keys('java')
    10.         time.sleep(1)
    11.         self.driver.find_element_by_id('kw').clear()
    12.         time.sleep(1)
    13.         self.driver.find_element_by_id('kw').send_keys('123456')
    14.         time.sleep(1)

    15.     def test_ddt2(self):
    16.         self.driver.find_element_by_id('kw').send_keys('selenium')
    17.         time.sleep(1)
    18.         self.driver.find_element_by_id('kw').clear()
    19.         time.sleep(1)
    20.         self.driver.find_element_by_id('kw').send_keys('abcdef')
    21.         time.sleep(1)

    22.     def tearDown(self) -> None:
    23.         self.driver.quit()


    24. if __name__ == '__main__':
    25.     unittest.main()
    复制代码
    由代码可以看出,中间的测试用例部分很多代码是重复的,造成代码冗余,为了解决代码冗余,我们采用数据驱动的方式;同时,为了方便后期代码的维护,进行数据与代码的分离。UnitTest没有自带数据的驱动功能,如果在使用UnitTest的同时又想使用数据驱动,那么就可以使用DDT来完成。
      使用方法如下:
      (1)ddt.data:装饰测试方法,参数是一系列的值,比如元组等;
      (2)ddt.file_data:装饰测试方法,参数是文件名,测试数据保存在参数文件中。文件类型可以是JSON或者YAML;
      (3)ddt.unpack:当ddt传递复杂的数据结构时使用,通常称为解包。
      下面分别将这几个方法进行示例演示,在使用ddt之前我们需要导包:import ddt。

      1. ddt.data方法
    1. import unittest
    2. from selenium import webdriver
    3. import time
    4. import ddt


    5. @ddt.ddt
    6. class UnitForTestddt(unittest.TestCase):

    7.     def setUp(self) -> None:
    8.         self.driver = webdriver.Chrome()
    9.         self.driver.get('http://www.baidu.com')

    10.     @ddt.data('java', 'selenium', 'python')
    11.     def test_ddt(self, a):
    12.         self.driver.find_element_by_id('kw').send_keys(a)
    13.         time.sleep(1)

    14.     def tearDown(self) -> None:
    15.         self.driver.quit()


    16. if __name__ == '__main__':
    17.     unittest.main()
    复制代码
    以上示例中,传递数据的格式为元组,元组中包含了三个元素,浏览器共打开了三次,而三次中分别输入了java、selenium、python,很显然可以看出,代码中只编写了一次测试用例,而实际结果中却执行了三次,减少了代码的冗余,实现了不同的输入条件执行相同的测试用例。
      ddt.data在使用过程中,需要注意一下几点:
      (1)导包:import ddt;
      (2)在测试类之前加装饰方法:@ddt.ddt;
      (3)在测试用例之前加 @ddt.data(),传入数据。

      2. ddt.unpack方法
      我们再看一个示例,如下:
    1. import unittest
    2. from selenium import webdriver
    3. import time
    4. import ddt

    5. @ddt.ddt
    6. class UnitForTestddt(unittest.TestCase):

    7.     def setUp(self) -> None:
    8.         self.driver = webdriver.Chrome()
    9.         self.driver.get('http://www.baidu.com')

    10.     @ddt.data(['java', '123456'], ['python', '666666'])
    11.     @ddt.unpack
    12.     def test_ddt1(self, username, pwd):
    13.         self.driver.find_element_by_id('kw').send_keys(username)
    14.         time.sleep(1)
    15.         self.driver.find_element_by_id('kw').clear()
    16.         time.sleep(1)
    17.         self.driver.find_element_by_id('kw').send_keys(pwd)
    18.         time.sleep(1)

    19.     def tearDown(self) -> None:
    20.         self.driver.quit()

    21. if __name__ == '__main__':
    22.     unittest.main()
    复制代码
     当我们传递的内容为list列表时,需要添加@ddt.unpack进行解包,否则会运行错误,示例中传递了两个list,用例执行了两次,分别将java、python传递给了username,将123456,666666传递给了pwd。

      3. 从文件中读取数据
      在实际项目中,一般测试数据都比较多,测试数据都会写在文件中,下面我们以.txt文件为例,介绍一下如何从文件中读取数据。
      在当前包下新建一个testdata.txt文件,文件的内容如下:
    1. java,123456
    2. python,666666
    3. selenium,777777
    复制代码
    现在在测试用例中读取testdata.txt中的数据,代码如下:
    1. import unittest
    2. from selenium import webdriver
    3. import time
    4. import ddt

    5. @ddt.ddt
    6. class UnitForTestddt(unittest.TestCase):
    7.     # 读取文件内容
    8.     def read_file():
    9.         file = open('testdata.txt', 'r', encoding='utf-8')
    10.         li = []
    11.         for line in file.readlines():
    12.             li.append(line.strip('\n').split(','))
    13.             file.close()
    14.         return li

    15.     def setUp(self) -> None:
    16.         self.driver = webdriver.Chrome()
    17.         self.driver.get('http://www.baidu.com')

    18.     # 一个*表示以元祖的形式去解读,两个*表示以字典的形式去解读
    19.     @ddt.data(*read_file())
    20.     @ddt.unpack
    21.     def test_ddt1(self, username, pwd):
    22.         self.driver.find_element_by_id('kw').send_keys(username)
    23.         time.sleep(1)
    24.         self.driver.find_element_by_id('kw').clear()
    25.         time.sleep(1)
    26.         self.driver.find_element_by_id('kw').send_keys(pwd)
    27.         time.sleep(1)

    28.     def tearDown(self) -> None:
    29.         self.driver.quit()

    30. if __name__ == '__main__':
    31.     unittest.main()
    复制代码
    以上读取txt文件的方式,是基于Python中open方法、readlines方法等原本的处理方式去读取,并未实现完全的兼容,而ddt中直接兼容了yaml文件的读取。

      4. 从YAML文件中读取数据(file_data)
      首先yaml的安装:pip install pyyaml
      在当前包下新建一个testdata.yaml文件,文件的内容(编写时注意格式)如下:


    1. -
    2.   username: java
    3.   pwd: 123456
    4. -
    5.   username: python
    6.   pwd: 666666
    7. -
    8.   username: selenium
    9.   pwd: 777777
    复制代码

      现在在测试用例中读取testdata.yaml中的数据,代码如下:


    1. import unittest
    2. from selenium import webdriver
    3. import time
    4. import ddt

    5. @ddt.ddt
    6. class UnitForTestddt(unittest.TestCase):

    7.     def setUp(self) -> None:
    8.         self.driver = webdriver.Chrome()
    9.         self.driver.get('http://www.baidu.com')

    10.     # 读取文件中的数据
    11.     @ddt.file_data('testdata.yaml')
    12.     def test_ddt(self,**user):
    13.         self.driver.find_element_by_id('kw').send_keys(user.get('username'))
    14.         time.sleep(1)
    15.         self.driver.find_element_by_id('kw').clear()
    16.         time.sleep(1)
    17.         self.driver.find_element_by_id('kw').send_keys(user.get('pwd'))
    18.         time.sleep(1)

    19.     def tearDown(self) -> None:
    20.         self.driver.quit()

    21. if __name__ == '__main__':
    22.     unittest.main()
    复制代码
     七、UnitTest生成测试报告(HTMLTestRunner)
      批量执行完用例后,生成的测试报告是文本形式的,不够直观,为了更好的展示测试报告,最好是生成HTML格式的。unittest里面是不能生成html格式报告的,需要导入一个第三方的模块:HTMLTestRunner。

      环境搭建
      (1)下载HTMLTestRunner.py,导入到Python中的lib文件夹下;
      (2)修改部分源码
      由于HTMLTestRunner.py是基于python2开发,为了使其支持python3的环境,需要对其内容进行部分修改;
    1. #第94行
    2. import StringIO 修改为:import io

    3. #第539行
    4. self.outputBuffer = StringIO.StringIO() 修改为:self.outputBuffer = io.StringIO()

    5. #第631行
    6. print >>sys.stderr, '\nTime Elapsed: %s' % (self.stopTime-self.startTime)修改为:print(sys.stderr, '\nTime Elapsed: %s' % (self.stopTime-self.startTime))

    7. #第642行
    8. if not rmap.has_key(cls):修改为:if not cls in rmap:

    9. #第766行
    10. uo = o.decode('latin-1')修改为:uo = o

    11. #第772行
    12. ue = e.decode('latin-1')修改为:ue = e
    复制代码

    (3)导包:from HTMLTestRunner import HTMLTestRunner。
      示例代码如下:
    1. # 导入unittest的包
    2. import unittest
    3. # 导入测试类
    4. from unittest_demo.unit_for_testA import UnitForTestA
    5. # 导入生成报告所需要的包
    6. from HTMLTestRunner import HTMLTestRunner
    7. import os
    8. # 创建一个测试套件
    9. suite = unittest.TestSuite()

    10. # 添加测试用例的第二种方法
    11. cases = [UnitForTestA('test_1'), UnitForTestA('test_2'), UnitForTestA('test_3')]

    12. # 集成测试报告
    13. report_name = '测试报告名称'
    14. report_title = '测试报告标题'
    15. report_desc = '测试报告描述'
    16. report_path = './report/'
    17. report_file = report_path + 'report.html'
    18. if not os.path.exists(report_path):
    19.     os.mkdir(report_path)
    20. else:
    21.     pass
    22. with open(report_file, 'wb') as report:
    23.     suite.addTests(cases)
    24.     runner = HTMLTestRunner(stream=report, title=report_title, description=report_desc)
    25.     runner.run(suite)
    复制代码

     执行完成后,在当前的目录下会生成一个report/report.html文件,通过浏览器打开,界面如下:


      八、后记
      以上是作为一个测试小白关于python中UnitTest的理解,烦请各位大佬们不吝赐教,在软件测试方面我还有很多很多知识要学习,希望未来一起加油!!!


    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏
    回复

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-10-7 00:46 , Processed in 0.069280 second(s), 23 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表