关于selenium+python的框架

目前公司需要上自动化,先学习之。现在努力在优化架构。现在我搭建的架构如下:

其中:

autocase:自动化用例

data:参数数据

pagescreens:截图(当出现错误,或者需要监控时)

report:测试报告

test_case:测试用例

all_test:测试用例集

 

现在的架子还有一点就是封装,基础类的封装。这个没有做好,需要继续的完善

 

2015-7-22,框架补充

目前研究的框架为selenium2+python+unittest,模式为po(pageobject),在实践中进行学习。

首先建立基础类(basepage)

# -*- coding: utf-8 -*-
'''
Created on 2015年7月21日

@author: admin
方法:基础类,供所有类继承
'''
from selenium.webdriver.support.wait import WebDriverWait
from selenium import webdriver
import time
import sys
reload(sys)
import time, os

class Action(object):
    """
    BasePage封装所有页面都公用的方法,例如driver, url
    """
    kb_url = "http://127.0.0.1:1080/"
    
    #初始化driver、url、等
    def __init__(self, selenium_driver, base_url=kb_url, parent=None):
    
        self.base_url = base_url
        self.driver = selenium_driver
        self.timeout = 30
        self.parent = parent
        self.tabs = {}
        """
        通过传参选择启动浏览器
        # self.browser = "Firefox" #传入浏览器对象
        # if Action.driver == None:
        #     if self.browser.upper() == 'IE': Action.driver = webdriver.Ie()
        #     elif self.browser.upper() == 'CHROME': Action.driver = webdriver.Chrome()
        #     elif self.browser.upper() == 'FIREFOX': Action.driver = webdriver.Firefox()
        #     elif self.browser.upper() == 'SAFARI': Action.driver = webdriver.Safari()
        #     else: Action.driver = webdriver.Ie()
        #     Action.driver.maximize_window()
        # #pass
        #     #print u"加载浏览器驱动失败!"
        # self.driver = Action.driver
        self.verificationErrors = []
        """
    #打开页面,校验页面链接是否加载正确
    def _open(self, url):
        #使用get打开访问链接地址
        url = self.base_url + url
        self.driver.get(url)
        self.driver.maximize_window()
        #使用assert进行校验,打开的链接地址是否与配置的地址一致。调用on_page()方法
        assert self.on_page(), u"打开开页面失败 %s" % url

    #重写元素定位方法
    def find_element(self, *loc):
        #return self.driver.find_element(*loc)
        try:
            WebDriverWait(self.driver, 15).until(lambda driver: driver.find_element(*loc).is_displayed())
            return self.driver.find_element(*loc)
        except:
            print u"%s 页面中未能找到 %s 元素" % (self, loc)

    #重写一组元素定位方法
    def find_elements(self, *loc):
        #return self.driver.find_element(*loc)
        try:
            if len(self.driver.find_elements(*loc)):
                return self.driver.find_elements(*loc)
        except:
            print u"%s 页面中未能找到 %s 元素" % (self, loc)

    def open(self):
        self._open(self.url)

    def on_page(self):
        return self.driver.current_url == (self.base_url + self.url)
    #定义script方法,用于执行js脚本,范围执行结果
    def script(self, src):
        self.driver.execute_script(src)

    #重写定义send_keys方法
    def send_keys(self, loc, vaule, clear_first=True, click_first=True):
        try:
            if click_first:
                self.find_element(*loc).click()
            if clear_first:
                self.find_element(*loc).clear()
            self.find_element(*loc).send_keys(vaule)
        except AttributeError:
            print u"%s 页面中未能找到 %s 元素" % (self, loc)

    #savePngName:生成图片的名称
    def savePngName(self, name):
        """
        name:自定义图片的名称
        """
        day = time.strftime('%Y-%m-%d', time.localtime(time.time()))
        fp = "..\\result\\" + day + "\\image"
        tm = self.saveTime()
        type = ".png"
        if os.path.exists(fp):
            filename = str(fp)+"\\" + str(tm)+str("_")+str(name)+str(type)
            print filename
            return filename
        else:
            os.makedirs(fp)
            filename = str(fp)+ "\\" + str(tm)+str("_")+str(name)+str(type)
            print filename
            return filename

    #获取系统当前时间
    def saveTime(self):
        """
        返回当前系统时间以括号中(2014-08-29-15_21_55)展示
        """
        return time.strftime('%Y-%m-%d-%H_%M_%S', time.localtime(time.time()))

    #saveScreenshot:通过图片名称,进行截图保存
    def saveScreenshot(self, driver, name):
        """
        快照截图
        name:图片名称
        """
        #获取当前路径
        #print os.getcwd()
        image = driver.save_screenshot(self.savePngName(name))
        return image
        
        
View Code

 

接着定义我目前要使用的登陆类的page

# -*- coding: utf-8 -*-
'''
Created on 2015年7月21日

@author: admin
方法:登陆页面方法
'''
import basepage
from selenium.webdriver.common.by import By
import sys, os,time
reload(sys)
#继承BasePage类
class LoginPage(basepage.Action):
    
#定位器
    url = "/WebTours/"
    username_loc=(By.NAME, "username")
    password_loc=(By.NAME,"password")
    login_loc=(By.NAME,"login")
    #Action
    def open(self):
        self._open(self.url)
          
    #调用send_keys,输入用户名
    def input_username(self, username):
        #print self.username_loc
        self.send_keys(self.username_loc, username)
    #调用send_keys,输入密码
    def input_password(self, password):
        self.send_keys(self.password_loc, password)

    #调用click,点击登录
    def click_submit(self):
        self.find_element(*self.login_loc).click()
def test_user_login(driver, username, password):
    login_page = LoginPage(driver)
    login_page.open()
    time.sleep(3)
    driver.switch_to_frame("body")
    driver.switch_to_frame("navbar")
    login_page.input_username(username)
    login_page.input_password(password)
    login_page.click_submit()
View Code

然后在测试用例中,实现具体的操作

# -*- coding: utf-8 -*-

'''
Created on 2015年7月22日

@author
方法:登陆
'''
from selenium import webdriver
import sys, time
import unittest
import sys
reload(sys)
sys.path.append("po")
from po import logpage
class Log(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Firefox()
        self.driver.implicitly_wait(30)
        self.verificationErrors = []
        self.accept_next_alert = True
        
    def test_log(self):
        driver = self.driver
        username = 'today'
        password = '123'
        logpage.test_user_login(driver, username, password)
        
    def tearDown(self):
        time.sleep(5)
        self.driver.quit()
        self.assertEqual([], self.verificationErrors)  
if __name__ == "__main__":
    unittest.main()
View Code

一个简单的po模式就完成了。

在做这个之前,由于觉得难度很大,一直没有下决心去写,到处找源码,找别人的代码。其实真正写了,才有不同的体会,这个需要好好把握的一个度

目前完善的架构如下,当然还有很多需要改进的。继续努力吧

 

posted on 2015-07-15 15:44  today123  阅读(1288)  评论(0编辑  收藏  举报