自动化测试 - 黑马头条测试项目

article/2025/10/28 19:03:36

黑马头条测试项目

1. 自动化测试流程

1. 自动化测试流程

  1. 需求分析
  2. 挑选适合做自动化测试的功能
  3. 设计测试用例
  4. 搭建自动化测试环境
    • web自动化测试环境(4个)
      • python开发者工具(pycharm, python解释器)
      • 浏览器
      • 浏览器驱动
      • selenium
    • app自动化测试环境(5个)
      • 手机或模拟器
      • 安卓sdk
      • python开发工具
      • appium服务器
      • appium服务客户端
  5. 设计自动化测试项目架构
  6. 编写代码
  7. 执行测试用例
  8. 生成测试报告并分析结果

2. 黑马头条项目简介

1. 项目背景

作为一个IT教育机构,拥有自己开发且实际运营的产品,将开发和运营的技术作为授课的内容,对于学员而言学到的都是一手的真实案例和实际经验,知识内容也可以细化深入。 而且一个产品就可以涵盖公司多个学科的技术,衍生的课程价值辐射多个学科。这可以作为公司的一个核心竞争力。

2. 产品定位

一款汇集科技资讯、技术文章和问答交流的用户移动终端产品。 用户通过该产品,可以获取最新的科技资讯,发表或学习技术文章,讨论交流技术问题。

3. 项目目标

  1. 研发并上线运营头条产品
  2. 从实际的产品技术中孵化产品经理、Python 人工智能、Python 数据分析、Python Web、测试、运维等课程案例
  3. 构建公司自己的数据仓库和算法模型

3. 产品功能架构

自媒体:又称“个人媒体”,是指私人化、平民化、自主化的传播者, 以现代化、电子化的手段,向不特定的大多数或者特定的单个人传递信息的新媒体的总称。 自媒体平台包括:博客、微博、微信、抖音、百度贴吧、论坛/BBS等网络社区。

在这里插入图片描述
产品主要分为三个前端子产品:

  1. 用户端
    APP,用户可以查看资讯、文章内容,进行问答讨论交流
  2. 自媒体运营平台
    PC网站,自媒体用户可以管理文章、评论,查看分析粉丝数据
  3. 系统后台
    PC网站,内部运营管理系统

产品后端系统功能可分为以下几个部分:

  1. 推荐系统部分
    负责为用户个性化推荐资讯和文章
  2. 人工智能部分
    机器自动审核文章、文章画像提取、机器学习推荐算法等
  3. 日志系统部分
    收集保存用户行为数据和系统运行状态数据
  4. 爬虫部分
    爬取网站资讯文章数据,作为产品启动的初期数据来源

4. 产品技术架构

在这里插入图片描述

5. 负载均衡

负载均衡器: 负载均衡(Load Balance)可以将工作任务分摊到多个处理单元, 从而提高并发处理能力
负载均衡器建立在现有网络结构上, 使用它可以实现网络设备的带宽, 增加吞吐量, 加强网络数据处理能力, 提高网络的灵活性和可用性

负载均衡器在工作当中, 要么使用nginx(软件负载均衡), 要么使用F5(硬件负载均衡), 如果使用的是阿里云或者是腾讯云, SLB负载均衡, nginx既可以做负载均衡, 也可以做web前端的中间件

6. 消息队列

消息队列(Message Queue, MQ): 是在消息传输过程中保存消息的容器
消息队列中间件是分布式系统中重要的组件, 主要解决应用解耦, 异步消息, 流量削峰等问题, 实现高性能, 高可用, 可伸缩和最终一致性架构

目前使用较多的消息队列有: Kafka, ActiveMQ, RabbitMQ, ZeroMQ, MetaMQ, RocketMQ

应用场景

  • 异步处理
    将业务逻辑处理由串行方式变成并行方式(好友推荐, 新闻推荐)
  • 应用解耦
    订单系统 --> 库存系统
    发送短信验证码
  • 流量削峰
    秒杀, 抢购活动(用户访问量过大, 导致流量暴增, 应用挂掉)
  • 日志处理
    将消息队列用早日志处理中, 解决大量日志传输的问题

7. 用例设计

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

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

2. 编写测试用例

1. 自媒体自媒体

2. 后台管理系统在这里插入图片描述

3. APP在这里插入图片描述

8. 自动化框架结构设计

1. 初始化项目

1. 新建项目

项目名称: uiAutoTestHmtt

2. 创建目录结构

  • uiAutoTestHmtt #项目名称
  • base #封装PO基类
  • page #封装PO页面对象
  • script #定义测试用例脚本
  • data #存放测试数据
  • report #存放生成的测试报告
  • log #存放测试文件
  • screenshot #存放截图
  • config.py #定义项目配置信息
  • utils.py #定义工具类
  • pytest.ini #pytest配置文件
  • conftest #pytest.ini运行配置

3. 安装依赖包

  • selenium包
  • Appium-Python-Client包
  • pytest包
  • pytest-ording包
  • allure-pytest包

2. 初始化代码

1. 封装工具类

  • 封装PO类, 定义BasePage和BaseHandle
    • pytest.ini
[pytest]
addopts = -s -v --html=report/report.html --reruns 3
testpaths = ./uiAutoTestHmtt/script
python_files = test_*.py
python_classes = Test*
python_functions = test_*
  • utils.py
from selenium import webdriver
from appium import webdriver as appdriverclass UtilsDriver:_mp_driver = None #表示的是自媒体平台的驱动_mis_driver = None #表示的是后台管理驱动_app_driver =None # 表示的是app的驱动# 定义获取自媒体平台的浏览器驱动@classmethoddef get_mp_driver(cls):if cls._mp_driver is None:cls._mp_driver = webdriver.Chorm()cls._mp_driver.get("http://ttmp.research.itcast.cn/")cls._mp_driver.maximize_window()return cls._mp_driver# 定义退出自媒体平台浏览器驱动@classmethoddef quit_mp_driver(cls):if cls._mp_driver is not None:cls.get_mp_qdriver().quit()cls._mp_driver = None# 定义获取后台管理的驱动@classmethoddef get_mis_driver(cls):if cls._mis_driver is None:cls._mis_driver = webdriver.Chrom()cls._mis_driver.maximize_window()cls._mis_driver.get("http://ttmis.research.itcast.cn/")return cls._mis_driver# 定义退出后台管理系统操作方法@classmethoddef quit_mis_driver(cls):if cls._mis_driver is not None:cls.get_mis_driver().quit()cls._mis_driver = None# 定义获取app驱动@classmethoddef get_app_driver(cls):if cls._app_driver is None:des_cap = {"platformName": "android","platformVersion": "5.1.1","deviceName": "emulator-5554","appPackage": "com.itcast.toutiaoApp","appActivity": ".MainActivity","noReset": True, #用来记住app的session"resetKeyboard": True,  #重置设备输入键盘"unicodeKeyboard": True # 采用unicode编码输入}cls._app_driver = appdriver.Romate("http://127.0.0.1:4723/wd/hub", des_cap)return cls._app_driver# 退出app浏览器驱动@classmethoddef quit_app_driver(cls):if cls._app_driver is not None:cls.get_app_driver().quit()cls._app_driver = None

基类的封装

  1. 媒体平台的封装
    base包 -> 创建mp包 -> 在mp包下创建base.py文件
	from selenium.webdriver.support.wait import WebDriverWaitfrom utils import UtilsDriver# 定义自媒体平台的基类# 对象库层基类的封装class BasePage:def __init__(self):self.driver = UtilsDriver.get_mp_driver()  # 获取自媒体浏览器驱动def get_element(self, location):wait = WebDriverWait(self.driver, 10, 1)element = wait.until(lambda x: x.find_element(*location))return element# 操作层基类的封装class BaseHandle:def input_text(self, element, text):element.clear()element.send_keys(text)
  1. 后台管理基类封装
    base包 -> 创建mis包 -> 在mis包下创建base.py文件
from selenium import webdriverfrom utils import UtilsDriver# 定义后台管理的基类# 页面对象层封装class BasePage:def __init__(self):self.driver = UtilsDriver.get_mis_driver()  # 获取后台管理驱动def get_element(self, location)wait = WebDriverWait(self.driver, 10, 1)element = wait.until(lambda x: x.find_element(*location))return element# 操作层的封装class BaseHandle:def input_text(self, element, text):element.clear()element.send_keys(text)
  1. app基类封装
    base包 -> 创建app包 -> 在app包下创建base.py文件
from selenium import webdriverfrom utils import UtilsDriver# 定义app平台的基类# 对象库层基类封装class BasePage:def __init__(self):self.driver = UtilsDriver.get_app_driver()   # 获取app浏览器驱动def get_element(self, location):wait = WebDriverWait(self.driver, 10, 1)element = wait.until(lambda x: x.find_element(*location))return element# 操作层基类封装	class BaseHandle:def input_text(self, element, text):element.clear()element.send_keys(text)

自媒体平台的封装

自媒体登录页面的封装

page包 -> 新建mp包 -> 创建登录界面login_page.py

from base.mp.base import BasePage, BaseHandlefrom selenium.webdriver.common.by import By# 定义对象库层
class LoginPage(BasePage):def __init__(self):super().__init__()# 手机号码输入框self.mobile = By.XPATH, "//*[@placeholder='请输入手机号']"# 验证码输入框self.code = By.XPATH, "//*[@placeholder='验证码']"# 登录按钮self.login_btn = By.CSS_SELECTOR, ".el-button--primary"# 定位手机号码输入框def find_mobile(self):return self.get_element(self.mobile)# 定位验证码输入框def find_code(self):return self.get_element(self.code)# 定位登录按钮def find_login_btn(self):return self.get_element(self.login_btn)# 定义操作层
class LoginHandle(BaseHandle):
def __init__(self):self.login_page = LoginPage()# 输入手机号码def input_mobile(self, mobile):self.input_text(self.login_page.find_mobile(), mobile)# 输入验证码def input_code(self, code):self.input_text(self.login_page.find_code(), code)# 点击登录按钮def click_login_btn(self):self.login_page.find_login_btn().click()# 定义业务层
class LoginProxy:def __init__(self):self.login_handle = LoginHandle()def login(self, mobile, code):self.login_page.input_mobile(mobile)  # 输入手机号码self.login_page.input_code(code)  # 输入验证码self.login_page.click_login_btn()  # 点击登录按钮
自媒体平台首页封装

page包 -> 新建mp包 -> 创建登录界面home_page.py

from selenium.webdriver.common.by import Byfrom base.mp.base import BasePage, BaseHandle# 定义对象层
class HomePage(BasePage):def __init__(self):super().__init__()# 用户名显示元素self.username = By.CSS_SELECTOR, ".user-name"# 内容管理菜单self.content_manage = By.XPATH, "//*[text()='内容管理']"# 发布文章self.public_btn = By.XPATH, "//*[@class='sidebar-el-menu el-menu']/div[2]/li/ul/li[1]"# 定位用户名显示元素def find_username(self):return self.get_element(self.username)# 定位内容管理菜单def find_content_manage(self):return self.get_element(self.content_manage)# 定位发布文章菜单def find_publish(self):return self.get_element(self.publish_btn)#定义操作层
class HomeHandle(BaseHandle):def __init__(self):self.home_page = HomePage()# 获取用户名信息def get_username(self):return self.home_page.find_username().text# 点击内容管理菜单def click_content_manage(self):self.home_page.find_content_manage().click()# 点击发布文章def click_publish_btn(self):self.home_page.find_publish().click()# 定义业务层
class HomeProxy:def __init__(self):self.home_handle = HomeHandle()# 获取用户名信息def get_username_msg(self):return self.home_handle.get_username()# 跳转到发布文章页面def go_publish_page(self):self.home_handle.click_content_manage()self.home_handle.click_publish_btn()

自媒体平台发布文章页面封装

page包 -> 新建mp包 -> 创建登录界面publish_page.py

from base.mp.base import BasePage, BaseHandlefrom selenium.webdriver.common.by import By# 定义对象库层
class PublicPage(BasePage):def __init__(self):super().__init__()#文章名称输入框self.title = By.XPATH, "//*[@placeholder='文章名称']"# iframe元素对象self.iframe_ele = By.ID, "publishTinymce_ifr"# 文章内容输入框self.content = By.CSS_SELECTOR, ".mce-content-body"# 封面选择self.cover = By.XPATH, "//*[@role=radiogroup]/label[4]/span[2]"# 频道选择self.channel = By.XPATH, "//*[@placeholder='请选择']"# 发表按钮self.publish_btn = By.CSS_SELECTOR, "[class='el-button filter-item el-button--primary']"# 寻找文章标题def find_title(self):return self.get_element(self.title)# 找到切换的iframedef find_iframe_ele(self):return self.get_element(self.iframe_ele)# 找到文章内容输入框def find_content(self):return self.get_element(self.content)# 找到封面选择输入框def find_cover(self):return self.get_element(self.cover)# 定位频道选择输入框def find_channel(self):return self.get_element(self.channel)# 定位发表按钮def find_publish_btn(self):return self.get_element(self.publish_btn)# 操作层
class PublishHandle(BaseHandle):def __init__(self):self.publish_page = PublishPage()self.driver = UtilsDriver.get_mp_driver()# 输入文章标题def input_title(self, title)self.input_text(self.publish_page.find_title(), title)# 输入文章内容def input_content(self)# 切换到iframe中self.driver.switch_to.frame(self.publish_page.find_iframe())# 输入文章内容self.input_text(self.publish_page.find_input_content(), content)# 切回默认首页self.driver.switch_to.default_content()# 选择封面def choice_cover(self):self.publish_page.find_cover().click()#选择频道def choice_channel(self):choice_channel(self.driver, self.publish_page.find_channel_choice(), channel)#点击发布按钮def click_publish_btn(self):self.publish_page.find_publish_btn().click()# 业务层封装
class PublishProxy:def __init__(self):self.publish_handle = PublishHandle()# 发布文章def publish_article(self, title, content, channel):# 输入文章标题self.publish_handle.input_title(title)self.publish_handle.input_content(content)self.publish_handle.choice_cover()self.publish_handle.choice_channel(channel)self.publish_handle.click_publish_btn()

在utils模块中封装选择频道的方法

......
def choice_channel(driver, element, channel)
"""
param driver: 浏览器驱动对象
param element: 选择元素
param channel: 要选择的文本内容
"""
element.click()
time.sleep(1)
xpath = "//*[@class='el-select-dropdown__wrap el-scrollbar__wrap']//*[text()='{0}']".format(channel)
driver.find_element(By.XPATH, xpath).click()

在utils中封装一个方法, 判断元素是否存在

......
# 封装一个方法判断元素是否存在
def is_exis(driver, text):"""param driver: 浏览器驱动对象param text: 定位元素的文本内容"""xpath = "//*[contains(text(), '{0}')]".format(text)try:time.sleep(2)return driver.find_element(By.XPATH, xpath)expect Expection as e:return False

自媒体测试用例的编写

scripts模块 -> 创建mp模块 -> 创建test_publish_article.py文件

from page.mp.login_page import LoginProxy
from page.mp.home_page import HomeProxy
from page.mp.publish_page import PublishProxyclass TestPublishArticle:# 定义类级别的fixture初始化方法def setup_class(self):self.login_proxy = LoginProxy()self.home_proxy = HomeProxy()self.publish_proxy = PublishProxy()# 定义类级别的fixture销毁方法def teardowm_class(self):UtilsDriver.quit_mp_driver()# 定义登录测试用例def test_login(self):self.login_proxy.login("18815687257", "246810")username = self.home_proxy.get_username_msg()assert "test123" == username# 定义文章测试用例def test_publish_article(self):self.home_proxy.go_publish_page()self.publish_proxy.publish_article("发布文章_0321_09", "发布文章_0321_09发布文章_0321_09", "数据库")assert is_exist(UtilsDriver.get_mp_driver(), "新增文章成功")

后台管理系统页面的封装

后台管理系统登录页面的封装

page包 -> 新建mis包 -> 创建登录界面login_page.py

from selenium.webdriver.commom.by import By
'''页面对象层'''
class LoginPage(BasePage):def __init__(self):super().__init__()self.username = By.Name, "username"self.password = By.Name, "password"self.login_btn = By.ID, "inp1"# 定位用户名输入框def find_username(self):return self.get_element(self.username)# 定位密码框def find_password(self):return self.get_element(self.password)# 定位登录按钮def find_login_btn(self):return self,get_element(self.login_btn)"""操作层"""
class LoginHandle(BaseHandle):def __init__(self):self.login_page = LoginPage()# 输入用户名def input_usernane(self, username):self.input_text(self.login_page.find_username(), username)# 输入密码def input_password(self, password):self.input_text(self.login_page.find_password(), password)# 点击登录def _click_login_btn(self):# 定义JSjs = "document.getElementById('inp1').removeAttribute('disabled')"# 通过execute_script方法执行JSself.login_page.driver.execute_script(js)# 点击登录按钮self.login_page.find_login_btn().click()# 定义业务层
class LoginProxy:def __init__(self):self.login_handle = LoginHandle()# 登录业务操作def login(self, username, password):self.login_handle.input_username(username)self.login_handle.input_password(password)self.login_handle.click_login_btn()
后台登录系统主页的封装

page包 -> mis包 -> 创建登录界面home_page.py

# 页面对象层
class HomePage(BasePage):def __init__(self):super().__init__()# 用户信息self.user_info = By.CSS_SELECTOR, ".user_info.span"# 信息管理seld.content_manage = By.XPATH, "//*[@class='side_bar']/ul/li[3]/a"# 内容审核self.content_audit = By.XPATH, "//*[@class='current3']/li[3]/a"# 定位用户信息def find_user_info(self):return self.get_element(self.user_info)# 定位信息管理菜单def find_content_manage(self):return self.get_elememt(self.content_manage)# 定位内容审核状态def find_context_audit(self):return self.get_element(self.content_audit)# 定义操作层
class HomeHandle(BaseHnadle):def __init__(self):self

http://chatgpt.dhexx.cn/article/CK9oQRYq.shtml

相关文章

用户画像标签体系包括哪些维度?有哪些应用场景?(附完整导图)

来源:大数据DT 本文约2600字,建议阅读7分钟 本文详细介绍用户标签体系的构成及应用场景。 互联网相关企业在建立用户画像时一般除了基于用户维度(userid)建立一套用户标签体系外,还会基于用户使用设备维度(…

《用户画像--方法论与工程化解决方法》读后感

代码下载: GitHub - HunterChao/User-Portrait: 用户画像相关的参考代码 前言 第1章 用户画像基础1 1.1 用户画像是什么1 1.1.1 画像简介1 用户画像,即用户信息标签化,通过收集用户的社会属性、消费习惯、偏好特征等各个维度的数据&…

【数据分析】信用卡用户画像及违约预测逻辑回归模型

1、数据源说明 kaggle上比较经典的数据集,来源某银行个人信贷业务,包含客户数据、信用卡数据、交易订单等基本数据,通过这些数据可以了解银行信贷业务及风险防控相关内容。 2、数据库导入及宽表建立 为便于理解及跨软件处理,已…

「BUAA SE 个人作业-2」软件案例分析

项目内容这个作业属于哪个课程2023年北航敏捷软件工程这个作业的要求在哪里个人作业-软件案例分析我在这个课程的目标是学习并掌握现代软件工程的开发模式和流程,锻炼个人能力及团队协作能力这个作业在哪个具体方面帮助我实现目标深入分析软件功能,了解软…

山东大学软件学院软件工程作业

第一章 1、请谈一下关于软件工程的整体认识和印象。 软件工程是指用系统化,模块化的工程性方法解决软件开发中的问题。简单来说,软件工程就是使用一种系统化的方法,解决软件开发中的各种困难。解决耦合度高等等的问题。 软件工程的目的是为了…

软件案例分析:商业音乐软件还是开源音乐软件?

项目内容这个作业属于哪个课程2023北航敏捷软件工程这个作业的要求在哪里个人作业-软件案例分析我在这个课程的目标是积累软工经验,进行软工方法论实践,提高工程能力这个作业在哪个具体方面帮助我实现目标从软件工程角度看待一款软件,了解一款…

软件测试质量或时效,版本质量总结的纬度

在一些大的团队,一般会有专职的角色来负责质量管理,即QA。QA在每个项目或版本结束时,追本溯源,重新审视项目过程,从不同纬度来分析版本的各种数据,从而挖掘出整个研发流程和团队存在的问题,进行流程改善和质量、效率提升。 那么通常可以从哪些方面来进行版本质量分析呢。…

一文搞懂用户画像︱敏捷软件开发之用户故事

用户画像,最简单理解为一堆用户特征或者标签的组合。 关于“用户特征” 特征,是指对于同一个指标,在某个维度上的表现特别与众不同。并且这种与众不同在营销上也具备较强的知道意义。所以,用户画像中的维度并不是什么阿猫阿狗都能…

Profile_Day05:企业级360全方位用户画像

Profile_Day05:企业级360全方位用户画像 1昨日内容回顾 主要讲解2个方面的内容: 如何基于SparkSQL实现自定义外部数据源HBase和统计类型标签模型开发. 1, SparkSQL外部数据源HBase 按照SparkSQL模块提供的外部数据源接口,实现HBase表中加载和保存数据 2,今日课程内容提纲 3,…

从理论到工程实践——用户画像入门宝典

用户画像是大数据顶层应用中最重要的一环,搭建一套适合本公司体系的用户画像尤为重要。但是,用户画像的资料往往理论居多,实践少,更少有工程化的实战案例。 本文档结合了常见的用户画像架构,使用Elasticsearch作为底层…

实战案例:场景测试之ATM机取款业务测试

本期,我们通过经典案例——ATM机的操作,来为大家详细说说如何撰写对应的测试用例。 【案例】 在我们日常生活中,ATM机是个大家都非常熟悉的事物。银行为例提高工作效率,方便客户随时办理基础的储蓄和提现业务,于是&a…

干货收藏!快速掌握用户画像项目的开发流程(附流程图)

导读:随着大数据技术的深入研究与应用,企业的关注点日益聚焦在如何利用大数据来为精细化运营和精准营销服务,而要做精细化运营,首先要建立本企业的用户画像。 在画像系统的项目规划阶段需要明确好项目的开发上线流程以及项目各个阶…

音乐软件案例分析

项目内容这个作业属于哪个课程2023年北航敏捷软件工程这个作业的要求在哪里软件案例分析我在这个课程的目标是学习软件工程理论,在实践中体会并运用软件工程理论,收获团队开发和软件工程实践经验这个作业在哪个具体方面帮助我实现目标实践了软件案例分析…

计算机转岗测试,软件测试人员转岗哪些岗位

对于大多数的大龄程序员来说,转岗也是比较常见的一种职业发展方向,而今天我们就通过案例分析来了解一下,软件测试人员转岗哪些岗位。 1.项目经理 测试人员,尤其是敏捷团队的测试人员,涉及到项目质量相关的方方面面&…

如何构建用户画像?

在《4个问题带你了解用户画像》中,我们了解了用户画像的定义、作用及使用注意事项等。 就有用户留言问了:在实际工作中,构建用户画像的方法有哪些?如何构建用户画像呢? 下面我将结合通过案例,带你了解构建用…

软件工程-案例分析

软件工程-案例分析 Mashiroln 项目内容这个作业属于哪个课程https://bbs.csdn.net/forums/buaa-ase2023这个作业的要求在哪里https://bbs.csdn.net/topics/613598122我在这个课程的目标是通过案例分析总结经验和教训,学习以现代软件工程的视角思考问题这个作业在哪…

python用户画像_python用户画像

广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! 06某用户画像案例这里通过一个实践案例来将大家更好地带入实际开发画像、应用画像标签的场景中。 本节主要介绍案例背景及相关的元数据,以及开发标签中可以设计…

实战项目:Java分布式优惠券系统后台(持续更新)

前言 陆陆续续总算是把Java基础、计算机网络基础以及数据库相关技术初步看完了,离深层次的理解还有一定的距离。今天开始准备跟着做一个实际项目吧,也希望在过程中能够把相关技术跟实际应用结合起来,俗话说实践出真知,希望通过这次…

Java生鲜电商平台-优惠券系统设计详解

Java生鲜电商平台-优惠券系统设计详解 Java生鲜电商平台-优惠券系统设计详解 优惠券作为电商最常用的营销手段,对于商家而言可以起到拉新、促活、提高转化的作用,对用户而言也可以获得实惠,今天就来谈谈优惠券系统的设计逻辑。 我对于优惠…