selenium+python⾃动化测试系列(⼀):登录
    最近接⼿商城的项⽬,针对后台测试,功能⽐较简单,但是流程⽐较繁多,涉及到前后台的交叉测试。在对整个项⽬进⾏第⼀轮测试完成之后,考虑以后回归测试任务⽐较重,为了减轻回归测试的⼯作量,所以考虑后台可以进⾏部分⾃动化测试。
    之前⼀个项⽬使⽤robotframework进⾏回归测试,了解了python语⾔,所以这次就使⽤python+selenium进⾏⾃动化回归测试了。
配置环境
python2.7
运⾏⼯具pycharm2017
流程说明
登录操作步骤说明
1. 打开登录url,如19
2.168.10.6/login
2. 在⽤户名输⼊框中输⼊登录的⽤户名,如test001
3. 在密码是输⼊框中输⼊密码,如testgood001
4. 点击登录页⾯的登录按钮,
5. 登录成功页⾯,断⾔登录成功
线性操作
根据上⾯的步骤提⽰下⾯代码显⽰登录操作,如下
#coding=utf-8
from selenium import webdriver
import unittest
import sys
reload(sys)
sys.setdefaultencoding('utf8')
class TestLogin(unittest.TestCase):
# 指定浏览器
def setUp(self):
self.driver = webdriver.Firefox()
# 打开url
("192.168.10.6/login")
# 登录操作
def test_login(self):
title = self.driver.title
print title
now_url = self.driver.current_url
print now_url
username = "test001"
password = "testgood001"
# 执⾏登录操作
#⽤户名的定位
self.driver.find_element_by_id("username").clear()
self.driver.find_element_by_id("username").send_keys(username)
#密码的定位
self.driver.find_element_by_id("password").clear()
self.driver.find_element_by_id("password").send_keys(password)
# 点击登录
self.driver.find_element_by_css_selector(".btn.btn-success.btn-block").click()
# 登录成功断⾔
login_name = self.driver.find_element_by_xpath('html/body/div[3]/div[2]/ul/li[1]/a/strong').text
login_name = login_name.strip('您好:')
assert login_name == username
# 关闭浏览器
def tearDown(self):
self.driver.quit()
if __name__ == "__main__":
unittest.main()
    上⾯代码显⽰的是登录成功的正常⽤例;实际操作中,针对登录不仅仅有正常⽤例,还有异常⽤例,如⽤户名为空,密码为空,⽤户名错误,密码错误等;我们不能⼀个⽤例编写⼀个py⽂件,如果这样操作从本质⽽⾔相反增加了⼯作量。
    既然问题出来了,那么如何解决这个问题呢?
    思路:针对登录⽽⾔,所有的步骤都是⼀样的,唯⼀不同的就是登录的⽤户名和密码,所以我们可以封装登录步骤,然后只需要专注不
同测试⽤例中的登录的⽤户名和密码的验证即可。
    这⾥为了后续测试的简便,使⽤了selenium中的po模式,即针对每个功能的操作页⾯进⾏封装,⽽后在针对该页⾯进⾏测试⽤例的编写。如这⾥的登录页⾯,我们需要针对登录页⾯进⾏封装操作,把登录页⾯中的⽤户名、密码和登录按钮的定位进⾏封装,这样⽤例中只关注输⼊不同的⽤户名和密码进⾏验证即可。
说明:
    这⾥浏览器的打开和关闭也进⾏了封装,放在myunit.py中。
po模式设计
    整体设计的结构如图所⽰
    models/driver.py中封装了打开浏览器的操作,这⾥使⽤的⽕狐浏览器进⾏操作。代码如下
# -*-coding:utf-8-*-
# _author_ = "janehost"
from selenium.webdriver import Remote
from selenium import webdriver
import sys
# 启动浏览器
reload(sys)
sys.setdefaultencoding('utf8')
def browser():
driver = webdriver.Firefox()
return driver
if __name__ == '__main__':
dr = browser()
<("192.168.10.6/login")
dr.quit()
    models/myunit.py中主要封装了浏览器的启动和关闭的操作,代码如下
# -*-coding:utf-8-*-
# _author_ = "janehost"
import unittest,sys
from selenium import webdriver
from driver import browser
reload(sys)
sys.setdefaultencoding('utf8')
class MyTest(unittest.TestCase):
def setUp(self):
self.driver = browser()
self.driver.implicitly_wait(10)
self.driver.maximize_window()
def tearDown(self):
self.driver.quit()
if __name__ == '__main__':
unittest.main()
    models/function.py中主要封装了截图的操作⽅法,代码参考如下
# -*-coding:utf-8-*-
# _author_ = "janehost"
from selenium import webdriver
import os,sys
reload(sys)
sys.setdefaultencoding('utf8')
# 截图函数
def insert_img(driver, file_name):
base_dir = os.path.dirname(os.path.dirname(__file__))
base_dir = str(base_dir)
base_dir = place('\\', '/')
base = base_dir.split('test_case')[0]
file_path = base + "report/image/" + file_name
<_screenshot_as_file(file_path)
if __name__ == '__main__':
driver = webdriver.Firefox()
<("192.168.10.6/login")
insert_img(driver, 'login.jpg')
driver.quit()
    下⾯就是po模式的重点,针对页⾯的封装,⾸先创建⼀个page页⾯的基本页⾯,page_obj\base.py代码如下# -*-coding:utf-8-*-
# _author_ = "janehost"
from selenium.webdriver.support.wait import WebDriverWait
selenium xpath定位from selenium.webdriver.support import expected_conditions as EC
import sys
reload(sys)
sys.setdefaultencoding('utf8')
class Page(object):
'''
页⾯基础类,⽤于所有页⾯的继承
'''
base_url = "192.168.10.6/login"
def __init__(self, selenium_driver, base_url=base_url, parent=None):
self.base_url = base_url
self.driver = selenium_driver
self.timeout = 30
self.parent = parent
def _open(self, url):
url = self.base_url + url
(url)
_page(), 'Did not land on %s' % url
def open(self):
self._open(self.url)
def on_page(self):
#return (self.driver.current_url).encode('utf-8') == (self.base_url + self.url)
return self.driver.de('utf-8') == (self.base_url + self.url)
def find_element(self, *loc):
# return self.driver.find_element(*loc)
try:
# 确保所有元素是可见的
# 注意:以下⼊参为元组的元素,需要加*。python存在这种特性,就是将⼊参放在元组⾥。
#WebDriverWait(self.driver,10).until(lambda driver: driver.find_element(*loc).is_displayed())
# 注意:以下⼊参本⾝是元组,不需要加*
WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(loc))
return self.driver.find_element(*loc)
except:
print u"%s 页⾯中未能到 %s 元素"%(self, loc)
def find_elements(self, *loc):
return self.driver.find_elements(*loc)
def script(self, src):
return ute_script(src)
def swtich_frame(self, loc):
return self.driver.swith_to_frame(loc)
def send_keys(self, loc, value, clear_first=True, click_first=True):
try:
# getattr相当于self.loc
loc = getattr(self, "_%s" % loc)
if click_first:
self.find_element(*loc).click()
if clear_first:
self.find_element(*loc).clear()
self.find_element(*loc).send_keys(value)
except ArithmeticError:
print u"%s 页⾯中未能到 %s 元素" % (self, loc)
    登录页⾯元素的封装page_obj\loginPage.py,代码如下
# -*-coding:utf-8-*-
# _author_ = "janehost"
"""
思路:创建登录页⾯对象,对⽤户登录页⾯上的⽤户名/密码输⼊框、登录按钮和
提⽰信息等元素的定位进⾏封装。
"""
from selenium.webdrivermon.action_chains import ActionChains
from selenium.webdrivermon.by import By
from base import Page
from time import sleep
class login(Page):
'''
⽤户登录界⾯
'''
url = '/'
# 登录⽤户名的定位
login_username_loc = (By.ID, 'username')
# 登录密码的定位
login_password_loc = (By.ID,'password')
# 登录按钮的定位
login_button_loc = (By.CSS_SELECTOR,'.btn.btn-success.btn-block')
# 登录错误提⽰的定位
login_error_loc = (By.ID,'error_msg')
# 登录成功⽤户名信息
login_user_success_loc = (By.XPATH, 'html/body/div[3]/div[2]/ul/li[1]/a/strong') # 登录⽤户名
def login_username(self, username):
self.find_element(*self.login_username_loc).clear()
self.find_element(*self.login_username_loc).send_keys(username)
# 登录密码
def login_password(self, password):
self.find_element(*self.login_password_loc).clear()
self.find_element(*self.login_password_loc).send_keys(password)
# 登录按钮
def login_button(self):
self.find_element(*self.login_button_loc).click()
# 统⼀登录⼊⼝
def user_login(self, username="testuser01", password="testgood001"):
# 获取⽤户名和页⾯登录
self.open()
self.login_username(username)
self.login_password(password)
self.login_button()
sleep(3)
# 登录错误提⽰信息
def login_error_hint(self):
return self.find_element(*self.login_error_loc).text
# 登录成功⽤户名信息
def login_user_success(self):
#return self.find_element(*self.login_user_success_loc).text
username = self.find_element(*self.login_user_success_loc).text
username = username.strip('您好:')
return username
    登录测试⽤例信息test_case\login_sta.py,代码如下
# -*-coding:utf-8-*-
# _author_ = "janehost"
from time import sleep
import unittest, random, sys
from models import myunit, function
from page_obj.loginPage import login
sys.path.append("./models")
sys.path.append("./page_obj")
reload(sys)
sys.setdefaultencoding('utf8')
class loginTest(myunit.MyTest):
'''
测试⽤户登录
'''
def user_login_verify(self, username="", password=""):
login(self.driver).user_login(username, password)
def test_login1(self):
'''⽤户名、密码为空登录'''
self.user_login_verify()
po = login(self.driver)
self.assertEqual(po.login_error_hint(), '⽤户名或密码不能为空')
function.insert_img(self.driver, "user_pawd_empty.jpg")
def test_login2(self):
'''⽤户名正确,密码为空登录验证'''
self.user_login_verify(username="ces")
po = login(self.driver)
self.assertEqual(po.login_error_hint(), "⽤户名或密码不能为空")
function.insert_img(self.driver,"pawd_empty.jpg")
def test_login3(self):
'''⽤户名为空,密码正确'''
self.user_login_verify(password="12334ddf")
po = login(self.driver)
self.assertEqual(po.login_error_hint(),"⽤户名或密码不能为空")
function.insert_img(self.driver, "user_empty.jpg")
def test_login4(self):
'''⽤户名和密码不匹配'''
character = random.choice('abcdefghijklmnopqrstuvwxyz')
username = "sdw" + character
self.user_login_verify(username=username, password="2sdfd")
po = login(self.driver)
self.assertEqual(po.login_error_hint(), "⽤户名或密码错误")
function.insert_img(self.driver, "user_pass_error.jpg")
def test_login5(self):
'''⽤户名、密码正确'''
self.user_login_verify(username="adtest" , password="4dscsdx")
sleep(3)
po = login(self.driver)
self.assertEqual(po.login_user_success(), u'adtest')
function.insert_img(self.driver, "user_pwd_true.jpg")
if __name__ == '__main__':
unittest.main()
    这样登录的测试⽤例就完成了。使⽤po模式之后,如果页⾯ui发⽣变化,我们只需要修改元素的定位⽅法,⽽不需要改动整个框架,相对⽽⾔⽐较快捷。
参考:
⼩⼩的博客 []
selenium2 python⾃动化测试实战(⾍师)

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。