Selenium Web自动化测试框架搭建

所需环境

  1. 浏览器 Chrome
  2. Python 3.9
  3. Selenium
  4. Pytest

 配置驱动

在项目根目录下创建 conftest.py

import pytest
from selenium import webdriver
from selenium.webdriver.chrome.webdriver import WebDriver
import os
import time

# 配置driver  在所有的用例执行之前开始
@pytest.fixture(scope="session",autouse=True)
def driver():
    driverpath = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'drivers/chromedriver.exe')
    driver = webdriver.Chrome(executable_path=driverpath)
    driver.implicitly_wait(5)
    driver.maximize_window()

    yield driver

    # 运行结束
    # driver.quit()

@pytest.fixture(scope='function',autouse=True)
def handler_case(driver:WebDriver):
    yield
    # 每个用例执行完成之后进行截图
    screenshots =  os.path.join(os.path.dirname(os.path.abspath(__file__)),"screenshots")
    if not os.path.exists(screenshots):
        os.mkdir(screenshots)
    filename = time.strftime('%Y-%m-%d_%H_%M_%S')
    file = os.path.join(screenshots,filename+".png")
    driver.save_screenshot(file) 

 创建测试用例

testcases/test_login.py 

from selenium.webdriver.chrome.webdriver import WebDriver
def test_login(driver:WebDriver):
    """
    用户登录
    :param driver:
    :return:
    """
    driver.get("http://1.117.45.85/zentao/my/")
    driver.find_element_by_id('account').send_keys("abtester")
    driver.find_element_by_css_selector('[name="password"]').send_keys('Abtester123')
    driver.find_element_by_id("submit").click()



def test_create_topic(driver:WebDriver):
    driver.find_element_by_css_selector('li[title="测试"]').click()
    # 切换iframe
    qa = driver.find_element_by_id('appIframe-qa')
    driver.switch_to.frame(qa)
    driver.find_element_by_css_selector('li[data-id="testcase"]').click()

    driver.find_element_by_css_selector('a.btn.btn-primary[data-app="qa"]').click()


    driver.find_element_by_id('title').send_keys('用户登录测试成功登录')
    driver.find_element_by_id('precondition').send_keys('网络正常:存在用户 abtester 密码:Abtester123')
    # step1
    driver.find_element_by_xpath('//tbody[@id="steps"]/tr[1]/td[2]//textarea').send_keys('打开登录页面')
    driver.find_element_by_xpath('//tbody[@id="steps"]/tr[1]/td[3]//textarea').send_keys('能够正常打开')
    # step2
    driver.find_element_by_xpath('//tbody[@id="steps"]/tr[2]/td[2]//textarea').send_keys("输入用户名 abtester")
    driver.find_element_by_xpath('//tbody[@id="steps"]/tr[2]/td[3]//textarea').send_keys('输入成功')
    # step3
    driver.find_element_by_xpath('//tbody[@id="steps"]/tr[3]/td[2]//textarea').send_keys('输入密码:Abtester123')
    driver.find_element_by_xpath('//tbody[@id="steps"]/tr[3]/td[3]//textarea').send_keys('输入成功')

    # submit
    driver.find_element_by_id('submit').click() 

 封装POM

将自动化脚本直接写在代码中不是好的方案,如果后期页面进行了更改,那么维护起来很麻烦,一种业界通用的做法就是配置页面模型 POM

POM是将每个页面封装到一个类中,类中定义相关的操作,将上面的自动化创建测试用例的操作封装一下

pom/mainnav.py 

"""
页面导航
"""
from selenium.webdriver.chrome.webdriver import WebDriver
from pom.testcasepage import TestCasePage


class MainNavgation:

    def __init__(self,driver:WebDriver):
        self.driver = driver

    def nav_qa(self):
        """
        导航到测试页面
        :return:
        """
        self.driver.find_element_by_xpath('//li[@title="测试"]').click()
        qa = self.driver.find_element_by_id('appIframe-qa')
        self.driver.switch_to.frame(qa)

        return TestCasePage(self.driver)

pom/testcasepage.py 

from selenium.webdriver.chrome.webdriver import WebDriver

class TestCasePage:
    """
    测试用例相关的页面
    """
    def __init__(self,driver:WebDriver):
        self.driver = driver
        self.driver.find_element_by_xpath('//li[@data-id="testcase"]').click()

    def create_testcase(self,title,*steps,precondition=''):
        """
        创建测试用例
        :param title: 标题
        :param precondition: 前置条件
        :param steps: 测试步骤
        :return:
        """
        self.driver.find_element_by_id('title').send_keys(title)
        self.driver.find_element_by_id('precondition').send_keys(precondition)
        # 约定测试数据 steps=[{step:"打开登录页面",expect:""},{step:"打开登录页面",expect:""}]
        for i in range(len(steps)):
            self.driver.find_element_by_xpath(f'//tbody[@id="steps"]/tr[{i+1}]/td[2]//textarea').send_keys(steps[i].get("step"))
            self.driver.find_element_by_xpath(f'//tbody[@id="steps"]/tr[{i+1}]/td[3]//textarea').send_keys(steps[i].get("expect"))
        # submit
        self.driver.find_element_by_id('submit').click()


    def click_add_testcase(self):
        """
        点击添加测试用例
        :return:
        """
        self.driver.find_element_by_css_selector('a.btn.btn-primary[data-app="qa"]').click() 

将页面封装为独立的类,在测试用例中调用测试方法

testcases\test_login.py 

from selenium.webdriver.chrome.webdriver import WebDriver
from pom.mainnav import MainNavgation

def test_login(driver:WebDriver):
    """
    用户登录
    :param driver:
    :return:
    """
    driver.get("http://1.117.45.85/zentao/my/")
    driver.find_element_by_id('account').send_keys("abtester")
    driver.find_element_by_css_selector('[name="password"]').send_keys('Abtester123')
    driver.find_element_by_id("submit").click()



def test_create_topic(driver:WebDriver):
    mainnav = MainNavgation(driver)
    # 导航到测试页面
    qa = mainnav.nav_qa()
    # 点击添加测试用例
    qa.click_add_testcase()
    step1 = {'step':"输入用户名zhangsan","expect":"输入成功"}
    step2 = {'step': "输入密码zhangsan", "expect": "输入成功"}
    step3 = {'step': "输入确认密码zhangsan", "expect": "输入成功"}
    step4 = {'step': "输入确认密码zhangsan", "expect": "输入成功"}
    step5 = {'step': "输入确认密码zhangsan", "expect": "输入成功"}
    qa.create_testcase("用户注册",step1,step2,step3,step4,step5,precondition='网络正常') 

yaml配置页面元素定位

 当创建的页面越来越多的时候,单纯的pom模型在维护元素定位时也会变得不方便,这时可以将页面上的元素放到yaml配置文件中;

安装 pyyaml 可以解析yaml文件

pip install pyyaml 

配置页面的定位

pageconf/testcase.yaml 

testcase:
  xpath: //li[@data-id="testcase"] #测试
createbtn:
  css: a.btn.btn-primary[data-app="qa"] # 创建用例
title:
  id: title # 用例的标题
precondition:
  id: precondition  # 前置条件
submit:
  id: submit  # 提交 

在pom文件中定义解析yaml文件的基类

pom\basepage.py 

from selenium.webdriver.chrome.webdriver import WebDriver
import os
import yaml

class BasePage:
    def __init__(self,driver:WebDriver,yamlfile):
        self.driver = driver
        self.__yamlpath = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),'pageconf')
        self.__yamlfile = yamlfile
        self.config = self.__load_yaml()

    def __load_yaml(self):
        """加载yaml文件"""
        with open(os.path.join(self.__yamlpath,self.__yamlfile),encoding="utf8") as file:
           return yaml.load(file,Loader=yaml.SafeLoader)

    def find_element_by_yaml_config(self,name):
        """
        自定义从yaml文件中获取元素定位
        :param name:
        :return:
        """
        selector:dict = self.config.get(name)
        for key,value in selector.items():
            if key == "xpath":
                return self.driver.find_element_by_xpath(value)
            elif key=="css":
                return self.driver.find_element_by_css_selector(value)
            elif key=="id":
                return self.driver.find_element_by_id(value)
            elif key=="name":
                return self.driver.find_element_by_name(value)
            elif key=="class":
                return self.driver.find_element_by_class_name(value)

定义所有页面的基类,在基类中设置从yaml文件中读取配置的方法,后续所有的页面类都继承basepage 父类;

pom/testcasepage.py 

from selenium.webdriver.chrome.webdriver import WebDriver
from pom.basepage import BasePage
class TestCasePage(BasePage):
    """
    测试用例相关的页面
    """
    def __init__(self,driver:WebDriver):
        # 调用父类的构造器   'testcase.yaml' 传入页面的配置文件路径
        super(TestCasePage, self).__init__(driver,'testcase.yaml')
        self.find_element_by_yaml_config("testcase").click()
    def create_testcase(self,title,*steps,precondition=''):
        """
        创建测试用例
        :param title: 标题
        :param precondition: 前置条件
        :param steps: 测试步骤
        :return:
        """
        self.find_element_by_yaml_config('title').send_keys(title)
        # self.driver.find_element_by_id('title').send_keys(title)
        self.find_element_by_yaml_config('precondition').send_keys(precondition)
        # self.driver.find_element_by_id('precondition').send_keys(precondition)
        # 约定测试数据 steps=[{step:"打开登录页面",expect:""},{step:"打开登录页面",expect:""}]
        for i in range(len(steps)):
            self.driver.find_element_by_xpath(f'//tbody[@id="steps"]/tr[{i+1}]/td[2]//textarea').send_keys(steps[i].get("step"))
            self.driver.find_element_by_xpath(f'//tbody[@id="steps"]/tr[{i+1}]/td[3]//textarea').send_keys(steps[i].get("expect"))
        # submit
        self.find_element_by_yaml_config('submit').click()


    def click_add_testcase(self):
        """
        点击添加测试用例
        :return:
        """
        self.find_element_by_yaml_config('createbtn').click() 

至此,实现了自动化测试框架中的最常用的操作

POM页面配置

Yaml元素定位配置

Pytest 配置单独driver

整个代码架构 

附录-所涉及到的知识点 

  1.  Selenium基本用法  
  2. yaml文件处理 
  3. pytest的使用 

测试人必看

感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接免费拿走:

① 2000多本软件测试电子书(主流和经典的书籍应该都有了)

② 软件测试/自动化测试标准库资料(最全中文版)

③ 项目源码(四五十个有趣且经典的练手项目及源码)

④ Python编程语言、API接口自动化测试、web自动化测试、App自动化测试(适合小白学习)


⑤ Python学习路线图(告别不入流的学习) 

上图的资料 在我的QQ技术交流群里(技术交流和资源共享,广告进来腿给你打断)

可以自助拿走,群号953306497(备注“csdn111”)群里的免费资料都是笔者十多年测试生涯的精华。还有同行大神一起交流技术哦。

  • 3
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值