一步一步搭建数据驱动测试框架的过程和总结
数据驱动框架结构:
Action:
封装的操作元素的函数,如login,添加联系人。。。
conf:
日志配置文件
定位元素配置文件
数据库配置文件
PageObject:
一个页面是一个类,类的方法可以获取页面上的相关元素
ProjectVar:
工程路径
工程相关的全局变量
TestData:(文件或excel)
测试用例
测试数据
TestScript:
运行测试框架的主程序:入口,主要读取测试数据的文件
记录测试结果。
Util-工具类
功能:
读取配置文件
excel工具类
时间类
查找元素的方法
读取定位元素配置文件的方法
日志方法
日志操作
截图
报告模板
我的思路是从小到大的来继承这个框架,首先明确的是我要实现的功能是登录126邮箱,并添加联系人。
步骤1--如果我不用框架的方式,直接罗列代码的话,怎么实现呢,先来试着完成这个,
pycharm里新建一个工程-dataDrivenTestPractice1
在工程下新建一个TestScript的包
在TestScript包下新建一个TestScript的python文件
代码:
#encoding=utf-8
#author-夏晓旭
from selenium import webdriver
import time
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException, NoSuchElementException
import traceback
driver=webdriver.Firefox(executable_path=‘c:\\geckodriver‘)
driver.get(‘http://mail.126.com‘)
try:
wait=WebDriverWait(driver,10,0.2)#显示等待
driver.switch_to.frame(driver.find_element_by_xpath("//iframe[@id=‘x-URS-iframe‘]"))#切换到用户名和密码输入框所在的frame元素
name=wait.until(lambda x:x.find_element_by_xpath("//input[@placeholder=‘邮箱帐号或手机号‘ and @name=‘email‘]"))
name.send_keys(‘xiaxiaoxu1987‘)
password=wait.until(lambda x:x.find_element_by_xpath("//input[@placeholder=‘密码‘]"))
password.send_keys(‘gloryroad‘)
submit=wait.until(lambda x:x.find_element_by_xpath("//a[@id=‘dologin‘]"))
submit.click()
driver.switch_to.default_content()#在pycharm里用switch_to_default_content()会被加删除线,out了
time.sleep(5)
assert u"退出" in driver.page_source,"no exist in page_source"
address_book_link=wait.until(lambda x:x.find_element_by_xpath("//div[text()=‘通讯录‘]"))
address_book_link.click()
#assert u"新建联系人" in driver.page_source
add_contact_button=wait.until(lambda x:x.find_element_by_xpath("//span[text()=‘新建联系人‘]"))
add_contact_button.click()
contact_name=wait.until(lambda x:x.find_element_by_xpath("//a[@title=‘编辑详细姓名‘]/preceding-sibling::div/input"))
contact_name.send_keys(u"徐凤钗")
contact_email=wait.until(lambda x:x.find_element_by_xpath("//*[@id=‘iaddress_MAIL_wrap‘]//input"))
contact_email.send_keys("593152023@qq.com")
contact_is_star=wait.until(lambda x:x.find_element_by_xpath("//span[text()=‘设为星标联系人‘]/preceding-sibling::span/b"))
contact_is_star.click()
contact_mobile=wait.until(lambda x:x.find_element_by_xpath("//*[@id=‘iaddress_TEL_wrap‘]//dd//input"))
contact_mobile.send_keys(‘18141134488‘)
contact_other_info=wait.until(lambda x:x.find_element_by_xpath("//textarea"))
contact_other_info.send_keys(‘my wife‘)
contact_save_button=wait.until(lambda x:x.find_element_by_xpath("//span[.=‘确 定‘]"))
contact_save_button.click()
except TimeoutException, e:
# 捕获TimeoutException异常
print traceback.print_exc()
except NoSuchElementException, e:
# 捕获NoSuchElementException异常
print traceback.print_exc()
except Exception, e:
# 捕获其他异常
print traceback.print_exc()
结果:
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/TestScript.py
Process finished with exit code 0
登录邮箱-->打开联系人页面-->点击添加联系人按钮-->在弹窗中输入联系人的信息-->点击保存按钮。
还有数据驱动的核心-->数据和程序的分离
首先,登录邮箱的步骤可以抽离出来,进行独立的封装,暂定login模块
接下来就对login的功能做一个封装,然后在出程序里进行调用。
#encoding=utf-8
#author-夏晓旭
from selenium import webdriver
import time
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException, NoSuchElementException
import traceback
class LoginPage(object):
def __init__(self,driver):
self.driver=driver
def login(self):
try:
wait = WebDriverWait(driver, 10, 0.2) # 显示等待
self.driver.switch_to.frame(
self.driver.find_element_by_xpath("//iframe[@id=‘x-URS-iframe‘]")) # 切换到用户名和密码输入框所在的frame元素
name = wait.until(lambda x: x.find_element_by_xpath("//input[@placeholder=‘邮箱帐号或手机号‘ and @name=‘email‘]"))
name.send_keys(‘xiaxiaoxu1987‘)
password = wait.until(lambda x: x.find_element_by_xpath("//input[@placeholder=‘密码‘]"))
password.send_keys(‘gloryroad‘)
submit = wait.until(lambda x: x.find_element_by_xpath("//a[@id=‘dologin‘]"))
submit.click()
self.driver.switch_to.default_content() # 在pycharm里用switch_to_default_content()会被加删除线,out了
time.sleep(5)
assert u"退出" in self.driver.page_source, "no exist in page_source"
except TimeoutException, e:
# 捕获TimeoutException异常
print traceback.print_exc()
except NoSuchElementException, e:
# 捕获NoSuchElementException异常
print traceback.print_exc()
except Exception, e:
# 捕获其他异常
print traceback.print_exc()
if __name__=="__main__":
driver=webdriver.Firefox(executable_path=‘c:\\geckodriver‘)
driver.get("http:\\mail.126.com")
login=LoginPage(driver)
login.login()
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/PageObject/Login_page.py
Process finished with exit code 0
#encoding=utf-8
#author-夏晓旭
from selenium import webdriver
import time
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException, NoSuchElementException
import traceback
from PageObject.Login_Page import *
driver=webdriver.Firefox(executable_path=‘c:\\geckodriver‘)
driver.get(‘http://mail.126.com‘)
lp=LoginPage(driver)
wait = WebDriverWait(driver, 10, 0.2) # 显示等待
try:
lp.login()
address_book_link=wait.until(lambda x:x.find_element_by_xpath("//div[text()=‘通讯录‘]"))
address_book_link.click()
#assert u"新建联系人" in driver.page_source
add_contact_button=wait.until(lambda x:x.find_element_by_xpath("//span[text()=‘新建联系人‘]"))
add_contact_button.click()
contact_name=wait.until(lambda x:x.find_element_by_xpath("//a[@title=‘编辑详细姓名‘]/preceding-sibling::div/input"))
contact_name.send_keys(u"徐凤钗")
contact_email=wait.until(lambda x:x.find_element_by_xpath("//*[@id=‘iaddress_MAIL_wrap‘]//input"))
contact_email.send_keys("593152023@qq.com")
contact_is_star=wait.until(lambda x:x.find_element_by_xpath("//span[text()=‘设为星标联系人‘]/preceding-sibling::span/b"))
contact_is_star.click()
contact_mobile=wait.until(lambda x:x.find_element_by_xpath("//*[@id=‘iaddress_TEL_wrap‘]//dd//input"))
contact_mobile.send_keys(‘18141134488‘)
contact_other_info=wait.until(lambda x:x.find_element_by_xpath("//textarea"))
contact_other_info.send_keys(‘my wife‘)
contact_save_button=wait.until(lambda x:x.find_element_by_xpath("//span[.=‘确 定‘]"))
contact_save_button.click()
except TimeoutException, e:
# 捕获TimeoutException异常
print traceback.print_exc()
except NoSuchElementException, e:
# 捕获NoSuchElementException异常
print traceback.print_exc()
except Exception, e:
# 捕获其他异常
print traceback.print_exc()
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/TestScript/TestScript.py
Process finished with exit code 0
从主程序来看,添加联系人的动作也是可以进行封装的 ,先来进行这部分的封装,后续有问题再往回推导,先按照这个思路做一遍,然后再做一遍
#encoding=utf-8
#author-夏晓旭
from selenium import webdriver
import time
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException, NoSuchElementException
import traceback
from PageObject.Login_Page import *
class AddressBook(object):
def __init__(self,driver):
self.driver=driver
def add_contact(self):
try:
wait = WebDriverWait(self.driver, 10, 0.2) # 显示等待
address_book_link = wait.until(lambda x: x.find_element_by_xpath("//div[text()=‘通讯录‘]"))
address_book_link.click()
# assert u"新建联系人" in driver.page_source
add_contact_button = wait.until(lambda x: x.find_element_by_xpath("//span[text()=‘新建联系人‘]"))
add_contact_button.click()
contact_name = wait.until(
lambda x: x.find_element_by_xpath("//a[@title=‘编辑详细姓名‘]/preceding-sibling::div/input"))
contact_name.send_keys(u"徐凤钗")
contact_email = wait.until(lambda x: x.find_element_by_xpath("//*[@id=‘iaddress_MAIL_wrap‘]//input"))
contact_email.send_keys("593152023@qq.com")
contact_is_star = wait.until(
lambda x: x.find_element_by_xpath("//span[text()=‘设为星标联系人‘]/preceding-sibling::span/b"))
contact_is_star.click()
contact_mobile = wait.until(lambda x: x.find_element_by_xpath("//*[@id=‘iaddress_TEL_wrap‘]//dd//input"))
contact_mobile.send_keys(‘18141134488‘)
contact_other_info = wait.until(lambda x: x.find_element_by_xpath("//textarea"))
contact_other_info.send_keys(‘my wife‘)
contact_save_button = wait.until(lambda x: x.find_element_by_xpath("//span[.=‘确 定‘]"))
contact_save_button.click()
except TimeoutException, e:
# 捕获TimeoutException异常
print traceback.print_exc()
except NoSuchElementException, e:
# 捕获NoSuchElementException异常
print traceback.print_exc()
except Exception, e:
# 捕获其他异常
print traceback.print_exc()
if __name__=="__main__":
driver=webdriver.Firefox(executable_path=‘c:\\geckodriver‘)
driver.get(‘http://mail.126.com‘)
lp=LoginPage(driver)
lp.login()
ab=AddressBook(driver)
ab.add_contact()
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/PageObject/AddressBook.py
Process finished with exit code 0
#encoding=utf-8
#author-夏晓旭
from selenium import webdriver
import time
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException, NoSuchElementException
import traceback
from PageObject.Login_Page import *
from PageObject.AddressBook import *
driver=webdriver.Firefox(executable_path=‘c:\\geckodriver‘)
driver.get(‘http://mail.126.com‘)
loginPage=LoginPage(driver)
addressBook=AddressBook(driver)
loginPage.login()
addressBook.add_contact()
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/TestScript/TestScript.py
Process finished with exit code 0
登录邮箱-->打开联系人页面-->点击添加联系人按钮à在弹窗中输入联系人的信息-->点击保存按钮。还有数据驱动的核心-->数据和程序的分离
从程序来看,调用数据的部分是在刚才封装的两个模块里,Login_Page和AddressBook,看下程序是咋用数据的
Login_page:
AddressBook:
在封装这两个函数时,没有留出参数,直接在函数里写死了,这显然是比较low的,那怎么弄呢?下面尝试把函数中需要调用的数据用参数代替,然后在调用的时候传进去
先来修改login函数,看看怎么改成用参数传,这时候本人突然懵逼了,这么多个不一样的数据,没办法用参数啊。。。
如果要用参数传需要把login函数进行拆分,可以看到login函数中有几个部分是可以进行封装起来的,比如找frame元素的功能,找到用户名输入框元素的功能,然后再找单个元素的函数中就可以传递数据给参数进行查找了
#encoding=utf-8
#author-夏晓旭
from selenium import webdriver
import time
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException, NoSuchElementException
import traceback
class LoginPage(object):
def __init__(self,driver):
self.driver=driver
self.wait = WebDriverWait(self.driver, 10, 0.2) # 显示等待
def getFrame(self,locateType,locateExpression):
frame=self.wait.until(lambda x: x.find_element(by=locateType,value=locateExpression))#"//iframe[@id=‘x-URS-iframe‘]"
return frame
def getUserName(self,locateType,locateExpression):
userName=self.wait.until(lambda x: x.find_element(by=locateType,value=locateExpression))#"//input[@placeholder=‘邮箱帐号或手机号‘ and @name=‘email‘]"
return userName
def getPassword(self,locateType,locateExpression):
password=self.wait.until(lambda x: x.find_element(by=locateType,value=locateExpression))#"//input[@placeholder=‘密码‘]"
return password
def getLoginButton(self,locateType,locateExpression):
loginButton=self.wait.until(lambda x: x.find_element(by=locateType,value=locateExpression))#"//a[@id=‘dologin‘]"
return loginButton
if __name__=="__main__":
driver=webdriver.Firefox(executable_path=‘c:\\geckodriver‘)
driver.get("http:\\mail.126.com")
lp=LoginPage(driver)
driver.switch_to.frame(lp.getFrame("xpath","//iframe[@id=‘x-URS-iframe‘]"))
time.sleep(2)
lp.getUserName("xpath","//input[@placeholder=‘邮箱帐号或手机号‘ and @name=‘email‘]").clear()
lp.getUserName("xpath","//input[@placeholder=‘邮箱帐号或手机号‘ and @name=‘email‘]").send_keys("xiaxiaoxu1987")
lp.getPassword("xpath","//input[@placeholder=‘密码‘]").send_keys("gloryroad")
lp.getLoginButton("xpath","//a[@id=‘dologin‘]").click()
driver.switch_to.default_content()
time.sleep(5)
assert u"退出" in driver.page_source, "no exist in page_source"
调用的时候需要手动的去输入查找元素需要的数据,这样就比较麻烦,一个字母输错了都会找不到元素,怎么弄呢?
需要再封装,把数据放在文件里,然后再封装函数从文件里读数据,这样就需要建立一个配置文件来存数据,然后新建一个python文件来封装读取配置文件的方法
PageObjectRepository.ini:
[126mail_login]
login_page.frame=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[.=‘确 定‘]
#encoding=utf-8
#author-夏晓旭
from ConfigParser import ConfigParser
class ParsePageObjectRepositoryConfig(object):
def __init__(self,config_path):
self.cf=ConfigParser()#生成解析器
self.cf.read(config_path)
def getItemSection(self,sectionName):
print self.cf.items(sectionName)
return dict(self.cf.items(sectionName))
def getOptionValue(self,sectionName,optionName):#返回一个字典
print self.cf.get(sectionName,optionName)
return self.cf.get(sectionName,optionName)
if __name__==‘__main__‘:
pp=ParsePageObjectRepositoryConfig("D:\\test\\dataDrivenTestPractice1\\Conf\\PageObjectRepository.ini")
print pp.getItemSection("126mail_login")
print pp.getOptionValue("126mail_login","login_page.username")
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/Util/ParsePageObjectRepository.py
[(‘login_page.frame‘, ‘id>x-URS-iframe‘), (‘login_page.username‘, "xpath>//input[@name=‘email‘]"), (‘login_page.password‘, "xpath>//input[@name=‘password‘]"), (‘login_page.loginbutton‘, ‘id>dologin‘)]
{‘login_page.loginbutton‘: ‘id>dologin‘, ‘login_page.username‘: "xpath>//input[@name=‘email‘]", ‘login_page.frame‘: ‘id>x-URS-iframe‘, ‘login_page.password‘: "xpath>//input[@name=‘password‘]"}
xpath>//input[@name=‘email‘]
xpath>//input[@name=‘email‘]
Process finished with exit code 0
一般存文件路径的变量要放在ProjectVar包下的var.py文件里,之后所有的配置文件的路径都以变量的形式维护在这个文件中,路径的获取用相对路径的方式,稳妥一些
#encoding=utf-8
#author-夏晓旭
import os
#获取工程所在目录的绝对路径
project_path=os.path.dirname(os.path.dirname(__file__))
#获取页面对象库文件的绝对路径
page_object_repository_path=project_path.decode("utf-8")+u"/conf/PageObjectRepository.ini"
if __name__==‘__main__‘:
print "project_path:", project_path
print "page_object_repository_path:",page_object_repository_path
print os.path.exists(project_path)
print os.path.exists(page_object_repository_path)
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/ProjectVar/var.py
project_path: D:/test/dataDrivenTestPractice1
page_object_repository_path: D:/test/dataDrivenTestPractice1/conf/PageObjectRepository.ini
True
True
Process finished with exit code 0
ParsePageObjectRepository.py:
#encoding=utf-8
#author-夏晓旭
from ConfigParser import ConfigParser
from ProjectVar.var import page_object_repository_path#新加的
class ParsePageObjectRepositoryConfig(object):
def __init__(self):#去掉了config_path参数
self.cf=ConfigParser()#生成解析器
self.cf.read(page_object_repository_path)#直接用变量代替
def getItemSection(self,sectionName):
print self.cf.items(sectionName)
return dict(self.cf.items(sectionName))
def getOptionValue(self,sectionName,optionName):#返回一个字典
print self.cf.get(sectionName,optionName)
return self.cf.get(sectionName,optionName)
if __name__==‘__main__‘:
pp=ParsePageObjectRepositoryConfig()#在构造函数中已经把配置文件的地址变量初始化了
print pp.getItemSection("126mail_login")
print pp.getOptionValue("126mail_login","login_page.username")
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/Util/ParsePageObjectRepository.py
[(‘login_page.frame‘, ‘id>x-URS-iframe‘), (‘login_page.username‘, "xpath>//input[@name=‘email‘]"), (‘login_page.password‘, "xpath>//input[@name=‘password‘]"), (‘login_page.loginbutton‘, ‘id>dologin‘)]
{‘login_page.loginbutton‘: ‘id>dologin‘, ‘login_page.username‘: "xpath>//input[@name=‘email‘]", ‘login_page.frame‘: ‘id>x-URS-iframe‘, ‘login_page.password‘: "xpath>//input[@name=‘password‘]"}
xpath>//input[@name=‘email‘]
xpath>//input[@name=‘email‘]
#encoding=utf-8
#author-夏晓旭
from selenium import webdriver
import time
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException, NoSuchElementException
import traceback
from Util.ParsePageObjectRepository import *#新加
from ProjectVar.var import *#新加
class LoginPage(object):
def __init__(self,driver):
self.driver=driver
self.parse_config_file=ParsePageObjectRepositoryConfig()#新加,获取配置文件信息
self.login_page_items=self.parse_config_file.getItemSection("126mail_login")#新加
print "self.login_page_items:",self.login_page_items
self.wait = WebDriverWait(self.driver, 10, 0.2) # 显示等待
def getFrame(self):#参数去掉,在里面处理
locateType,locateExpression=self.login_page_items[‘login_page.frame‘].split(‘>‘)#id>x-URS-iframe
frame=self.wait.until(lambda x: x.find_element(by=locateType,value=locateExpression))#"//iframe[@id=‘x-URS-iframe‘]"
return frame
def getUserName(self): #参数去掉,在里面处理
locateType, locateExpression = self.login_page_items[‘login_page.username‘].split(‘>‘)#xpath>//input[@name=‘email‘]
userName=self.wait.until(lambda x: x.find_element(by=locateType,value=locateExpression))#"//input[@placeholder=‘邮箱帐号或手机号‘ and @name=‘email‘]"
return userName
def getPassword(self): #参数去掉,在里面处理
locateType, locateExpression = self.login_page_items[‘login_page.password‘].split(‘>‘)#xpath>//input[@name=‘password‘]
password=self.wait.until(lambda x: x.find_element(by=locateType,value=locateExpression))#"//input[@placeholder=‘密码‘]"
return password
def getLoginButton(self): #参数去掉,在里面处理
locateType, locateExpression = self.login_page_items[‘login_page.loginbutton‘].split(‘>‘) #id>dologin
loginButton=self.wait.until(lambda x: x.find_element(by=locateType,value=locateExpression))#"//a[@id=‘dologin‘]"
return loginButton
if __name__=="__main__":
driver=webdriver.Firefox(executable_path=‘c:\\geckodriver‘)
driver.get("http:\\mail.126.com")
lp=LoginPage(driver)
driver.switch_to.frame(lp.getFrame())
time.sleep(2)
lp.getUserName().clear()
lp.getUserName().send_keys("xiaxiaoxu1987")
lp.getPassword().send_keys("gloryroad")
lp.getLoginButton().click()
driver.switch_to.default_content()
time.sleep(5)
assert u"退出" in driver.page_source, "no exist in page_source"
1-在login_page.py文件中的获取登录页面元素的方法中,下面这个找元素的步骤是可以封装起来的,
self.wait.until(lambda x: x.find_element(by=locateType,value=locateExpression)),就不用在每个找元素的方法中写这个了,而且这个找元素的步骤在给账户添加联系人的功能中也会用到,把找元素的方法封装起来就方便多了。
2-其次是在执行登录的操作中,用户名和密码信息是我们手动输入的,这个也是可以封装起来的,如何封装呢,起始login.py这个文件中的每个方法得到的都是登录时所需要的元素,在进行登录操作的时候我们手动的调用这几个方法,获取元素后,进行输入字符或者点击的动作来完成登录操作的,那这几个步骤就可以在另外一个文件中进行封装,说白了就是把login_page中的获取各个元素的方法进行一个封装来实现登录的功能,不用每次自己来组织零散的方法了,把他放到一个盒子里,盒子的名字叫login,每次执行这个盒子就行了,不用管里面的细节,所有的封装都是这个道理。
在开始的框架结构中可以看到,查找元素的方法可以放到Util包中
#encoding=utf-8
#author-夏晓旭
from selenium.webdriver.support.ui import WebDriverWait
#获取单个元素对象
def getElement(driver,locateType,locateExpression):
try:
element=WebDriverWait(driver,10).until(lambda x:x.find_element(by=locateType,value=locateExpression))
return element
except Exception,e:
raise e
#获取多个相同页面元素对象,以list返回
def getElements(driver,locateType,locatorExpression):
try:
elements=WebDriverWait(driver,5).until(lambda x:x.find_elements(by=locateType,value=locateExpression))
return elements
except Exception,e:
raise e
if __name__=="__main__":
#测试代码
from selenium import webdriver
driver=webdriver.Firefox(executable_path=‘c:\\geckodriver‘)
driver.get(‘http://www.baidu.com‘)
searchBox=getElement(driver,"xpath","//input[@id=‘kw‘]")
driver.quit()
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/Util/ObjectMap.py
Process finished with exit code 0
#encoding=utf-8
#author-夏晓旭
from selenium import webdriver
import time
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException, NoSuchElementException
import traceback
from Util.ParsePageObjectRepository import *
from ProjectVar.var import *
from Util.ObjectMap import *
class LoginPage(object):
def __init__(self,driver):
self.driver=driver
self.parse_config_file=ParsePageObjectRepositoryConfig()
self.login_page_items=self.parse_config_file.getItemSection("126mail_login")
print "self.login_page_items:",self.login_page_items
self.wait = WebDriverWait(self.driver, 10, 0.2) # 显示等待
def getFrame(self):
locateType,locateExpression=self.login_page_items[‘login_page.frame‘].split(‘>‘)#id>x-URS-iframe
frame=getElement(self.driver,locateType,locateExpression)#"//iframe[@id=‘x-URS-iframe‘]"
return frame
def getUserName(self):
locateType, locateExpression = self.login_page_items[‘login_page.username‘].split(‘>‘)#xpath>//input[@name=‘email‘]
userName=getElement(self.driver,locateType,locateExpression)#"//input[@placeholder=‘邮箱帐号或手机号‘ and @name=‘email‘]"
return userName
def getPassword(self):
locateType, locateExpression = self.login_page_items[‘login_page.password‘].split(‘>‘)#xpath>//input[@name=‘password‘]
password=getElement(self.driver,locateType,locateExpression)#"//input[@placeholder=‘密码‘]"
return password
def getLoginButton(self):
locateType, locateExpression = self.login_page_items[‘login_page.loginbutton‘].split(‘>‘) #id>dologin
loginButton=getElement(self.driver,locateType,locateExpression)#"//a[@id=‘dologin‘]"
return loginButton
def login(self):
self.driver.switch_to.frame(self.getFrame())
self.getUserName().clear()
self.getUserName().send_keys("xiaxiaoxu1987")
self.getPassword().send_keys("gloryroad")
self.getLoginButton().click()
if __name__=="__main__":
#测试代码
driver=webdriver.Firefox(executable_path=‘c:\\geckodriver‘)
driver.get("http:\\mail.126.com")
lp=LoginPage(driver)
lp.login()
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/PageObject/Login_Page.py
self.login_page_items: {‘login_page.loginbutton‘: ‘id>dologin‘, ‘login_page.username‘: "xpath>//input[@name=‘email‘]", ‘login_page.frame‘: ‘id>x-URS-iframe‘, ‘login_page.password‘: "xpath>//input[@name=‘password‘]"}
Process finished with exit code 0
下面我们把login函数的封装从Login_page.py中挪出去,作为单独的一个文件存在,把方法和调用分隔开,以后如果有变动,修改login_page.py就可以了。
#encoding=utf-8
#author-夏晓旭
from PageObject.Login_Page import *
from selenium import webdriver
def login(driver,username,password):
lp=LoginPage(driver)
driver.switch_to.frame(lp.getFrame())
lp.getUserName().clear()
lp.getUserName().send_keys(username)
lp.getPassword().send_keys(password)
lp.getLoginButton().click()
if __name__==‘__main__‘:
#测试代码
driver=webdriver.Firefox(executable_path=‘c:\\geckodriver‘)
driver.get("http://mail.126.com")
login(driver,"xiaxiaoxu1987","gloryroad")
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/Action/login.py
self.login_page_items: {‘login_page.loginbutton‘: ‘id>dologin‘, ‘login_page.username‘: "xpath>//input[@name=‘email‘]", ‘login_page.frame‘: ‘id>x-URS-iframe‘, ‘login_page.password‘: "xpath>//input[@name=‘password‘]"}
Process finished with exit code 0
在AddressBook.py里把添加联系人页面需要的各个元素封装成方法,其中找各个元素需要的xpath数据放在配置文件中,然后用一个函数来调用这些元素的方法,实现输入字符或者点击操作来实现添加联系人功能
#encoding=utf-8
#author-夏晓旭
from selenium import webdriver
import time
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException, NoSuchElementException
import traceback
from PageObject.Login_Page import *
from Action.login import *
class AddressBook(object):
def __init__(self,driver):
self.driver=driver
self.parse_config_file=ParsePageObjectRepositoryConfig()
self.address_book_page=self.parse_config_file.getItemsFromSection("126mail_homepage")
print "self.address_book_page:",self.address_book_page
self.address_book_page_itmes=self.parse_config_file.getItemsFromSection("126mail_addcontactspage")
print "self.address_book_page_itmes:", self.address_book_page_itmes
def address_book_link(self):
locateType,locateExpression = self.address_book_page[‘home_page.addressbook‘].split(">")
print locateType,locateExpression
return getElement(self.driver,"xpath","//div[text()=‘通讯录‘]")
def add_contact_button(self):
locateType,locateExpression=self.address_book_page_itmes[‘addcontacts_page.createcontactsbtn‘].split(">")
print locateType,locateExpression
return getElement(self.driver,locateType,locateExpression)
def contact_name(self):
locateType,locateExpression=self.address_book_page_itmes[‘addcontacts_page.contactpersonname‘].split(">")
print locateType, locateExpression
return getElement(self.driver, locateType, locateExpression)
def contact_email(self):
locateType, locateExpression = self.address_book_page_itmes[‘addcontacts_page.contactpersonemail‘].split(">")
print locateType, locateExpression
return getElement(self.driver, locateType, locateExpression)
def contact_is_star(self):
locateType, locateExpression = self.address_book_page_itmes[‘addcontacts_page.starcontacts‘].split(">")
print locateType, locateExpression
return getElement(self.driver, locateType, locateExpression)
def contact_mobile(self):
locateType, locateExpression = self.address_book_page_itmes[‘addcontacts_page.contactpersonmobile‘].split(">")
print locateType, locateExpression
return getElement(self.driver, locateType, locateExpression)
def contact_other_info(self):
locateType, locateExpression = self.address_book_page_itmes[‘addcontacts_page.contactpersoncomment‘].split(">")
print locateType, locateExpression
return getElement(self.driver, locateType, locateExpression)
def contact_save_button(self):
locateType, locateExpression = self.address_book_page_itmes[‘addcontacts_page.savecontaceperson‘].split(">")
print locateType, locateExpression
return getElement(self.driver, locateType, locateExpression)
if __name__=="__main__":
driver = webdriver.Firefox(executable_path=‘c:\\geckodriver‘)
driver.get("http://mail.126.com")
login(driver, "xiaxiaoxu1987", "gloryroad")
addressbook=AddressBook(driver)
time.sleep(5)
addressbook.address_book_link().click()
addressbook.add_contact_button().click()
addressbook.contact_name().send_keys("sam")
addressbook.contact_email().send_keys("367224698@qq.com")
addressbook.contact_is_star().click()
addressbook.contact_mobile().send_keys("18142244444")
addressbook.contact_other_info().send_keys("myself")
addressbook.contact_save_button().click()
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/PageObject/AddressBook.py
self.login_page_items: {‘login_page.loginbutton‘: ‘id>dologin‘, ‘login_page.username‘: "xpath>//input[@name=‘email‘]", ‘login_page.frame‘: ‘id>x-URS-iframe‘, ‘login_page.password‘: "xpath>//input[@name=‘password‘]"}
self.address_book_page: {‘home_page.addressbook‘: "xpath>//div[text()=‘\xe9\x80\x9a\xe8\xae\xaf\xe5\xbd\x95‘]"}
self.address_book_page_itmes: {‘addcontacts_page.createcontactsbtn‘: "xpath>//span[text()=‘\xe6\x96\xb0\xe5\xbb\xba\xe8\x81\x94\xe7\xb3\xbb\xe4\xba\xba‘]", ‘addcontacts_page.contactpersonmobile‘: "xpath>//*[@id=‘iaddress_TEL_wrap‘]//dd//input", ‘addcontacts_page.contactpersonemail‘: "xpath>//*[@id=‘iaddress_MAIL_wrap‘]//input", ‘addcontacts_page.contactpersoncomment‘: ‘xpath>//textarea‘, ‘addcontacts_page.contactpersonname‘: "xpath>//a[@title=‘\xe7\xbc\x96\xe8\xbe\x91\xe8\xaf\xa6\xe7\xbb\x86\xe5\xa7\x93\xe5\x90\x8d‘]/preceding-sibling::div/input", ‘addcontacts_page.savecontaceperson‘: "xpath>//span[.=‘\xe7\xa1\xae \xe5\xae\x9a‘]", ‘addcontacts_page.starcontacts‘: "xpath>//span[text()=‘\xe8\xae\xbe\xe4\xb8\xba\xe6\x98\x9f\xe6\xa0\x87\xe8\x81\x94\xe7\xb3\xbb\xe4\xba\xba‘]/preceding-sibling::span/b"}
xpath //div[text()=‘通讯录‘]
xpath //span[text()=‘新建联系人‘]
xpath //a[@title=‘编辑详细姓名‘]/preceding-sibling::div/input
xpath //*[@id=‘iaddress_MAIL_wrap‘]//input
xpath //span[text()=‘设为星标联系人‘]/preceding-sibling::span/b
xpath //*[@id=‘iaddress_TEL_wrap‘]//dd//input
xpath //textarea
xpath //span[.=‘确 定‘]
#encoding=utf-8
#author-夏晓旭
from PageObject.AddressBook import *
from selenium import webdriver
def add_contact(driver):
driver.switch_to.default_content()
addressbook = AddressBook(driver)
addressbook.address_book_link().click()
addressbook.add_contact_button().click()
addressbook.contact_name().send_keys("sam")
addressbook.contact_email().send_keys("367224698@qq.com")
addressbook.contact_is_star().click()
addressbook.contact_mobile().send_keys("18142244444")
addressbook.contact_other_info().send_keys("myself")
addressbook.contact_save_button().click()
if __name__==‘__main__‘:
driver=webdriver.Firefox(executable_path="c:\\geckodriver")
driver.get("http://mail.126.com")
login(driver, "xiaxiaoxu1987", "gloryroad")
add_contact(driver)
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/Action/add_contact.py
self.login_page_items: {‘login_page.loginbutton‘: ‘id>dologin‘, ‘login_page.username‘: "xpath>//input[@name=‘email‘]", ‘login_page.frame‘: ‘id>x-URS-iframe‘, ‘login_page.password‘: "xpath>//input[@name=‘password‘]"}
Process finished with exit code 0
#encoding=utf-8
#author-夏晓旭
from PageObject.AddressBook import *
from selenium import webdriver
def add_contact(driver,name="",email="",is_star=True,mobile="",otherinfo=""):
driver.switch_to.default_content()
addressbook = AddressBook(driver)
addressbook.address_book_link().click()
addressbook.add_contact_button().click()
addressbook.contact_name().send_keys(name)
addressbook.contact_email().send_keys(email)
if is_star==True:
addressbook.contact_is_star().click()
addressbook.contact_mobile().send_keys(mobile)
addressbook.contact_other_info().send_keys(otherinfo)
addressbook.contact_save_button().click()
if __name__==‘__main__‘:
driver=webdriver.Firefox(executable_path="c:\\geckodriver")
driver.get("http://mail.126.com")
login(driver, "xiaxiaoxu1987", "gloryroad")
add_contact(driver,"xiaxiaoxu","367224698@qq.com",True,"13333334444","gloryroad")
driver.quit()
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/Action/add_contact.py
self.login_page_items: {‘login_page.loginbutton‘: ‘id>dologin‘, ‘login_page.username‘: "xpath>//input[@name=‘email‘]", ‘login_page.frame‘: ‘id>x-URS-iframe‘, ‘login_page.password‘: "xpath>//input[@name=‘password‘]"}
Process finished with exit code 0
#encoding=utf-8
#author-夏晓旭
from selenium import webdriver
import time
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException, NoSuchElementException
import traceback
from PageObject.Login_Page import *
from PageObject.AddressBook import *
from Action.add_contact import *
from Action.login import *
driver=webdriver.Firefox(executable_path=‘c:\\geckodriver‘)
driver.get(‘http://mail.126.com‘)
login(driver, "xiaxiaoxu1987", "gloryroad")
add_contact(driver,"xiaxiaoxu","367224698@qq.com",True,"13333334444","gloryroad")
driver.quit()
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/TestScript/TestScript.py
Process finished with exit code 0
#encoding=utf-8
#author-夏晓旭
# encoding=utf-8
from openpyxl import load_workbook
from openpyxl.styles import Border, Side, Font
import time
from ProjectVar.var import *
class parseExcel(object):
def __init__(self, excelPath):
self.excelPath = excelPath
self.workbook = load_workbook(excelPath) # 加载excel
self.sheet = self.workbook.active # 获取第一个sheet
self.font = Font(color=None)
self.colorDict = {"red": ‘FFFF3030‘, "green": ‘FF008B00‘}
# 设置当前要操作的sheet对象,使用index来获取相应的sheet
def set_sheet_by_index(self, sheet_index):
sheet_name = self.workbook.get_sheet_names()[sheet_index]
self.sheet = self.workbook.get_sheet_by_name(sheet_name)
return self.sheet
# 获取当前默认sheet的名字
def get_default_sheet(self):
return self.sheet.title
# 设置当前要操作的sheet对象,使用sheet名称来获取相应的sheet
def set_sheet_by_name(self, sheet_name):
sheet = self.workbook.get_sheet_by_name(sheet_name)
self.sheet = sheet
return self.sheet
# 获取默认sheet中最大的行数
def get_max_row_no(self):
return self.sheet.max_row
# 获取默认 sheet 的最大列数
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):
return list(self.sheet.iter_rows())
# return list(self.rows)也可以
# 获取默认sheet中的所有列对象
def get_all_cols(self):
return list(self.sheet.iter_cols())
# return list(self.sheet.columns)也可以
# 从默认sheet中获取某一列,第一列从0开始
def get_single_col(self, col_no):
return self.get_all_cols()[col_no]
# 从默认sheet中获取某一行,第一行从0开始
def get_single_row(self, row_no):
return self.get_all_rows()[row_no]
# 从默认sheet中,通过行号和列号获取指定的单元格,注意行号和列号从1开始
def get_cell(self, row_no, col_no):
return self.sheet.cell(row=row_no, column=col_no)
# 从默认sheet中,通过行号和列号获取指定的单元格中的内容,注意行号和列号从1开始
def get_cell_content(self, row_no, col_no):
return self.sheet.cell(row=row_no, column=col_no).value
# 从默认sheet中,通过行号和列号向指定单元格中写入指定内容,注意行号和列号从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.excelPath)
return self.sheet.cell(row=row_no, column=col_no).value
# 从默认sheet中,通过行号和列号向指定单元格中写入当前日期,注意行号和列号从1开始
# 调用此方法的时候,excel不要处于打开状态
def write_cell_current_time(self, row_no, col_no):
time1 = time.strftime("%Y-%m-%d %H:%M:%S")
self.sheet.cell(row=row_no, column=col_no).value = str(time1)
self.workbook.save(self.excelPath)
return self.sheet.cell(row=row_no, column=col_no).value
def save_excel_file(self):
self.workbook.save(self.excelPath)
if __name__ == ‘__main__‘:
#测试代码
p = parseExcel(test_data_excel_path)
print u"获取默认sheet:", p.get_default_sheet()
print u"设置sheet索引为1", p.set_sheet_by_index(1)
print u"获取默认sheet:", p.get_default_sheet()
print u"设置sheet索引为0", p.set_sheet_by_index(0)
print u"获取默认sheet:", p.get_default_sheet()
print u"最大行数:", p.get_max_row_no()
print u"最大列数:", p.get_max_col_no()
print u"最小起始行数:", p.get_min_row_no()
print u"最小起始列数:", p.get_min_col_no()
print u"所有行对象:", p.get_all_rows()
print u"所有列对象:", p.get_all_cols()
print u"获取某一列(2):", p.get_single_col(2)
print u"获取某一行(1):", p.get_single_row(1)
print u"取得行号和列号(2,2)单元格:", p.get_cell(2, 2)
print u"取得行号和列号单元格的内容(2,2)", p.get_cell_content(2, 2)
print u"行号和列号写入内容(11,11):‘xiaxiaoxu‘", p.write_cell_content(11, 11, ‘xiaxiaoxu‘) #
print u"行号和列号写入当前日期(13,13):", p.write_cell_current_time(13, 13)
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/Util/Excel.py
获取默认sheet: 联系人
设置sheet索引为1 <Worksheet "\u8054\u7cfb\u4eba">
获取默认sheet: 联系人
设置sheet索引为0 <Worksheet "126\u8d26\u53f7">
获取默认sheet: 126账号
最大行数: 3
最大列数: 6
最小起始行数: 1
最小起始列数: 1
所有行对象: [(<Cell u‘126\u8d26\u53f7‘.A1>, <Cell u‘126\u8d26\u53f7‘.B1>, <Cell u‘126\u8d26\u53f7‘.C1>, <Cell u‘126\u8d26\u53f7‘.D1>, <Cell u‘126\u8d26\u53f7‘.E1>, <Cell u‘126\u8d26\u53f7‘.F1>), (<Cell u‘126\u8d26\u53f7‘.A2>, <Cell u‘126\u8d26\u53f7‘.B2>, <Cell u‘126\u8d26\u53f7‘.C2>, <Cell u‘126\u8d26\u53f7‘.D2>, <Cell u‘126\u8d26\u53f7‘.E2>, <Cell u‘126\u8d26\u53f7‘.F2>), (<Cell u‘126\u8d26\u53f7‘.A3>, <Cell u‘126\u8d26\u53f7‘.B3>, <Cell u‘126\u8d26\u53f7‘.C3>, <Cell u‘126\u8d26\u53f7‘.D3>, <Cell u‘126\u8d26\u53f7‘.E3>, <Cell u‘126\u8d26\u53f7‘.F3>)]
所有列对象: [(<Cell u‘126\u8d26\u53f7‘.A1>, <Cell u‘126\u8d26\u53f7‘.A2>, <Cell u‘126\u8d26\u53f7‘.A3>), (<Cell u‘126\u8d26\u53f7‘.B1>, <Cell u‘126\u8d26\u53f7‘.B2>, <Cell u‘126\u8d26\u53f7‘.B3>), (<Cell u‘126\u8d26\u53f7‘.C1>, <Cell u‘126\u8d26\u53f7‘.C2>, <Cell u‘126\u8d26\u53f7‘.C3>), (<Cell u‘126\u8d26\u53f7‘.D1>, <Cell u‘126\u8d26\u53f7‘.D2>, <Cell u‘126\u8d26\u53f7‘.D3>), (<Cell u‘126\u8d26\u53f7‘.E1>, <Cell u‘126\u8d26\u53f7‘.E2>, <Cell u‘126\u8d26\u53f7‘.E3>), (<Cell u‘126\u8d26\u53f7‘.F1>, <Cell u‘126\u8d26\u53f7‘.F2>, <Cell u‘126\u8d26\u53f7‘.F3>)]
获取某一列(2): (<Cell u‘126\u8d26\u53f7‘.C1>, <Cell u‘126\u8d26\u53f7‘.C2>, <Cell u‘126\u8d26\u53f7‘.C3>)
获取某一行(1): (<Cell u‘126\u8d26\u53f7‘.A2>, <Cell u‘126\u8d26\u53f7‘.B2>, <Cell u‘126\u8d26\u53f7‘.C2>, <Cell u‘126\u8d26\u53f7‘.D2>, <Cell u‘126\u8d26\u53f7‘.E2>, <Cell u‘126\u8d26\u53f7‘.F2>)
取得行号和列号(2,2)单元格: <Cell u‘126\u8d26\u53f7‘.B2>
取得行号和列号单元格的内容(2,2) xiaxiaoxu1987
行号和列号写入内容(11,11):‘xiaxiaoxu‘ xiaxiaoxu
行号和列号写入当前日期(13,13): 2018-07-10 21:28:14
Process finished with exit code 0
#encoding=utf-8
#author-夏晓旭
from selenium import webdriver
import time
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException, NoSuchElementException
import traceback
from PageObject.Login_Page import *
from PageObject.AddressBook import *
from Action.add_contact import *
from Action.login import *
from ProjectVar.var import *
from Util.Excel import *
driver=webdriver.Firefox(executable_path=‘c:\\geckodriver‘)
driver.get(‘http://mail.126.com‘)
pe=parseExcel(test_data_excel_path)
pe.set_sheet_by_name(u"126账号")
print pe.get_default_sheet()
rows=pe.get_all_rows()[1:]
for id,row in enumerate(rows):
if row[4].value ==‘y‘:
username = row[1].value
password = row[2].value
print username, password
try:
login(driver,username,password)
pe.set_sheet_by_name(u"联系人")
print pe.get_default_sheet()
rows1=pe.get_all_rows()[1:]
print "rows1:",rows1
for id1,row in enumerate(rows1):
if row[7].value == ‘y‘:
try:
#print row[1].value,row[2].value,row[3].value,row[4].value,row[5].value
#print "execute1"
add_contact(driver,row[1].value,row[2].value,row[3].value,row[4].value,row[5].value)
print "assert word:",row[6].value in driver.page_source
print row[6].value
pe.write_cell_content(id1+2,10,"pass")
except Exception,e:
print u"异常信息:",e.message
pe.write_cell_content(id1+2,10,"fail")
else:
pe.write_cell_content(id1+2,10,u"忽略")
continue
except Exception,e:
pe.set_sheet_by_name(u"126账号")
print u"异常信息:",e
pe.write_cell_content(id+2,5,"fail")
else:
pe.set_sheet_by_name(u"126账号")
pe.write_cell_content(id+2,6,u"忽略")
continue
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/TestScript/TestScript.py
126账号
xiaxiaoxu1987 gloryroad
联系人
rows1: [(<Cell u‘\u8054\u7cfb\u4eba‘.A2>, <Cell u‘\u8054\u7cfb\u4eba‘.B2>, <Cell u‘\u8054\u7cfb\u4eba‘.C2>, <Cell u‘\u8054\u7cfb\u4eba‘.D2>, <Cell u‘\u8054\u7cfb\u4eba‘.E2>, <Cell u‘\u8054\u7cfb\u4eba‘.F2>, <Cell u‘\u8054\u7cfb\u4eba‘.G2>, <Cell u‘\u8054\u7cfb\u4eba‘.H2>, <Cell u‘\u8054\u7cfb\u4eba‘.I2>, <Cell u‘\u8054\u7cfb\u4eba‘.J2>), (<Cell u‘\u8054\u7cfb\u4eba‘.A3>, <Cell u‘\u8054\u7cfb\u4eba‘.B3>, <Cell u‘\u8054\u7cfb\u4eba‘.C3>, <Cell u‘\u8054\u7cfb\u4eba‘.D3>, <Cell u‘\u8054\u7cfb\u4eba‘.E3>, <Cell u‘\u8054\u7cfb\u4eba‘.F3>, <Cell u‘\u8054\u7cfb\u4eba‘.G3>, <Cell u‘\u8054\u7cfb\u4eba‘.H3>, <Cell u‘\u8054\u7cfb\u4eba‘.I3>, <Cell u‘\u8054\u7cfb\u4eba‘.J3>), (<Cell u‘\u8054\u7cfb\u4eba‘.A4>, <Cell u‘\u8054\u7cfb\u4eba‘.B4>, <Cell u‘\u8054\u7cfb\u4eba‘.C4>, <Cell u‘\u8054\u7cfb\u4eba‘.D4>, <Cell u‘\u8054\u7cfb\u4eba‘.E4>, <Cell u‘\u8054\u7cfb\u4eba‘.F4>, <Cell u‘\u8054\u7cfb\u4eba‘.G4>, <Cell u‘\u8054\u7cfb\u4eba‘.H4>, <Cell u‘\u8054\u7cfb\u4eba‘.I4>, <Cell u‘\u8054\u7cfb\u4eba‘.J4>), (<Cell u‘\u8054\u7cfb\u4eba‘.A5>, <Cell u‘\u8054\u7cfb\u4eba‘.B5>, <Cell u‘\u8054\u7cfb\u4eba‘.C5>, <Cell u‘\u8054\u7cfb\u4eba‘.D5>, <Cell u‘\u8054\u7cfb\u4eba‘.E5>, <Cell u‘\u8054\u7cfb\u4eba‘.F5>, <Cell u‘\u8054\u7cfb\u4eba‘.G5>, <Cell u‘\u8054\u7cfb\u4eba‘.H5>, <Cell u‘\u8054\u7cfb\u4eba‘.I5>, <Cell u‘\u8054\u7cfb\u4eba‘.J5>)]
assert word: True
lily@qq.com
assert word: True
李四
Process finished with exit code 0
至此,该框架大部分功能已经封装好了,下面再搞一下日志模块,使程序在执行的时候能够打印日志
#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
#encoding=utf-8
#author-夏晓旭
import logging
import logging.config
from ProjectVar.var import *
#读取日志的配置文件
logging.config.fileConfig(project_path+"\\Conf\\Logger.conf")
#选择一个日志格式
logger=logging.getLogger("example02")
def error(message):
#打印debug级别的信息
logger.error(message)
def info(message):
#打印info级别的信息
logger.info(message)
def warning(message):
#打印warning级别的信息
logger.warning(message)
if __name__=="__main__":
#测试代码
info("hi")
print "config file path:",project_path+"\\Conf\\Logger.conf"
error("world!")
warning("gloryroad!")
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/Util/log.py
2018-07-11 21:32:12 log.py[line:19] INFO hi
config file path: D:\test\dataDrivenTestPractice1\Conf\Logger.conf
2018-07-11 21:32:12 log.py[line:15] ERROR world!
2018-07-11 21:32:12 log.py[line:23] WARNING gloryroad!
Process finished with exit code 0
日志的封装已经ok了,下面修改主程序并且调用日志。
#encoding=utf-8
#author-夏晓旭
from selenium import webdriver
import time
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException, NoSuchElementException
import traceback
from PageObject.Login_Page import *
from PageObject.AddressBook import *
from Action.add_contact import *
from Action.login import *
from ProjectVar.var import *
from Util.Excel import *
from Util.log import *
driver=webdriver.Firefox(executable_path=‘c:\\geckodriver‘)
driver.get(‘http://mail.126.com‘)
pe=parseExcel(test_data_excel_path)
pe.set_sheet_by_name(u"126账号")
print pe.get_default_sheet()
rows=pe.get_all_rows()[1:]
for id,row in enumerate(rows):
if row[4].value ==‘y‘:
username = row[1].value
password = row[2].value
print username, password
try:
login(driver,username,password)
pe.set_sheet_by_name(u"联系人")
print pe.get_default_sheet()
rows1=pe.get_all_rows()[1:]
print "rows1:",rows1
test_data_pass_flag=True#结果表示,用于最后写入excel结果
for id1,row in enumerate(rows1):
if row[7].value == ‘y‘:
try:
#print row[1].value,row[2].value,row[3].value,row[4].value,row[5].value
print "log0711",row[1],row[1].value
print "log0711",type(row[1].value)
#进行添加联系人的实际操作
add_contact(driver,row[1].value,row[2].value,row[3].value,row[4].value,row[5].value)
print "assert word:",row[6].value
assert row[6].value in driver.page_source
pe.write_cell_content(id1+2,10,"pass")#assert没有报错,说明断言成功
except Exception,e:
#print u"异常信息01",e.message
pe.write_cell_content(id1+2,10,"fail")
test_data_pass_flag=False#代码走到这里,说明有异常,测试失败
info(u"异常信息01" + e.message) # 输出日志
else:#说明标识为‘n‘,忽略该数据
pe.write_cell_content(id1+2,10,u"忽略")
continue
if test_data_pass_flag ==True:#如果标识是True,说明结果是成功的
pe.set_sheet_by_name(u"126账号")
pe.write_cell_content(id+2,5,"成功")
else:#说明标识是False
pe.set_sheet_by_name(u"126账号")
pe.write_cell_content(id+2,5,"失败")
except Exception,e:
pe.set_sheet_by_name(u"126账号")
#print u"异常信息02:",e
pe.write_cell_content(id+2,6,"fail")
info(u"异常信息02:"+e.message)#输出日志
time.sleep(2)
driver.quit()
else:#走这个分支,说明标识为"n"
pe.set_sheet_by_name(u"126账号")
pe.write_cell_content(id+2,6,u"忽略")
continue
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/TestScript/TestScript.py
126账号
xiaxiaoxu1987 gloryroad
2018-07-11 22:55:25 log.py[line:19] INFO login successfully
联系人
rows1: [(<Cell u‘\u8054\u7cfb\u4eba‘.A2>, <Cell u‘\u8054\u7cfb\u4eba‘.B2>, <Cell u‘\u8054\u7cfb\u4eba‘.C2>, <Cell u‘\u8054\u7cfb\u4eba‘.D2>, <Cell u‘\u8054\u7cfb\u4eba‘.E2>, <Cell u‘\u8054\u7cfb\u4eba‘.F2>, <Cell u‘\u8054\u7cfb\u4eba‘.G2>, <Cell u‘\u8054\u7cfb\u4eba‘.H2>, <Cell u‘\u8054\u7cfb\u4eba‘.I2>, <Cell u‘\u8054\u7cfb\u4eba‘.J2>), (<Cell u‘\u8054\u7cfb\u4eba‘.A3>, <Cell u‘\u8054\u7cfb\u4eba‘.B3>, <Cell u‘\u8054\u7cfb\u4eba‘.C3>, <Cell u‘\u8054\u7cfb\u4eba‘.D3>, <Cell u‘\u8054\u7cfb\u4eba‘.E3>, <Cell u‘\u8054\u7cfb\u4eba‘.F3>, <Cell u‘\u8054\u7cfb\u4eba‘.G3>, <Cell u‘\u8054\u7cfb\u4eba‘.H3>, <Cell u‘\u8054\u7cfb\u4eba‘.I3>, <Cell u‘\u8054\u7cfb\u4eba‘.J3>), (<Cell u‘\u8054\u7cfb\u4eba‘.A4>, <Cell u‘\u8054\u7cfb\u4eba‘.B4>, <Cell u‘\u8054\u7cfb\u4eba‘.C4>, <Cell u‘\u8054\u7cfb\u4eba‘.D4>, <Cell u‘\u8054\u7cfb\u4eba‘.E4>, <Cell u‘\u8054\u7cfb\u4eba‘.F4>, <Cell u‘\u8054\u7cfb\u4eba‘.G4>, <Cell u‘\u8054\u7cfb\u4eba‘.H4>, <Cell u‘\u8054\u7cfb\u4eba‘.I4>, <Cell u‘\u8054\u7cfb\u4eba‘.J4>), (<Cell u‘\u8054\u7cfb\u4eba‘.A5>, <Cell u‘\u8054\u7cfb\u4eba‘.B5>, <Cell u‘\u8054\u7cfb\u4eba‘.C5>, <Cell u‘\u8054\u7cfb\u4eba‘.D5>, <Cell u‘\u8054\u7cfb\u4eba‘.E5>, <Cell u‘\u8054\u7cfb\u4eba‘.F5>, <Cell u‘\u8054\u7cfb\u4eba‘.G5>, <Cell u‘\u8054\u7cfb\u4eba‘.H5>, <Cell u‘\u8054\u7cfb\u4eba‘.I5>, <Cell u‘\u8054\u7cfb\u4eba‘.J5>)]
log0711 <Cell u‘\u8054\u7cfb\u4eba‘.B2> lily
log0711 <type ‘unicode‘>
assert word: lily@qq.com
Process finished with exit code 0
#encoding=utf-8
#author-夏晓旭
#encoding=utf-8
import time
from datetime import timedelta,date
def date_time_chinese():
print u"returns the current time string,format for YYYY年mm月dd日HH时MM分SS秒"
return time.strftime("%Y年%m月%d日 %H时%M分%S秒",time.localtime())
def date_chinese():
print u"returns the current time string, format for YYYY年mm月dd日"
return time.strftime("%Y年%m月%d日",time.localtime())
def time_chinese():
print u"returns the current time string,format for HH时 MM分 SS秒"
return time.strftime("%H时%M分%S秒",time.localtime())
def date_time():
print "returns the current time string, format for YYYY-mm-dd HH:MM:SS"
return time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())
def date_time_slash():
print "returns the current time string,format for YYYY/mm/dd HH:MM:SS"
return time.strftime("%Y/%m/%d %H:%M:%S",time.localtime())
def dates():
print "returns the current time string,format for YYYY-mm-dd"
return time.strftime("%Y-%m-%d",time.localtime())
def date_slash():
print "returns the current time string,format for YYYY/mm/dd"
return time.strftime("%Y/%m/%d",time.localtime())
def times():
print "returns the current time string, format for HH:MM:SS"
return time.strftime("%H:%M:%S",time.localtime())
def year():
print "returns the current time string,format for year"
return time.strftime("%Y",time.localtime())
def month():
print "returns the current time string,format for month"
return time.strftime("%m",time.localtime())
def day():
print "returns the current time string,format for day"
return time.strftime("%d",time.localtime())
def hour():
print "returns the current time string, format for Hour"
return time.strftime("%H",time.localtime())
def minute():
print "returns the current time string,format for minute"
return time.strftime("%M",time.localtime())
def seconds():
print "return the current time string,format for seconds"
return time.strftime("%S",time.localtime())
def str_to_tuple(stime):
print "returns the string variable into time tuples"
return time.strptime(stime,"%Y-%m-%d %H:%M:%S")
def add_date(day_num):
today=date.today()
print "returns the current date-%s and a time interval-%s" %(today,day_num)
times=today+timedelta(days=day_num)
return times
def sub_date(day_num):
today=date.today()
print "returns the current date-%s minus one time interval-%s" %(today,day_num)
times=today-timedelta(days=day_num)
return times
if __name__==‘__main__‘:
#测试代码
print date_time_chinese()
print date_chinese()
print time_chinese()
print date_time()
print date_time_slash()
print dates()
print date_slash()
print times()
print year()
print month()
print day()
print hour()
print minute()
print seconds()
time1=time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())
print str_to_tuple(time1)
print add_date(2)
print sub_date(2)
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/Util/FormatTime.py
returns the current time string,format for YYYY年mm月dd日HH时MM分SS秒
2018年07月11日 23时01分36秒
returns the current time string, format for YYYY年mm月dd日
2018年07月11日
returns the current time string,format for HH时 MM分 SS秒
23时01分36秒
returns the current time string, format for YYYY-mm-dd HH:MM:SS
2018-07-11 23:01:36
returns the current time string,format for YYYY/mm/dd HH:MM:SS
2018/07/11 23:01:36
returns the current time string,format for YYYY-mm-dd
2018-07-11
returns the current time string,format for YYYY/mm/dd
2018/07/11
returns the current time string, format for HH:MM:SS
23:01:36
returns the current time string,format for year
2018
returns the current time string,format for month
07
returns the current time string,format for day
11
returns the current time string, format for Hour
23
returns the current time string,format for minute
01
return the current time string,format for seconds
36
returns the string variable into time tuples
time.struct_time(tm_year=2018, tm_mon=7, tm_mday=11, tm_hour=23, tm_min=1, tm_sec=36, tm_wday=2, tm_yday=192, tm_isdst=-1)
returns the current date-2018-07-11 and a time interval-2
2018-07-13
returns the current date-2018-07-11 minus one time interval-2
2018-07-09
Process finished with exit code 0
#encoding=utf-8
#author-夏晓旭
from selenium import webdriver
import time
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException, NoSuchElementException
import traceback
from PageObject.Login_Page import *
from PageObject.AddressBook import *
from Action.add_contact import *
from Action.login import *
from ProjectVar.var import *
from Util.Excel import *
from Util.log import *
from Util.FormatTime import *
driver=webdriver.Firefox(executable_path=‘c:\\geckodriver‘)
driver.get(‘http://mail.126.com‘)
pe=parseExcel(test_data_excel_path)
pe.set_sheet_by_name(u"126账号")
print pe.get_default_sheet()
rows=pe.get_all_rows()[1:]
for id,row in enumerate(rows):
if row[4].value ==‘y‘:
username = row[1].value
password = row[2].value
print username, password
try:
login(driver,username,password)
pe.set_sheet_by_name(u"联系人")
print pe.get_default_sheet()
rows1=pe.get_all_rows()[1:]
print "rows1:",rows1
test_data_pass_flag=True#结果表示,用于最后写入excel结果
for id1,row in enumerate(rows1):
if row[7].value == ‘y‘:
try:
#print row[1].value,row[2].value,row[3].value,row[4].value,row[5].value
print "log0711",row[1],row[1].value
print "log0711",type(row[1].value)
#进行添加联系人的实际操作
add_contact(driver,row[1].value,row[2].value,row[3].value,row[4].value,row[5].value)
pe.write_cell_content(id1 + 2, 9, date_time())
print "assert word:",row[6].value
assert row[6].value in driver.page_source
pe.write_cell_content(id1+2,10,"pass")#assert没有报错,说明断言成功
except Exception,e:
#print u"异常信息01",e.message
pe.write_cell_content(id1+2,10,"fail")
pe.write_cell_content(id1+2,9,date_time())
test_data_pass_flag=False#代码走到这里,说明有异常,测试失败
info(u"异常信息01" + e.message) # 输出日志
else:#说明标识为‘n‘,忽略该数据
pe.write_cell_content(id1+2,10,u"忽略")
pe.write_cell_content(id1 + 2, 9,date_time())
continue
if test_data_pass_flag ==True:#如果标识是True,说明结果是成功的
pe.set_sheet_by_name(u"126账号")
pe.write_cell_content(id+2,6,"成功")
else:#说明标识是False
pe.set_sheet_by_name(u"126账号")
pe.write_cell_content(id+2,6,"失败")
except Exception,e:
pe.set_sheet_by_name(u"126账号")
#print u"异常信息02:",e
pe.write_cell_content(id+2,6,"fail")
info(u"异常信息02:"+e.message)#输出日志
time.sleep(2)
driver.quit()
else:#走这个分支,说明标识为"n"
pe.set_sheet_by_name(u"126账号")
pe.write_cell_content(id+2,6,u"忽略")
continue
C:\Python27\python.exe D:/test/dataDrivenTestPractice1/TestScript/TestScript.py
126账号
xiaxiaoxu1987 gloryroad
2018-07-11 23:17:39 log.py[line:19] INFO login successfully
联系人
rows1: [(<Cell u‘\u8054\u7cfb\u4eba‘.A2>, <Cell u‘\u8054\u7cfb\u4eba‘.B2>, <Cell u‘\u8054\u7cfb\u4eba‘.C2>, <Cell u‘\u8054\u7cfb\u4eba‘.D2>, <Cell u‘\u8054\u7cfb\u4eba‘.E2>, <Cell u‘\u8054\u7cfb\u4eba‘.F2>, <Cell u‘\u8054\u7cfb\u4eba‘.G2>, <Cell u‘\u8054\u7cfb\u4eba‘.H2>, <Cell u‘\u8054\u7cfb\u4eba‘.I2>, <Cell u‘\u8054\u7cfb\u4eba‘.J2>), (<Cell u‘\u8054\u7cfb\u4eba‘.A3>, <Cell u‘\u8054\u7cfb\u4eba‘.B3>, <Cell u‘\u8054\u7cfb\u4eba‘.C3>, <Cell u‘\u8054\u7cfb\u4eba‘.D3>, <Cell u‘\u8054\u7cfb\u4eba‘.E3>, <Cell u‘\u8054\u7cfb\u4eba‘.F3>, <Cell u‘\u8054\u7cfb\u4eba‘.G3>, <Cell u‘\u8054\u7cfb\u4eba‘.H3>, <Cell u‘\u8054\u7cfb\u4eba‘.I3>, <Cell u‘\u8054\u7cfb\u4eba‘.J3>), (<Cell u‘\u8054\u7cfb\u4eba‘.A4>, <Cell u‘\u8054\u7cfb\u4eba‘.B4>, <Cell u‘\u8054\u7cfb\u4eba‘.C4>, <Cell u‘\u8054\u7cfb\u4eba‘.D4>, <Cell u‘\u8054\u7cfb\u4eba‘.E4>, <Cell u‘\u8054\u7cfb\u4eba‘.F4>, <Cell u‘\u8054\u7cfb\u4eba‘.G4>, <Cell u‘\u8054\u7cfb\u4eba‘.H4>, <Cell u‘\u8054\u7cfb\u4eba‘.I4>, <Cell u‘\u8054\u7cfb\u4eba‘.J4>), (<Cell u‘\u8054\u7cfb\u4eba‘.A5>, <Cell u‘\u8054\u7cfb\u4eba‘.B5>, <Cell u‘\u8054\u7cfb\u4eba‘.C5>, <Cell u‘\u8054\u7cfb\u4eba‘.D5>, <Cell u‘\u8054\u7cfb\u4eba‘.E5>, <Cell u‘\u8054\u7cfb\u4eba‘.F5>, <Cell u‘\u8054\u7cfb\u4eba‘.G5>, <Cell u‘\u8054\u7cfb\u4eba‘.H5>, <Cell u‘\u8054\u7cfb\u4eba‘.I5>, <Cell u‘\u8054\u7cfb\u4eba‘.J5>)]
log0711 <Cell u‘\u8054\u7cfb\u4eba‘.B2> lily
log0711 <type ‘unicode‘>
returns the current time string, format for YYYY-mm-dd HH:MM:SS
assert word: lily@qq.com
returns the current time string, format for YYYY-mm-dd HH:MM:SS
returns the current time string, format for YYYY-mm-dd HH:MM:SS
returns the current time string, format for YYYY-mm-dd HH:MM:SS
Process finished with exit code 0
总结:
现在我们就是先从组装零散的功能实现一个较大的功能,然后把较大的功能组织成一个更大的功能,到最后在主程序中我们看到的就是独立大块儿功能的组合,看起来很整洁,简单,可读性高,也方便维护。
这样我们把整个框架从零散的罗列代码到封装成一块块的功能,把数据和程序做一个分离,把某一个独立的功能进行封装,整合,在这个过程中,就把搭框架的步骤熟悉了,知道了封装成几大块的来龙去脉和带来的好处,之后再搭建测试框架的时候,就直接按照这几大块来搭就行了,相对会比较容易接受这个思路和逻辑还有它的必要性,从根本上理解了为什么要搭建这样的测试框架,以及这个测试框架的原理,进而会举一反三,扩展到其他类型的测试框架当中。
多动手实践~
python webdriver 一步一步搭建数据驱动测试框架的过程和总结
原文:https://www.cnblogs.com/xiaxiaoxu/p/9297298.html