WebUi自动化测试

一、UI自动化测试基础知识点(元素定位暂不写)

              1、 技术架构:python+selenium;
              2、 自动化测试webdriver运行原理:
                  自动化测试代码发送请求给浏览器的驱动,浏览器驱动自动识别代码,解析后发送给浏览器,浏览器执行驱动发来的指令,完成自动化测试的工作;
              3、 webdriver长用属性以及方法:
                  driver.title---查看标题
                  driver.Current_url----查看地址
                  driver.windows_handles----查看浏览器句柄
              4、 close()与quit()区别:
                  close---退出当前页面,quit---退出浏览器;
              5、 webelement属性以及方法:
                  属性:
                  id:标识;
                  size:宽高;
                  rect:宽高和坐标;
                  tag_name:标签名称;
                  text:文本内容;
                  方法:
                  Send_size:输入内容
                  Click:点击
                  Clear:清除
                  Is_selected:是否被选中;
              6、 form表单操作:
                  流程:定位表单元素、输出测试数据、判断表单元素属性、获得表单元素属性、提交表单进行验证;
              7、 下拉列表操作:
                  Select_by_value():根据值选择
                  Select_by_index():根据索引选择
                  Select_by_visible_text():根据文本选择
弹窗处理:
1、alert:普通提示框。切换至弹窗--self.driver.swich_to.alert
2、confirm:删除数据提示框。切换至弹窗--self.driver.swich_to.alert
3、prompt:输入文本内容提示框。切换至弹窗--self.driver.swich_to.alert
以上三种弹窗的方法:accept()--接受、dismiss()--取消、text()--显示文本、send_keys()--输入内容;
三种等待:
1、wait:遇到环境网络等不稳定时候,如果不做处理,代码会因为没有找到元素而报错,这个时候需要使用wait等待方式;
2、time.sleep:让当前的线程睡眠,用于调试脚本;
3、implicitly_wait:隐式等待,最开始设置一次全程有效,按规定时间内网页加载完成,才执行下一步,否则会抛出异常;
4、webdriverwait:显式等待;参数:driver--webdriver实例、timeout--设置超时时间、poll_frequency--调试方法中的时间,默认0.5秒。方法:until--等待时间内,每隔一段时间传入这个方法,查看返回结果是不是TRUE、message--如果超时,就传入message异常;
鼠标操作:
之前定位的时候,用到了click点击元素,selenium除了click模拟鼠标单击操作外,还提供了双击、右击、悬停、拖动等操作,使用这些要导入ActionChains类:
from selenium.webdriver.common.action_chains import ActionChains。

ActionChains提供的操作如下:
*   perform() 执行所有 ActionChains 中存储的行为
*   context_click() 右击
*   double_click() 双击
*   drag_and_drop() 拖拽到某个元素
*   move_to_element() 鼠标悬停
*   drag_and_drop_by_offset()拖拽到某个坐标
示例:
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from time import sleep

driver=webdriver.Chrome()
driver.get("https://www.baidu.com/")
driver.maximize_window()
driver.find_element_by_css_selector("#kw").send_keys("锄禾")

#获取搜索框元素对象
element=driver.find_element_by_css_selector("#kw")
sleep(3)
#双击
ActionChains(driver).double_click(element).perform()
sleep(2)
#右击
ActionChains(driver).context_click(element).perform()
#鼠标悬停
#悬停在设置上
above=driver.find_element_by_css_selector(".pf")
ActionChains(driver).move_to_element(above).perform()
sleep(3)
driver.quit()

键盘操作:
1.模拟键盘的操作需要先导入键盘模块:
from selenium.webdriver.common.keys import Keys
2.Keys()类提供了键盘上几乎所有按键的方法。前面了解到,send_keys()方法可以用来模拟键盘 输入, 除此 之外, 我们还可以用它来输入键盘上的按键甚至是组合键, 如 Ctrl+A、 Ctrl+C 等。
3.常见的键盘操作:
send_keys(Keys.BACK_SPACE) #删除键(BackSpace)
send_keys(Keys.SPACE) #空格键(Space)
send_keys(Keys.TAB) #制表键(Tab)
send_keys(Keys.ESCAPE) #回退键(Esc)
send_keys(Keys.ENTER) #回车键(Enter)
send_keys(Keys.CONTROL,‘a’) #全选(Ctrl+A)
send_keys(Keys.CONTROL,‘c’) #复制(Ctrl+C)
send_keys(Keys.CONTROL,‘x’) #剪切(Ctrl+X)
send_keys(Keys.CONTROL,‘v’) #粘贴(Ctrl+V)
send_keys(Keys.F1) #键盘 F1
send_keys(Keys.F12) #键盘 F12

二、自动化项目实战

1、需求分析与用例设计:深度挖掘需求,设计测试用例
2、项目架构设计:合理设计目录以及包结构:
    Testcase测试用例:用来存放测试用例;
    Data测试数据:数据驱动实现测试,用于存放数据;
    Logs:log日志;
    Config:配置文件;
    Reports:测试报告;
    Screenshots:截屏;
    Lib:第三方库;
    Utils:工具类;
    Main.py:用于执行测试;
3、PyAutoGUI:图形用户界面自动化测试工具,通过X,Y坐标确定目标位置,控制鼠标键盘发送虚拟点击,完成按钮以及表单等操作;
    Pyautogui.position():确定鼠标当前位置;
    Pyautogui.moveTo(x,y[,duration=t]):移动;
    举例:
from selenium import webdriver
from time import sleep
import pyautogui

'''
定位按钮时,元素定位技术无法定位时,可以选择使用pyautogui技术通过x,y坐标进行定位
'''
def test():
    driver = webdriver.Chrome()
    driver.get("http://jpress.io/user/register")
    driver.maximize_window()
    sleep(2)
    elem = driver.find_element_by_id("agree")
    rect = elem.rect   #获取坐标
    pyautogui.click(rect['x']+30,rect['y']+130)
    sleep(4)
4、解决验证码验证问题:
    1、通过pytesseract某块和PIL模块进行验证
    具体步骤:1、获取整个页面;2、 获得验证码坐标位置数据;3、根据坐标位置抠图;4、使用pytesseract验证;
    举例:
from selenium import webdriver
from PIL import Image
import time
import pytesseract

#获取验证码截图
def test1():
    #打开谷歌浏览器
    browser = webdriver.Chrome()
    #打开首页
    browser.get("http://localhost:8080/jpress/user/register")
    browser.maximize_window()

    #获取验证码图片
    t = time.time()
    picture_name_1 = str(t) + '.png'
    browser.save_screenshot(picture_name_1)

    ce = browser.find_element_by_id("captchaimg")
    #获取位置信息
    print(ce.location)
    left = ce.location['x']
    top = ce.location['y']
    right = ce.size['width'] + left
    height = ce.size['height'] + top

    #扣图
    im = Image.open(picture_name_1)
    img = im.crop((left,top,right,height))

    #保存为第二章图片
    t = time.time()
    picture_name_2 = str(t) + '.png'
    img.save(picture_name_2)
    browser.close()

#得到截图中的字符串
def test2():
    #引入pytesseract方法识别图片中的验证码
    picture_name_2 = 'test.png'
    image_1 = Image.open(picture_name_2)
    str = pytesseract.image_to_string(image_1)
    #输出字符串
    print(str)
    2、通过第三方平台,AI算法识别:https://www.showapi.com/apiGateway/view/184?skuid=5f8e59a76e3607c363634c7e
5、完成用户注册功能测试用例(这点就直接编写测试用例,可以初始创建一个basic基础模块,用于封装用例,也为后期使用框架重构做准备)
6、pytest框架进行测试用例重构:简单灵活,支持参数化,可以支持简单的单元测试以及复杂的功能测试,具有丰富的第三方插件,集成selenium,集成html生成测试报告;
    编写规则:
    测试文件以test开头(以test结尾也可以)
    测试类以test开头,并且不能带有init方法
    测试函数以test开头
    断言使用基本的assert就可以
    控制台参数信息:-v---用于显示每个测试函数的执行结果
                   -s---用于显示测试函数中print()函数输出
                   -q---只显示整体测试结果
    标记:可以标记用例或者函数哪些执行哪些不执行;
    1、pytest查找策略:默认情况下pytest会递归查找以test开头或结尾的测试脚本,并执行文件内以test开始或结束的函数或方法;
    2、标记测试函数:由于某种原因,我们想执行指定的函数用例,可以通过标记进行编写;
        1、显示指定函数名,通过::标记:
         控制台输入:pytest test01.py :: test01
        2、使用模糊匹配,-k参数进行标识
         控制台输入:pytest -k add(模糊查询的字段) test01.py
    
    参数化设置:可以同时运行多个数据的测试:pytest.mark.parametrize
    举例:
import pytest

# 列表
data = ['123', '456']


@pytest.mark.parametrize('pwd', data)
def test1(pwd):
    print(pwd)

# 元组

data2 = [
    (1, 2, 3),  # 或者[1, 2,3]
    (4, 5, 6)  # 或者[4, 5,6]
]


@pytest.mark.parametrize('a, b, c', data2)
def test2(a, b, c):
    print(a, b, c)


# 字典

data3 = (
    {
        'user': 1,
        'pwd': 2
    },
    {
        'user': 3,
        'pwd': 4
    }
)


@pytest.mark.parametrize('dic', data3)
def test3(dic):
    print(dic)


data_1 = [
    pytest.param(1, 2, 3, id="(a+b):pass"),  # id的值可以自定义, 只要方便理解每个用例是干什么的即可
    pytest.param(4, 5, 10, id="(a+b):fail")
]


def add(a, b):
    return a + b


class TestParametrize(object):

    @pytest.mark.parametrize('a, b, expect', data_1)
    def test_parametrize_1(self, a, b, expect):
        assert add(a, b) == expect


if __name__ == '__main__':
    pytest.main(['-sv', 'test3.py'])
7、pytest fixture:使用fixture实现用例之间的一个调用;
    在函数上加一个装饰器:@pytest.fixture()
    fixture不能以test开头,与用例区分开,fixture有返回值,没有得话默认返回none;
    调用fixture得返回值,就是直接把fixture得函数名当作变量名;
示例:
import pytest

@pytest.fixture()
def init():
    print('init...')
    return 1

def test1(init):
    print('test1')

def test2(init):
    print('test2')

if __name__ == '__main__':
    pytest.main(['-s', '04 pytest Fixture.py']

8、pytest中setup与teardown:每次用例开始和结束都执行一次,可以之启动一次浏览器执行多个用例;
"""
模块级别:(setup_module/teardown_module)开始于模块的始末,全局的
函数级别:(setup_function/teardown_function)只对函数的用例生效,不在类中
类级别:(setup_class/teardown_class)只在类中前后运行一次(在类中,需要使用装饰器@classmethod)
方法级别:(setup_method/teardown_method)开始于方法始末(在类中)
类里面的:(setup/teardown)运行在调用方法的前后
所有级别名称必须写对
"""
import pytest

print("=========模块级别==========")
def setup_module():
    print("setup_module")

def teardown_module():
    print("teardown_module")

def test():
    print("test")

print("=========函数级别==========")
def setup_function():
    print("setup_function")

def teardown_function():
    print("teardown_function")

def test01():
    print("test01")
print("=========类级别==========")
class TestCase01(object):
    @classmethod
    def setup_class(cls):
        print("setup_class")
    @classmethod
    def teardown_class(cls):
        print("teardown_class")

    def test03(self):
        print("test03")
if __name__ == '__main__':
    pytest.main('-sv','test07.py')
9、生成测试报告:
    安装allure-pytest:pip install allure-pytest
    电脑本地安装allure,配置环境变量
    举例:
import allure
import pytest


@pytest.fixture(scope="session")
def login():
    print("用例先登录")


@allure.step("步骤1:点xxx")
def step_1():
    print("111")


@allure.step("步骤2:点xxx")
def step_2():
    print("222")


@allure.feature("编辑页面")
class TestEditPage():
    '''编辑页面'''

    @allure.story("这是一个xxx的用例")
    def test_1(self, login):
        '''用例描述:先登录,再去执行xxx'''
        step_1()
        step_2()
        print("xxx")

    @allure.story("打开a页面")
    def test_2(self, login):
        '''用例描述:先登录,再去执行yyy'''
        print("yyy")


if __name__ == '__main__':
    # 注意生成测试报告 必须在命令行执行

    #1、pytest --alluredir ./reports testcase/pytest/test6.py  (目录一定找对)
    #2、 allure serve reports
    pytest.main(['--alluredir', './reports', 'test08.py'])
10、进行重构:
    类中继承object;
    setup方法改为pytest setup;
    报告使用pytest插件;
    断言延用python自带得断言;
    使用pytest解决用例之间依赖关系:安装dependency:pip install pytest-dependency
        使用时在需要依赖得用例上加入装饰器:@pytest.mark.dependency(name='xxxx')
11、selenium读取数据库数据:
    安装mysqlclient
    获得数据库连接
    查询数据
    实例:
import MySQLdb

import pytest

conn = MySQLdb.connect(
    user='root',
    passwd='123456',
    host='localhost',
    port=3306,
    db='testing_db'
)


def get_data():
    query_sql = 'select id,username,pwd from user_tb'
    lst = []
    try:
        cursor = conn.cursor()
        cursor.execute(query_sql)
        r = cursor.fetchall()
        for x in r:
            u = (x[0], x[1], x[2])
            lst.append(u)
        return lst
    finally:
        cursor.close()
        conn.close()


@pytest.mark.parametrize('id, name, pwd', get_data())
def test1(id, name, pwd):
    print(id, name, pwd)


if __name__ == '__main__':
    pytest.main(['-sv'])

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,711评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,079评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,194评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,089评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,197评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,306评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,338评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,119评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,541评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,846评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,014评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,694评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,322评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,026评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,257评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,863评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,895评论 2 351

推荐阅读更多精彩内容