web自动化——电子商务实战

一、产品分析

二、测试用例分析

2.1、传统线性测试脚本


import sys
import os

from hogwartsCourse.webAuto.business.login import login

curPath = os.path.abspath(os.path.dirname(__file__))
print(os.path.dirname(__file__))
print(curPath)
sys.path.append(curPath)

import time
import allure
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait
from business_base import UIBase


class TestMgtGoodList(UIBase):
    def setup_class(self):
        self.driver.maximize_window()
        self.driver.implicitly_wait(5)
        login(self.driver)
        self.driver.find_element(By.XPATH, '//*[text()="商品管理"]').click()
        self.driver.find_element(By.XPATH, '//*[text()="商品列表"]').click()

    def get_screenshot(self):
        timestamp = int(time.time())
        picture_path = f"./pictures/screenshot_{timestamp}.PNG"
        self.driver.save_screenshot(picture_path)
        allure.attach.file(picture_path, name="pictures", attachment_type=allure.attachment_type.PNG)

    def test_add(self):
        product_name = "IQ02"
        self.driver.find_element(By.XPATH, '//*[@class="el-icon-edit"]').click()
        WebDriverWait(self.driver, 10).until(
            expected_conditions.element_to_be_clickable(
                (By.XPATH, '//*[@class="el-icon-plus avatar-uploader-icon"]')
            )
        )
        self.driver.find_elements(By.XPATH, '//*[@class="el-input__inner"]')[0].send_keys("CC090102")
        self.driver.find_elements(By.XPATH, '//*[@class="el-input__inner"]')[1].send_keys(product_name)
        ele = self.driver.find_element(By.XPATH, '//*[text()="上架"]')
        self.action.scroll_to_element(ele)
        self.action.scroll_by_amount(0, 20)
        ele.click()
        self.get_screenshot()
        # 断言1:可以找到创建成功字样的元素证明创建成功
        assert self.driver.find_element(By.XPATH, '//*[text()="创建成功"]')
        # 断言2:在商品列表查找新增商品的名字,如果不为空,则断言成功
        assert self.driver.find_elements(By.XPATH, f'//*[text()="{product_name}"]')
        # 清理脏数据
        self.driver.find_element(By.XPATH, f'//*[text()="{product_name}"]/../..//*[text()="删除"]').click()

    def test_update(self):
        product_name = "IQ02"
        # 构造测试数据
        self.driver.find_element(By.XPATH, '//*[@class="el-icon-edit"]').click()
        WebDriverWait(self.driver, 10).until(
            expected_conditions.element_to_be_clickable(
                (By.XPATH, '//*[@class="el-icon-plus avatar-uploader-icon"]')
            )
        )
        self.driver.find_elements(By.XPATH, '//*[@class="el-input__inner"]')[0].send_keys("CC090102")
        self.driver.find_elements(By.XPATH, '//*[@class="el-input__inner"]')[1].send_keys(product_name)
        ele = self.driver.find_element(By.XPATH, '//*[text()="上架"]')
        self.action.scroll_to_element(ele)
        self.action.scroll_by_amount(0, 20)
        ele.click()

        self.driver.find_element(By.XPATH, f'//*[text()="{product_name}"]/../..//*[text()="编辑"]').click()
        ele = self.driver.find_element(By.XPATH, '//*[text()="更新商品"]')
        self.action.scroll_to_element(ele)
        # self.action.scroll_by_amount(0, 20)
        ele.click()
        self.get_screenshot()
        # 断言1:可以找到编辑成功字样的元素证明编辑成功
        assert self.driver.find_element(By.XPATH, '//*[text()="编辑成功"]')
        # 清理脏数据
        self.driver.find_element(By.XPATH, f'//*[text()="{product_name}"]/../..//*[text()="删除"]').click()

    def test_find(self):
        product_name = "IQ02"
        # 构造测试数据
        self.driver.find_element(By.XPATH, '//*[@class="el-icon-edit"]').click()
        WebDriverWait(self.driver, 10).until(
            expected_conditions.element_to_be_clickable(
                (By.XPATH, '//*[@class="el-icon-plus avatar-uploader-icon"]')
            )
        )
        self.driver.find_elements(By.XPATH, '//*[@class="el-input__inner"]')[0].send_keys("CC090102")
        self.driver.find_elements(By.XPATH, '//*[@class="el-input__inner"]')[1].send_keys(product_name)
        ele = self.driver.find_element(By.XPATH, '//*[text()="上架"]')
        self.action.scroll_to_element(ele)
        self.action.scroll_by_amount(0, 20)
        ele.click()

        self.driver.find_element(By.XPATH, f'//*[text()="{product_name}"]/../..//*[text()="查看"]').click()
        self.get_screenshot()
        # 断言1:可以找到【商品详情】字样的元素证明查看成功
        assert self.driver.find_element(By.XPATH, '//*[text()="商品详情"]')
        self.driver.refresh()
        # 清理脏数据
        self.driver.find_element(By.XPATH, f'//*[text()="{product_name}"]/../..//*[text()="删除"]').click()

    def test_delete(self):
        product_name = "IQ02"
        # 构造测试数据
        self.driver.find_element(By.XPATH, '//*[@class="el-icon-edit"]').click()
        WebDriverWait(self.driver, 10).until(
            expected_conditions.element_to_be_clickable(
                (By.XPATH, '//*[@class="el-icon-plus avatar-uploader-icon"]')
            )
        )
        self.driver.find_elements(By.XPATH, '//*[@class="el-input__inner"]')[0].send_keys("CC090102")
        self.driver.find_elements(By.XPATH, '//*[@class="el-input__inner"]')[1].send_keys(product_name)
        ele = self.driver.find_element(By.XPATH, '//*[text()="上架"]')
        self.action.scroll_to_element(ele)
        self.action.scroll_by_amount(0, 20)
        ele.click()

        self.driver.find_element(By.XPATH, f'//*[text()="{product_name}"]/../..//*[text()="删除"]').click()
        self.get_screenshot()
        # 断言1:可以找到【删除成功】字样的元素证明【删除成功】
        assert self.driver.find_element(By.XPATH, '//*[text()="删除成功"]')
        # 断言2:在商品列表查找删除商品的名字,如果为空,则断言成功
        assert not self.driver.find_elements(By.XPATH, f'//*[text()="{product_name}"]')

三、PageObjectModel简介

3.1、PO模式设计原则

  • 不要暴露页面内部的元素给外部
  • 不需要建模 UI 内的所有元素
  • 要用公共方法代表 UI 所提供的功能
  • 同样的行为不同的结果可以建模为不同的方法
  • 方法应该返回其他的 PageObject ,或者返回用于断言的数据
  • 不要在方法内加断言

四、编写POM测试脚本

PO模式改造
image

4.1、梳理测试用例

1、业务操作流程

class TestLitemall

    # 测试用例
    # 添加商品类型:

        """登录页面:用户登录"""
        # 访问登录页
        # 输入“用户名”
        # 输入“密码”
        # 点击“登录”按钮
        # ==》首页

        """系统首页:进入商品类目"""
        # 点击菜单“商场管理”
        # 点击菜单“商品类目”
        # ==》类目列表页面

        """类目列表页面:点击添加"""
        # 点击“添加”按钮
        # ==》创建类目页面

        """创建类目页面:创建类目"""
        # 输入“类目名称”
        # 点击“确定”按钮
        # ==》类目列表页面

        """类目列表页面:获取操作结果"""
        # 获取冒泡消息文本
        # ==》返回消息文本

2、前置后置动作

class TestLitemall:

    # 前置动作
    def setup_class(self):
        # 初始化开始页面
        pass

    # 后置动作
    def teardown_class(self):
        # 退出浏览器
        pass

4.2、构造PO模型

1、 页面类和方法

  • 创建页面类
  • 定义页面方法

4.3、编写测试用例

1、链式调用

  • 新增功能
# 演示代码,直接复制不可用
# Python版本代码
# 新增功能
def test_add_type(self):
  # 链式调用
  res = self.home\
      .go_to_category()\
      .click_add()\
      .create_category()\
      .get_res()

4.4、业务具体实现

1、封装BasePage

  • 封装driver
  • 封装selenium api

2、实现页面方法

    def click_create(self):
        # 1、点击添加按钮
        logger.info("商品列表页面:点击创建按钮")
        self.wait_until_clickable(self.__BTN_CREATE)
        self.do_find(self.__BTN_CREATE).click()
        # ==>>进入到添加商品页面
        from hogwartsCourse.webAuto.web_auto_po.page_obj.good_create_page import GoodCreatePage
        return GoodCreatePage(self.driver)

3、封装页面元素

__BTN_CREATE = (By.XPATH, '//*[@class="el-icon-edit"]')
__SUCCESS = (By.XPATH, '//*[text()="创建成功"]')

五、测试脚本的优化

  • 测试断言
  • 数据清理
  • 参数化
  • 添加日志
  • 测试报告