自动化测试框架的搭建
1、自动化测试框架
(1)概述:
自动化测试框架是应用于自动化测试的程序框架。它提供了可重用的自动化测试模块,提供最基础的自动化测试功能(如:打开浏览器、单击链接等功能),或提供自动化测试执行和管理功能的架构模块(如TestNG)。它是由一个或多个自动化测试基础模块、自动化测试管理模块、自动化测试统计模块等组成的工具集合。
(2)常见模式
>数据驱动测试框架:使用数据数组、测试数据文件或者数据库等方式作为测试过程输入的自动化测试框架
>关键字驱动测试框架:使用被操作的元素对象、操作的方法和操作的数据值作为测试过程输入的自动化测试框架
>混合型测试框架:在关键字驱动测试框架中加入了数据驱动
>行为驱动测试框架:支持自然语言作为测试用例描述的自动化测试框架
(3)作用:
>能够有效组织和管理测试脚本
>进行数据驱动或关键字驱动的测试
>将基础的测试代码进行封装,降低测试脚本编写的复杂性和重复性
>提高测试脚本维护和修改的效率
>自动执行测试脚本,并自动发布测试报告,为持续集成的开发方式提供脚本支持
>让不具备编程能力的测试工程师开展自动化测试工作
(4)自动化测试框架的设计核心思想
将常用的脚本代码或者测试逻辑进行抽象和总结,然后将这些代码进行面向对象设计,将需要重复的代码封装到可公用的类方法中。通过调用公用的类立法,测试类中的脚本复杂度会被大大降低,让更多脚本能力不强的测试人员来实施自动化测试。
创建和实施Web自动化测试框架的步骤如下:
1)根据测试业务的手工测试用例,选出需要可自动化执行的测试用例
2)根据可自动化执行的测试用例,分析出测试框架需要模拟的手工操作和重复高的测试流程或逻辑
3)将手工操作和重复高的测试逻辑在代码中实现,并在类中进行封装方法的编写
4)根据测试业务的类型和本身技术能力,选择数据驱动框架、关键字驱动框架、混合型框架还是行为驱动框架
5)确定框架模型后,将框架中常用的浏览器选择、测试数据处理、文件操作、数据库操作、页面元素的原始操作、日志和报告等功能进行类方法的封装实现
6)对框架代码进行集成测试和系统测试,采用PageObject模式和TestNG框架(或JUnit)编写测试脚本,使用框架进行自动化测试,验证框架的功能可以满足自动化测试的需求
7)编写自动化测试框架的常用 Api文档,以供他人参阅
8)在测试组内部进行培训和推广
9)不断收集测试过程中的框架使用问题和反馈意见,不断增加和优化自动化框架的功能,不断增强框架中复杂操作的封装效果,尽量降低测试脚本的编写复杂性。
10)定期评估测试框架的使用效果,评估自动化测试的投入产出比,再逐推广自动化框架的应用范围
2、数据驱动框架及实践
(1)框架大体包含目录:
新建一个工程,下面包含以下部分
1)Util包:封装常用的函数和功能(复用的)
Excel、时间、取元素、写日志、mapobject程序、解析ini文件,可选(截屏、建目录、文件操作、数据库操作等)
2)工程变量包
存放所有通用的变量或配置相关的变量
3)PageObject 包:一个页面一个类,里面有很多方法,方法是用于获取页面中的一个元素
如:login类 get_frame get_username get_password 等 返回页面元素对象
4)conf配置目录:存放所有的配置文件(日志的配置文件、定位元素的配置文件)
5)Action包:
login函数:所有登录的脚本逻辑
addContact : 添加联系人为脚本逻辑
6)可选的(截屏目录)
出错的截屏
(2)框架搭建步骤:
1)在PyCharm中新建一个工程:my_datadriven_frame
2)在工程my_datadriven_frame下新建一个包:Util
a、在Util下新增一个模块,即python模块:Excel.py 内容如下:
#encoding=utf-8 from openpyxl import * from openpyxl.styles import Font from FormatTime import data_time_chinese class ParseExcel(object): def __init__(self,excel_file_path): self.excel_file_path=excel_file_path self.workbook=load_workbook(excel_file_path) self.font=Font(color=None) self.colorDict={"red":'FFFF3030',"green":'FF008B00'} self.sheet=self.get_sheet_by_index(0) # 通过序号设置当前要操作的sheet,使用index来获取相应的sheet def set_sheet_by_index(self,sheet_index): self.sheet = self.get_sheet_by_index(sheet_index) # 通过名字设置操作的sheet def set_sheet_by_name(self,sheet_name): self.sheet = self.workbook.get_sheet_by_name(sheet_name) # 获取当前操作的sheet和title名字 def get_default_name(self): return self.sheet.title # 通过名字获取要操作的sheet def get_sheet_by_name(self,sheet_name): self.sheet = self.workbook.get_sheet_by_name(sheet_name) return self.sheet # 通过序号获取要操作的sheet def get_sheet_by_index(self, sheet_index): sheet_name = self.workbook.get_sheet_names()[sheet_index] self.sheet = self.get_sheet_by_name(sheet_name) return self.sheet #获取sheet中的最大行号,从0开始 def get_max_row_no(self): return self.sheet.max_row # 获取sheet中的最大列号,从0开始 def get_max_col_no(self): return self.sheet.max_column #获取默认sheet中的最小行号 def get_min_row_no(self): return self.sheet.min_row # 获取默认sheet中的最小列号 def get_min_col_no(self): return self.sheet.min_column #获取正在操作的sheet中的所有行对象 def get_all_rows(self): # rows = [] # for row in self.sheet.iter_rows(): # rows.append(row) # return rows #也可用以上方法 return list(self.sheet.iter_rows()) #获取正在操作的sheet中的所有列对象 def get_all_cols(self): # cols = [] # for col in self.sheet.iter_cols(): # cols.append(col) # return cols #也可用以上方法 return list(self.sheet.iter_cols()) #获取某一个行对象,第一行从0开始 def get_single_row(self,row_no): return self.get_all_rows()[row_no] # 获取某一个列对象,第一列从0开始 def get_single_col(self, col_no): return self.get_all_cols()[col_no] #获取某一个单元格对象,行号和列号从1开始 def get_cell(self,row_no,col_no): return self.sheet.cell(row = row_no,column = col_no) # 获取某一个单元格内容 def get_cell_content(self, row_no, col_no): return self.sheet.cell(row = row_no,column = col_no).value # 给某一个单元格写入指定内容,行号和列号从1开始 #调用此方法时,excel不要处于打开状态 def write_cell_content(self, row_no, col_no,content,font=None): self.sheet.cell(row=row_no,column=col_no).value = content self.workbook.save(self.excel_file_path) #给某个单元格写入当前时间,行号和列号从1开始 #调用此方法时,excel不要处于打开状态 def write_cell_current_time(self,row_no,col_no): self.sheet.cell(row=row_no,column=col_no).value = data_time_chinese() self.workbook.save(self.excel_file_path) def save_excel_file(self): self.workbook.save(self.excel_file_path) #保存所有对单元格的修改 if __name__ == "__main__": #测试所有的方法 pe = ParseExcel("D:\test\test.xlsx") pe.set_sheet_by_index(0) print pe.get_default_name() pe.set_sheet_by_name("2") print pe.get_default_name() print pe.get_sheet_by_name("2") print pe.get_sheet_by_index(0) print "max rows:",pe.get_max_row_no() print "min row",pe.get_min_row_no() print pe.get_all_rows() #获取所有行对象 print pe.get_all_rows()[2] #获取某一行 print pe.get_all_rows()[0][2] #获取某一个单元格 print pe.get_all_rows()[2][1].value #获取某一单元格的值 print "max cols:",pe.get_max_col_no() print "min col",pe.get_min_col_no() print pe.get_all_cols() #获取所有行对象 print pe.get_all_cols()[2] #获取某一行 print pe.get_all_cols()[0][2] #获取某一个单元格 print pe.get_all_cols()[2][1].value #获取某一单元格的值 print len(pe.get_all_rows()) for cell in pe.get_all_rows()[1]: print cell.value print len(pe.get_all_cols()) for cell in pe.get_all_cols()[2]: print cell.value print "================================" for cell in pe.get_single_col(0): print cell.value for cell in pe.get_single_row(0): print cell.value print "--------------------" print pe.get_cell(1,2) print pe.get_cell_content(1,1) pe.write_cell_content(5,6,"hello") print pe.get_cell_content(5,6) pe.write_cell_current_time(7,7) print pe.get_cell_content(7,7)
b、封装时间模块,FormatTime.py,内容如下:
#encoding=utf-8 import time #返回中文的年月日时分秒 def data_time_chinese(): return time.strftime("%Y年%m月%d日 %H时%M分%S秒",time.localtime()) #返回中文的时分秒 def time_chinese(): return time.strftime("%H时%M分%S秒", time.localtime()) # 返回英文的年月日时分秒 def data_time_english(): return time.strftime("%Y-%m-%d %H:%M:%S秒", time.localtime()) # 返回英文的时分秒 def time_english(): return time.strftime("%H:%M:%S秒", time.localtime()) if __name__ == "__main__": print data_time_chinese() print time_chinese() print data_time_english() print time_english()
c、封装日志模块,Log.py,内容如下:
#encoding=utf-8 import logging import logging.config from ProjectVar.var import * #读取日志的配置文件 logging.config.fileConfig(log_config_file_path) #选择一个日志格式 logger = logging.getLogger("example02") def info(message): #打印info级别的信息 logging.info(message) def error(message): #打印error级别的信息 logging.error(message) def warning(message): #打印warning级别的信息 logging.warning(message) if __name__ == "__main__": error("---ERROR---") info("===Test===") warning("````Wang`````")
d、封装获取页面元素模块,ObjectMap.py,内容如下:
#encoding=utf-8 from selenium.webdriver.support.ui import WebDriverWait import time #获取单个页面元素对象 def getElement(driver,locateType,locateExpression): try: element = WebDriverWait(driver,5).until(lambda x: x.find_element(by = locateType,value = locateExpression)) return element except Exception,e: raise e #获取多个相同页面元素对象,以list返回 def getElements(driver,locateType,locateExpression): try: element = WebDriverWait(driver,5).until(lambda x: x.find_elements(by = locateType,value = locateExpression)) return element except Exception,e: raise e if __name__ == "__main__": from selenium import webdriver #进行单元测试 driver = webdriver.Firefox(executable_path = "D:\geckodriver") driver.maximize_window() driver.get("https://mail.126.com/") time.sleep(2) lb = getElement(driver,"id","lbNormal") print lb driver.quit()
e、封装解析配置文件的模块,ParsePageObjectRepository.py,内容如下:
#encoding=utf-8 from ConfigParser import ConfigParser from ProjectVar.var import page_object_repository_path class ParsePageObjectRepositoryConfig(object): def __init__(self): self.cf = ConfigParser() self.cf.read(page_object_repository_path) #获取某个section,所有的key和value,用字典方式返回 def getItemsFromSection(self,sectionName): print self.cf.items(sectionName) return dict(self.cf.items(sectionName)) #获取某一个具体的选项对应的value def getOptionValue(self,sectionName,optionName): return self.cf.get(sectionName,optionName)
3)新建一个包,ProjectVar
在ProjectVar下新增一个模块,var.py,内容如下:
#encoding=utf-8 import os #获取工程所在目录的绝对路径 project_path = os.path.dirname(os.path.dirname(__file__)) #日志配置文件的绝对路径 log_config_file_path = project_path + "/Conf/logger.conf" #测试数据excel文件的绝对路径 test_data_excel_path = project_path.decode("utf-8") + u"/TestData/126邮箱联系人.xlsx" # page_object_repository_path = project_path.decode("utf-8") + "/Conf/PageProjectRepository.ini" username_col_no=1 password_col_no=2 is_executed_col_no=4 test_result_col_no=6 exception_info_col_no=7 assert_keyword_col_no = 6 firefox_driver_path= 'D:\geckodriver' if __name__ == "__main__": print os.path.dirname(__file__) print os.path.dirname(os.path.dirname(__file__)) print os.path.dirname(project_path+"/Conf/logger.conf") #路径斜杠向左向右都可以 print log_config_file_path print test_data_excel_path
4)新建一个目录 Conf
在Conf下新建一个log配置文件, logger.conf内容如下:
#logger.conf ############################################### [loggers] keys=root,example01,example02 [logger_root] level=DEBUG handlers=hand01,hand02 [logger_example01] handlers=hand01,hand02 qualname=example01 propagate=0 [logger_example02] handlers=hand01,hand03 qualname=example02 propagate=0 ############################################### [handlers] keys=hand01,hand02,hand03 [handler_hand01] class=StreamHandler level=INFO formatter=form01 args=(sys.stderr,) [handler_hand02] class=FileHandler level=DEBUG formatter=form01 args=('DataDrivenFrameWork.log', 'a') [handler_hand03] class=handlers.RotatingFileHandler level=INFO formatter=form01 args=('DataDrivenFrameWork.log', 'a', 10*1024*1024, 5) ############################################### [formatters] keys=form01,form02 [formatter_form01] format=%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s datefmt=%Y-%m-%d %H:%M:%S [formatter_form02] format=%(name)-12s: %(levelname)-8s %(message)s datefmt=%Y-%m-%d %H:%M:%S
在Conf目录下新建一个PageProjectRepository配置文件,PageProjectRepository.ini内容如下:
[126mail_login] login_page.lbnormalbutton=id>lbNormal login_page.frame=xpath>//iframe[contains(@id,"x-URS-iframe")] login_page.username=xpath>//input[@name='email'] login_page.password=xpath>//input[@name='password'] login_page.loginbutton=id>dologin [126mail_homepage] home_page.addressbook=xpath>//div[text()='通讯录'] [126mail_addcontactspage] addcontacts_page.createcontactsbtn=xpath>//span[text()='新建联系人'] addcontacts_page.contactpersonname=xpath>//a[@title='编辑详细姓名']/preceding-sibling::div/input addcontacts_page.contactpersonemail=xpath>//*[@id='iaddress_MAIL_wrap']//input addcontacts_page.starcontacts=xpath>//span[text()='设为星标联系人']/preceding-sibling::span/b addcontacts_page.contactpersonmobile=xpath>//*[@id='iaddress_TEL_wrap']//dd//input addcontacts_page.contactpersoncomment=xpath>//textarea addcontacts_page.savecontaceperson=xpath>//span[.='确 定']
5)新建一个目录TestData,存放测试数据: 126邮箱联系人.xlsx
sheet1数据:
序号 用户名 密码 数据表 是否执行 测试结果
1 xxx xxx 联系人 y
2 xxx xxx 联系人 y
sheet2数据(联系人):
序号 联系人姓名 联系人邮箱 是否设为星标联系人 联系人手机号 联系人备注信息 验证页面包含的关键字 是否执行 执行时间 测试结果
1 lily lily@qq.com 是 13512319865 lily lily@qq.com y
2 张三 zhangsan@qq.com 否 15812316893 忽略 zhangsan@qq.com n
3 amy am y@qq.com 是 13901902408 lily amy n
4 李四 lisi@qq.com 否 15796356569 lily 李四 y
6)新建一个包,PageProject(一个页面一个类,里面有很多方法,方法是用于获取页面中的一个元素)
新建login_page(登录页面)模块,login_page.py,内容如下:
#ecoding=utf-8 import time from Util.ObjectMap import * from Util.ParsePageObjectRepository import ParsePageObjectRepositoryConfig class LoginPage(object): def __init__(self,driver): self.driver = driver self.parse_config_file = ParsePageObjectRepositoryConfig() self.login_page_items = self.parse_config_file.getItemsFromSection("126mail_login") print self.login_page_items #获取元素 def lbnormalbutton(self): locateType, locateExpression = self.login_page_items['login_page.lbnormalbutton'].split(">") print locateType, locateExpression return getElement(self.driver, locateType, locateExpression) def frame(self): locateType, locateExpression = self.login_page_items['login_page.frame'].split(">") print locateType, locateExpression return getElement(self.driver, locateType, locateExpression) def username(self): locateType, locateExpression = self.login_page_items['login_page.username'].split(">") print locateType, locateExpression return getElement(self.driver, locateType, locateExpression) def password(self): locateType, locateExpression = self.login_page_items['login_page.password'].split(">") print locateType, locateExpression return getElement(self.driver, locateType, locateExpression) def loginbutton(self): locateType, locateExpression = self.login_page_items['login_page.loginbutton'].split(">") print locateType, locateExpression return getElement(self.driver, locateType, locateExpression) #操作元素 def lbnormalbutton_click(self): self.lbnormalbutton().click() def switch_to_frame(self): self.driver.switch_to.frame(self.frame()) def input_username(self,username): self.username().send_keys(username) def input_password(self,password): self.password().send_keys(password) def loginbutton_click(self): self.loginbutton().click() if __name__ == "__main__": from selenium import webdriver driver = webdriver.Firefox(executable_path = "D:\geckodriver") driver.maximize_window() driver.get("https://mail.126.com") lp = LoginPage(driver) # lp.lbnormalbutton().click() lp.lbnormalbutton_click() time.sleep(1) # driver.switch_to.frame(lp.frame()) lp.switch_to_frame() time.sleep(3) # lp.username().send_keys("xxx") lp.input_username("xxx") # lp.password().send_keys("xxx") lp.input_password("xxx") lp.loginbutton_click() time.sleep(5) driver.quit()
新建home_page(邮箱首页)模块,home_page.py,内容如下:
#encoding=utf-8 import time from Util.ObjectMap import * from Util.ParsePageObjectRepository import ParsePageObjectRepositoryConfig from Action.login import * class HomePage(object): def __init__(self,driver): self.driver = driver self.parse_config_file = ParsePageObjectRepositoryConfig() self.home_page_items = self.parse_config_file.getItemsFromSection("126mail_homepage") print self.home_page_items def address_book_page_link(self): locateType, locateExpression = self.home_page_items['home_page.addressbook'].split(">") print locateType, locateExpression return getElement(self.driver, locateType, locateExpression) if __name__ == "__main__": from selenium import webdriver driver = webdriver.Firefox(executable_path = "D:\geckodriver") driver.maximize_window() login(driver,"xxx","xxx") hp = HomePage(driver) hp.address_book_page_link().click() time.sleep(5) driver.quit()
新建addressBook(通讯录)模块,addressBook.py,内容如下:
#encoding=utf-8 import time from Util.ObjectMap import * from Util.ParsePageObjectRepository import ParsePageObjectRepositoryConfig from Action.login import * from Action.visit_address_page import * class AddressPage(object): def __init__(self,driver): self.driver = driver self.parse_config_file = ParsePageObjectRepositoryConfig() self.address_page_items = self.parse_config_file.getItemsFromSection("126mail_addcontactspage") print self.address_page_items def add_contact_button(self): locateType, locateExpression = self.address_page_items['addcontacts_page.createcontactsbtn'].split(">") print locateType, locateExpression return getElement(self.driver, locateType, locateExpression) def contact_name(self): locateType, locateExpression = self.address_page_items['addcontacts_page.contactpersonname'].split(">") print locateType, locateExpression return getElement(self.driver, locateType, locateExpression) def contact_email(self): locateType, locateExpression = self.address_page_items['addcontacts_page.contactpersonemail'].split(">") print locateType, locateExpression return getElement(self.driver, locateType, locateExpression) def contact_is_star(self): locateType, locateExpression = self.address_page_items['addcontacts_page.starcontacts'].split(">") print locateType, locateExpression return getElement(self.driver, locateType, locateExpression) def contact_mobile(self): locateType, locateExpression = self.address_page_items['addcontacts_page.contactpersonmobile'].split(">") print locateType, locateExpression return getElement(self.driver, locateType, locateExpression) def contact_other_info(self): locateType, locateExpression = self.address_page_items['addcontacts_page.contactpersoncomment'].split(">") print locateType, locateExpression return getElement(self.driver, locateType, locateExpression) def contact_save_button(self): locateType, locateExpression = self.address_page_items['addcontacts_page.savecontaceperson'].split(">") print locateType, locateExpression return getElement(self.driver, locateType, locateExpression) if __name__ == "__main__": from selenium import webdriver driver = webdriver.Firefox(executable_path="D:\geckodriver") login(driver, "xxx", "xxx") hp=HomePage(driver) hp.address_book_page_link().click() time.sleep(5) ap=AddressPage(driver) ap.add_contact_button().click() time.sleep(2) ap.contact_name().send_keys("gloryroad") ap.contact_email().send_keys("87393932@qq.com") ap.contact_is_star().click() ap.contact_mobile().send_keys("1322222222") ap.contact_other_info().send_keys(u"光荣之路") ap.contact_save_button().click()
7)新建一个包,Action ,封装各种方法
新建一个模块,login.py,内容如下:
#encoding=utf-8 import time from selenium import webdriver from Util.Log import * from Util.FormatTime import data_time_chinese from PageProject.login_page import * def login(driver,username,password): driver.get("https://mail.126.com") time.sleep(2) lp = LoginPage(driver) lp.lbnormalbutton_click() lp.switch_to_frame() time.sleep(2) lp.input_username(username) lp.input_password(password) lp.loginbutton_click() time.sleep(2) info("Login Successfully!") print data_time_chinese() if __name__ == "__main__": driver = webdriver.Firefox(executable_path = "D:\geckodriver") login(driver,"xxx","xxx")
新建一个模块,visit_address_page.py,内容如下:
#encoding=utf-8 from selenium import webdriver from Util.Log import * import time from PageObject.login_page import * from PageObject.home_page import * from login import * def visit_address_page(driver): hp = HomePage(driver) hp.address_book_page_link().click() time.sleep(5) if __name__ == "__main__": driver = webdriver.Firefox(executable_path = "D:\geckodriver") login(driver,"xxx","xxx") visit_address_page(driver)
新建一个模块,add_contact.py,内容如下:
#encoding=utf-8 from selenium import webdriver from Util.Log import * from Util.FormatTime import * import time from PageObject.login_page import * from PageObject.home_page import * from PageObject.addressBook import * from Util.Excel import * from ProjectVar.var import * def add_contact(driver,name="",email="",is_star=True,mobile="",other_info=""): ap = AddressPage(driver) ap.add_contact_button().click() time.sleep(2) ap.contact_name().send_keys(name) ap.contact_email().send_keys(email) if is_star == "True": ap.contact_is_star().click() ap.contact_mobile().send_keys(mobile) ap.contact_other_info().send_keys(other_info) ap.add_contact_button().click() time.sleep(3) if __name__ == "__main__": driver = webdriver.Firefox(executable_path = "D:\geckodriver") login(driver,"xxx","xxx") visit_address_page(driver) add_contact(driver,"Tom","1234@qq.com","True","18702235965",u"自己") driver.quit()
8)新建一个目录TestScript,存放测试脚本
新建一个python文件,testContact.py,内容如下:
#encoding=utf-8 from selenium import webdriver from Util.Log import * from Util.Excel import * from Util.FormatTime import * import time from Action.add_contact import * from Action.visit_address_page import * from Action.login import * from ProjectVar.var import * import sys reload(sys) sys.setdefaultencoding("utf8") #取出所有行,使用切片取非第一行的所有行,因为第一行是标题,所以不用取 #遍历每一行,然后使用读取单元格的方法,将用户名和密码读取到两个变量里面,然后传到login方法中,调用即可 pe = ParseExcel(test_data_excel_path) pe.set_sheet_by_index(0) print pe.get_default_name() rows = pe.get_all_rows()[1:] for id,row in enumerate(rows): if row[is_executed_col_no].value.lower() == "y": username = row[username_col_no].value password = row[password_col_no].value print "username:",row[username_col_no].value print "password:",row[password_col_no].value driver = webdriver.Firefox(executable_path = firefox_driver_path) try: login(driver,username,password) visit_address_page(driver) time.sleep(3) pe.set_sheet_by_index(1) print pe.get_default_name() print pe.get_all_rows() test_data_result_flag = True #新建联系人都成功才是True,有一个失败就是False for id2,row in enumerate(pe.get_all_rows()[1:]): if row[7].value == "y": try: print "log:",row[1],row[1].value print "log:",type(row[1]) add_contact(driver,row[1].value,row[2].value,row[3].value,row[4].value,row[5].value) pe.write_cell_content(id2 + 2,9,data_time_chinese()) print "assert word:",row[assert_keyword_col_no].value assert row[assert_keyword_col_no].value in driver.page_source pe.write_cell_content(id2 + 2,10,"pass") except Exception,e: print u"异常信息:",e.message error(u"异常信息:" + e.message) pe.write_cell_content(id2 + 2,9,data_time_chinese()) pe.write_cell_content(id2 + 2,10,"fail") test_data_result_flag = False else: pe.write_cell_content(id2 + 2,10,u"忽略") continue if test_data_result_flag == True: pe.set_sheet_by_index(0) pe.write_cell_content(id + 2,test_result_col_no,u"成功") else: pe.set_sheet_by_index(0) pe.write_cell_content(id + 2, test_result_col_no, u"失败") except Exception,e: print u"异常信息:",e.message info(u"异常信息:" + e.message) driver.quit() else: print u"第" + str(id+1) + u"行数据不执行" pe.set_sheet_by_index(0) pe.write_cell_content(id+2,test_result_col_no,u"忽略") continue