基于aw的关键字驱动模式介绍

关键字驱动是自动化测试框架搭建的一种思想,基于关键字驱动搭建的自动化测试框架也被称为表格驱动测试或者基于动作字的测试,也就是将测试执行的步骤,测试数据、预期结果都写在excel文件或yaml文件等文件中,可以从文件中读取相关步骤和数据执行测试并自动断言。以关键字驱动的思想来搭建自动化测试框架,就是把编码从测试用例和测试步骤中分离出来,这样对于不会编码的人员更容易理解自动化,从而让手工测试人员也可以编写自动脚本,这样可以降低整个团队的自动化测试成本。对于一个小型项目的测试团队来说有两三个自动化测试的技术人员,就可以满足自动化框架的构建,代码维护更新等自动化方面的工作,没有必要全员自动化,这样将大大减少人力成本。
本文就以一个登录功能来简单介绍一下关键字驱动的实现。我们将简化这个案例就不把测试的步骤和数据写到excel或者yaml这种文件中了,实际搭建框架时只是多了一步测试数据读取。
接下来我们来看一下实现的过程

## 首先封装一下AW,这个在之前的文章中已经介绍过了

# '''
# author=测试-老姜   交流微信/QQ:349940839
# 欢迎添加微信或QQ,加入学习群共同学习交流。
# QQ交流群号:877498247
# 西安的朋友欢迎当面交流。
# '''

from playwright.sync_api import Playwright, sync_playwright, expect

def element_click(locator):
    locator.click()

def element_fill(locator,value ):
    locator.clear()
    locator.fill(value )

def get_element_text(locator):
    return locator.inner_text()



def locat_element(page,selector):
    #定位元素
    return page.locator(selector)

def locat_frame_element(frame,selector):
    #定位frame框架内的元素
    return frame.locator(selector)

def locat_frame(page,selector,frame_index=0):
    #定位frame框架,可以传字符串或列表
    if type(selector) is str:
        return page.frame_locator(selector)
    elif type(selector) is list:
        frame = page.frame_locator(selector[0])
        for i in range(1,len(selector)):
            frame = frame.frame_locator(selector[i])
        return frame
    
def locat_element_click(page,selector):
    #定位元素,点击
    loc = locat_element(page,selector)
    element_click(loc)

def locat_frame_element_click(page,frame_selector,selector):
     #定位frame框架内元素,点击
    frame = locat_frame(page,frame_selector)
    loc = locat_frame_element(frame,selector)
    element_click(loc)



def locat_element_fill(page,selector,value):
    #定位元素,输入
    loc = locat_element(page,selector)
    element_fill(loc,value)

def locat_frame_element_fill(page,frame_selector,selector,value):
    #定位frame框架内元素,输入
    frame = locat_frame(page,frame_selector)
    loc = locat_frame_element(frame,selector)
    element_fill(loc,value)



def locat_element_get_text(page,selector):
    # 定位元素并获取元素上文本
    loc = locat_element(page,selector)
    return get_element_text(loc)

def locat_frame_element_get_text(page,frame_selector,selector):
    #定位frame框架内元素,获取元素上文本
    frame = locat_frame(page,frame_selector)
    loc = locat_frame_element(frame,selector)
    return get_element_text(loc)

def get_img(page,img_path,img_name):
    path = f'{img_path}\{img_name}.png'
    page.screenshot(path=path)

def assert_web_title(page,expect_title):
    """
    断言标题
    """
    try:
        act_title = page.title()
        assert expect_title == act_title
    except AssertionError as e:
        raise e
    except Exception as e:
        raise e

def assert_element_text(page,selector,expect_text):
    """
    断言元素上的文字
    """
    try:
        text = locat_element_get_text(page,selector)
        assert expect_text == text
    except AssertionError as e:
        raise e
    except Exception as e:
        raise e

def assert_tipinfo(page,expect_info):

    """
    断言提示信息
    """
    def handler(dialog):
        try:
            m = dialog.message
            assert m==expect_info
        except AssertionError as e:
            raise e
        except Exception as e:
            raise e
    page.on('dialog',handler) # 打印提示信息

def alert_accept(page):
    page.on('dialog',lambda dialog: dialog.accept()) # 点击弹出窗口上的确定

def move_to_element(page,selector):
page.locator(selector).hover() # 鼠标悬停

接下来我们以登录功能整理两个用例,本文经就不把测试数据整理到excel或yaml中了,我直接将其写在了模块中

# '''
# author: 测试-老姜   交流微信/QQ:349940839
# 欢迎添加微信或QQ,加入学习群共同学习交流。
# QQ交流群号:877498247
# 西安的朋友欢迎当面交流。
# '''
# 这个测试数据可以整理到excel中
login_testdata = {
    'case_001':[{
        'step':'输入用户名',
        'aw':'locat_element_fill',
        'params':('#account','admin') #参数的个数与顺序必须与aw的一致
    },
    {
        'step':'输入密码',
        'aw':'locat_element_fill',
        'params':('[name="password"]','Deshifuzhi01') #参数的个数与顺序必须与aw的一致
    },
    {
        'step':'点击登录',
        'aw':'locat_element_click',
        'params':('#submit') #参数的个数与顺序必须与aw的一致
    },
    {
        'step':'断言',
        'aw':'assert_web_title',
        'params':('地盘 - 禅道') #参数的个数与顺序必须与aw的一致
    },
    {
        'step':'移动到A上',
        'aw':'move_to_element',
        'params':('text="A"') #参数的个数与顺序必须与aw的一致
    },
    {
        'step':'点击退出',
        'aw':'locat_element_click',
        'params':('text=" 退出"') #参数的个数与顺序必须与aw的一致
    },
    ],
    'case_002':[{
        'step':'输入用户名',
        'aw':'locat_element_fill',
        'params':('#account','admin') #参数的个数与顺序必须与aw的一致
    },
    {
        'step':'输入密码',
        'aw':'locat_element_fill',
        'params':('[name="password"]','') #参数的个数与顺序必须与aw的一致
    },
    {
        'step':'点击登录',
        'aw':'locat_element_click',
        'params':('#submit') #参数的个数与顺序必须与aw的一致
    },
    {
        'step':'断言',
        'aw':'assert_tipinfo',
        'params':('登录失败,请检查您的用户名或密码是否填写正确。') #参数的个数与顺序必须与aw的一致
    },
    {
        'step':'点击提示信息确定按钮',
        'aw':'alert_accept',
    }
    ]
}

第三步,我们来封装执行过程

# '''
# author: 测试-老姜   交流微信/QQ:349940839
# 欢迎添加微信或QQ,加入学习群共同学习交流。
# QQ交流群号:877498247
# 西安的朋友欢迎当面交流。
# '''

from _51_test_data import login_testdata 
import _44_aw as AW
class Case_Run():

    def case_run_by_test_data(self,page,case_number):
        test_case = login_testdata[case_number] # 安装编号读取测试数据,实际工作中可以从excel或yaml中读取
        try: 
            for tc in test_case: # 执行用例中的aw
                aw_func = getattr(AW,tc['aw']) # 利用反射机制,从aw模块中找到
                if "params" in tc:
                    aw_func(page,*tc['params'])
                else:
                    aw_func(page)
        except Exception as e:
            AW.get_img(page,'img',case_number) #失败时截图

最后我们来编写自动化测试用例

# '''
# author=测试-老姜   交流微信/QQ:349940839
# 欢迎添加微信或QQ,加入学习群共同学习交流。
# QQ交流群号:877498247
# 西安的朋友欢迎当面交流。
# '''

from playwright.sync_api import Playwright, sync_playwright, expect
import pytest

from _52_case_run import Case_Run

class Test_Login():
    def setup_class(self):
        self.playwright = sync_playwright().start()
        self.browser = self.playwright.chromium.launch(headless=False) #默认无头模式
        self.context = self.browser.new_context() # 创建上下文,相当浏览器于实例化,即打开浏览器
        self.page = self.context.new_page() # 打开一个新标签页
        self.page.goto('http://127.0.0.1/zentao/user-login.html')
    def teardown_class(self):
        self.context.close()
        self.browser.close()
        self.playwright.stop()

    @pytest.mark.parametrize('case_number',['case_001','case_002'])
    def test_modify_password(self,case_number):
        Case_Run().case_run_by_test_data(self.page,case_number)



if __name__=='__main__':
    case_path = r'D:\jnc\自动化测试\playwright\playwright_project\test_login_chandao.py'
    pytest.main(['-s',case_path])

执行结果:
在这里插入图片描述

在实际工作中,采用关键字驱动搭建测试框架的话可以有效降低自动化测试的难度,没有编码基础的测试人员只要掌握基本的元素定位(可以要求开发给每个元素都设置id属性或者name属性,元素定位可以非常容易掌握),掌握每个AW的含义,知道如何给AW传参,然后编辑测试数据将这个执行过程定义好就可以来执行自动化测试脚本了。

Logo

一站式 AI 云服务平台

更多推荐