软件测试教程 自动化测试selenium篇(三)

软件测试教程 自动化测试selenium篇(三)


之前讲解了selenium的脚本录制和api。在进行脚本录制导出的脚本中,我们发现其中多了很多代码,这些代码正是unittest测试框架。

class chandao(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Firefox()
        self.driver.implicitly_wait(30)
        self.base_url = "http://127.0.0.1/"
        self.verificationErrors = []
        self.accept_next_alert = True

现在我们编写了单独的脚本,但是我们还缺少以下的部分,只有当有了以下部分,才能将自动化测试组织起来并持续进行。

批量执行

参数化

断言

测试报告

本课程将围绕unittest来介绍测试框架。

unittest框架解析

批量执行脚本

unittest断言

HTML报告生成

异常捕捉与错误截图

数据驱动

unittest框架解析

unittest 是python 的单元测试框架, 在python 的官方文档中,对unittest有详细的介绍,想更深一步研究的同学可以到https://www.python.org/doc/ 去了解。

unittest 单元测试提供了创建测试用例,测试套件以及批量执行的方案, unittest 在安装pyhton 以后就直接自带了,直接import unittest 就可以使用。

作为单元测试的框架, unittest 也是可以对程序最小模块的一种敏捷化的测试。在自动化测试中,我们虽然不需要做白盒测试,但是必须需要知道所使用语言的单元测试框架。利用单元测试框架,创建一个类,该类继承unittest 的TestCase,这样可以把每个case看成是一个最小的单元, 由测试容器组织起来,到时候直接执行,同时引入测试报告。

unittest 各组件的关系为:

image.png
  • test fixture:初始化和清理测试环境,比如创建临时的数据库,文件和目录等,其中 setUp()setDown() 是最常用的方法
  • test case:单元测试用例,TestCase 是编写单元测试用例最常用的类
  • test suite:单元测试用例的集合,TestSuite 是最常用的类
  • test runner:执行单元测试
  • test report:生成测试报告
# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import NoAlertPresentException
import unittest, time, re

class Baidu1(unittest.TestCase):
#test fixture,初始化环境
    def setUp(self):
        self.driver = webdriver.Firefox()
        self.driver.implicitly_wait(30)
        self.base_url = "http://www.baidu.com/"
        self.verificationErrors = []
        self.accept_next_alert = True
 
 #测试用例,必须以test开头  
 
    def test_baidusearch(self):
        driver = self.driver
        driver.get(self.base_url + "/")
        driver.find_element_by_id("kw").click()
        driver.find_element_by_id("kw").clear()
        driver.find_element_by_id("kw").send_keys(u"测试")
        driver.find_element_by_id("su").click()
        driver.find_element_by_id("su").click()
      
    def test_hao(self):
        driver = self.driver
        driver.get(self.base_url + "/")
        driver.find_element_by_link_text("hao123").click()
        self.assertEqual(u"hao123_上网从这里开始", driver.title)
 #判断element是否存在,可删除   
    def is_element_present(self, how, what):
        try: self.driver.find_element(by=how, value=what)
        except NoSuchElementException as e: return False
        return True
 #判断alert是否存在,可删除      
    def is_alert_present(self):
        try: self.driver.switch_to_alert()
        except NoAlertPresentException as e: return False
        return True
 #关闭alert,可删除     
    def close_alert_and_get_its_text(self):
        try:
            alert = self.driver.switch_to_alert()
            alert_text = alert.text
            if self.accept_next_alert:
                alert.accept()
            else:
                alert.dismiss()
            return alert_text
        finally: self.accept_next_alert = True
 #test fixture,清除环境   
    def tearDown(self):
        self.driver.quit()
        self.assertEqual([], self.verificationErrors)

if __name__ == "__main__":
#执行用例
    unittest.main()

'''
可以增加verbosity参数,例如unittest.main(verbosity=2)
在主函数中,直接调用main() ,在main中加入verbosity=2 ,这样测试的结果就会显示的更加详细。
这里的verbosity 是一个选项, 表示测试结果的信息复杂度,有三个值:
0 ( 静默模式): 你只能获得总的测试用例数和总的结果比如总共100个失败,20 成功80
1 ( 默认模式): 非常类似静默模式只是在每个成功的用例前面有个“ . ” 每个失败的用例前面有个“F”
2 ( 详细模式): 测试结果会显示每个测试用例的所有相关的信息
'''

批量执行脚本

构建测试套件

完整的单元测试很少只执行一个测试用例,开发人员通常都需要编写多个测试用例才能对某一软件功能进行比较完整的测试,这些相关的测试用例称为一个测试用例集,在unittest中是用TestSuite 类来表示的。

假设我们已经编写了testbaidu1.py,testbaidu2.py两个文件,那么我们怎么同时执行这两个文件呢?

testbaidu1.py

# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import NoAlertPresentException
import unittest, time, re

class Baidu1(unittest.TestCase):
#test fixture,初始化环境
    def setUp(self):
        self.driver = webdriver.Firefox()
        self.driver.implicitly_wait(30)
        self.base_url = "http://www.baidu.com/"
        self.verificationErrors = []
        self.accept_next_alert = True
 
 #测试用例,必须以test开头  
 
    def test_baidusearch(self):
        driver = self.driver
        driver.get(self.base_url + "/")
        driver.find_element_by_id("kw").click()
        driver.find_element_by_id("kw").clear()
        driver.find_element_by_id("kw").send_keys(u"测试")
        driver.find_element_by_id("su").click()
        driver.find_element_by_id("su").click()
      
    def test_hao(self):
        driver = self.driver
        driver.get(self.base_url + "/")
        driver.find_element_by_link_text("hao123").click()
        self.assertEqual(u"hao123_上网从这里开始", driver.title)
 #判断element是否存在,可删除   
    def is_element_present(self, how, what):
        try: self.driver.find_element(by=how, value=what)
        except NoSuchElementException as e: return False
        return True
 #判断alert是否存在,可删除      
    def is_alert_present(self):
        try: self.driver.switch_to_alert()
        except NoAlertPresentException as e: return False
        return True
 #关闭alert,可删除     
    def close_alert_and_get_its_text(self):
        try:
            alert = self.driver.switch_to_alert()
            alert_text = alert.text
            if self.accept_next_alert:
                alert.accept()
            else:
                alert.dismiss()
            return alert_text
        finally: self.accept_next_alert = True
 #test fixture,清除环境   
    def tearDown(self):
        self.driver.quit()
        self.assertEqual([], self.verificationErrors)

if __name__ == "__main__":
#执行用例
    unittest.main()

testbaidu2.py

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import NoAlertPresentException
import unittest, time, re

class Baidu2(unittest.TestCase):
#test fixture,初始化环境
    def setUp(self):
        self.driver = webdriver.Firefox()
        self.driver.implicitly_wait(30)
        self.base_url = "http://www.baidu.com/"
        self.verificationErrors = []
        self.accept_next_alert = True
 
 #测试用例,必须以test开头  
 
    def test_baidusearch(self):
        driver = self.driver
        driver.get(self.base_url + "/")
        driver.find_element_by_id("kw").click()
        driver.find_element_by_id("kw").clear()
        driver.find_element_by_id("kw").send_keys(u"selenium")
        driver.find_element_by_id("su").click()
        driver.find_element_by_id("su").click()
      
 #判断element是否存在,可删除   
    def is_element_present(self, how, what):
        try: self.driver.find_element(by=how, value=what)
        except NoSuchElementException as e: return False
        return True
 #判断alert是否存在,可删除      
    def is_alert_present(self):
        try: self.driver.switch_to_alert()
        except NoAlertPresentException as e: return False
        return True
 #关闭alert,可删除     
    def close_alert_and_get_its_text(self):
        try:
            alert = self.driver.switch_to_alert()
            alert_text = alert.text
            if self.accept_next_alert:
                alert.accept()
            else:
                alert.dismiss()
            return alert_text
        finally: self.accept_next_alert = True
 #test fixture,清除环境   
    def tearDown(self):
        self.driver.quit()
        self.assertEqual([], self.verificationErrors)

if __name__ == "__main__":
#执行用例
    unittest.main()

addTest() 的应用

当有多个或者几百测试用例的时候, 这样就需要一个测试容器( 测试套件) ,把测试用例放在该容器中进行执行, unittest 模块中提供了TestSuite 类来生成测试套件,使用该类的构造函数可以生成一个测试套件的实例,该类提供了addTest来把每个测试用例加入到测试套件中。

将testbaidu1.py、testbaidu2.py、runall.py放在同一个目录testcase中

runall.py

# -*- coding: utf-8 -*-
import unittest,csv
import os,sys
import time
#导入testbaidu1,testbaidu2
import testbaidu1
import testbaidu2


#手工添加案例到套件,
def createsuite():
     suite = unittest.TestSuite()
     #将测试用例加入到测试容器(套件)中
     suite.addTest(testbaidu1.Baidu1("test_baidusearch"))
     suite.addTest(testbaidu1.Baidu1("test_hao"))
     suite.addTest(testbaidu2.Baidu2("test_baidusearch"))
     return suite
     
if __name__=="__main__":
     suite=createsuite()
     runner = unittest.TextTestRunner(verbosity=2)
     runner.run(suite)

上述做法有两个不方面的地方,阻碍脚本的快速执行,必须每次修改runall.py:

1)需要导入所有的py文件,比如import testbaidu1,每新增一个需要导入一个

2)addTest需要增加所有的testcase,如果一个py文件中有10个case,就需要增加10次

makeSuite()和TestLoader()的应用

在unittest 框架中提供了makeSuite() 的方法,makeSuite可以实现把测试用例类内所有的测试case组成的测试套件TestSuite ,unittest 调用makeSuite的时候,只需要把测试类名称传入即可。

TestLoader 用于创建类和模块的测试套件,一般的情况下,使TestLoader().loadTestsFromTestCase(TestClass) 来加载测试类。

runall.py

# -*- coding: utf-8 -*-
import unittest,csv
import os,sys
import time
import testbaidu1
import testbaidu2

#手工添加案例到套件,
def createsuite():

     suite = unittest.TestSuite()
     #将测试用例加入到测试容器(套件)中
     suite.addTest(unittest.makeSuite(testbaidu1.Baidu1))
     suite.addTest(unittest.makeSuite(testbaidu2.Baidu2))
     return suite
     '''
     suite1 = unittest.TestLoader().loadTestsFromTestCase(testbaidu1.Baidu1) 
     suite2 = unittest.TestLoader().loadTestsFromTestCase(testbaidu2.Baidu2) 
     suite = unittest.TestSuite([suite1, suite2])
     return suite
     '''
     
if __name__=="__main__":
     suite=createsuite()
     runner = unittest.TextTestRunner(verbosity=2)
     runner.run(suite)

经过makeSuite()和TestLoader()的引入,我们不用一个py文件测试类,只需要导入一次即可。

那么能不能测试类也不用每次添加指定呢?

discover()的应用

discover 是通过递归的方式到其子目录中从指定的目录开始, 找到所有测试模块并返回一个包含它们对象的TestSuite ,然后进行加载与模式匹配唯一的测试文件,discover 参数分别为discover(dir,pattern,top_level_dir=None)

runall.py

# -*- coding: utf-8 -*-
import unittest,csv
import os,sys
import time

#手工添加案例到套件,
def createsuite():
     discover=unittest.defaultTestLoader.discover('../testcase',pattern='test*.py',top_level_dir=None)
     print discover
     return discover
     
if __name__=="__main__":
     suite=createsuite()
     runner = unittest.TextTestRunner(verbosity=2)
     runner.run(suite)

用例的执行顺序

unittest 框架默认加载测试用例的顺序是根据ASCII 码的顺序,数字与字母的顺序为: 09,AZ,a~z 。

所以, TestAdd 类会优先于TestBdd 类被发现, test_aaa() 方法会优先于test_ccc() 被执行。对于测试目录与测试文件来说, unittest 框架同样是按照这个规则来加载测试用例。

addTest()方法按照增加顺序来执行。

忽略用例执行

@unittest.skip(u'The function was canceled, neglects to perform thecase')
# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import NoAlertPresentException
import unittest, time, re

class Baidu1(unittest.TestCase):
#test fixture,初始化环境
    def setUp(self):
        self.driver = webdriver.Firefox()
        self.driver.implicitly_wait(30)
        self.base_url = "http://www.baidu.com/"
        self.verificationErrors = []
        self.accept_next_alert = True

    @unittest.skip("skipping")
    def test_baidusearch(self):
        driver = self.driver
        driver.get(self.base_url + "/")
        driver.find_element_by_id("kw").click()
        driver.find_element_by_id("kw").clear()
        driver.find_element_by_id("kw").send_keys(u"测试")
        driver.find_element_by_id("su").click()
        driver.find_element_by_id("su").click()
      
    def test_hao(self):
        driver = self.driver
        driver.get(self.base_url + "/")
        driver.find_element_by_link_text("hao123").click()
        self.assertEqual(u"hao123_上网从这里开始", driver.title)
 #判断element是否存在,可删除   
    def is_element_present(self, how, what):
        try: self.driver.find_element(by=how, value=what)
        except NoSuchElementException as e: return False
        return True
 #判断alert是否存在,可删除      
    def is_alert_present(self):
        try: self.driver.switch_to_alert()
        except NoAlertPresentException as e: return False
        return True
 #关闭alert,可删除     
    def close_alert_and_get_its_text(self):
        try:
            alert = self.driver.switch_to_alert()
            alert_text = alert.text
            if self.accept_next_alert:
                alert.accept()
            else:
                alert.dismiss()
            return alert_text
        finally: self.accept_next_alert = True
 #test fixture,清除环境   
    def tearDown(self):
        self.driver.quit()
        self.assertEqual([], self.verificationErrors)

if __name__ == "__main__":
#执行用例
    unittest.main()

unittest断言

自动化的测试中, 对于每个单独的case来说,一个case的执行结果中, 必然会有期望结果与实际结果, 来判断该case是通过还是失败, 在unittest 的库中提供了大量的实用方法来检查预期值与实际值, 来验证case的结果, 一般来说, 检查条件大体分为等价性, 逻辑比较以及其他, 如果给定的断言通过, 测试会继续执行到下一行的代码, 如果断言失败, 对应的case测试会立即停止或者生成错误信息( 一般打印错误信息即可) ,但是不要影响其他的case执行。

unittest 的单元测试库提供了标准的xUnit 断言方法。下面是一些常用的断言

序号 断言方法 断言描述
1 assertEqual(arg1, arg2, msg=None) 验证arg1=arg2,不等则fail
2 assertNotEqual(arg1, arg2, msg=None) 验证arg1 != arg2, 相等则fail
3 assertTrue(expr, msg=None) 验证expr是true,如果为false,则fail
4 assertFalse(expr,msg=None) 验证expr是false,如果为true,则fail
5 assertIs(arg1, arg2, msg=None) 验证arg1、arg2是同一个对象,不是则fail
6 assertIsNot(arg1, arg2, msg=None) 验证arg1、arg2不是同一个对象,是则fail
7 assertIsNone(expr, msg=None) 验证expr是None,不是则fail
8 assertIsNotNone(expr, msg=None) 验证expr不是None,是则fail
9 assertIn(arg1, arg2, msg=None) 验证arg1是arg2的子串,不是则fail
10 assertNotIn(arg1, arg2, msg=None) 验证arg1不是arg2的子串,是则fail
11 assertIsInstance(obj, cls, msg=None) 验证obj是cls的实例,不是则fail
12 assertNotIsInstance(obj, cls, msg=None) 验证obj不是cls的实例,是则fail
举例:
self.assertEqual("admin", driver.find_element_by_link_text("admin").text)

可以通过IDE来添加断言:

image.png

HTML报告生成

脚本执行完毕之后,还需要看到HTML报告,下面我们就通过HTMLTestRunner.py 来生成测试报告。HTMLTestRunner支持python2.7。python3可以参见http://blog.51cto.com/hzqldjb/1590802来进行修改。

HTMLTestRunner.py 文件,下载地址:
http://tungwaiyip.info/software/HTMLTestRunner.html

下载后将其放在testcase目录中去或者放入...\Python27\Lib 目录下(windows)。

修改runall.py

# -*- coding: utf-8 -*-
import unittest,csv
import os,sys
import time
import HTMLTestRunner

#手工添加案例到套件,
def createsuite():
     discover=unittest.defaultTestLoader.discover('./testcase',pattern='test*.py',top_level_dir=None)
     print discover
     return discover
     
if __name__=="__main__":
     curpath=sys.path[0]
     #取当前时间
     now=time.strftime("%Y-%m-%d-%H %M %S",time.localtime(time.time()))

     if not os.path.exists(curpath+'/resultreport'):
          os.makedirs(curpath+'/resultreport')
          
     filename=curpath+'/resultreport/'+now+'resultreport.html'
     with open(filename,'wb') as fp:
     #出html报告
          runner=HTMLTestRunner.HTMLTestRunner(stream=fp,title=u'测试报告',description=u'用例执行情况',verbosity=2)
          suite=createsuite()
          runner.run(suite)

异常捕捉与错误截图

用例不可能每一次运行都成功,肯定运行时候有不成功的时候。如果可以捕捉到错误,并且把错误截图保存,这将是一个非常棒的功能,也会给我们错误定位带来方便。

例如编写一个函数,关键语句为driver.get_screenshot_as_file:

    def savescreenshot(self,driver,file_name):
        if not os.path.exists('./image'):
            os.makedirs('./image')
        now=time.strftime("%Y%m%d-%H%M%S",time.localtime(time.time()))
        #截图保存
        driver.get_screenshot_as_file('./image/'+now+'-'+file_name)
        time.sleep(1)

一个引用的例子:

testscreenshot.py

# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import NoAlertPresentException
import unittest, time, re
import os

class Baidu1(unittest.TestCase):
#test fixture,初始化环境
    def setUp(self):
        self.driver = webdriver.Firefox()
        self.driver.implicitly_wait(30)
        self.base_url = "http://www.baidu.com/"
        self.verificationErrors = []
        self.accept_next_alert = True
 
 #测试用例,必须以test开头  
       
    def test_hao(self):
        driver = self.driver
        driver.get(self.base_url + "/")
        driver.find_element_by_link_text("hao123").click()
        time.sleep(2)
        try:
            self.assertEqual(u'hao_上网从这里开始', driver.title)
        except:
            self.savescreenshot(driver,'hao.png')
            
 #判断element是否存在,可删除   
    def is_element_present(self, how, what):
        try: self.driver.find_element(by=how, value=what)
        except NoSuchElementException as e: return False
        return True
 #判断alert是否存在,可删除      
    def is_alert_present(self):
        try: self.driver.switch_to_alert()
        except NoAlertPresentException as e: return False
        return True
 #关闭alert,可删除     
    def close_alert_and_get_its_text(self):
        try:
            alert = self.driver.switch_to_alert()
            alert_text = alert.text
            if self.accept_next_alert:
                alert.accept()
            else:
                alert.dismiss()
            return alert_text
        finally: self.accept_next_alert = True
 #test fixture,清除环境   
    def tearDown(self):
        self.driver.quit()
        self.assertEqual([], self.verificationErrors)

    def savescreenshot(self,driver,file_name):
        if not os.path.exists('./image'):
            os.makedirs('./image')
        now=time.strftime("%Y%m%d-%H%M%S",time.localtime(time.time()))
        #截图保存
        driver.get_screenshot_as_file('./image/'+now+'-'+file_name)
        time.sleep(1)

if __name__ == "__main__":
#执行用例
    unittest.main()

'''
可以增加verbosity参数,例如unittest.main(verbosity=2)
在主函数中,直接调用main() ,在main中加入verbosity=2 ,这样测试的结果就会显示的更加详细。
这里的verbosity 是一个选项, 表示测试结果的信息复杂度,有三个值:
0 ( 静默模式): 你只能获得总的测试用例数和总的结果比如总共100个失败,20 成功80
1 ( 默认模式): 非常类似静默模式只是在每个成功的用例前面有个“ . ” 每个失败的用例前面有个“F”
2 ( 详细模式): 测试结果会显示每个测试用例的所有相关的信息
'''

数据驱动

之前我们的case都是数据和代码在一起编写。考虑如下场景:

需要多次执行一个案例,比如baidu搜索,分别输入中文、英文、数字等进行搜索,这时候需要编写3个案例吗?有没有版本一次运行?

python 的unittest 没有自带数据驱动功能。所以如果使用unittest,同时又想使用数据驱动,那么就可以使用DDT来完成。

ddt的安装:

pip install ddt

ddt使用方法:

参考文档:http://ddt.readthedocs.io/en/latest/

dd.ddt:

装饰类,也就是继承自TestCase的类。

ddt.data:

装饰测试方法。参数是一系列的值。

ddt.file_data:

装饰测试方法。参数是文件名。文件可以是json 或者 yaml类型。

注意,如果文件以”.yml”或者”.yaml”结尾,ddt会作为yaml类型处理,其他所有文件都会作为json文件处理。

如果文件中是列表,每个列表的值会作为测试用例参数,同时作为测试用例方法名后缀显示。

如果文件中是字典,字典的key会作为测试用例方法的后缀显示,字典的值会作为测试用例参数。

ddt.unpack:

传递的是复杂的数据结构时使用。比如使用元组或者列表,添加unpack之后,ddt会自动把元组或者列表对应到多个参数上。字典也可以这样处理。

下面看一个样例:

test_data_list.json:

[
    "Hello",
    "Goodbye"
]

Testddt.py:

# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import NoAlertPresentException
import unittest, time, re
import os,sys,csv
from ddt import ddt, data, unpack ,file_data

def getCsv(file_name):
    rows=[]
    path=sys.path[0].replace('\\test_case','')
    print path
    
    with open(path+'/data/'+file_name,'rb') as f:
        readers=csv.reader(f,delimiter=',',quotechar='|')
        next(readers,None)
        for row in readers:
            temprows=[]
            for i in row:
                temprows.append(i.decode('gbk'))
            rows.append(temprows)
    return rows
#引入ddt
@ddt
class Testddt(unittest.TestCase):
#test fixture,初始化环境
    def setUp(self):
        self.driver = webdriver.Firefox()
        self.driver.implicitly_wait(30)
        self.base_url = "http://www.baidu.com/"
        self.verificationErrors = []
        self.accept_next_alert = True
 
 #测试用例,必须以test开头
    #增加ddt数据
    #@data('selenium',u'测试中文','9999999999')
    @data(*getCsv('test_baidu_data.csv'))
    #使用file_data需要在cmd窗口下运行,否则找不到文件
    #@file_data('test_data_list.json')
    @unpack
    def test_hao(self,value,expected_value):
    #def test_hao(self,value):
        driver = self.driver
        driver.get(self.base_url + "/")
        driver.find_element_by_id("kw").clear()
        driver.find_element_by_id("kw").send_keys(value)
        driver.find_element_by_id("su").click()
        time.sleep(2)
        self.assertEqual(expected_value, driver.title)
            
 #判断element是否存在,可删除   
    def is_element_present(self, how, what):
        try: self.driver.find_element(by=how, value=what)
        except NoSuchElementException as e: return False
        return True
 #判断alert是否存在,可删除      
    def is_alert_present(self):
        try: self.driver.switch_to_alert()
        except NoAlertPresentException as e: return False
        return True
 #关闭alert,可删除     
    def close_alert_and_get_its_text(self):
        try:
            alert = self.driver.switch_to_alert()
            alert_text = alert.text
            if self.accept_next_alert:
                alert.accept()
            else:
                alert.dismiss()
            return alert_text
        finally: self.accept_next_alert = True
 #test fixture,清除环境   
    def tearDown(self):
        self.driver.quit()
        self.assertEqual([], self.verificationErrors)

    def savescreenshot(self,driver,file_name):
        if not os.path.exists('./image'):
            os.makedirs('./image')
        now=time.strftime("%Y%m%d-%H%M%S",time.localtime(time.time()))
        #截图保存
        driver.get_screenshot_as_file('./image/'+now+'-'+file_name)
        time.sleep(1)
    

if __name__ == "__main__":
#执行用例
    unittest.main()

'''
可以增加verbosity参数,例如unittest.main(verbosity=2)
在主函数中,直接调用main() ,在main中加入verbosity=2 ,这样测试的结果就会显示的更加详细。
这里的verbosity 是一个选项, 表示测试结果的信息复杂度,有三个值:
0 ( 静默模式): 你只能获得总的测试用例数和总的结果比如总共100个失败,20 成功80
1 ( 默认模式): 非常类似静默模式只是在每个成功的用例前面有个“ . ” 每个失败的用例前面有个“F”
2 ( 详细模式): 测试结果会显示每个测试用例的所有相关的信息
'''
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,029评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,395评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,570评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,535评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,650评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,850评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,006评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,747评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,207评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,536评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,683评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,342评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,964评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,772评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,004评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,401评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,566评论 2 349

推荐阅读更多精彩内容