Selenium自动化测试-unittest单元测试框架使用

一、什么是unittest

这里我们将要用的unittest是python的单元测试框架,它的官网是

https://docs.python.org/2/library/unittest.html,在这里我们可以得到全面的信息。

当我们写的用例越来越多时,我们就需要考虑用例编写的规范与组织,以便于后期的维护,而unittest正是这样一款工具。我们这里用一个示例来展示用unittest脚本是什么样子的

 1 # -*- coding: utf-8 -*-
 2 from selenium import webdriver
 3 from selenium.webdriver.common.by import By
 4 from selenium.webdriver.common.keys import Keys
 5 from selenium.webdriver.support.ui import Select
 6 from selenium.common.exceptions import NoSuchElementException
 7 from selenium.common.exceptions import NoAlertPresentException
 8 #导入unittest包
 9 import unittest, time, re
10
11 #SearchTest类继承自unittest.TestCase,表明这是一个测试案例
12 class SearchTest(unittest.TestCase):
13     #setUp用于初始化工作
14     def setUp(self):
15         self.driver = webdriver.Firefox()
16         self.driver.implicitly_wait(30)
17         self.base_url = "https://www.baidu.com/"
18         self.verificationErrors = []
19         self.accept_next_alert = True
20
21     #以test开头的是我们的测试脚本
22     def test_search(self):
23         driver = self.driver
24         driver.get(self.base_url + "/")
25         driver.find_element_by_id("kw").click()
26         driver.find_element_by_id("kw").clear()
27         driver.find_element_by_id("kw").send_keys("selenium2")
28         driver.find_element_by_id("su").click()
29
30     def is_element_present(self, how, what):
31         try: self.driver.find_element(by=how, value=what)
32         except NoSuchElementException as e: return False
33         return True
34
35     def is_alert_present(self):
36         try: self.driver.switch_to_alert()
37         except NoAlertPresentException as e: return False
38         return True
39
40     def close_alert_and_get_its_text(self):
41         try:
42             alert = self.driver.switch_to_alert()
43             alert_text = alert.text
44             if self.accept_next_alert:
45                 alert.accept()
46             else:
47                 alert.dismiss()
48             return alert_text
49         finally: self.accept_next_alert = True
50
51     #在每个测试方法后执行,完成清理工作
52     def tearDown(self):
53         self.driver.quit()
54         self.assertEqual([], self.verificationErrors)
55
56 #整个测试过程集中在unittest的main()模块中,其默认执行以test开头的方法
57 if __name__ == "__main__":
58     unittest.main()

通过这个我们大概对unittest有个直观的了解了。unittest.main():使用它可以将一个单元测试模块变为可直接运行的测试脚本,main()方法使用TestLoader类来搜索所有包含在该模块中以“test”命名开头的测试方法,并自动执行。执行方法的默认顺序是:根据ASCII码的顺序加载测试用例,数字与字母的顺序为:0-9,A-Z,a-z。所以以A开头的测试用例方法会优先执行,以a开头会后执行。

二、unittest中的概念

TestCase:

一个Testcase的实例就是一个测试用例,测试用例就是一个完整的测试流程,包括初始化setUp、运行run、测试后的还原tearDown。unittest.TestCase类,所有测试用例类继承的基本类。此类提供了很多assert方法用于检查比较,部分如下:

多数方法都可以见其名知其意,使用的门槛很低。

TestSuite:

对一个功能的测试往往需要多测试用例的,可以把多的测试用例集合在一起执行,这就是TestSuite的概念。常用addTest()方法将一个测试用例添加到测试套件中。

TextTestRunner:

是用来执行测试用例的,其中的run(test)用来执行TestSuite/TestCase。测试的结果会保存在TextTestResult实例中。

TestFixture:

测试准备前要做的工作和测试执行完后要做的工作.包括setUp()和tearDown()。通过覆盖TestCase的setUp和tearDown来实现。

知道了这几个主要的概念,我们就可以把上面的脚本中的最后一行unittest.main(),改为以下代码:

1  #构造测试套件
2     suite = unittest.TestSuite()
3     suite.addTest(SearchTest("test_search"))
4     #执行测试
5     runner = unittest.TextTestRunner()
6     runner.run(suite)

执行之后发现和之前用unittest.main()的结果一样。

三、用例组织

这里我们假设,脚本当中有多个TestCase如test_case1,test_case2…,那我们应该怎样去控制它们的执行顺序呢?

执行测试用例方案一:

直接用

unittest.main()

执行,这里它搜索所有以test开头的测试用例方法,按照ASCII的顺序执行多个用例。

执行测试用例方案二:

先实例化测试套件,将用例加载进去,再用TextTestRunner去执行用例:

1  suite=unittest.TestSuite()
2  suite.addTest(Test(‘test_case2‘))
3  suite.addTest(Test(‘test_case1‘))
4  runner=unittest.TextTestRunner()
5  runner.run(suite)

执行的顺序是用例的加载顺序,比如这里是先执行2后执行1。

执行测试用例方案三:

在方案2中,如果我们有成百上千个用例的话,一个一个add进去,是不太现实的,那么我们可以用defaultTestLoader来加载:

1     test_dir = ‘./‘
2     discover = unittest.defaultTestLoader.discover(test_dir, pattern=‘*test.py‘)
3     runner = unittest.TextTestRunner()
4     runner.run(discover)

这里用./指定了当前目录,指定了*test.py文件,对其当中的用例进行执行,顺序和方案一相同。

如果这里指定的目录下面有多个经pattern匹配上的.py文件呢?调用discover方法,首先通过test_dir定义查找目录,如果文件名满足定义的pattern,那么我们要用for循环来找出所有被筛选出来的用例,并将其循环加到套件中,主要代码如下:

1  for test_suite in discover:
2         for test_case in test_suite:
3             test_unit.addTests(test_case)

由上面组织用例的方式我们可以知道,在实际的测试用脚本开发中,我们可以在目录下创建xx.py的文件,当用例稳定运行后,可以修改成test_xx.py,以便于添加到测试套件中。注意,文件名的匹配规则,我们可以随便由pattern参数定义。

如果要执行多级目录结构的用例呢?要想被discover读取执行,我们要在目录下加_ init _.py文件

四、一个例子

下面简单的介绍一个用unittest组织的用例结构,先建立D:\Test_Project目录,下面放上test_case和test_report来分别存放用例和报告。

1. 编写测试用例

在test_case下面编写用例,如下简单的示范了在百度上搜索关键字和点击设置的操作:

 1 文件名为:test_baidu.py
 2
 3 # -*- coding: utf-8 -*-
 4 from selenium import webdriver
 5 import unittest, time, re
 6
 7 class MyTest(unittest.TestCase):
 8
 9     def setUp(self):
10         self.driver = webdriver.Firefox()
11         self.driver.implicitly_wait(30)
12         self.base_url = "https://www.baidu.com"
13         self.accept_next_alert = True
14
15     def test_02baidu_search(self):
16         u‘‘‘ 测试百度搜索‘‘‘
17         driver = self.driver
18         driver.get(self.base_url + "/")
19         driver.find_element_by_id("kw").click()
20         driver.find_element_by_id("kw").clear()
21         driver.find_element_by_id("kw").send_keys("selenium-test")
22         driver.find_element_by_id("su").click()
23         print("test_baidu__test_02baidu_search")
24
25     def test_01baidu_setting(self):
26         u‘‘‘ 测试百度首页设置 ‘‘‘
27         driver = self.driver
28         driver.get(self.base_url + "/")
29         driver.find_element_by_css_selector("div#u1 a.pf").click()
30         driver.find_element_by_class_name("setpref").click()
31         driver.find_element_by_css_selector("div#gxszButton>a.prefpanelgo").click()
32         driver.switch_to_alert().accept()
33         print("test_baidu__test_01baidu_setting")
34
35     def tearDown(self):
36         self.driver.close()
37
38 #从all_test中调用时,可以不要这个
39 if __name__ == "__main__":
40     unittest.main()

为了显示出组织测试用例的效果,我们将此文件再复制一份,把文件名和方法名等修改一下:

 1 文件名为:test_baidu2.py
 2
 3 # -*- coding: utf-8 -*-
 4 from selenium import webdriver
 5 import unittest, time, re
 6
 7 class MyTest(unittest.TestCase):
 8     u‘‘‘ 测试baidu的第二个用例‘‘‘
 9     def setUp(self):
10         self.driver = webdriver.Firefox()
11         self.driver.implicitly_wait(30)
12         self.base_url = "https://www.baidu.com"
13         self.accept_next_alert = True
14
15     def test_02baidu_search(self):
16         u‘‘‘ 测试baidu的第二个用例的test_02baidu_search‘‘‘
17         driver = self.driver
18         driver.get(self.base_url + "/")
19         driver.find_element_by_id("kw").click()
20         driver.find_element_by_id("kw").clear()
21         driver.find_element_by_id("kw").send_keys("selenium-test")
22         driver.find_element_by_id("su").click()
23         print("test_baidu2__test_02baidu_search")
24
25
26     def test_01baidu_setting(self):
27         u‘‘‘ 测试baidu的第二个用例的test_01baidu_setting‘‘‘
28         driver = self.driver
29         driver.get(self.base_url + "/")
30         driver.find_element_by_css_selector("div#u1 a.pf").click()
31         driver.find_element_by_class_name("setpref").click()                        driver.find_element_by_css_selector("div#gxszButton>a.prefpanelgo").click()
32         driver.switch_to_alert().accept()
33         print("test_baidu2__test_01baidu_setting")
34
35     def tearDown(self):
36         self.driver.close()
37
38 if __name__ == "__main__":
39     unittest.main()

2. 美化报告样式和发送结果邮件

上面我们写了 两个测试用例作为示例,我们也可以添加更多的进去。接着我们使用HTMLTestRunner这个开源模块来美化测试报告,关于它的下载使用可以参考https://pypi.python.org/pypi/HTMLTestRunner。然后,我们可以在代码中写上运行完成之后自动发送测试邮件出来,便于我们查看。请参看以下代码:

 1 #coding=utf-8
 2 import unittest
 3 import smtplib
 4 from email.mime.text import MIMEText
 5 from email.header import Header
 6 import time
 7 import HTMLTestRunner
 8 from email.mime.application import MIMEApplication
 9
10 #---发送邮件---
11 def send_email(report_file):
12     sender = "[email protected]"
13     receiver = "[email protected]"
14     smtpserver = "smtp.qq.com"
15     #发送邮箱的账号密码,此处使用的是qq邮箱和第三方登录的授权码
16     username = "[email protected]"
17     password = "gfomcomojtuudijc"
18
19     #定义邮件正文
20     file = open(report_file,"rb")
21     mail_body = file.read()
22     file.close()
23
24     msg = MIMEText(mail_body, _subtype="html", _charset="utf-8")
25     msg["Subject"] = u"自动化测试报告"
26
27     smtp = smtplib.SMTP_SSL("smtp.qq.com")
28     smtp.login(username, password)
29     smtp.sendmail(sender, receiver, msg.as_string())
30     smtp.quit()
31     print("Email has send out !")
32
33 #---将用例添加到测试套件---
34 def creatsuite():
35     testunit=unittest.TestSuite()
36     test_dir = "D:\\Test_Project\\test_case"
37     discover = unittest.defaultTestLoader.discover(test_dir, pattern="test*.py",
38                                                  top_level_dir = None)
39     for test_suite in discover:
40         for test_case in test_suite:
41             testunit.addTest(test_case)
42             print (testunit)
43     return testunit
44
45 if __name__ == "__main__":
46     current_time = time.strftime("%Y-%m-%d-%H-%M")
47     report_dir = "D:\\Test_Project\\test_report\\"
48     report_file = report_dir + current_time + "-Test_Result.html"
49     report_stream = open(report_file, "wb")
50     # runner = unittest.TextTestRunner()
51     # 注意HTMLTestRunner只支持python2
52     runner = HTMLTestRunner.HTMLTestRunner(stream=report_stream,title=u"自动化测试报告",  description=u"用例执行情况如下:")
53     runner.run(creatsuite())
54     report_stream.close()
55     send_email(report_file)

在上面的代码中我们使用了runner = HTMLTestRunner.HTMLTestRunner()方法来代替runner = unittest.TextTestRunner(),是为了使用HTMLTestRunner这个模块来美化和输出美观的报告。然后调用方法来发送邮件。运行此文件后,可以得到以下输出的报告:

可以看见使用这个可以清晰的看到用例的执行情况,也便于查看失败用例的原因去调试它。 
同时,在我们输入的收件箱里也会受到一份通知邮件,我们可以将此输出报告添加到邮件的正文或附件中,以便于查看
 

原文地址:https://www.cnblogs.com/linuxchao/p/linuxchao-unittest.html

时间: 2024-10-31 16:33:54

Selenium自动化测试-unittest单元测试框架使用的相关文章

Selenium基于Python web自动化基础二 -- 免登录、等待及unittest单元测试框架

一.免登录在进行测试的过程中难免会遇到登录的情况,给测试工作添加了工作量,本文仅提供一些思路供参考解决方式:手动请求中添加cookies.火狐的profile文件记录信息实现.人工介入.万能验证码.去掉验证码 1.手动在请求中添加cookies信息 1 url = "http://www.baidu.com" 2 driver = webdriver.Firefox() 3 driver.get(url) 4 time.sleep(3) 5 #添加cookies的方式 6 7 c1 =

Python+Selenium ----unittest单元测试框架

unittest是一个单元测试框架,是Python编程的单元测试框架.有时候,也做叫做"PyUnit",是Junit的Python语言版本.这里了解下,Junit是Java语言的单元测试框架,Java还有一个很好用的单元测试框架叫TestNG,本系列只学习Python,所以只需要unittest是Python里的一个单元测试框架就可以了.       unittest支持测试自动化,共享测试用例中的初始化和关闭退出代码,在unittest中最小单元是test,也就是一个测试用例.要了解

第 6 章 unittest 单元测试框架 - Selenium3 自动化测试

第 6 章 unittest 单元测试框架 单元测试是一项对技术要求很高的工作,只有白盒测试人员和软件开发人员才能胜任但用单元测试框架做单元测试却十分简单,而且单元测试框架不仅可以用来做单元测试,它还适用于不同类型的「自动化」测试. 1.提供测试用例组织和执行在 Python 中,我们编写的代码可以定义类.方法和函数,那么如何定义一条「测试用例」?如何灵活地控制这些「测试用例」的执行?单元测试框架会告诉我们. 2.提供丰富的断言方法当我们进行功能测试时,测试用例需要有预期结果.当测试用例的执行结

Python基础入门-unittest单元测试框架

unittest单元测试框架不仅可以适用于单元测试,还可以适用WEB自动化测试用例的开发与执行,该测试框架可组织执行测试用例,并且提供了丰富的断言方法,判断测试用例是否通过,最终生成测试结果.今天笔者就总结下如何使用unittest单元测试框架来进行WEB自动化测试. 目录 一.unittest模块的各个属性说明 二.使用unittest框架编写测试用例思路 三.使用unittest框架编写测试用例实例 一.unittest模块的各个属性说明 先来聊一聊unittest模块的各个属性,所谓知己知

unittest单元测试框架总结

unittest单元测试框架不仅可以适用于单元测试,还可以适用WEB自动化测试用例的开发与执行,该测试框架可组织执行测试用例,并且提供了丰富的断言方法,判断测试用例是否通过,最终生成测试结果.今天笔者就总结下如何使用unittest单元测试框架来进行WEB自动化测试. 目录 一.unittest模块的各个属性说明 二.使用unittest框架编写测试用例思路 三.使用unittest框架编写测试用例实例 一.unittest模块的各个属性说明 点击返回目录 先来聊一聊unittest模块的各个属

15. Unittest单元测试框架的介绍与使用

?什么是单元测试 在计算机编程中,单元测试(英语:Unit Testing)又称为模块测试, 是针对程序模块(软件设计的最小单位)来进行正确性检验的测试工作.程序单元是应用的最小可测试部件.在过程化编程中,一个单元就是单个程序.函数.过程等:对于面向对象编程,最小单元就是方法,包括基类(超类).抽象类.或者派生类(子类)中的方法. 上面这段内容摘自维基百科.笔者在入职的时候,一直搞不明白什么是单元测试.即使搜了很多资料,也还是搞不明白.一直到接触代码的时候,才对单元测试有了一个大概的认识.当然以

python3+unittest单元测试框架

#unittest单元测试框架,主要由四部分组成:测试固件.测试用例.测试套件.测试执行器 #1.测试固件: '''def setUp(self): # 每条用例执行前都要执行,例如测试前的准备工作 print('setup') def tearDown(self): # 每条用例执行后都要执行,例如测试执行完成后的清除配置工作 print('tearDown') ''' #例如: 1 import unittest 2 3 def calc(a,b): 4 return a+b 5 6 cla

unittest单元测试框架小白入门

unittest单元测试框架: 一般也称为pyunit,是从java程序中广泛应用的junit启发而来的,unittest使我们具备创建测试用例,测试套件,测试·夹具的能力.unittest组件:1):Test fixture(测试夹具): 使用测试夹具,可以定义在单个或多个测试执行之前的准备工作和执行之后的清理工作.2)Test Case(测试用例):unittest中执行测试的最小单元,通过验证unittest提供的assert方法来验证一组特定的操作和输入以后得到的响应,unittest提

基于appium实现的线性代码引用unittest单元测试框架

在前段时间,分享了几篇关于appium基础的博文,再加上期间也有讲到unittest测试框架,所以今天就来一个专题,在appium+python实现的线性代码基础上,引入unittest框架,使代码更简洁. 之前的博客,可以见以下链接快速阅读: 基于Python的Appium环境搭建合集 Genymotion模拟器的安装及脚本制作 Appium Python API 中文版 Appium-Server与Appium-Desktop的区别 单元测试框架Uinttest一文详解 在以上博文中,代码示