WebUI自动化测试

WebUI自动化测试,第1张

主要是selenium+pytest+POM

一、selenium

初始框架:

# 导入模块
from selenium import webdriver
from time import sleep

# 实例化浏览器对象
driver = webdriver.Chrome()

# 打开网页
driver.get('***.html')

# 展示效果
sleep(3)
# 关闭页面
driver.quit()

元素定位

# 使用id定位
element = driver.find_element_by_id('xx')
# 使用name定位
element = driver.find_element_by_name('xx')
# class_name根据元素class属性定位元素
element = driver.find_element_by_class_name('xx')
# tag_name:标签名
element = driver.find_element_by_tag_name('xx')
# 使用link_text定位访问超链接
l = driver.find_element_by_link_text('xx')
# 只需要超链接的部分文本信息

pl = driver.find_element_by_partial_link_text('xx')

除了id唯一外,其他都有重复的可能,所以其他要保证唯一性

元素信息

element.size, element.text, element.get_attribute('class'), element.is_displayed(),element.is_enabled(), element.is_selected()

元素 *** 作方法

element.send_keys('xx')、element.click()

driver *** 作

driver.back()
driver.forward()
driver.refresh()
driver.close()
driver.quit()
driver.title
driver.current_url

定位一组元素

usernames = driver.find_elements_by_name('xxx')
for username in usernames:
    username.send_keys('xxx')
    sleep(3)

XPath

# XPath
# 路径:定位
# 利用元素属性:定位
# 属性与逻辑结合:定位
# 层级与属性结合:定位
# 方法名:find_element_by_xpath(xpath)
# 绝对路径:从最外层元素到指定元素之间所有经过元素层级的路径,以/html开始
# 相对路径:匹配任意层级的元素,不限制元素的位置,以//开始
# 利用元素属性策略
# 语法://标签名[@属性名='属性值']
# 语法: //*[@属性名='属性值' and @属性名='属性值']
# 层级与属性结合
# //*[@id='p1']/input

# 延伸://*[text()="xxx"] 文本内容是xxx的元素
# //*[contains(@attribute,'xxx')] 属性中含有xxx的元素
# //*[starts-with(@attribute, 'xxx')] 属性以xxx开头

CSS

# 推荐使用CSS比Xpath快
# CSS定位常用策略:
# 1. id选择器  #id
# 2. class选择器 .class
# 3. 元素选择器  element(标签)
# 4. 属性选择器 [属性=值]
# 5. 层级选择器
# 方法:find_element_by_css_selector
# 层级:父子:>,祖辈和后代:空格
# CSS延伸
# input[type^='p'] 以p开头
# input[type$='d'] 以d结尾
# input[type*='w'] 包含w的

下拉框

select = Select(wb.find_element_by_id('selectA'))
select.select_by_index(2)

元素等待

# 在定位页面元素时如果未找到,会在指定时间内一直等待的过程
# 为什么设置?1. 网络速度慢 2. 电脑配置低 3. 服务器处理请求慢
# 隐式等待和显示等待
# 隐式等待:如果能找到元素就不等待,如果找不到就隔一段时间(默认值)定位,如果达到最大时间还没找到,就抛出异常
# driver.implicitly_wait(timeout)
# timeout为等待最大时长,单位为s
# 隐式等待为全局设置,设置一次作用于所有元素
# 当隐式等待被激活时,虽然目标元素已经出现了,但是还是会因为页面内其他元素未加载完成而继续等待,进而增加代码执行时间
# 显示等待,如果能找到元素就不等待,如果找不到就隔一段时间(默认值)定位,如果达到最大时间还没找到,就抛出异常
element = WebDriverWait(driver, 10, 1).until(lambda x: x.find_element_by_id("userA"))
element.send_keys('admin') #显示

frame

# 当确定id却提示没有定位到元素的时候,可以考虑是不是有frame
# 如果有frame包含的要先获取frame
driver.switch_to_frame('idframe1')

多窗口

# 当点击超链接的时候,切换到另一个窗口的时候要切换handle,每次调用的时候每个窗口都会创建自己独立的handle
hand = driver.current_window_handle
driver.switch_to.window(hand)

截图

driver.get_screenshot_as_file('./1.png')

系统d窗

# alert元素
element = driver.find_element_by_xpath('//*[@id="alerta"]').click()
#alert = driver.switch_to_alert()
# 切换到d窗
alert = driver.switch_to.alert
print(alert.text)
sleep(3)
# 去除d窗
alert.accept() # 同意

键盘 *** 作

# 删除:BACK_SPACE, SPACE 空格, TAB 制表, ESCAPE 回退, ENTER 回车, CONTROL 'a' 全选, CONTROL 'c' 复制
str = username.send_keys(Keys.CONTROL, 'c')
password.send_keys(Keys.CONTROL, 'v')

鼠标 *** 作

username = driver.find_element_by_id('userA')
action.context_click(username)# 右键,鼠标右键只能展示菜单内容,菜单中的元素无法 *** 作
action.perform() # 该方法必须调用
sleep(3)
# 左键
action.click(username)
action.perform() # 该方法必须调用
sleep(2)

# 双击
username.send_keys("admin")
action.double_click(username)
action.perform()
sleep(3)

# 拖拽, 起点元素和终点, 主要用于滑块验证码(以前)
ll = driver.find_element_by_link_text('访问 新浪 网站')
action.drag_and_drop(ll, username)
action.perform()
sleep(3)

# 悬停
element = driver.find_element_by_xpath('//*[@id="zc"]/fieldset/button')
action.move_to_element(element)
action.perform()
sleep(3)

验证码

# 验证码处理方式
# 去掉,设置万能验证码,验证码识别技术,记录cookie
cookie_value = {'name':'BDUSS',
 'value':'cookie'}

driver.add_cookie(cookie_value)
driver.refresh()

滚动条

# selenium没有专门 *** 作滚动条的,但是可以用js代码来实现
js = 'window.scrollTo(0, 1000)'
driver.execute_script(js)
sleep(3)
js = 'window.scrollTo(0, 0)'
driver.execute_script(js)
sleep(3)

Pytest(python自动化测试框架)

# 函数形式 pytest -s 1.py -s表示输出打印信息
def test_func():
    print('我是测试函数')
# 测试类 类名必须以Test开头
class Test_demo(object):
    def test_method1(self):
        print('测试方法1')

    def test_method2(self):
        print('测试方法2')
# 主函数方法执行
import pytest

if __name__ == "__main__":
    pytest.main(['-s', './2.py'])
class Test_demo():
    def setup_class(self):# 类级别
        print('start')

    def teardown_class(self):# 类级别
        print('end')

    def setup(self):# 方法级别
        print('开始')

    def test_1(self):
        print('1')

    def test_2(self):
        print('2')

    def teardown(self):# 方法级别
        print('结束')
# 控制顺序
import pytest

class Test_demo():
    def setup_class(self):# 类级别
        print('start')

    def teardown_class(self):
        print('end')

    def setup(self):
        print('开始')

    @pytest.mark.run(order=2)# 控制执行顺序
    def test_1(self):
        print('1')

    @pytest.mark.run(order=1)
    @pytest.mark.skip('noreason') #跳过 *** 作
    def test_2(self):
        print('2')
        assert 1==2

    @pytest.mark.parametrize('password, username', [('123456', 'li'), ('4444', 'e')]) #参数
    def test_canshu(self, password, username):
        print(username, password)
    def teardown(self):
        print('结束')

pytest执行顺序就是定义的顺序,而unittest顺序是根据ASCII码来的

pytest.ini

[pytest]

test_path=./
addopts=-s
        --html=./test.html # 测试报告
        --reruns 2 # 重跑
python_files=*.py
python_classes=Test*
python_functions=test*

断言直接使用assert

PO设计模式

Base:base.py get_driver.py

# base.py
from selenium.webdriver.support.wait import WebDriverWait
import time

class Base:
    def __init__(self, driver):
        self.driver = driver

    def base_find_element(self, loc, timeout=30, poll=0.5):
        return WebDriverWait(self.driver, timeout=timeout, poll_frequency=poll).until(lambda x:x.find_element(*loc))

    def base_click(self, loc):
        self.base_find_element(loc).click()

    def base_get_value(self, loc):
        return self.base_find_element(loc).get_attribute('value')

    def base_get_img(self):
        self.driver.get_screenshot_as_file('./{}.png'.format(time.strftime('%Y_%m_%d_%H_%M_%S')))
#get_driver.py
from selenium import webdriver
import PO设计模式.v4.page as page

class GetDriver:
    driver = None
    @classmethod
    def get_driver(cls):
        if cls.driver == None:
            cls.driver = webdriver.Chrome()
            cls.driver.maximize_window()
            cls.driver.get(page.url)
        return cls.driver

    @classmethod
    def quit_driver(cls):
        if cls.driver:
            cls.driver.quit()
            cls.driver = None

data: 主要放json数据

test.json

page:__init__.py、以及各种对页面的 *** 作

#__init__.py
from selenium.webdriver.common.by import By

url='http://cal.apple886.com/'
xx = By.CSS_SELECTOR,"xx"

page: xx.py

from time import sleep
from PO设计模式.v4 import page
from PO设计模式.v4.base.base import Base
from selenium.webdriver.common.by import By

class xx(Base):
    def page_click_xx(self):
        self.base_click(page.xx)
    ...

scripts:放各种test类

import pytest

from PO设计模式.v4.base.get_driver import GetDriver
from PO设计模式.v4.page.page_cal import xx

from PO设计模式.v4.tool.read_json import read_json


def get_data():
    data = read_json("xx.json")
    # print(data)
    """
    期望数据格式:[(xx,xx), (xx,xx), (xx,xx)]
    """
    list = []
    for n in data.values():
        list.append((n["a"], n["b"], n["expect_result"]))
    return list

class Testxx():
    # driver = None
    @classmethod
    def setup_class(cls):
        cls.driver = GetDriver().get_driver()
        cls.xx = Pagexx(cls.driver)

    @classmethod
    def teardown_class(cls):
        GetDriver().quit_driver()

    @pytest.mark.parametrize('a,expect_result', get_data())
    def test_add_cla(self,a,expect_result):
        self.xx.page_add_xx(a)
        result = ...
        try:
            self.assertEqual(result,str(expect_result))
        except:
            raise
        finally:
            pass

if __name__ == '__main__':
    pytest.main('-s', 'test_xx.py', "--html='./result.html'")

tool:read_json.py

import json

def read_json(filename):
    filepath ="../data/"+ filename
    with open(filepath,"r",encoding="utf8") as f:
        return json.load(f)

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/883467.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-14
下一篇 2022-05-14

发表评论

登录后才能评论

评论列表(0条)

保存