0


UI自动化测试实战--- app订单、web发货(9)

目标

1.掌握使用Selenium实现批量企业级执行测试用例
2.熟悉自动化测试的流程
3.能够对Web项目和APP项目实现自动化测试
4、掌握如何在Jenkins中配置并运行测试脚本 - **持续集成 CI **(Continuous integration) / CD

项目实施

要实现的业务:1、app下单流程 2、web发货业务

实现技术:python+appium+selenium + unittest

结构实现:po模式 +日志+数据驱动+报告

执行方式:持续集成

自动化测试流程 - 熟悉

1、需求分析

2、挑选适合做自动化测试的功能

3、设计测试用例

4、搭建测试环境 【可选】

5、设计自动化测试项目的架构 【可选】

6、编写代码

7、执行测试用例

8、生成测试报告并分析结果

编写自动化测试用例的原则:

  1. 自动化测试用例一般只实现核心业务流程或者重复执行率较高的功能
  2. 自动化测试用例的选择一般以“正向”逻辑的验证为主
  3. 不是所有手工用例都可以使用自动化测试用例来执行
  4. 尽量减少多个脚本之间的依赖
  5. 自动化测试用例执行完毕之后,一般需要回归原点

项目实施UI自动化测试的时机:** 一般情况下在手工测试完成之后** 版本或项目功能趋于稳定

项目需要实施UI自动化测试需要满足以下前置条件:

  1. 项目需要回归测试 (甲⽅⾃营项⽬、⾦融、电商)
  2. 项目需要实现自动化的功能模块需求变更不频繁 :稳定的模块
  3. 项目周期要长:(甲⽅⾃营项⽬、6个⽉以上的外包)

项目依赖包

1、安装Selenium 包

2、安装 Appium-Python-Client 包

3、移动端自动化环境搭建

UI自动化测试--- 移动端自动化环境搭建 - (6)

4、安装 parameterized 参数化

5、安装 HTMLTestReport 生成测试报告

结构搭建

1、新建项目

项目名称:uiAutoTestTpshop

2、创建目录结构

base:所有page页面公共方法

data:测试数据存储文件

img:存放截图图片文件

log:日志

page:页面对象

report:测试报告

script:测试脚本

config.py:配置文件

run_suite.py:运行套件

utils.py:工具类

3、实现config.py 配置文件

import os
# web后台url
HOST = 'http://hmshop-test.itheima.net/index.php/Admin/Admin/login'
# 项目路径
DIR_PATH = os.path.dirname(__file__)
print(DIR_PATH)

4、实现base.py文件

import os
import time
from selenium.webdriver.support.wait import WebDriverWait

from config import DIR_PATH

class Base:
    # 初始化方法
    def __init__(self, driver):
        self.driver = driver

    # 查找元素方法
    def base_find(self, loc, timeout=10, poll_frequency=0.5):
        return WebDriverWait(self.driver, timeout, poll_frequency).until(lambda x: x.find_element(*loc))

    # 点击方法
    def base_click(self, loc):
        self.base_find(loc).click()

    # 输入方法
    def base_input(self, loc, value):
        # 获取元素
        el = self.base_find(loc)
        # 清空
        el.clear()
        # 输入
        el.send_keys(value)

    # 获取文本方法
    def base_get_text(self, loc):
        return self.base_find(loc).text

    # 截图方法
    def base_screenshot_img(self):
        img_path = DIR_PATH + os.sep + 'img' + os.sep + '{}.png'.format(time.strftime('%Y%m%d %H%M%S'))
        return self.driver.get_screen_as_file(img_path)

5、登录业务结构搭建

app 登录page结构搭建

"""
   将操作步骤封装 + 组合业务方法
"""

class PageAppLogin:

    # 1、点击 我的
    def page_app_click_me(self):
        pass

    # 2、点击 登录头像
    def page_app_click_login_link(self):
        pass

    # 3、输入用户名
    def page_app_input_username(self):
        pass

    # 4、输入密码
    def page_app_input_password(self):
        pass

    # 5、点击勾选协议
    def page_app_click_protocol(self):
        pass

    # 6、点击登录按钮
    def page_app_click_login_btn(self):
        pass

    # 7、获取登录昵称
    def page_app_get_login_nickname(self):
        pass

    # 组合业务
    def page_app_login(self):
        pass

2、登录配置信息整理 page---> __init__文件

from selenium.webdriver.common.by import By

"""
   一、以下为app登录模块配置信息
"""
# 我的
app_login_me = By.XPATH, "//*[@text='我的']"
# 登录头像
app_login_icon = By.XPATH, "//*[@resource-id='com.tpshop.malls:id/head_img']"
# 用户名
app_username = By.XPATH, "//*[@resource-id='com.tpshop.malls:id/mobile_et']"
# 密码
app_pwd = By.XPATH, "//*[@resource-id='com.tpshop.malls:id/pwd_et']"
# 协议
app_pro = By.XPATH, "//*[@resource-id='com.tpshop.malls:id/agree_btn']"
# 登录按钮
app_login_btn = By.XPATH, "//*[@resource-id='com.tpshop.malls:id/login_tv']"
# 登录昵称
app_nickname = By.XPATH, "//*[@resource-id='com.tpshop.malls:id/nick_name_tv']"

3、登录page页面实现

page_app_login.py 文件实现

"""
   将操作步骤封装 + 组合业务方法
"""
from time import sleep
import page
from base.base import Base

class PageAppLogin(Base):

    # 1、点击 我的
    def page_app_click_me(self):
        self.base_click(page.app_login_me)

    # 2、点击 登录头像
    def page_app_click_login_link(self):
        self.base_click(page.app_login_icon)

    # 3、输入用户名
    def page_app_input_username(self, username):
        self.base_input(page.app_username, username)

    # 4、输入密码
    def page_app_input_password(self, pwd):
        self.base_input(page.app_pwd, pwd)

    # 5、点击勾选协议
    def page_app_click_protocol(self):
        self.base_click(page.app_pro)

    # 6、点击登录按钮
    def page_app_click_login_btn(self):
        self.base_click(page.app_login_btn)

    # 7、获取登录昵称
    def page_app_get_login_nickname(self):
        sleep(2)
        return self.base_get_text(page.app_nickname)

    # 组合业务
    def page_app_login(self, username=15826331234, pwd=123456):
        self.page_app_click_me()
        self.page_app_click_login_link()
        self.page_app_input_username(username)
        self.page_app_input_password(pwd)
        self.page_app_click_protocol()
        self.page_app_click_login_btn()

提示:获取昵称需要加个强制等待时间 sleep(2)

原因:查找到元素之后,页面内容还没刷新,没有显示出来,可能会出现 昵称为 “优惠券”的bug

**4、登录测试脚本实现 **

import unittest
from utils import GetDriver
from page.page_app_login import PageAppLogin

class TestAppLoginOrder(unittest.TestCase):
    def setUp(self):
        self.driver = GetDriver.get_app_driver()
        # 获取PageAppLogin实例
        self.app = PageAppLogin(self.driver)

    def tearDown(self):
        self.driver.quit()

    def test01_login(self):
        """登录测试用例"""
        # 调用登录
        self.app.page_app_login()
        # 获取昵称  --> 断言
        nickname = self.app.page_app_get_login_nickname()
        print('登录账户昵称为:', nickname)

6、订单业务

1、订单page业务结构搭建

from base.base import Base

class PageAppOrder(Base):
    # 说明:app项目环境的问题,本来应该通过点击首页搜索,但是测试环境中  首页 没有元素,故切换到分类选项卡中搜索,原理是一样的
    # 1、点击分类
    def page_app_click_cate(self):
        pass

    # 2、点击搜索框
    def page_app_click_search_text(self):
        pass

    # 3、输入搜索内容  小米
    def page_app_input_search_text(self):
        pass

    # 4、点击搜索按钮
    def page_app_click_search_btn(self):
        pass

    # 5、选择商品
    def page_app_choose_goods(self):
        pass

    # 6、加入购物车
    def page_app_add_cart(self):
        pass

    # 7、点击确定
    def page_app_click_sure(self):
        pass

    # 8、点击购物车
    def page_app_click_goodscart(self):
        pass

    # 9、点击立即购买
    def page_app_now_buy(self):
        pass

    # 10、点击提交订单
    def page_app_click_submit_order(self):
        pass

    # 11、点击立即支付
    def page_app_now_click_now_pay_money(self):
        pass

    # 12、输入支付密码   123456
    def page_app_input_pay_pwd(self):
        pass

    # 13、点击确定
    def page_app_pay_sure(self):
        pass

    # 14、获取订单编号
    def page_app_get_ordernum(self):
        pass

    # 15、下单业务方法
    def page_app_order(self):
        pass

2、app订单配置信息整理

"""
   二、以下为app订单模块配置信息
"""

# 1、点击首页
app_order_index = By.XPATH, "//*[@text='分类']"
# 2、点击搜索框1
app_order_search_text1 = By.XPATH, "//*[@class='android.widget.EditText']"
# 点击搜索框2
app_order_search_text2 = By.XPATH, "//*[@class='android.widget.EditText']"
# 3、输入搜索内容
# app_order_sarch_content =
# 4、点击搜索按钮
app_order_search_btn = By.XPATH, "//*[@resource-id='com.tpshop.malls:id/search_btn']"
# 5、点击选择第一张图片的商品
app_choose_img = By.XPATH, "//*[@resource-id='com.tpshop.malls:id/product_pic_img']"
# 6、点击加入购物车
app_order_add_cart = By.XPATH, "//*[@text='加入购物车']"
# 7、点击确定
app_order_cart_ok = By.XPATH, "//*[@text='确定']"
# 8、点击购物车
app_order_cart = By.XPATH, "//*[@text='购物车']"
# 9、点击 立即购买
app_order_cart_now_purchase = By.XPATH, "//*[@text='立即购买']"
# 10、点击 提交订单
app_order_submit = By.XPATH, "//*[@text='提交订单']"
# 11、点击 立即支付
app_order_now_pay = By.XPATH, "//*[@text='立即支付']"
# 12、输入支付密码
app_order_pay_pwd = By.XPATH, "//*[@resource-id='com.tpshop.malls:id/pwd_et']"
# 13、点击 确定
app_order_pay_ok = By.XPATH, "//*[@text='确定']"
# 14、获取订单编号
app_order_no = By.XPATH, "//*[@resource-id='com.tpshop.malls:id/pay_trade_no_tv']"

注意:在base.py文件加上: print('-->正在查找:{}'.format(loc)) 代码,方便调试输出到控制台,运行时最右边可以与模拟器两相对照

  # 查找元素方法
    def base_find(self, loc, timeout=10, poll_frequency=0.5):
        print('-->正在查找:{}'.format(loc))
        return WebDriverWait(self.driver, timeout, poll_frequency).until(lambda x: x.find_element(*loc))

3、订单page页面实现

from time import sleep

from base.base import Base
import page

class PageAppOrder(Base):
    # 1、点击分类
    def page_app_click_cate(self):
        sleep(2)
        self.base_click(page.app_order_index)

    # 2、点击搜索框
    def page_app_click_search_text(self):
        sleep(1)
        self.base_click(page.app_order_search_text1)

    # 3、输入搜索内容  小米
    def page_app_input_search_text(self, value='小米'):
        sleep(1)
        self.base_input(page.app_order_search_text1, value)

    # 4、点击搜索按钮
    def page_app_click_search_btn(self):
        sleep(1)
        self.base_click(page.app_order_search_btn)

    # 5、选择商品
    def page_app_choose_goods(self):
        sleep(1)
        self.base_click(page.app_choose_img)

    # 6、加入购物车
    def page_app_add_cart(self):
        sleep(1)
        self.base_click(page.app_order_add_cart)

    # 7、点击确定
    def page_app_click_sure(self):
        sleep(1)
        self.base_click(page.app_order_cart_ok)

    # 8、点击购物车
    def page_app_click_goodscart(self):
        sleep(1)
        self.base_click(page.app_order_cart)

    # 9、点击立即购买
    def page_app_now_purchase(self):
        sleep(1)
        self.base_click(page.app_order_cart_now_purchase)

    # 10、点击提交订单
    def page_app_click_submit_order(self):
        sleep(1)
        self.base_click(page.app_order_submit)

    # 11、点击立即支付
    def page_app_now_click_now_pay_money(self):
        sleep(1)
        self.base_click(page.app_order_now_pay)

    # 12、输入支付密码   123456
    def page_app_input_pay_pwd(self, pwd='123456'):
        sleep(1)
        self.base_input(page.app_order_pay_pwd, pwd)

    # 13、点击确定
    def page_app_pay_sure(self):
        sleep(1)
        self.base_click(page.app_order_pay_ok)

    # 14、获取订单编号
    def page_app_get_order_no(self):
        sleep(2)
        return self.base_get_text(page.app_order_no)

    # 15、下单业务方法
    def page_app_order(self, value='小米', pwd='1233456'):
        self.page_app_click_cate()
        self.page_app_click_search_text()
        self.page_app_input_search_text(value)
        self.page_app_click_search_btn()
        self.page_app_choose_goods()
        self.page_app_add_cart()
        self.page_app_click_sure()
        self.page_app_click_goodscart()
        self.page_app_now_purchase()
        self.page_app_click_submit_order()
        self.page_app_now_click_now_pay_money()
        self.page_app_input_pay_pwd(pwd)
        self.page_app_pay_sure()

4、订单script 测试脚本实现

import unittest

from page.page_app_order import PageAppOrder
from utils import GetDriver
from page.page_app_login import PageAppLogin

class TestAppLoginOrder(unittest.TestCase):
    def setUp(self):
        self.driver = GetDriver.get_app_driver()
        # 获取PageAppLogin实例
        self.app = PageAppLogin(self.driver)
        # 获取PageAppOrder实例
        self.order = PageAppOrder(self.driver)

    def tearDown(self):
        self.driver.quit()

    def test01_login_order(self, search_value='小米', pwd='123456'):
        """登录测试用例"""
        # 1、调用登录
        self.app.page_app_login()
        # 获取昵称  --> 断言
        nickname = self.app.page_app_get_login_nickname()
        print('登录账户昵称为:', nickname)
        # 2、下订单
        self.order.page_app_order(search_value, pwd)
        # 获取订单编号
        order_no = self.order.page_app_get_order_no()
        print('获取的订单编号为:', order_no)

不完善之处记录:

思考:第一次运行时,为什么会出现“请先安装QQ”的错误提示?

解决方案:第一次运行时需要手动加入购物车

报错:获取的订单编号为:None

原因:在获取订单编号方法一定要返回 return ,获取文本值一定要返回,后续做断言用

    # 14、获取订单编号
    def page_app_get_order_no(self):
        sleep(2)
        # 注意:一定要返回
        return self.base_get_text(page.app_order_no)

断言和参数化

在data目录下新增 app_order.json文件 文件代码如下:

{
  "order": [
    {
      "desc": "下单成功",
      "search_value": "小米",
      "pwd": "123456",
      "expect": "13600001111"
    }
  ]
}

在utils.py文件中新增方法:

# 读取json文件方法
def read_json(filename, key):
    filepath = DIR_PATH + os.sep + "data" + os.sep + filename
    arrs = []
    with open(filepath, encoding='utf-8') as f:
        for data in json.load(f).get(key):
            arrs.append(tuple(data.values())[1:])

    return arrs

参数化:在 test01_app_from_login_to_orde.py 文件中新增以下代码:

from parameterized import parameterized

 @parameterized.expand(read_json('app_order.json', 'order'))
    def test01_login_order(self, search_value, pwd, expect):
        try:
            """登录测试用例"""
            # 1、调用登录
            self.app.page_app_login()
            # 获取昵称  --> 断言
            nickname = self.app.page_app_get_login_nickname()
            print('登录账户昵称为:', nickname)
            self.assertEqual(expect, nickname)
            # 2、下订单
            self.order.page_app_order(search_value, pwd)
            # 获取订单编号
            order_no = self.order.page_app_get_order_no()
            print('获取的订单编号为:', order_no)
        except Exception as e:
            log.error(e)
            # 1、截图
            self.order.base_screenshot_img()
            # 2、抛异常
            raise

7、web端登录业务

1、web登录配置信息整理 page---> __init__文件:

"""
   三、以下为web登录模块配置信息
"""
# 用户名
web_username = By.CSS_SELECTOR, '[name="username"]'
# 密码
web_pwd = By.CSS_SELECTOR, '[name="password"]'
# 验证码
web_verify = By.CSS_SELECTOR, '[name="vertify"]'
# 登录按钮
web_login_btn = By.CSS_SELECTOR, '[name="submit"]'
# 登录昵称
web_login_nickname = By.CSS_SELECTOR, '.bgdopa-t'

2、page_web_login.py文件实现:

import page
from base.base import Base

class PageWebLogin(Base):
    # 1、输入用户名
    def page_web_input_username(self, uname):
        self.base_input(page.web_username, uname)

    # 2、输入密码
    def page_web_input_pwd(self, pwd):
        self.base_input(page.web_pwd, pwd)

    # 3、输入验证码
    def page_web_input_verify(self, code):
        self.base_input(page.web_verify, code)

    # 3、点击登录按钮
    def page_web_click_login_btn(self):
        self.base_click(page.web_login_btn)

    # 4、获取登录昵称
    def page_web_get_login_nickname(self):
        return self.base_get_text(page.web_login_nickname)

    # 5、登录业务方法
    def page_web_login(self, uname='admin', pwd='123456', code='8888'):
        self.page_web_input_username(uname)
        self.page_web_input_pwd(pwd)
        self.page_web_input_verify(code)
        self.page_web_click_login_btn()

3、web端测试脚本实现

script目录下----> 新建 test01_web_from_login_to_order.py 文件

import unittest
from time import sleep

from page.page_web_login import PageWebLogin
from utils import GetDriver

class TestWebLoginOrder(unittest.TestCase):
    def setUp(self):
        self.driver = GetDriver.get_web_driver()
        # 获取PageWebLogin实例
        self.web_login = PageWebLogin(self.driver)

    def tearDown(self):
        sleep(3)
        self.driver.quit()

    def test01_web_login_order(self):
        # 调用登录
        self.web_login.page_web_login()
        # 获取登录昵称
        nickname = self.web_login.page_web_get_login_nickname()
        print('登录后的昵称为:', nickname)

8、web端发货业务

说明:由于web发货页面需要切换iframe标签,所以在Base类中新增两个方法:

1、切换frame

2、回到默认目录

    # 切换frame
    def base_switch_to_frame(self, loc):
        log.info('正在调用切换frame方法,切换对象:{}'.format(loc))
        el = self.base_find(loc)
        self.driver.switch_to.frame(el)

    # 恢复frame
    def base_swtich_to_default_content(self):
        self.driver.switch_to.default_content()

1、web登录配置信息整理 page---> __init__文件:

"""
   四、以下为web后台发货模块配置信息
"""
# 1、点击 订单 菜单
web_order = By.XPATH, "//a[text()='订单']"
# 2、点击左侧菜单 发货单
web_order_goods_list = By.XPATH, "//a[text()='发货单']"
# 切换frame
web_order_frame_workspace = By.CSS_SELECTOR, '#workspace'
# 3、点击去发货
# web_order_go_goods = By.XPATH, "//a[text()='去发货']"
# 指定编号发货      //div[text()=202206222103597720]/../..//td[@class="handle"]//a[1]
web_order_go_goods = "//div[text()='{}']/../..//td[@class='handle']//a[1]"
# 4、勾选物流公司  韵达
web_order_company = By.CSS_SELECTOR, '[value="YD"]'
# 5、输入配送单号  [name="invoice_no"]
web_order_goods_no = By.CSS_SELECTOR, '[name="invoice_no"]'
# 6、点击确认发货
web_order_ok = By.CSS_SELECTOR, '.ncap-btn-send'
# 7、打印配货单单
web_order_print_order = By.XPATH, "//a[text()='打印配货单']"
# 8、获取订单编号
web_order_no = By.XPATH, "//div[@id='printDiv']/div[@class='contact-info']/dl[1]/dd[2]"

# 难点:如何根据指定的订单编号,查找对应的去发货元素
# 思路:先找共同的父级,再逐级查找

2、 utils.py文件 完整文件代码:

import json
import os
import appium.webdriver
from config import DIR_PATH, HOST
from selenium import webdriver
import logging.handlers

class GetDriver:
    __app_driver = None
    __web_driver = None

    # 获取APP Driver
    @classmethod
    def get_app_driver(cls):
        if cls.__app_driver is None:
            # 定义字典变量
            desired_caps = dict()

            # 字典追加启动参数
            desired_caps["platformName"] = "Android"
            # 注意:版本号必须正确,报错时会提示正确的版本号
            desired_caps["platformVersion"] = " "
            # android不检测内容,但是不能为空
            desired_caps["deviceName"] = "192.168.56.101:5555"
            desired_caps["appPackage"] = "com.tpshop.malls"
            desired_caps["appActivity"] = ".SPMainActivity"
            # 设置中⽂
            desired_caps["unicodeKeyboard"] = True
            desired_caps["resetKeyboard"] = True
            # 获取driver
            cls.__app_driver = appium.webdriver.Remote("http://127.0.0.1:4723/wd/hub", desired_caps)

        return cls.__app_driver

    # 获取Web Driver
    @classmethod
    def get_web_driver(cls):
        if cls.__web_driver is None:
            cls.__web_driver = webdriver.Chrome()
            cls.__web_driver.get(HOST)
            cls.__web_driver.maximize_window()

        return cls.__web_driver

# 读取json文件方法
def read_json(filename, key):
    filepath = DIR_PATH + os.sep + "data" + os.sep + filename
    arrs = []
    with open(filepath, encoding='utf-8') as f:
        for data in json.load(f).get(key):
            arrs.append(tuple(data.values())[1:])

    return arrs

# 写入动态文件,方便生成的订单后 后续持续用
def write_json(value):
    filepath = DIR_PATH + os.sep + "data" + os.sep + "expect.json"
    with open(filepath, 'w', encoding='utf-8') as f:
        data = {"expect": [{"desc": "", "order_no": value}]}
        json.dump(data, f)

# 日志封装
class GetLog:
    __log = None

    @classmethod
    def get_log(cls):
        if cls.__log is None:
            # 获取日志器
            cls.__log = logging.getLogger()
            # 2、设置日志级别
            cls.__log.setLevel(logging.INFO)
            # 3、获取处理器
            filename = DIR_PATH + os.sep + 'log' + os.sep + 'tpshop_auto.log'
            # filename = DIR_PATH + os.sep + 'log' + os.sep + 'tpshop_auto_{}.log'.format('%Y%m%d %H%M%S')
            tf = logging.handlers.TimedRotatingFileHandler(filename=filename, when='midnight', interval=1,
                                                           backupCount=3, encoding='utf-8')
            # 4、获取格式器
            fmt = "%(asctime)s %(levelname)s [%(filename)s(%(funcName)s:%(lineno)d)] - %(message)s"
            fm = logging.Formatter(fmt)
            # 5、将格式器添加到处理器
            tf.setFormatter(fm)
            # 6、将处理器添加到日志器
            cls.__log.addHandler(tf)
        # 7、返回日志器
        return cls.__log

if __name__ == '__main__':
    # 预期:[(),()]
    print(read_json('app_order.json', 'order'))
    GetLog.get_log().info('日志测试')
    # write_json('2022062317250001')
    print(read_json('expect.json', 'expect')[0][0])

3、page_web_order.py 文件实现:

import time

from selenium.webdriver.common.by import By

import page
from base.base import Base
from utils import read_json

class PageWebOrder(Base):
    # 1、点击 订单 菜单
    def page_web_click_order_menu(self):
        self.base_click(page.web_order)

    # 2、点击左侧菜单 发货单
    def page_web_click_order_list(self):
        self.base_click(page.web_order_goods_list)

    # 3、工作区域 点击去发货
    def page_web_go_goods(self):
        # 1、切换frame
        self.base_switch_to_frame(page.web_order_frame_workspace)
        # 2、点击去发货
        loc = By.XPATH, page.web_order_go_goods.format(read_json('expect.json', 'expect')[0][0])
        self.base_click(loc)

    # 4、勾选物流公司
    def page_web_order_company(self):
        self.base_click(page.web_order_company)

    # 5、输入配送单号
    def page_web_input_goods_no(self):
        # 配送单号
        shipping_no = str(time.strftime('%Y%m%d%H%M%S'))
        self.base_input(page.web_order_goods_no, shipping_no)

    # 6、点击确认发货
    def page_web_order_goods_ok(self):
        self.base_click(page.web_order_ok)

    # 7、打印配货单
    def page_web_order_print(self):
        self.base_click(page.web_order_print_order)

    # 8、获取订单编号
    def page_web_get_order_no(self):
        return self.base_get_text(page.web_order_no)

    # 9、发货业务方法
    def page_web_order(self):
        self.page_web_click_order_menu()
        self.page_web_click_order_list()
        self.page_web_go_goods()
        self.page_web_order_company()
        self.page_web_input_goods_no()
        self.page_web_order_goods_ok()
        self.page_web_order_print()

4、web端测试脚本实现

script目录下----> test01_web_from_login_to_order.py 文件更新为:

import unittest
from time import sleep

from base import log
from page.page_web_login import PageWebLogin
from page.page_web_order import PageWebOrder
from utils import GetDriver, read_json

class TestWebLoginOrder(unittest.TestCase):
    def setUp(self):
        self.driver = GetDriver.get_web_driver()
        # 获取PageWebLogin实例
        self.web_login = PageWebLogin(self.driver)
        # 获取PageWebOrder实例
        self.web_order = PageWebOrder(self.driver)

    def tearDown(self):
        sleep(3)
        self.driver.quit()

    def test01_web_login_order(self):
        try:
            # 1、调用登录
            self.web_login.page_web_login()
            # 获取登录昵称
            nickname = self.web_login.page_web_get_login_nickname()
            print('登录后的昵称为:', nickname)
            # 2、调用发货业务方法
            self.web_order.page_web_order()
            # 打印订单编号
            order_no = self.web_order.page_web_get_order_no()
            print('发货的订单编号为:', order_no)
            self.assertIn(order_no, read_json('expect.json', 'expect')[0][0])
            log.info('======> web 后台发货成功,发货的订单编号为:{}'.format(read_json('expect.json', 'expect')[0][0]))
        except Exception as e:
            log.error(e)
            # 1、截图
            self.web_order.base_screenshot_img()
            # 2、抛异常
            raise

4、 更改 page_app_from_login_to_order.py 文件方法

默认返回的订单号格式为:

订单编号:202206231816135296 需要切割 [5:]

难点:动态根据订单号去发货 app下单成功的订单号,就是web端进行发货的订单号,两者对应关系

如果不是动态根据订单号,就可以用下面的配置信息:

#      page目录 --->  __init__配置文件
web_order_go_goods = By.XPATH, "//a[text()='去发货']"  

#       page目录 --->  page_web_order.py文件   --> PageWebOrder类
 # 3、工作区域 点击去发货
    def page_web_go_goods(self):
        # 1、切换frame
        self.base_switch_to_frame(page.web_order_frame_workspace)
        # 2、点击去发货
        self.base_click(page.web_order_go_goods)

write_json(order_no[5:])
log.info('======> app发货成功,发货的订单编号为:{}'.format(read_json('expect.json', 'expect')[0][0]))

  @parameterized.expand(read_json('app_order.json', 'order'))
    def test01_login_order(self, search_value, pwd, expect):
        try:
            """登录测试用例"""
            # 1、调用登录
            self.app.page_app_login()
            # 获取昵称  --> 断言
            nickname = self.app.page_app_get_login_nickname()
            print('登录账户昵称为:', nickname)
            self.assertEqual(expect, nickname)
            # 2、下订单
            self.order.page_app_order(search_value, pwd)
            # 获取订单编号
            order_no = self.order.page_app_get_order_no()
            print('获取的订单编号为:', order_no)
            write_json(order_no[5:])
            log.info('======> app发货成功,发货的订单编号为:{}'.format(read_json('expect.json', 'expect')[0][0]))
        except Exception as e:
            log.error(e)
            # 1、截图
            self.order.base_screenshot_img()
            # 2、抛异常
            raise

5、批量运行测试用例 run_suite.py 文件完整代码:

import os
import unittest
from htmltestreport import HTMLTestReport

from config import DIR_PATH

suite = unittest.defaultTestLoader.discover('./script')
file_path = DIR_PATH + os.sep + 'report' + os.sep + 'tpshop_auto_report.html'
HTMLTestReport(file_path, title='tpshop项目UI自动化测试报告(APP、Web)').run(suite)

9、持续集成

1、把代码分享到Gitee上,步骤如下:

1)Pycharm软件直接 点击 **VCS **- -->Import into Version Control--> Share Project on Gitee

2)在弹出的对话框中去掉 .idle的勾选,其他自己写的目录和py文件都勾选上,点击 Add 按钮

分享成功提示:Successfully shared project on Gitee

2、打开jenkins所在目录,点击地址栏输入cmd打开命令提示符黑窗口

jenkins目录:D:\jenkins

执行:java -jar jenkins.war

java -jar jenkins.war

3、拷贝Gitee项目地址,点击目标项目仓库,点击“克隆/下载” 地址

4、打开浏览器输入网址:** http://localhost:8080/**,输入用户名和密码,登录jenkins工作台

5、配置jenkins:

1)点击新建Item

2)输入一个任务名称:xxx-pro,点击 freestyle project / 构建一个自由风格的软件项目,点击确定

  1. 源码管理--->Git---> Repository URL:第三步拷贝的Gitee仓库地址 Credentials:添加的证书即邮件

4)构建触发器 ---> Poll SCM 日程表(配置一分钟触发一次):***/1 * * * * ** 每分钟轮询

5)构建---> Excute Windows batch command ---> python run_suite.py

  1. 构建后操作 --> Publish HTML Report -->

  1. 构建后操作 --> Editable Email Notification ---> 邮箱收信人和HTML报告模板
HTML报告模板:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>${ENV, var="JOB_NAME"}-第${BUILD_NUMBER}次构建日志</title>
</head>
<body leftmargin="8" marginwidth="0" topmargin="8" marginheight="4" offset="0">
<div>
<h2>项目信息</h2>
<ul>
<li>项目名称:${PROJECT_NAME}</li>
<li>详细测试报告:<a href="${PROJECT_URL}HTML_20Report/">${PROJECT_URL}HTML_20Report/</a></li>
<li>触发原因:${CAUSE}</li>
<li>项目Url:<a href="${PROJECT_URL}">${P OJECT_URL}</a></li>
</ul>
<hr/>
<h2>构建日志</h2>
<div>${JELLY_SCRIPT,template="html"}</div>
<hr/>
</div>
</body>
</html>

报告样式问题: jenkins 倒三角 系统管理 Manage Jenkins ---》 脚本执行行 Script Console

代码如下:

System.setProperty("hudson.model.DirectoryBrowserSupport.CSP", "")

Jenkins构建出错,一般是由于权限或者环境导致的!!!


本文转载自: https://blog.csdn.net/qq_39270023/article/details/125415331
版权归原作者 樱桃小丸子测试 所有, 如有侵权,请联系我们删除。

“UI自动化测试实战--- app订单、web发货(9)”的评论:

还没有评论