黑马头条测试项目

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

自动化测试 - 黑马头条测试项目相关推荐

  1. 黑马头条推荐项目知识点总结(一)

    实际生产环境中,我们要处理的数据来自可能各个地方,业务数据库,爬虫数据库,日志文件,api网关买入数据等. 本次黑马头条推荐项目中,业务数据存储在mysql中,用户行为数据存储在日志中,因此采用两种技 ...

  2. 2019黑马python面试资料_2019最新Python黑马头条推荐系统项目

    『课程目录』:├─黑马头条推荐第一天) L) P$ Q$ }7 U│ ├─01_视频 │ │ 01_黑马头条推荐架构与业务流 │ │ 02_开发环境介绍( k# }! [2 n8 S$ }│ │ 03 ...

  3. 黑马python2019_2019最新Python黑马头条推荐系统项目

    『课程目录』:├─黑马头条推荐第一天) L) P$ Q$ }7 U│  ├─01_视频 │  │      01_黑马头条推荐架构与业务流 │  │      02_开发环境介绍( k# }! [2 ...

  4. python视频教程推荐it教程网_2019年最新Python黑马头条推荐系统项目开发视频教程完整版...

    课程定位 * 课程是机器学习(包含推荐算法)算法原理在推荐系统的实践 * 深入推荐系统的业务流场景.工具使用 * 作为人工智能的数据挖掘(推荐系统)方向应用项目 ## 课程目标 * 熟练掌握推荐系统的 ...

  5. 黑马头条移动项目(一):项目介绍、项目技术点介绍、项目包介绍

    1. 项目介绍 黑马头条移动端是一个IT资讯移动web应用,有着和今日头条类似的资讯浏览体验. 主要功能:资讯列表.标签页切换,文章举报,频道管理.文章详情.关注功能.点赞功能.评论功能.搜索功能.登 ...

  6. 黑马头条移动项目(十):登录页面的布局

    目标 能实现登录页面的布局 1. 登录页面的布局 1.1 创建组件并配置路由,访问登录页面 src/views/Login/index.vue - 作为登录页面 - 先随意弄写标签显示 <tem ...

  7. 软件测试项目实战32讲,软件测试入门-黑马头条项目实战

    课程简介 本课程以黑马头条实战项目为例,将项目的整个测试流程做了详细的介绍,并带着大家一起进行产品需求评审,项目测试计划编写,测试需求分析,以及测试用例的设计编写和执行操作,通过完成实际的功能业务测试 ...

  8. Python黑马头条推荐系统第一天 架构介绍和离线计算更新Item画像

    Python黑马头条推荐系统项目课程定位.目标 定位 课程是机器学习(包含推荐算法)算法原理在推荐系统的实践 深入推荐系统的业务流场景.工具使用 作为人工智能的数据挖掘(推荐系统)方向应用项目 目标 ...

  9. 前端基础第五天项目 社交媒体黑马头条项目-文章模块和评论

    七.文章详情 创建组件并配置路由 1.创建 views/article/index.vue 组件 <template><div class="article-contain ...

最新文章

  1. 2019年十大数据与分析技术趋势
  2. 【Linux+vscode】配置好秘钥之后还是不能ssh连接(离线配置)
  3. oracle 带有变量的语句_Oracle 动态SQL语句(2)之含变量的WHERE语句与日期变量
  4. How to resolve ATC error message Package Violation (Error) - Missing Use Access (USEM)
  5. Navigator 对象,能够清楚地知道浏览器的相关信息
  6. 1.0jpa 2.0_JPA 2.1实体图–第1部分:命名实体图
  7. 第五十一期:互联网不如国企,去BAT的程序员都是diao丝?
  8. 自定义View(四) ViewGroup 动态添加变长Tag标签 支持自动换行
  9. 凸函数与简森不等式(Jensen's inequality)
  10. 通过实例学习编写需求文档 【转】
  11. OSPF与EIGRP的比较
  12. 锦锐单片机开发工具_飞思卡尔单片机PE开发工具硬件及软件
  13. 色彩转换系列之RGB格式与YUV格式互转原理及实现
  14. oracle 函数索引
  15. R语言和医学统计学(4):秩和检验
  16. NYOJ - 小柯的编译器
  17. 【JavaSE】自定义异常
  18. STM32 实数FFT 极速配置
  19. 基于Python的二维有限元声波方程正演计算
  20. java 初级、中级、高级工程师

热门文章

  1. phpstorm使用教程
  2. 解密宜人贷:科技驱动金融创新
  3. 关于日本川崎重工中标高速铁路的事
  4. Mybatis报错org.apache.ibatis.binding.BindingException: Type interface com.trf.dao.UserDao is not known
  5. ssh 连接报错:Unable to negotiate with 192.168.xx.xx port 22: no matching key exchange method found.
  6. 面向 C++ 的测试驱动开发
  7. 2021年秋招面经分享·乐鑫【数字IC设计工程师】
  8. 华为交换机M-LAG配置
  9. 计算机图形学课程总结
  10. win10_940MX python3.6深度学习gpu环境搭建入门必看!anaconda3+cuda9.0+cudnn7.0.5+tensorflow1.7.0+keras2.1.6+openCV