首页 > 编程语言 > 详细

python webdriver 一步一步搭建数据驱动测试框架的过程和总结

时间:2018-07-11 23:49:16      阅读:573      评论:0      收藏:0      [点我收藏+]

一步一步搭建数据驱动测试框架的过程和总结
数据驱动框架结构:
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的功能做一个封装,然后在出程序里进行调用。

 

步骤2—把登录的功能抽离出来,进行封装,在主程序中调用

在工程下新建一个PageObject的包
在PageObject包下新建一个LoginPage的python文件,来封装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

 

至此,login功能封装好了,下面在修改主程序,调用LoginPage
TestScript.py:

#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

 

 

从主程序来看,添加联系人的动作也是可以进行封装的 ,先来进行这部分的封装,后续有问题再往回推导,先按照这个思路做一遍,然后再做一遍

步骤3—封装添加联系人的功能

在PageObject包下新建AddressBook的python文件
代码AddressBook.py:

#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

 

至此,添加联系人功能粗略的封装完了,下面在主程序中调用
TestScript.py:


#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元素的功能,找到用户名输入框元素的功能,然后再找单个元素的函数中就可以传递数据给参数进行查找了

步骤4—封装查找元素的功能

修改LoginPage.py:

#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文件来封装读取配置文件的方法

 

步骤5—把数据放到配置文件里,然后封装方法从文件里读数据

在工程下新建一个叫Conf的包(用来放配置相关的文件):
在Conf包下新建文件:PageObjectRepository.ini

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[.=‘确 定‘]

 

 

在工程下新建一个Util的包,这个包一般用来存放工具类,如读配置文件,查找元素方法,excel操作类,时间类,日志方法和操作,截图,报告模板之类的。
在Util包下新建一个python文件:ParsePageObjectRepository.py 用来封装读取配置文件的类

#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文件里,之后所有的配置文件的路径都以变量的形式维护在这个文件中,路径的获取用相对路径的方式,稳妥一些

 

步骤6—用变量来存配置文件的路径

在工程下新建一个ProjectVar的包
在ProjectVar包下新建一个var.py的python文件
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中读配置文件的执行

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‘]

 

接下来修来login.py文件中的调用,把需要手动输入的参数都用读配文件代替
修改login.py:

#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,每次执行这个盒子就行了,不用管里面的细节,所有的封装都是这个道理。

 

步骤7—封装查找元素的功能和login功能的进一步封装

在开始的框架结构中可以看到,查找元素的方法可以放到Util包中

在Util包中新建ObjectMap.py文件
ObjectMap.py:

#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

 

至此查找元素的方法封装起来了,下面修改Login_Page.py来调用ObjectMap的方法实现各个查找元素的方法,并且对等登录动作做个封装。
Login_page.py:

#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就可以了。

 

步骤8—单独封装login方法

在工程下新建一个Action的包
在Action包下新建login.py
Login.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里面了,但是跟一开始的login_page.py情况一样,查找元素操作、读取配置文件数据还没有做,下面开始做这个

步骤9—封装添加联系人操作

思路:

在AddressBook.py里把添加联系人页面需要的各个元素封装成方法,其中找各个元素需要的xpath数据放在配置文件中,然后用一个函数来调用这些元素的方法,实现输入字符或者点击操作来实现添加联系人功能

AddressBook.py:

#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[.=‘确 定‘]

 

现在,我们已经把添加联系人页面的各个元素操作封装起来了,在测试代码中进行了调用,同login功能的封装一样,我们把对添加联系人页面的各个元素的操作封装在另一个文件中,在主程序中直接调用就可以了,方便操作。

步骤10—单独封装addressBook的添加联系人功能

在Action包下新建add_contact.py文件
add_contact.py:

#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()

 

结果:ok

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

 

 

至此,我们已经封装了大部分功能,现在来试一下主程序中调用这几个功能:
TestScript.py:

#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

 

从主程序中的调用来看,还是有一些数据是需要手动来输入的,如用户名、密码、需要添加的联系人信息,如果需要添加多个联系人的话,还需要多次输入,下一步就来看怎么把这部分数据和程序分离开,也是存到文件中,这次来放Excel中,然后用操作excel的方法来出取数据。

步骤11-封装excel操作

创建一个excel文件,第一个sheet来放126账号的信息

技术分享图片

第二个sheet放联系人:

技术分享图片

在工程下新建一个TestData的包,把excel文件放到该包下
Excel.py:

#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

 

至此,对excel操作就封装完了,下面在主程序中试一下对数据的读取
TestScript.py:

#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

 

结果:执行ok

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

 

Excel结果:

技术分享图片

技术分享图片

 

至此,该框架大部分功能已经封装好了,下面再搞一下日志模块,使程序在执行的时候能够打印日志

 

步骤12—添加日志log模块

在Conf包下新建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

 

 

在Util包下新建log.py文件,来封装日志的操作
Log.py:

 

#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了,下面修改主程序并且调用日志。

 

 

TestScript.py:

#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

 

结果:运行ok

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

 

至此,主程序中实现了读取数据、登录邮箱、添加联系人、往excel里写入测试结果,基本的功能已经搞定了,下面再搞一个地方,就接近完美了,就是对时间的封装,在程序中调用时间函数写入指定的时间格式。

 

步骤13—常用时间操作的封装

在Util包下新建FormatTime.py
FormatTime.py

#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)

 

结果:ok,pycharm里中文不需要转码,在notepad里运行需要转码

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

 

修改主程序,调用时间函数,打印时间
TestScript.py:

 

#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

 

结果: ok

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

Excel写入结果:

技术分享图片

技术分享图片

总结:

现在我们就是先从组装零散的功能实现一个较大的功能,然后把较大的功能组织成一个更大的功能,到最后在主程序中我们看到的就是独立大块儿功能的组合,看起来很整洁,简单,可读性高,也方便维护。

这样我们把整个框架从零散的罗列代码到封装成一块块的功能,把数据和程序做一个分离,把某一个独立的功能进行封装,整合,在这个过程中,就把搭框架的步骤熟悉了,知道了封装成几大块的来龙去脉和带来的好处,之后再搭建测试框架的时候,就直接按照这几大块来搭就行了,相对会比较容易接受这个思路和逻辑还有它的必要性,从根本上理解了为什么要搭建这样的测试框架,以及这个测试框架的原理,进而会举一反三,扩展到其他类型的测试框架当中。

多动手实践~

 

python webdriver 一步一步搭建数据驱动测试框架的过程和总结

原文:https://www.cnblogs.com/xiaxiaoxu/p/9297298.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!