在2018泰国max泰拳直播看泰拳手对着镜子练拳的时候,双手都握个石头出拳,请问这个石头术语叫什么?哪能买到?

QTP IF - download. ??些模块,在博为峰网校我也录制了专门的课程 ... Smoke test for AP 此文件夹中 ... #加入上述语句即可以在此脚本中输入中文 ...DESCRIPTION(上 篇) 测试女巫之 Python Unit test 篇…………………………….…..….…..………….01 【搜狗专栏】时间管理方法……………………………………………………...19…Transcript
测试女巫之 Python Unit test 篇…………………………….…..….…..………….01
【搜狗专栏】时间管理方法……………………………………………………...19
【搜狗专栏】需求评审前的测试准备流程规范……………..………………….24
测试人生之谁的青春不迷茫……………………………………...........................30
如何处理大数据性能问题?………………..…………………………………….32
测试公主之为人鱼公主找到真爱………………………………...........................46
【搜狗专栏】测试人员例会会议议题制定规范…………………………………67
【搜狗专栏】性能测试流程……………………………………………………....70
QTP 使用之一个灵活的数据驱动的 IF 函数……………………………………..82
鱼儿妈的 4 年测试生活……………………………………………………………86
再论纯软件测试方法…………………………………………………....................89
【极测专栏】利用代码覆盖率进行精准测试和回归……………………………91
现实公司环境中的实际测试过程是什么样的?…………………………………97
《51 测试天地》四十四(上)
www.51testing.com
截止到目前对于 Python 我们已经介绍了 Pywinauto,Pymouse,Pykeyboard,Selenium
这些模块,在博为峰网校我也录制了专门的课程进行了深入的讲解,根据此模块的学习
我们可以实现自动化控制运行在 Windows 上的应用程序、可以自动化控制 Browser 上的
控件,可以控制鼠标和键盘。但是如何根据我们目前学习的这些模块,针对我们的待测
物如何搭建整个测试系统呢?进而如何产生外观漂亮,清晰明朗的测试报告呢?
这次我们学习的就是这方面的知识,可以帮我们搭建测试框架的模块是 Python 自带
的一个模块:Unittest,即 Unit test Framework 就可以搭建这个框架。
还会接触到一个模块 HTMLTestRunner,这个模块会帮助我们产出外观漂亮且清晰明
朗的测试报告,且不需要学习各种函数,直接调用这个模块即可。
这次 Unittest 相对于之前学习的模块例如 Selenium 或者 Pywinauto,最大的特点
是没有很多的函数需要学习,因为这个模块只是帮助我们建立测试框架,同样
HTMLTestRunner 也不需要了解其中的函数,只需要知道如何调用这个模块即可,且调用
模块的方法其实是非常简单的!
所以大家一起启动学习模式,一起为改变枯燥的工作努力吧!
第一阶段:工作需求
学习必须要有理由,我们如何也要有充足的工作需求才能说服老板。
所以对于 Unittest 的“工作需求”,女巫总结如下:
1、对一些复杂工作的自动化,需要规划自动化测试的架构,我们通过学习 UnitTest
这个模块可以帮助我们快速建立框架清晰,科学的自动化测试架构
测试女巫之 Python Unit Test 篇
? 作者:王平平
《51 测试天地》四十四(上)
www.51testing.com
2、我们在完成测试后,希望有一个看起来“高大上”的报告,但是又希望我们不要
写太多太复杂的代码,HTMLTestRunner 这个模块可以帮助我们实现这个需求
所以基于上述两个需求,我们可以进行接下来的 Unittest 以及 HTMLTestRunner 的学
第二阶段:unittest 基本知识
1、unittest 的作用
unittest 支持测试自动化,它是一个测试类来完成对整个软件模块的、测试,它的对
象的初始化工作可以在 setUp()方法中完成,而资源的释放则可以在 tearDown()方法中完
成,它是将 test case 收集起来一起执行,而产生的报告是针对每个 test Case 对立产生的
2、unittest 官网
https://docs.python.org/2/library/unittest.html
注意:unittest 此模块是 Python 自带的模块,所以不需要另外安装第三方模块。
3、unittest 的重要概念
1) Test fixture(测试治具)
表明一些准备工作需要执行一个或者更多的测试用例,和一些需要清除的动作,它
是一个概念,使用 TestCase,setUp 和 tearDown 这些方法来对于测试治具进行初始化,建
立测试用例,以及清除。
所以测试治具是被构建的,它是由 setup 方法,TestCase 组件以及 tearDown 方法组成
https://docs.python.org/2/library/unittest.html
《51 测试天地》四十四(上)
www.51testing.com
2) Test case
Test case 是测试的最小单元。根据特殊的一系列的输入产生特定的回应。Unittest 提
供一个基本的类:Test case 可以用来创建新的 test cases.
3) Test suite(测试集)
Test suit 是 test case 的集合,它可以用来整合 test cases,使其可以一起进行执行测试。
4) Test runner
Test runner 是执行测试以及提供测试结果给用户的一个组件,它可以使用图形接口,
文字接口或者返回一个特殊值来说明执行测试的结果。
4、具体常用类以及函数介绍说明
1) Test Case 类以及常用函数
a. TestCase 官网说明
进入官网点击左边树形结构的“Classes and Functions”第一个类需要学习的就是
TestCase 类,其中我们用的最多的是 setUp()以及 tearDown(),此两个函数没有任何 input,
只要在其中加入 user 自己定义的函数即可。在这两个函数之间加入用户自己定义的函数,
这样就建立了自己的 test fixture。
b. TestCase 源代码地址:C:\Python27\Lib\unittest\case.py
《51 测试天地》四十四(上)
www.51testing.com
c. TestCase 类的作用
主要是建立我们需要测试的若干单元测试用例,也可称为若干个执行函数
d. 框架如下:
? setUp 的处理(3 种方式)
a) 测试前的准备工作,可以添加恢复出厂值或者测试前需要设置的参数
b) 直接写 pass
c) 删除本函数
? tearDown 的处理(3 种方式)
a) 测试后的清除工作
b) 直接写 pass
c) 删除本函数
? 添加调用执行函数的相关的代码
需要测试几个功能就添加几个执行函数,这个执行函数可以理解为单元测试用例。
《51 测试天地》四十四(上)
www.51testing.com
e. 具体代码例子如下:
2) TestSuite 的类以及常用函数
a. TestSuite 官网
进入官网点击左边树形结构的“Grouping Testing”
此类中我们用的最多的函数是 addTest()
b. TestSuite 源代码地址:C:\Python27\Lib\unittest\suite.py
注意此脚本中有两个重要的类,BasicTestSuite 和 TestSuite,注意 TestSuite 是继承
BasicTestSuite,所以通过TestSuite可以同时调用BasicTestSuite和TestSuite其中的Function。
《51 测试天地》四十四(上)
www.51testing.com
c. TestSuit 类的作用
将测试用例聚合成测试套件,即把 test case 整合起来作为一个测试套件,以方便后续
运行,所以我们经常使用的一个函数就是 addTest(self, test),即使用这个函数将我们在上
一步建立的 test case 一步步的加入使用 addTest 这个函数将 TestCase 中导入的各个单元测
试导入到测试套件中
注意:addTest 这个函数的 input parameter 为 unittest 类名(单元测试函数名)
例如:testsuite.addTest(test_class("test_Data_Roaming"))
《51 测试天地》四十四(上)
www.51testing.com
第三阶段:运行方式说明
1、直接运行测试用例
1) 弊端:测试用例必须要以 test 开头命名
2) 优点:不需要额外将测试用例导入到 unittest 中
3) 运行方式: if __name__ == "__main__":
unittest.main()
4) 代码举例
《51 测试天地》四十四(上)
www.51testing.com
5) 执行顺序:以名字的大小为序
依次为 test_Enable_Logging, test_Log_Category_All,
test_Log_Category_Network
2、将测试用例聚合成测试套件运行方式
1) 弊端:测试用例必须一条一条手动添加,不想运行的用例要一条一条删除或屏蔽
2) 优点:执行测试的顺序一目了然,很好控制
3) 运行方式:testsuite=unittest.TestSuite ()
testsuite.addTest(test_smoke_test("Status_3G"))
testsuite.addTest(test_smoke_test("PIN_On"))
4) 代码举例:
5) 执行顺序:以添加测试用例的先后为序
依次为 Status_3G, PIN_On
3、嵌套测试套件
1) 弊端:执行测试的顺序不能一目了然,需要通过命名的方式来控制相似名称的测
试用例才能使用此方法
2) 优点:测试用例可以批量添加或批量删除
《51 测试天地》四十四(上)
www.51testing.com
3) 运行方式:testsuite1=unittest.makeSuite()
testsuite.addTest(test_smoke_test,"Time")
testsuite.addTest(test_smoke_test,"PIN")
testsuite=unittest.TestSuite(testsuite1,testsuite2)
4) 代码举例:
5) 执行顺序:
以 unittest.TestSuite(testsuite1,testsuite2)中添加的先后为序,testsuit 中以名字的大小为
依次为 PIN_Off, PIN_On, Time_Zone_INDEX_Daylight_0,
Time_Zone_INDEX_Daylight_10, Time_Zone_INDEX_Daylight_12,
Time_Zone_INDEX_Daylight_2, Time_Zone_INDEX_Daylight_9
第四阶段:Unittest 的框架
将不同的功能作为独立的模块进行被调用和维护,方便维护,同时也可以使自动化
脚本的框架清晰明了。
《51 测试天地》四十四(上)
www.51testing.com
2、文件夹建立
在某一存储位置下(例如:E 盘)建立一个文件夹:例如 smoke test for AP 在此文件夹下
建立有关各个模块的子文件夹(有多少模块就有多少子文件夹):例如 Advanced 和 Internet
就必须分别建立两个文件夹,如下图
此文件夹是根据下图红框所示的功能块进行建立的
如果 LAN 其中有两个 item 则在 LAN 中建立两个”.py”
文档一个命名为子 function 的名称,如下图:
注意:每个文件夹中必须有一个名称为”__init__.py”的内容为空白 py 文档,只有包含
此文档则此文件夹中的模块才能被其它的脚本正常调用。
《51 测试天地》四十四(上)
www.51testing.com
Smoke test for AP 此文件夹中放入调用各个脚本的 smoketest.py 和其中含有各个模块
都会调用的函数的 init.py 此两个脚本。
注意:每个模块只能实现一个大的功能模块,如此功能模块是由两个脚本组成:例
如 DHCP 和 LAN Setting。
3、脚本的分配
主要分成 3 个方面:smoketest.py , constant.py ,HTMLTestResult.py 和其它各个功
能的子模块(如下图中的各个文件夹)如下图
1) smoketest.py
此脚本的意义是调用各个模块中函数并执行,即执行自动化测试时只要运行此脚本
即可,因为它的用法就是调用各个模块并执行各个模块。
《51 测试天地》四十四(上)
www.51testing.com
smoketest.py 脚本的详细说明:
# coding=utf-8
#加入上述语句即可以在此脚本中输入中文,否则会报错
import HTMLTestRunner,unittest,time,sys,os
from selenium import webdriver
from LAN import DHCP
#导入所需要的各个模块
sys.path.append(os.path.dirname(__file__))
driver = webdriver.Firefox()
driver.implicitly_wait(30)
driver.get("http://192.168.1.1/")
driver.find_element_by_id("txtUserName").clear()
driver.find_element_by_id("txtUserName").send_keys("admin")
《51 测试天地》四十四(上)
www.51testing.com
driver.find_element_by_id("txtLoginPwd").clear()
driver.find_element_by_id("txtLoginPwd").send_keys("admin")
driver.find_element_by_name("button.login.users.home").click()
#上述语句是进入路由器的 Web UI 界面,并清空已输的内容,输入正
确的用户名和密码
class test_smoke_test(unittest.TestCase):
def setUp(self):
def DHCP_Settings(self):
DHCP.DHCP_Settings(self,driver)
def DHCP_Function(self):
DHCP.DHCP_Function(self,driver)
def DHCP_Reservation_Add(self):
DHCP.DHCP_Reservation_Add(self,driver)
def DHCP_Reservation_Edit(self):
DHCP.DHCP_Reservation_Edit(self,driver)
def DHCP_Reservation_Delete(self):
DHCP.DHCP_Reservation_Delete(self,driver)
def tearDown(self):
#上述内容是导入 DHCP 脚本中定义的函数
if __name__ == "__main__":
testsuite=unittest.TestSuite()
testsuite.addTest(test_smoke_test("DHCP_Settings"))
testsuite.addTest(test_smoke_test("DHCP_Function"))
testsuite.addTest(test_smoke_test("DHCP_Reservation_Add"))
testsuite.addTest(test_smoke_test("DHCP_Reservation_Edit"))
testsuite.addTest(test_smoke_test("DHCP_Reservation_Delete"))
#上述内容是将导入多的函数加到测试集中
#构建 report
filename="E:\\Selenium\\Auto test for AP\\results.html"
fp=file(filename,'wb')
《51 测试天地》四十四(上)
www.51testing.com
#上述内容是创建测试报告所在的位置以及创建测试报告
runner=HTMLTestRunner.HTMLTestRunner(stream=fp,title='Result',description='Test_Report')
#上述内容是调用 HTMLTestRunner 脚本,并产生报告
runner.run(testsuite)
2) constant.py
将各个模块使用的一些常量,均集中到此脚本中,其它的脚本如需用到这些常量通
过调用函数的方式来使用。这样做有一个很大的好处:
即如果这些常量发生变化,只要在此脚本中更改就可以了,其它需要使用这些常量
的脚本就不需要再进行更改。
Constant.py 脚本的详细说明如下
DHCP_Reservation_host_name_add_edit='44:37:e6:6b:88:63'
DHCP_Reservation_IP_address_add='192.168.2.10'
DHCP_Reservation_IP_address_edit='192.168.2.22'
DHCP_Reservation_IP_address_delete='192.168.2.26'
DHCP_Reservation_host_name_delete='40:16:9f:95:22:4f'
#上述代码是对这些常量定义对应的变量
def get_DHCP_Reservation_host_name_add_edit():
return DHCP_Reservation_host_name_add_edit
《51 测试天地》四十四(上)
www.51testing.com
def get_DHCP_Reservation_IP_address_add():
return DHCP_Reservation_IP_address_add
def get_DHCP_Reservation_IP_address_edit():
return DHCP_Reservation_IP_address_edit
def get_DHCP_Reservation_IP_address_delete():
return DHCP_Reservation_IP_address_delete
def get_DHCP_Reservation_host_name_delete():
return DHCP_Reservation_host_name_delete
#为了其它脚本便于调用,将这些变量定义为函数
Username='admin'
Password='admin'
def get_Username():
return Username
def get_Password():
return Password
3)各个子模块
这些脚本的作用是:具体操作路由器各个功能。
例如:实现的功能是在 DHCP 中”specify the number of devices/computers in your
network”自己设置一个值,点击 Apply 后确认设置的数值正确。如下图
from selenium.webdriver.support.ui import Select
import time
testcase=__name__.encode('utf-8')
def DHCP_Settings(self,driver):
driver.find_element_by_id("lan_menu_img").click()
#点击 LAN 进入 LAN 的设置界面
driver.find_element_by_link_text("DHCP").click()
#点击 DHCP 进入 DHCP 设置界面
driver.find_element_by_id("num_devices").clear()
#选择文本框 ""Specify the number of devices/computers in your network",并清除文本框默认的值
《51 测试天地》四十四(上)
www.51testing.com
driver.find_element_by_id("num_devices").send_keys("18")
#设置文本框的值为 18
driver.find_element_by_name("button.apply").click()
#点击 apply,保存此设置
after_set1=driver.find_element_by_id
("number_devices").get_attribute("value")
self.assertEqual(after_set1,"18")
#判断保存成功后的值与设置的值是否相同
第五阶段:自动产生 HTML 报告
1、下载 HTMLTestRunner.py 此脚本,下载地址:
http://www.51testing.com/html/12/n-3715212.html
http://www.51testing.com/html/12/n-3715212.html
《51 测试天地》四十四(上)
www.51testing.com
2、放置位置
将此脚本放到 c:\python27\lib 此文件夹中,或者放置到与 smoketest.py 在同一个文件
3、执行脚本中添加语句 import HTMLTestRunner
4、执行脚本中删除语句 unittest.main(),添加语句
testsuite=unittest.TestSuite()
testsuite.addTest(test_class("test_Data_Roaming"))
filename="E:\\re\\results5.html"
fp=file(filename,'wb') runner=HTMLTestRunner.HTMLTestRunner(stream=fp,title='Result',desc
ription='Test_Report')
runner.run(testsuite)
注:黄色标记为自己定义的内容
我们这一期介绍的是 Unittest 以及 HTMLTestRunner 这两个模块的学习,这两个模块
学习起来比较简单,因为并不需要学习模块中每个函数的用法,重点是学习 Unittest 的框
架以及其中的每个 test case 的运行方式,把框架和运行方式搞懂了,就可以根据我们自己
的测试需求搭建属于自己的自动化测试框架。HTMLTestRunner 实际上是一个开源的脚本,
目前这个脚本在官网上也可以直接下载,这个脚本大家不需要查看其中的内容,只要快
速了解如何调用这个脚本就可以了。所以我们这一期的学习还是非常轻松的,在积累的
前几期的知识的基础上,我们可以轻松搭建自动化测试框架,以及会非常轻松的产出看
起来非常“高大上”的报告。如果觉得这几期讲解的模块知识,光看文章学会运用还是
《51 测试天地》四十四(上)
www.51testing.com
有些难度的话,可以看看我录制的课程《Python 系列课程之玩转自动化》
(http://www.atstudy.com/course/158),配合这几期的文章知识,学习掌握会更形象透彻一些。
还是那句话大家在解决工作中的具体问题时,思路一定要灵活,对于具体问题一定
要先考虑这个模块的作用是什么,我如何快速学习这个模块,如何学习才会比较节省人
力物力,这样你才能与老板真的有共同语言:即一定要切记:一定要用最少的人力物力,
实现你的自动化!
参考文献:
1) Python 官网:http://www.python.org/getit/
2) UnitTest 的官网:https://docs.python.org/2/library/unittest.html#
(此网站包括如何使用,以及其中的一些常用函数的介绍)
3) HTMLTestRunner 下载官网:https://pypi.python.org/pypi/HTMLTestRunner
http://www.atstudy.com/course/158
《51 测试天地》四十四(上)
www.51testing.com
时间管理方法
◆搜狗测试:陈
1、工作是否忙碌?盲目?
盲目的原因:
a、人生关键时期,被迫要求角色转变
b.我们还来不及构建自己的职业规划和人生目标
c.我们不具备平衡生活和工作的能力
d.没有养成良好的习惯
确实很忙分两种人:一种是具备时间管理能力的人,另一种是不具备的人;前者用
20%的时间完成后者 80%的工作。
时间黑洞:它会永无止境的吞噬你宝贵的时间
2、价值观是什么?
成熟的标志是明确自己的价值观,价值观是指一个人对周围的客观事物(人、事、
物)的意义、重要性的总评价和总看法。职业价值观直接关系到我们判断工作任务的轻
重、缓急。
价值观没有对错。
比如有三种人
1) 拿着地图走路,做事之前已经做好详细的加护,按照计划执行
2) 看着路牌走路,走一步看一步,每到十字路口都要重新选择一次,最终到哪也不
《51 测试天地》四十四(上)
www.51testing.com
3) 顺着方向走,选择一个大的方向,朝着这个方向努力,靠信念往前走。
第一种是建筑师、第二种是科研人员、第三种是创业者。没有对错,只是看你愿意
做哪种人。
3、找到自己搞笑的时间段,如何寻找
坚持两天,每天每隔一小时计划下一个小时的任务,连续两天后,可以统计出自己
那个时段的效率最高,这个时段用来处理最重要的事
4、你是如何管理时间的?
讨论并记录
二、时间管理的方法
1、四象限法则
第一象限:重要紧急
比如危机公关、小孩填报志愿、紧急上线包。这类事情必须马上处理,否则有严重
思考:是否真的有那么多紧急重要的事?
第二象限:重要不紧急
《51 测试天地》四十四(上)
www.51testing.com
如制定 2017 年团队目标、制定明年家庭旅游计划、考驾照。这些事看起来不紧急,
但是我们不可能置之不理,如果不重视将来会发展为重要紧急的事。
思考如何避免更多的事进入到第一象限?
第三象限:紧急不重要
如突然来电、临时会议。
思考:如何减少这个象限的事务
第四象限:不重要不紧急
如追剧、闲聊、嗑瓜子儿等
思考:工作中应该避免这个象限的事
四象限使用方法:
c.对每个象限任务进行高、中、低优先级排列
d.优先解决重要且紧急的工作,制定计划去做重要但不紧急的工作
2、衣柜整理法
衣柜整理法的五个流程是:收集、整理、组织、执行、回顾
收集:通过尽量少的工具(手机、便签等)收集一切未完成的工作。
整理:将收集的条目进行分类,分为可以执行和不能执行两种。可执行的任务分为:
? 两分钟之内可以搞定的事——立即去做
? 需要多个步骤搞定的项目——分解成任务-下一步行动
? 可以直接做的事——有空的时候搞定
? 特定时间做的事——写在日程表里,设置到时提醒
组织:将分类的条目重新储存,形成一个“收集篮”和三个清单。
? “收集篮”:一切引起我们注意的东西,所有接收到的任务列表
《51 测试天地》四十四(上)
www.51testing.com
? 将来清单:将来或可能的清单;
? 项目清单:需要多个步骤才能完成的项目;
? 待办事项清单:今日可以立刻做的清单。
回顾:计划和目标并不是一成不变的,避免盲目,需要定期回顾,可以对计划进行
更新和完善。
? 回顾“将来清单”,可以将一些不感兴趣的事情和一些时机和条件不成熟的删去。
将一些可实现的事放到项目清单。
? 回顾“项目清单”,了解项目进展的进度,考虑各个项目中需要增加或者删除哪
些流程,确保项目的高效的执行。
? 回顾“待办事项清单”,了解哪些事情是否及时处理。
建议回顾频率:每天下班或每周一次
行动:执行我们的行动。
3、脑袋里只装一件事
假设有 100 件事待办,收集篮把所有问题都装起来,清空大脑,每次挑出一件事处
理,处理完一件事,扔掉,再挑下一件事处理,大脑只需要同时处理一件事,就不会有
那么大的压力了。
举例:车站咨询员,无论有多少旅客,只同时回答一个人的问题,这样就能有条不
好处:专注、成就感、摆脱压力
脑袋里只处理一件事,我们只需要思考,下一个行动是什么。
4、区分“项目”和“行动”
项目由行动组成,行动是可执行的步骤
如何找到下一步行动?
1) 动词开头
2) 内容清晰
《51 测试天地》四十四(上)
www.51testing.com
3) 描述结果
4) 设定开始时间、周期、最后期限
用 5W 正确描述“下一步行动”
为什么? 谁? 什么时候? 在哪里? 做什么?
项目举例:制作产品销售策略、计划周末旅行、建立 XX 制度、准备考研究生、学
任务举例:挑选一只鱼竿、跟进老大反馈的 bug
5、番茄工作法
使用番茄工作法,选择一个待完成的任务,将番茄时间设为 25 分钟,专注工作,中
途不允许做任何与该任务无关的事,直到番茄时钟响起,然后在纸上画一个 X 短暂休息
一下(5 分钟就行),每 4 个番茄时段多休息一会儿。
亲身体验:执行用例时使用番茄工作法,效率很高
6、时间管理的三大杀手
2) 犹豫不决
3) 目标不明确
解决方案:
? 细化目标,对每个任务进行分解,明确下一步动作
? 设定期限,并给自己设立一些奖惩措施
? 优先解决难啃的任务,举例:一半沙子和一般石头,如何装进一个瓶子里,装满。
两种方式,先沙子,后石头;先石头,后沙子,第二种会装满。沙子是琐事、小
事;石头是重要的事。
三、时间管理工具推荐
? 奇妙清单 app
? iphone 的提醒事项、日历
? outlook 约会
《51 测试天地》四十四(上)
www.51testing.com
目的:对于测试人员来说,要做好测试工作、让产品质量更高,用户体验更好,那
就需要尽早介入,通常在需求文档形成后需求评审前,分析需求文档,做好讲解前的测
试准备工作,这样就可以帮助完善需求文档,并为后续的测试工作铺平道路,节省沟通
成本、避免后续过多的需求变更和实现变更带来的各种麻烦。
一、分析需求目的合理性
分析为什么会提出这个需求,该需求的目的对用户来说是否可接受。即这个需求能
给用户带来什么,用户需要通过什么路径来得到需求带来的结果。
浏览器四周年时的刮刮乐扩展,此需求提出是为了借助四周年的契机,向沉默用户
推送安装刮刮乐扩展,以此唤起沉默用户。扩展的功能是登录通行证后可以参与刮刮乐
活动,此活动的奖品是几个苹果产品,中奖率很低。看到这里,你是否开始否定这个需
求了呢?我们可以分析一下,首先要明确一点,沉默用户是很久没有使用搜狗浏览器的
了,对于这些人,面对参与刮奖还需要登录通行证的繁琐操作和中奖率极低的奖品诱惑
时,是否会去参与活动呢?上线后该活动的参与用户为几百人。
二、细看需求描述,画出流程图
这里的流程图是需求流程图,也就是完全基于需求文档的流程图,不涉及到开发实
需求描述:用户可以在选项中打开或者关闭直播录制功能,关闭直播录制功能后直
需求评审前的测试准备流程规范
? 搜狗测试:李
《51 测试天地》四十四(上)
www.51testing.com
播录制按钮不再出现。当检测到用户在浏览器页面中观看直播时,显示直播录制功能按
需求流程:
三、根据流程,提出问题
根据需求流程图,争取在每一环节都提出问题,然后记录下来。
1.开启直播录制
(1)怎样开启直播录制?
(2)都支持哪些直播网站?
2.检测用户行为
《51 测试天地》四十四(上)
www.51testing.com
(3)怎样检测用户行为?
3.观看直播
(4)怎样才算观看直播呢?
4.显示/不显示直播录制按钮
(5)什么时机显示直播录制按钮?
(6)在哪里显示直播录制按钮?
(7)直播录制按钮长什么样子?
(8)滚动页面,直播录制按钮还显示么?
(9)什么时机直播录制按钮会消失呢?
四、根据需求描述,补充问题
上面需求描述是:用户可以在选项中打开或者关闭直播录制功能,关闭直播录制功
能后直播录制按钮不再出现。当检测到用户在浏览器页面中观看直播时,显示直播录制
功能按钮。
补充问题:
在选项中哪里打开直播录制?
既然在选项中有开关,那么该项纪录在 config.xml 还是 commcfg.xml?
这一项的字段是什么?
这一项是否跟随通行证同步?
五、问题回顾,增删问题
将文档全部看完后 ,回顾记录的问题,有的可能已经被解答,有的联系上下文可能
还说不通,产生新的问题,再次记录。
第一个问题问怎样开启直播录制,而在需求描述中已经说了在选项中打开或者关闭
直播录制功能,所以第一个问题已经解答,可以删掉。
《51 测试天地》四十四(上)
www.51testing.com
六、评估已有需求是否符合需求目的
主要是从已有需求是否符合需求目的、本需求是否符合需求目的、是否有更简单便
捷的路径满足需求目的三方面考虑。
追剧需求中的弹泡提醒时间,分为连续观看和固定星期观看。最近三天,每天都有
同一剧集的观影记录,对于观看日期连续的剧集,需要每日提醒。同一剧集,连续两周
的观看星期时间相同,则成为固定星期时间观看,需要在相应的星期时间提醒。
其实对于用户来说,分的这么仔细更容易让用户混淆,还不如直接采用最近一次观
看剧集的时间进行提醒更简单,更容易让用户理解和接受。
七、找寻缺陷,完善需求
找寻缺陷,主要指的是在需求中没有说明的但是又是必不可少的一项。
需求统计 pingback,隐性需求。
八、提出建议,锦上添花
可以从系统规范、产品 UI、需求细节合理性以及产品易用性几个方面入手,站在用
户角度进行思考。
1、符合系统规范
产品风格尽量与系统风格保持一致,这样使得产品更专业,同时增强用户易用性,
更容易让用户理解。
Window + M 是系统快捷键,那么在浏览器的快捷键中,就不要设置它为浏览器快捷
键,以免与系统快捷键冲突。
2、同一产品类似功能要界面风格一致
同一产品的类似功能界面风格保持一致,既规范产品,又减少用户混淆度,提高用
《51 测试天地》四十四(上)
www.51testing.com
直播录制过程中关闭标签页后弹出的提示框,都是在询问用户是否关闭,但是前面
的 icon 一个是叹号,一个是问号。
3、借鉴竞品类似功能逻辑
对于类似功能,可以对比竞品,如果竞品优于我们,我们可以借鉴或与其保持一致。
之前我的最爱搜索框中没有热词显示,对比竞品发现,他们类似的搜索框中有显示
热词,可以增加用户对实事的关注,提高用户体验,所以在我的最爱的搜索框中引入了
4、文案简洁通俗易懂
在产品的需求文档中,可能某些文案太长或者难于理解,都可以向产品提出建议。
直播录制过程中关闭标签页后弹出的提示框,文案就很长,可以向产品提出建议。
《51 测试天地》四十四(上)
www.51testing.com
隐性需求:没有被明确规定,但是有可能或不应该拥有的功能或特性。
《51 测试天地》四十四(上)
www.51testing.com
测试人生之谁的青春不迷茫
◆作者:谢
匆匆一年又将过去,除了年龄上增长了一岁;我还在想在一年里我成长了多少。
不变的其实是我们一直在变化。在测试的职场中,我已经忘了有多少成功和失败,
或许这些都不重要。重要的是我现在的心态,总结起来也就两个字:坚持。
我不曾一次想放弃测试这条路;在公司里的整个技术团队中,测试的团队是永远不
可能和开发成比例的,有的还是一个测试负责整个公司的项目,其实我就是这样。在每
次需求提出到产品原型再到开发,测试几乎没有能够完整的了解需求的走向和变更,到
最后开发完成,拿给了你与产品效果图完全不同的产品给你测时,你发现之前的测试用
例完全白写了,接下来的测试就根据自己的经验来吧;再或者你搭建起一个缺陷平台起
来后,发现一个月之后再也没人用了,领导不重视,流程不完整,缺陷交流繁杂。但是
说到底,一个公司还是不能缺少测试,就算它的流程在烂,没有测试的产品终究没有好
的用户体验,没有好的用户体验终究会导致公司倒闭。
自从来到新的公司,我就一直在做 APP 的测试。这是我之前没接触的模块,之前做
的都偏向 pc 端测试、web 测试。我自以为做 APP 测试能学到更多,我渐渐的发现一个小
的创业公司根本没有所谓的软件开发流程。我尝试改变,我搭建缺陷管理平台,用了两
个星期就没人用了,领导不重视,没有流程监督,就此作罢。但我没放弃,我在想做 APP
如何能做好,如何实现自动化测试,如何对 APP 进行性能测试。通过查看论坛、网页;
安装各种工具,不断去发现新的测试途径,慢慢的发现这些自动化工具需要编程语言的
支持,需要编写脚本代码和对工具的灵活使用;我作为测试,编程能力是薄弱的;我想
尽力去弥补自己的短板,在网上找公开课看,边看边学,想通过编写很小的程序来发现
乐趣;我发现我不能坚持下来,我想放弃,我想每天打打酱油多爽,何必搞得自己那么
累。是呀,我到现在都在不停的心里斗争中,但是我只要有那么点想学习的热情,我还
是会去看看,还是想提升自己,还是不能安心的打酱油,还是想做出点有用的东西。我
《51 测试天地》四十四(上)
www.51testing.com
有去书店买过《谁的青春不迷茫》这本书,说到底这本书其实就是作者成长的自述。看
完我就觉得书名是最有力的,我无力反驳,甚至可以说迷茫伴随了一生,但在迷茫中,
必须有自己的坚持;虽不见远方,亦路在脚下。
当然一个人的测试,负责整个公司的项目也有很多。网站测试,app 测试,微信测试...
等等。没有那么多人测试,我却可以借助工具。就比如手机的兼容性测试,一款 app 需
要兼容上千款手机,我如何去实现;这可以用到云端测试工具,国内有很多这种平台,
通过上传 APK,检测漏洞和机型兼容性,能即时给出测试结果,一目了然。再说到网页
测试,可以通过 webpage 测试平台,通过输入 url,图形化展示测试结果,方便迅速的看
到网页错误。当然还有很多工具,不胜枚举。
说到底,坚持还是会带来收获的,只是有的时候表现的不是那么明显。当我在一条
路上坚持不断的探索时,你会发现其实你的努力没有白费,即使你没看到任何结果,但
你却拥有了一颗坚定的心。
《51 测试天地》四十四(上)
www.51testing.com
下一代开源大数据框架如 spark 和 Flink 的目标是达到大规模并行处理数据库如
Netezza 那样的性能和良好的用户体验
由于所有主流的大数据框架(Hadoop,spark,Flink)使用 JVM,所有他们都有着两
个 JVM 限制:
1、Java 对象消耗的内存远大于对象中所有属性的大小
2、Major GC 的停顿会使得性能下降,尤其是当你尝试缓存更多的数据(Java 对象)
以便后期对数据进行纯内存处理
所有 Flink,Spark,Hadoop 为高性能引入的工程技术主要目的就是为了尽可能的减
少这两方面的影响.本文将为你展示这些技术。
在所有性能改进的之外,Alexey Grishchenko 所写的如下 blog 给了我们一个清晰的提
醒,虽然基于 Java 的大数据框架在性能方面已经有很大提升,但是要追上大规模并行处
理系统的性能还有很长一段路要走
性能的 80/20 原则
不是所有操作所需要的开销都是一样的,极少数的操作产生了很高的性能开销,许
多大数据框架常用操作组合是:
1、压缩 vs 不压缩–这直接影响到数据被读出和写入的速率,不同的压缩方式/算法消
耗的 cpu 资源差异很大
2、排序-大数据处理基本都会有“reduce”操作,而排序在 map-reduce 处理方式中则是
如何处理大数据性能问题?
者:yonger
《51 测试天地》四十四(上)
www.51testing.com
“reduce”阶段的关键。由于“join”操作会依赖于“reduce”,所以对 key 的排序也会关系到“join”
3、清洗-“reduce”阶段第二个最重要的操作就是清洗了,清洗操作也是关联操作的关
4、关联-只有 map 阶段的 job 通常有很好的性能.但当有 reduce 阶段的时候性能会变
成一个需要考虑的重要因素。一个 reduce 操作包含了关联,在只有 map 阶段的任务中可
以使用广播关联,但广播关联通常在关联的一端数据量足够小的时候才用,这个很小的
数据集被广播到所有节点,由一个 hashmap 的数据结构来维护同时由关联键来索引。另
外一端大一点的数据集通过使用关联键在这个内存中的 hashmap 中查找相应的记录。当
只有 map 阶段时,即使两端数据集都比较大也可以按照关联键来排序,Pig 框架就是充分
利用了这一点,被称为“merge-joins”技术,它会把两边的数据集都在 lock-step 中遍历,然
后在 map 阶段中关联起来(这里实际上有一个预先索引的过程)。当然有关联键进行自然排
序对数据集是很少见的,在关联大数据集的时候 reduce 操作还是必不可少的。
搞定上面的这些问题是使得大数据处理效率变得更快的关键。
性能约束和 JVM 特征
就像前面提到的,Java 在性能方面引入的两个约束因素:
1、Java 对象的存储开销不容小觑
2、使用大量生存周期很短的对象会使得吞吐量性能下降,因为大量的时间会花在
Major GC 上
只在 JVM 堆栈上操作处理大数据很容易导致内存溢出错误,这会使得 JVM 进程被
杀死退出(不像其他错误可以被处理).这是大数据应用中最常见的一个性能问题.
比如,在一个有许多记录但是只有少数键值对能够发生关联的不均衡数据集中,当
所有的键值都保存在内存中时 reduce 操作会失败
从索引技术可以避免在 reduce 阶段时把所有的键值放到内存中,图像应用就是属于
这类应用中的一种.
这就是大数据框架在使用内存时小心谨慎的重要原因了,比如磁盘溢出技术.这虽然
会影响性能,但是会使得框架足够健壮来处理不同的负载.
《51 测试天地》四十四(上)
www.51testing.com
比如,Pig 框架会把数据保存在磁盘上,DataBag 接口的实现及其广泛的应用在 Pig
中,当 tuples 的数量达到一个预先定义的值时会把数据刷到磁盘上(默认是 20000)
JVM 存储开销
在 Java 堆栈中一个典型的对象存储由如下组成-
1.对象头-只有几个字节用作维护信息.Hotspot 版本的 VM 使用 8 个字节来表示一个
普通对象的头,另外再使用 4 个字节来表示数组对象的长度
2.原始类型-原始类型也需要字节来存储.比如 boolean 类型需要 1 个字节,char 需要
两个字节,int 需要 4 个。
3.引用类型存储-引用类型占用 4 个字节
4.空占位符-每个对象存放时总字节数是 8 的倍数,所有这中间总是有空的占位符
如图 1 所示,一个 Java 类对象的实例包含了一个原始类型 boolean 实例所占用的 8
个字节用作头,另外一个字节表示 boolean实例本身,剩余 7个字节就会被空占位符填满。
图 1:一个只有一个 boolean 实例变量的 java 类在内存中的占用情况
这个例子证实了一个普通 java 对象很大的存储开销,并且随着如 hashmap 和 list 这
样复杂对象变得非常大
JVM 存储开销影响序列化和反序列化
在大数据范围内发生如下情形时你肯定需要序列化和反序列化:
1、Mapper 输出结果到本地磁盘
2、Mappers 从本地磁盘读出数据来做 map 端的排序
3、Reducers 从 mapper 节点上获取排序和清洗好的结果
在上面的每种情形中,实际的数据量都比原始字节表示的要多很多
《51 测试天地》四十四(上)
www.51testing.com
Java 对象的存储开销影响到内存如何有效的使用分级缓存。即使所有你想要的数据
在内存中,L1/L2/L3 级别的缓存也不可能大到能装下这些所有的数据,这也会使得缓存
在过渡的交换之中从而降低性能。
JVM 存储开销影响 GC
JavaGC 最关键的是要更多的对象在年轻代时就被收集. Java 堆栈被划分为两个区域,
年轻代和年老代。一般来说年轻代占用整个堆栈空间的 20%,而年老代占用了剩余的 80%。
当一个对象第一次被创建时,他们被分配在年轻代,当年轻代满了的时候,minorGC 就
会执行。在这个过程中不再被引用的对象就被清除掉,剩余的还在被引用的就移到年老
代。当年老代被填满时,major GC 最终就会发生。Major 收集算法会遍历在图中的每个
对象,从老年代中回收内存。注意这只是非常简单的描述了 GC 的过程,更加详细的了解
可以上官方网站查找。
JVM 的这些额外开销降低了 OOM 的可能性,但使得你真正可用的内存空间减少。
大数据框架一直朝着全内存存储和计算的方向进行。 Map-Reduce 过去一直主要是
I/O 资源受限型的做法。其早期实现的迭代算法使得在每一次迭代都需要从磁盘文件系统
中读取结果进行下次迭代,并且还要把结果写回磁盘上。这种做法使得整个 MR 的任务
运行非常慢。
Spark 提出以数据能被以分布式方式缓存在内存中的 RDD 概念,这种方式没有了过
渡的 I/O 开销,在启动和停止任务的开销方面也更小。然而,这种折中把风险转移到了
GC 上,原因是,当 Spark 使用磁盘溢出技术来控制对内存的过渡使用时,用户应用程序
能利用的内存也越来越少了
在 Java 中序列化方案的演变
Java 的序列化方案一直在进化,默认的 java.io.Serializable 性能消耗非常高,因为每
个实例都存储了类的 metadata 以及引用到的类型的 meta-data 信息。这种方案只适合当你
想要序列化字节里面包含所有信息且这些都会反序列化为一个 Java 实例的情况。
Java.io.Externalizable 接口已经能够处理解决部分问题了,当使用这个接口时,程序
员可以控制类中的属性如何序列化和反序列化,因此类属性的元信息不再需要存放到序
列化字节流中。但是当 java.io.Externaizable 接口需要调用包含没有参数的构造函数类反
序列化时,类的这些元信息还是需要存放到序列化字节流中的。
《51 测试天地》四十四(上)
www.51testing.com
Java.io.Serializable 和 java.io.Externaizable 都有同样的限制,对每一个反序列化的实
例都会创建一个单独的 java 对象,这就意味着当有非常多的实例反序列化时就会生成大
量的对象,这增加了 GC 的压力。
Kryo 类库改进了这些问题。Spark 支持默认的 Java 序列化方式,但它推荐你使用 Kryo
方案以提升性能。Kryo 通过如下的方式改建了以上的两个问题:
首先,Kryo 提供了一种选择来存储整型索引以代表类被序列化,因为一个完整的类
名称包含了包名称,这在序列化一个类的时候严重的降低了性能。当然缺点是,你必须
舍弃可移植性,因为当你反序列化一个实例时,你必须使用同一个整型索引来指向这个
类。在实际应用中,这确实是个问题。
第二,Kryo 支持在反序列化过程中池化实例,意思就是,即使你有数以万计的实例
在某个时刻被反序列化也只有非常少的实例占用内存
然而,这个方案仍然会存储每一个实例,如果一个流中只包含具体类的实例,这就
可以被进一步改进, 这个类的元数据需要在流的开始被存放一次,后面跟着这个流中所
有实例的序列化过的属性字节流。在反序列化的过程中,只有一个实例需要被创建,字
节流需要被一次读入到一个实例。在处理完当前反序列化实例后,下一个实例字节流就
会被读入在反序列化一开始就创建的那个相同实例中。 Hadoop
org.apache.hadoop.io.Writable就是使用这个方法,因为这是大数据处理模式中的常规方法,
同样也被 Spark 和 Flink 引入。
当你使用最后这种方案时,需要强调的是,你必须使用具体的类. 多态在大数据不能
很好的被支持。如果一个实例中的类只有在运行时才能确定,这个类的元数据需要被包
含在序列化字节流中。 这个解释应该很清晰的指出了为什么 java.io.Serializable 和
java.io.Externalizable 如此臃肿了,因为他们都支持多态,这也是为什么
setMapperOutputKeyClass,setMapperOutputValueClass,setOutputKeyClass 和
setOutputValueClass 方法在使用 Hadoop MapReduce 的任务实例时需要被精确调用的主要
原因。这些调用在程序员看来非常烦人,但是这是实现更高的性能的必要手段,这些调
用允许实例在没有概要定义时被序列化,图 2 展示了不同方案在存储开销和 GC 性能方面
《51 测试天地》四十四(上)
www.51testing.com
图 2:Java 序列化方案的进化
高性能工程-框架如何实现
一个高性能的分布式平台包含如下的技术:
1、特殊的序列化方案以减少序列化对象占用的内存空间,同样使得内存的分级缓存
利用更高效。新框架(Spark,Flink)由于这个目的积极使用 sun.misc.Unsafe 程序包
2、接管内存-最通用的技术是分配和释放大的内存块。首先,这避免了堆栈碎片化,
从而更高效的使用内存。第二,它能减少对象进入老年代使得 Major GC 能更快的完成。
Hbase 就是利用这种技术,Flink 甚至通过尽量避免 major GC 来把这项技术带入一个更高
3、通过最大化使用多级缓存更高效的利用内存-举个例子,排序操作只需要排序的属
性,如果整个对象都加载到内存会很有可能导致缓存被频繁的清除,这使得 CPU 变为瓶
《51 测试天地》四十四(上)
www.51testing.com
颈,因为 CPU 会需要更多的时间片来等待数据从主内存中读出而不是高速缓存。如果我
们只加载需要的后面操作中使用到的必要的属性,这就会提高 CPU 的利用率。大数据里
面的一个常规操作是“比较两个实例”(在排序阶段中需要的,也是关联 Reduce 中最关键的
操作),如果这种比较能通过二进制数据来实现的话,就不需要把字节流序列化成一个单
独的实例。所有的大数据框架基本都是这样做的,最常用的 Hadoop 数据类型
org.apache.hadoop.io.Text就是通过其父类org.apache.hadoop.io.BinaryComparable来利用这
个技术的。
4、利用堆外内存- 通过 Java NIO 或者 基于 sun.misc.Unsafe 包自定义实现来利用
Java 堆栈之外的内存。目的是提供一个接口出来用以访问不被 Java 堆栈所有管理的内存,
这种内存是不需要 GC 的,因此会是的 Java 堆内的 GC 运行的非常快。缺点是,编程者
必须自己来管理这些内存,HBase 为块缓存提供了堆外内存的选项,Spark 在清洗和块缓
存过程中也利用了堆外内存。Flink 也正在实现堆外内存的选项来管理内存子系统。
框架本身特定的序列化方案
前面我们已经简单的讨论过这个问题,现在让我们讨论下更细节地方。
在大数据范畴中需要专门的序列化技术是因为流式处理的数据通常都有同样的数据
类型,我们可以使用一个自己实现的序列化方案来达成下面的优化-
1、每个数据集只需要保存一个次额外的 schema(不是多态)
2、为每个元组类型保存字节流,利用偏移量来指向实例属性(看如下 Spark 的例子)
通常当你需要读取一个实例的属性时,我们需要先反序列化整个实例然后写一个
getXXX 的调用来获取实例的属性. 自定义的序列化方案允许我们仅抽取出需要的属性的
字节,然后反序列化. 当一个实例拥有许多属性时,这种方法允许我们抽取只想要的那个,
它通过重要性排序减少很多额外实例对象的生成,从而更高效的利用高速多级缓存。因
为排序,清洗,关联操作就是这种只需要少量属性的操作过程,这使得内存和 CPU 的利
用率非常高。
Hadoop 方案-org.apache.hadoop.io.Writable
这个话题在前面已经讲过,可以参考图 2
Spark 方案-Project Tungsten
《51 测试天地》四十四(上)
www.51testing.com
Spark 鼓励你在 Java 序列化的时候使用 Kryo,它对 Spark 的数据类型有着非常成熟
的面向对象模型支持,当然序列化后也会占用更多的内存(Kryo 能够使得数据类型转化为
一个整型,但是每个实例需要额外的 4 个字节的开销来关联这个整型)
Project Tungsten 最终认为上面这个方法做的太纯粹了,为了性能必须牺牲一定的这
种纯粹性。
如下的展示提供了一个例子来了解 Project Tungsten 的全貌:
最关键的主意是利用了在 Spark 中一个具有如下特征的典型数据集-
1、数据集通常使用唯一的 schema 来重组(如果你想象这是一个基于关系型数据库的
结果集,这就更加明显了)
2、为每个元组存储类型信息非常浪费,为元组的每个部分存储数据类型信息当然更
加浪费,最有效的方式是只存储 schema 一次,使用多次
在这个 slide 中最关键的点是:
通用化是有成本的,所以我们应该使用语义和概要来利用特性代替
Tungsten 也通过自定义的序列化方案来提高清洗阶段的性能.序列化方案的效率比起
通过网络传送对清洗阶段影响更大。
压缩自定义的序列化概要会通过减少字节在网络上传输的数量从而使得序列化过程
更快来节省时间。可以通过如下 Blog 的代码生成片段获取更加详细的信息,那段代码展
示了基于清洗自定义序列化实现比 Kryo 快两倍
如果你想要进一步提升你大数据应用的性能,你就需要充分了解利用你应用的特征
(数据如何到达以及数据结构如何)
Flink 方案
Flink 设计了一套从更本上更高效的序列化方案.首先,跟 Spark 一样,Flink 也支持
任意的 Java 和 Scala 类型,随着数据类型必须像 hadoop 一样实现特定接口,这是一个很
大的进步,Flink 利用反射来确定用户自定义函数的返回类型,Scala 的程序是使用 Scala
编译器来分析的,Flink利用了一个叫TypeInformation的自定义类来表示任意的数据类型,
这个类支持如下的类型:
? 任何 Java 原生类型或者 java.lang.string
《51 测试天地》四十四(上)
www.51testing.com
? 任何 Java 原生数组类型和 java.lang.String
? Hadoop Writable 接口的任何实现类
? 任意的 Flink 元组类型,Flink 元组是有着类型域的固定长度元组的 Java 表示
? 任意的 Scala CaseClass 类型(包含 Scala 元组类型)
? 任意的 POJO(Java or Scala),比如,所有域都是 public 的对象,或者遵循通用命
名习惯的可以通过 getter 和 setter 方法访问的
? 任何不能被另外一种类型确定的数据类型
上面的每种TypeInformation类型实现提供了一个自定义的序列化器,GenericTypeInfo
是 TypeInformation 后面的重排序和对 Kryo 的委托,更多的细节请阅读这段-Flink 是如何
序列化对象的?
TypeInformation 也提供了一个在二进制格式数据类型比较方面更高效的自定义类型
TypeComparators,它通过把数据类型用作 key 以便快速比较和排序. TypeInformation 在
Flink 中是一个公共的 API,能够被用来扩展支持自定义的 TypeInformation,序列化器和
比较器则在处理自定义类型上更高效.
TypeInformation 也集成 Flink 的自定义内存管理(这就是我们会在稍后说的
MemorySegment),这利用了 JavaUnsafe 操作的高性能.
Flink 完美的结合一个高效可扩展的序列化机制,对自定义数据类型可扩展,并且集
成了为支持尽量避免 majorGC,提高吞吐量而设计的更高效的内存管理模块.
接管内存管理
Major GC 是达到高性能最大的一个障碍,它跟一个通用技术-缓存,在实现高性能之
路上是冲突的,缓存太多会导致更频繁的 major GC,从而影响吞吐量. 在最差的情况下
它也会造成内存溢出. 过渡使用内存也会导致更多的内存碎片,从而导致出现总的可用内
存超过程序请求的内存时发生的可拍的内存溢出现象
HBase 中的内存管理
接管内存管理对于 Spark 或者 Flink 来说不是个新鲜的事情,HBase 同样也已经做的
很好,这段将说说在大数据应用中早期的内存管理系统是怎么样的,同时也会讲述 Spark
和 Flink 他们是如何为了达到更高的性能对内存管理技术进行改进的.
《51 测试天地》四十四(上)
www.51testing.com
HBase 使用 Memstore 作为它的内存数据存放,然后定期把这些数据刷到磁盘,在
HBase MemStore 中是以 2MB 的内存块作为分配单元,这项技术在由 Cloudera 发布的系
列文章- 在 Apache HBase MemStore 中如何避免 Full GCs-本地缓存 中详细的讲解了,这
些文章对 Java 垃圾回收方面讲述的相当详细,以及 HBase 是如何在处理由 Java 垃圾回收
所产生的这些限制的。
HBase 所使用的方法可以总结如下:
1) HBase 是一个 key-value 的存储方式,它把 key-value 对作为字节数组方式存储
2) 很多的 key-value 对都是很小的,这主要是为了避免每个 key-value 对都会创建单
独的字节数组.
3) 当一个 key-value 对第一次存储到 HBase 中,它就是存放在一个叫 MemStore 中
的,这个 MemStore 对它所使用的内存有一个预算阀值,当这个阀值超过了的时
候,数据会从 Memstore 刷到磁盘中,更多细节请阅读这个 blog
4) 在这个阀值之内,Memstore 会以 2MB 的块分配内存以存储内存中的 key-value
对,当一个 2MB 的块存满时就会分配一个新的块以继续存储新的 key-value 对这
项技术对内存的使用很高效,由于以 2MB 分配为单元,所产生的空内存碎片也
会少很多。对于 GC 来说,比起更小的内存块,2MB 的内存块在垃圾回收的时
候也会更快,另外 2MB 的大内存块在回收后也更容易被重新分配,一个 2000
个单独的 1KB 的片段在内存中比分配一个 2MB 的片段要困难很多.
Flink 中的内存管理
Flink 做得跟 HBase 差不多,只不过范围更大而已,Flink 把 Java 堆栈内存划分为 3
? 网络缓存-默认只有 2048 个字节,Flink 在启动阶段分配了 32KB 缓存作为启动缓
存,而且这个缓存还可以通过参数 taskmanager.network.numberOfBuffers 来调整
? 内存管理池-这是一个由 MemoryManager 实例管理的 32KB 缓存大集合. 每个缓
存都是 MemorySegment 的一个实例,MemoryManager 面向很多算法池化
MemorySegments,使用单实例 MemoryManager 来分配和释放 MemorySegment,
在内存管理池和网络缓存中将近 70%的堆栈内存空间是共享的
《51 测试天地》四十四(上)
www.51testing.com
? 用户代码的内存-剩余的内存主要是留给用户代码的,从 GC 的角度看这一部分
主要是年轻代区域,意味着主要用来存放用户代码所产生的短生命周期的实例.
上面这些方法的好处是-
1) 短生命周期实例放在最后的片段,这样收集会非常快
2) 算法申请的内存是以 32KB 为单位的片段,释放的时候也是 32KB,但是从 GC
的角度看,内存从来不会释放,MemoryManager 实例仍然会持有应用分配和释
放的 MemorySegment 实例的引用
3) 算法对他们使用的内存片段个数有严格的预算阀值,如果一个算法超过它的这个
预算阀值,它需要把未使用到的片段存放到磁盘,并且在需要的时候再把这些数
据片段从磁盘读出来. 如果这个算法需要比它允许的预算更多的内存,它就需要
把一些片段放到磁盘上并且重用 MemorySegment
我们再一次看到“为了高性能需要特征性而牺牲通用性”,为了达到更好的吞吐量和性
能我们必须使得我们的代码更复杂。图 3 表明了 Flink 方式的内存管理
图 3:Flink 内存管理
《51 测试天地》四十四(上)
www.51testing.com
算法都是以 32KB 的片段申请和释放内存,但是从 GC 的角度看,内存从来不会被真
正释放,很多用户自定义的短生命周期对象在 major GC 的时候就被回收,只要应用程序
不尝试为他们自己创建缓存,在老年代中的内存就不会变,major GC 也不会被触发.这极
大的提升了 Flink 系统的整体吞吐量. 关键的地方在于-一个编程者不应该尝试为长生命
周期的实例自己创建缓存,这会使得年老代会被填满,从而触发 majorGC,甚至内存溢
出,如果编程者必须要这么做的话,它需要使用 MemoryMnager 来自行管理内存。
使用分级缓存实现更高性能
随着网络速度越来越快,CPU 开始在大数据范畴内慢慢成为瓶颈,从 L1/L2/L3 高速
缓存中读取数比起直接从内存中要快,已经分析深入分析程序执行,我们发现在从主内
存中读取数据时 CPU 等了相当长的一段时间比起整个时间来说,如果这些数据从分级高
速缓存中读取的话,这个等待时间要大大缩短,整个算法的性能也会有很大的提升
上面,我们讨论过直接使用二进制数据的自定义序列化方案来尽量避免对整个实例
反序列化,这种自定义的序列化方案提供了一个实例的字节是如何存放在内存中的细颗
粒度控制,这就允许直接指向一个实例的特性属性而不需要在内存中反序列化整个实例,
比如排序操作,它就让算法仅以 sort-key+pointer 的方式来指向实例,从根本上提升了 CPU
Flink 方案
考虑 Flink 是如何执行实例的排序,这是一个非常常见的操作,假设 Flink 需要一个
只有由单个整型属性组成的数据集进行排序,Flink 在为了实现更高性能方面做了这样一
1、数据集被分成两个内存片段存放
代表所有数据的字节存放在其中一个内存段中,许多的数据集有相同的概要,因此
Flink 像”框架特有的序列化方案”那段那样对存储专门进行了优化.
另外一个内存段用来存放数据集中每个元素的两个属性-指向数据集元素的指针按照
排序关键字来排序
2、排序现在可以按照指针和排序属性和组合来执行了,这样由于不是所有的数据都
需要完全排序,充分利用了内存中的高速缓存,效率相当快。
《51 测试天地》四十四(上)
www.51testing.com
上面这些方法的其他优点-
Flink 可以直接在二进制数据上进行操作,如果实在一个字节数组上操作就完全不需
要反序列化排序的属性,记得 org.apache.hadoop.ioText 两个实例使用仅使用一个字节数组
对于由内存片段维护的数据集元素也不需要反序列化,这个数据集可以安全的被存
放在磁盘上.
Spark 方案-Project Tungsten
Spark 在排序算法方面跟 Flink 基本是一样的,更多细节可以看这个 blog
利用堆外内存
利用堆外内存是让 Java 性能最大化的最后一种方法。Java 提供了这样的库,可以让
程序非常明了的管理内存。托管堆是 JAVA 编程语言的特征,它让程序员在执行内存管理
任务的时候可以减少复杂度及避免容易犯错的地方。然而,它也有缺点。首先,作为一
个程序员,你无法控制垃圾回收的运行频率以及运行多久。其次,如果你不加鉴别地缓
存,你就会碰到“OutOfMemoryError”。就跟之前谈到的,尽管机器上由于内存碎片还有
一些可用的内存空间,但托管堆也会占尽空间。
没人逼迫你只能使用 Java 的内存管理。通过利用 java.nio 或者 sun.misc.misc.Unsafe
程序包,程序员可以进入到非托管内存。缺点是:程序员需要负责分配和释放内存。优
点是:内存管理不会收到垃圾回收进程的限制,大大减少了迅速返回的垃圾回收上的负
载。平衡点就是:你需要采用更高的更复杂开发程序达到预期或者更高的吞吐量。
虽然在构建自定义应用时不常使用,但高性能计算框架一直并会长久使用堆外内存。
Terracotta 在 BigMemory 产品上利用非托管内存。BigMemory 可以使用缓存达到 1 个 G
OpenHFT 提供了 Chronicle Library,它可以支持高性能,低延迟及被动的处理框架。
这个框架大量使用堆外内存。
HBase 对于 Block Cache 支持堆外内存选项.
Flink 正在开发 MemoryManager,它将利用堆外内存。更多细节详见这里:
Spark 通过 Tachyon 抽样缓存支持堆外存储(实验性)。
我开发一个叫 LargeCollections 的库,它采用 LevelDB 去支持大量的堆外 Hashmap。
https://github.com/sameeraxiomine/LargeCollections
《51 测试天地》四十四(上)
www.51testing.com
这个项目在 LevelDB C++实现上也使用了 JNI 包装。
最终所有框架的目标是实现 MPP 的性能水平。堆的使用让 JAVA 程序员更进一步的
使用 JAVA 像 C 编程语言。
将这些经验应用到你自己的大数据应用中
尽管以上谈到的工程方案可能看上去很独特,但这些经验可以运用到你自己的大数
据应用中。我所应用的技术如下:
1、开发你自己的简洁的序列化方案。这个减少了任务之间的输入/输出。
2、尽可能使用二进制数据。尽可能避免从二进制到对象,然后又返回到二进制。CPU
确实是大数据的瓶颈。每次你开始 org.apache.hadoop.io.Text 的时候,你已经在做了。找
到机会采用 org.apache.hadoop.io.Text 用到的技术来比较你自己的键值类。
3、总是处理最少的数据。假如只有一小部分数据是在你处理的那部分中,而大部分
数据不是,你需要在最后执行一个开销很大的关联,但这样你不用通过网络或者反序列
大的对象发送太多不必要的数据到内存。
4、不要回避使用堆外内存。有时候使用它可以帮助高性能技术如 Map-Side 的加入。
如果你要关联的数据集一端数据量不是很大,就可以把这部分数据存放在堆外内存中,
这样就可以通过关联键来进行查找,而且在 Mapper 阶节点上没有很大的 Reduce 操作的
开销(需要清洗和排序),这是在本文谈到的广播关联的变化。我已经开发了
LargeCollections 提供简单的界面去使用堆外内存。它剔除了在使用 Usafe 或者 NIO 库时
的复杂性,给程序员提供了他们熟悉的简单的 Hashmap 的抽象概念。它支持像
org.apache.hadoop.io.Writable types 高效的数据类型。它也支持开发定制的
Serializer/De-Serializer (SerDe)去支持自定义序列化方案。因为它使用的是 Java 的堆外内
存,所以大大的减少了对 Java 内存管理过程的压力。
写此文的目的是能够收集在大数据框架下使用的性能工程技术的演变从而实现 C 级
水平的性能。
https://github.com/sameeraxiomine/LargeCollections
《51 测试天地》四十四(上)
www.51testing.com
测试公主之为人鱼公主找到真爱
◆作者:测试小公主
当 APP 开发出来后,Lisiya 就和天蝎星的居民们一起愉快地连接 wifi,并使用 wifi
愉快地上网和发送信息。
Lisiya 在天蝎星上使用 APP 已经很熟练了,同时 APP 的联网功能也已经日趋稳定。
在和天蝎星上的国民一起交流的时候,Lisiya 也为 APP 研制了各种新的需求,使得 APP
更加易于使用,功能多样。
由于水星宝宝们给天平星带来了和平和欢乐,天平星的所有国民都非常感激。
不久,他们便收到了来自天平星和天蝎星的来信,信中附了一份绝密的,宇宙飞船
操作手册!
并说让他们在一个月内将这个操作手册背熟,然后就能驾驶宇宙飞船了!而当他们
学会了驾驶宇宙飞船之后,天平星的国王和王后邀请 Lisiya 参观天平星,作为奖赏。
这时候,Lucherian 来了,他说,晚上带她们去看看宇宙飞船!
然后 Lucherian 将宇宙飞船的操作要领都全部教了一遍给 Lisiya,她马上都能倒背如
操作手册的主要内容有:
Test case:
1:分别使用宇宙飞船的计算机和手机,连接宇宙星际 wifi
2:确保宇宙飞船和手机都是有电的
3:拥有足够的上网时长
4:在宇宙飞船的计算机中认证上网,在手机中认证上网
5:在宇宙飞船的计算机中的上网页面点击- “去往天平星”-”视频“
《51 测试天地》四十四(上)
www.51testing.com
6:在手机的上网页面点击- “去往天平星”-”视频“
7:在宇宙飞船上点击“去往天平星”按钮,宇宙飞船就可以自动往天平星的方向前
(Lisiya 写着宇宙飞船的测试用例,运用等价类,边界值,流程图的方法,进行分析和写作,并在
一边研究,一边还和 Christina 进行交流,确保在遇到各种问题的时候,都有具体的应对方案)
同理,点击“去往天蝎星”按钮,宇宙飞船就可以自动往天蝎星的方向前进
手机不仅拥有和宇宙飞船的计算机一样的功能,更能方便携带。
Lisiya 按照测试用例所写的,在宇宙飞船中,发现显示屏上面的人竟然是外婆
Christina,外婆会一路陪伴和保护 Lisiya 的,这是个秘密,连 Victoria 女王都不知道! 因
为 Victoria 并不欢迎 Lisiya,她如果知道 Lisiya 旅行的途中,一直都由 Christina 保护着,
她会生气的。
Christina:亲爱的孩子,你好吗?
Lisiya:我非常好,外婆!
Lisiya:外婆,您在显示屏中看起来好年轻,和我妈妈长得非常的像!
Lisiya:真希望,外公能进来看到你的样子啊!
Christina:我还没做好心理准备让他看呢!我们分别太久了。
Christina:但是我们一直通信。这就够了。
Christina:这次旅行是特别为你设计安排的,你要感谢天平星,当然天平星更要感谢
一路上他们就这么聊着聊着,都忘了跟 liyiya 和 Lucherian 说道别了,
一路上非常的平稳,安全。
如果遇到任何情况,外婆都及时指点,很快就离开了大气层,到达了宇宙中!
浩瀚的宇宙!美丽的宇宙!让人流连忘返,沉醉其中,一路上他们遇到好多颗美丽
的行星,好像上面都是有生命的,多么让人遐想连篇……
虽然去的路上他们都很安全,但是回来的时候, 飞船经历了强烈的震荡和牵引,这
出自于一颗路过的具有强烈引力的星球,仿佛在这颗星球上面有着某种异于和谐的磁场,
《51 测试天地》四十四(上)
www.51testing.com
那是混乱无章的磁场,是一种令人不安的磁场。
当 Lisiya 醒来的时候,她躺在了在百花丛中,阳光明媚,这花非常的大,因为花非
常的大,她才能非常安全的着陆,就像是落在了弹簧垫子上一般。
虽然宇宙飞船不知了踪影,但是幸好她的手机还在身边。
查看了手机,Lisiya 发现幸好在这颗星球上,是有星际宇宙 wifi 的。
并且手机还有电,依靠连上的星际宇宙 wifi,以及手机中的指引,她不断地走着,
终于,Lisiya 看到前面有一条河,河水非常纯净, 在河边,她发现了破损了的宇宙
Lisiya 利用宇宙飞船的电给手机充满了电。
她记得背过的操作手册中,写到如何联系 Lucherian 的方法,有一个秘密按钮的,她
找到了这个秘密按钮,于是,不一会,Lucherian 的影像就出现在她面前,他们都激动极
Lucherian 说,他们一时不会那么快有宇宙飞船飞过来的,至少要等到 24 小时,才能
有宇宙飞船飞过来救她……
这时候 Lisiya 看到在河中有美人鱼在唱歌。原来这美人鱼是当初海的女儿的投胎的
结果,她现在是她的水中的女王了,掌管着整个海域,她过着她认为开心的生活。他们
生活的星球叫做--转世星。但是她还是想念她前世的那个王子,她是多么的爱他 ,即便
是转世了,还是忘不了他!她知道他是地球人,但是她永远在这遥远的海域的水中,去
不了地球。300 年过去了,他到底去了哪里?
她告诉 Lisiya 到了晚上她必须到海底过夜,因为这个星球的晚上是非常恐怖的。所
以她让 Lisiya 坐到一个潜水艇中,然后下了海,顺便欣赏这美丽的水下世界!
人鱼公主在海底很好地招待了 Lisiya,Lisiya 感到无比的快乐。
人鱼公主告诉 Lisiya,转世星的夜晚之所以非常恐怖,是因为很多的妖魔鬼怪在夜晚
都会出现,当这一刻到来的时候,这些妖魔鬼怪有些会散落到外太空中,在外太空中,
如果他们遇上了一颗有人类的星球,比如地球,那么他们就会附着到地球上,将人类的
邪恶力量增强。
人鱼公主告诉 Lisiya,正是因为这个因素,妖魔鬼怪才会源源不断的去往地球等星球
《51 测试天地》四十四(上)
www.51testing.com
中,形成强大的恶势力,一旦白天到来,这些妖怪就会躲起来,到那些阴暗的地方,完
全没有光照的地方,一旦有人路过那些暗处,他们照样会兴风做悢的。到了夜晚,这些
妖魔鬼怪更是无法无天,残害无辜。
Lisiya 说:那我们该如何改变这种境况呢?难道就任由这些恶魔无法无天,伤天害理
人鱼公主说,按理说,这些妖魔鬼怪是被严格的控制住的,他们会被地狱或者地牢
所收纳,地狱中有着严格的制度,是不会让妖魔鬼怪出来作恶的。本来地狱 wifi 只有地
狱的妖魔鬼怪可以使用,并且认证上网,且使用 Lisiya 他们设计的 app 进行账号管理,
且每一个妖魔鬼怪只有一个账号。
可是 Lisiya 他们的 APP 不能识别这个账号是否就是本人的,以及一个人是否只有一
也就是说,一个恶魔可能拥有多个账号,而一个账号也可能被多个恶魔同时使用,
这时候地狱 wifi 和地牢 wifi 就无法控制和管理这些恶魔了。因为他们成为了游魂。 Wifi
的管理机制彻底崩溃。
而恶魔级别低的应该使用地狱 wifi,级别高的使用地牢 wifi,而现在他们甚至可以使
用宇宙星际 wifi(只有非常正义和善良的人才使用的 wifi),可见他们的破坏程度是如此
此刻 Lisiya 知道了,一旦能确保哪些妖怪是地狱的,哪些是地牢的,并且能让他们
每个妖怪都只有一个账号,每个账号同时只能使用在一个设备上,就可以很好的管束他
们的行为,即使是在晚上,转世星也会很安全,同时,地球,宇宙和其他具有人类的星
球也不会因此而成为妖魔聚集地。
于是 Lisiya 想了方法,每次登陆 wifi 都必须经过审核,每个妖魔登陆时都要有记录,
等一系列的举措,同时还要狠仔细地统计妖魔鬼怪的总数,不能遗漏任何一个妖魔鬼怪,
在 APP 中增加每天妖魔鬼怪需要学习的向善的课程。
24 小时之后新的宇宙飞船来解救 Lisiya 去了天蝎星,来到了测试团队中进行工作。
经过 Lisiya 团队的讨论,设定了新的需求,而需求是:
Lisiya 测试团队将 wifi 的使用者分为三个类型,他们分别是:
《51 测试天地》四十四(上)
www.51testing.com
? 地狱恶魔
? 地牢恶魔
? 正义生命
同时也开发了三种不同类型的 wifi:
? 地狱 wifi
? 地牢 wifi
? 宇宙星际 WIFI
1) 给每一个连接的用户设置一个唯一的用户号码。
2) 用户连接 wifi 后进行面部识别,确保是本人。
3) 用户登陆时确定每个用户只能登陆在一个手机上,用两个手机同时登陆,则之前
一个手机登陆无法上网。
4) 地狱恶魔只能连接地狱 wifi 并上网,地牢恶魔只能连接地牢 wifi 并上网,正义
生命只能连接宇宙星际 WIFI 并上网,否则无法连接上网。
5) 每次登陆 wifi 需要输入密码,且密码有一定的复杂度,比如必须要有数字,英文
和特殊符号。
6) 同一个生物使用宇宙身份证只能注册一个 wifi 账号。
7) 登陆密码输错多次将被锁定,解锁需要回答问题。
8) 登陆错误次数多的用户将进行统计和分析。
相应的测试工作紧张而忙碌的进行着并很快的完成了。
此刻,宇宙,地球,转世星,天蝎星得到了安宁。地狱 WIFI,地牢 WIFI,宇宙星际
WIFI 都有规律地使用着。
为了表达对于美人鱼家族的感谢,Lisiya 赠送给美人鱼家族每位美人鱼一个星际
WIFI 的账号,每位美人鱼 300 年的上网时长!
定时派遣天蝎星的专家去转世星视察 WIFI 的使用情况,而这个 WIFI 所连接的 APP
还可以连接转世星和天蝎星最最先进的科学技术!
《51 测试天地》四十四(上)
www.51testing.com
这里还想说明一点,虽然转世星上面的美人鱼只是地球上美人鱼的灵魂,但是所连
的 WIFI 并非地狱 WIFI,地牢 WIFI,而是宇宙星际 WIFI,这是因为这个美人鱼家族历
来都是善良的群体,挽救过无数地球上船员的生命,自始至终对于地球有着敬仰和爱慕
那种爱慕,自从 300 年前的小美人鱼那一代就有了,她们没有因此而成为人类,但
是她们也没有伤害过任何一个地球人。
所以他们是不会去地狱的,更不会去地牢的,他们理应获得使用宇宙星际 WIFI 的权
Lisiya 深深的理解,人鱼公主非常想要再次去一次地球,去寻找那个王子,不论那个
王子是否爱她,她都无怨无悔。
不出所料,人鱼公主非常愉快的答应去一次地球!去寻找那个当年她变为泡沫的地
“可是,我的腿还没有啊。。我怎么能离开这大海呢?” 人鱼公主说。
“明天让 Lucherian 和我的外婆给你想办法,今晚要好好休息!”Lisiya 说。
“好的”人鱼公主说。
于是 Lisiya 也好好的睡了一觉,因为白天实在是太累了!
白天到了,一切都恢复美好!
Lisiya 他们准备了一个大水缸放入了宇宙飞船,而人鱼公主就被放在这个大水缸里面。
飞船安全的来到了地球。
地球上的男子铺天盖地,到底谁才是,小人鱼所救的王子转世?
对了,应该去你救王子的地方, 你还记得吗?
于是他们在人鱼公主的指引下,飞去了那个地方。
小人鱼又跳入了大海……寻找她的记忆!
大海还是以前那个样子,只是小人鱼的家人已经消失了,小人鱼这么想的,
她继续往深处游着,游着……
《51 测试天地》四十四(上)
www.51testing.com
突然她,竟然发现了那个皇宫,还有她的画像!
当然,还有她的故事。
甚至,她的家人,后代!
300 年过去了,现在的人鱼们,已经完全是他们的后代,
他们认出了她!
她表明了来意,人鱼公主问,那个王子后来怎么样了,那个王子,他娶了新娘后,
过得并不幸福,因为那不是真爱!
那后来呢?
后来他还是,过世了,埋葬在海边。
因为他总是梦到美人鱼。
“我想去看看他的墓。”
于是她游过去了。
但是她看到的竟然就是王子本人,
为什么呢?
因为,既然他结婚的时候,小人鱼必须死,那么,当他离婚的时候,他就必须死, 而
且他再次见到小人鱼的一天 ,就会是他重生的日子了。
奇迹般的,小人鱼的鱼尾变成了两双完好的腿脚,而且这次一点都不疼了,而且她
的舌头也都还在,她多么美丽!他们结婚了!在这个新世纪,结婚了。Lisiya 和 Liyiya
参加了他们的婚礼。如此的隆重和美好!包括王子当年的后代的后代都参加了,婚礼结
束之后,接新娘和“王子”回到皇宫,作为皇族的新成员,住在了皇宫中。
从此小美人鱼成为了一个真正的人,而且还愉快地生活在了地球中。
参加完了地球上的人鱼公主的婚礼,Lisiya 他们立即乘坐宇宙飞船飞往转世星,将这
个人鱼公主寻找到真爱的故事告诉转世星上面的人鱼们,她们把地球婚礼图片和故事传
给了,人鱼世界的接班人。 另一条美丽的美人鱼。未来的人鱼海域掌管人,她是小人鱼
的亲姐姐的灵魂。
随即举行了一个庄重的仪式,让这位新美人鱼领导人能够牢牢记住自己的使命。 而
《51 测试天地》四十四(上)
www.51testing.com
这样她们的使命就完成了。
消失的人鱼和加固的防线
转世星的人鱼女王奉命管理好转世星的地狱和地牢,不让转世星有任何不安因素,
一旦有不安因素,立即通知 Lisiya。
有一天,人鱼女王告诉 Lisiya,有 5 条幼年的美人鱼消失了,不知了去向。
同时有一条尊贵的美人鱼皇室成员报告说她的手机被偷了。
而消失的时间,正好是她手机失踪后的 5 分钟内。
经过研究 Lisiya 发现,当手机连接了星际 wifi 并成功上网后,如果同一个手机被地
牢恶魔使用,地牢恶魔还可以使用星际 wifi 成功上网 5 分钟,5 分钟后,地牢恶魔无法再
次使用星际 wifi,只能使用地牢 wifi 上网。
一定是有一个地牢恶魔趁这 5 分钟的星际 wifi 的缓存时间,将 5 条美人鱼给带走的!
通过仔细的排查,他们发现,的确是这 5 条美人鱼被地牢恶魔带去了地牢,因为地
牢恶魔对于人鱼家族的嫉妒,他们趁着这 5 分钟的缓存时间,打破了只能连接地牢 wifi
的限制,连上了星际 wifi,逃出了地牢,来到了美人鱼水域,将 5 条还在睡觉的人鱼带入
了残忍的地牢中,并且对她们进行恶语相向,残忍虐待。
由于地牢水域非常凶险,Lisiya 找到了擅长游泳的测试工程师小暖暖,潜水将 5 条美
人鱼救出,并让开发修复了 bug。
然后测试组对缓存问题进行了测试,确保任何 APP 的改变带来的缓存时间尽可能的
虽然 5 条小人鱼被找到了,但是她们得了抑郁症,解救她们唯一的方法就是让他们
加入测试团队!
新的团队和新的任务建立了起来!
现在天蝎星测试团队的测试工程师一共有测试公主,测试暖暖和 5 条美人鱼。而测
试暖暖的妻子是另外一个星球的公主,在另外一个测试团队中从事测试工作。
为了更好的帮助 5 条美人鱼进行测试工作,测试团队决定利用 5 天时间,为测试团
队中的 7 个人进行测试培训。
《51 测试天地》四十四(上)
www.51testing.com
Lisiya,小暖暖和 5 条美人鱼在一起讨论测试方法,同时也治疗 5 条美人鱼的抑郁症。
Lisiya 说,现在我们来讨论一下性能测试和功能测试理论吧!
“好的”,大家说。
Lisiya 问,平时我们测试时,要考虑哪些测试方法呢?
小暖暖说:如果是测试网页的话,要考虑 cookie 的测试,要测试 cookie 的保存信息
是否正确,cookie 的有效期等等。
Lisiya 说,对,如果有多种设备,还需要测试兼容性测试,比如不同浏览器,不同设
备,比如手机(考虑到常用手机,比如 android 的各种手机品牌,ios 的手机),电脑(windows,
linux 等等),宇宙飞船的系统是否能支持所开发的软件。
小暖暖说,还有安全性测试,为了防止被刷,需要增加图形验证码,密码的规则增
加,安全提问,登陆次数限制,某个任务每日限制次数,为输入框限制输入内容,防止
SQL 注入等等。
Lisiya 说,我们讨论的非常好,请小美人鱼们仔细记下笔记。
Lisiya 说,常用的性能指标有:
1、时间--响应时间
响应时间就像是真爱,真爱是不会随着时间的流逝,而有一丝一毫的改变的,响应
时间的 x 轴是时间,就像是人所经过的时间,而 y 轴是响应时间,虽然响应时间会有一
定的波动,但是真爱是不会因为时间的不断推进而有大幅度的变化,允许有一定的变化,
但是绝对不能变为无穷大,否则那就不是真爱。
2、虚拟用户数量—响应时间
是不同虚拟用户数量下的响应时间曲线。
Lisiya 说,现在让我们来温习一遍有关性能测试数据的统计学方法吧!
1、平均值:
1)相对于整个数轴来分析时,平均的响应时间的值,可以看出响应时间的主要在什
么数值上,但是它有个缺点,当最长的响应时间和最短的响应时间相差特别大的时候,
这个平均值就显得没什么意义了,只有当最长的响应时间和最短的响应时间相差不大的
《51 测试天地》四十四(上)
www.51testing.com
时候,它才会有意义,可以说明响应时间的主要数值。
相对于某个时间点上来说,平均响应时间是有意义的,说明的是某个时间点上所有
并发用户的平均响应时间,如果在某个时间点上,平均响应时间特别长,说明有两种可
能性 1*所有用户的响应时间都特别长 2*有个别用户的响应时间特别长,就可以从这个时
间点来分析这个时间点的特征,从而得出相关的结论。
相关公式如下:
1:已知方差,检验一组数据的平均值
使用统计量:
2:未知方差,检验一组数据的平均值
使用统计量:
3:已知方差,检验两组数据的平均值
使用统计量:
4:未知两组数据的方差,但是知道两组数据的方差相等,检验两组数据的平均值
使用统计量:
5:平均值的置信区间 (sigma 已知)
《51 测试天地》四十四(上)
www.51testing.com
说明所检测的数值的离散程度的指标。
如果方差越大,就说明系统响应时间波动越大,因此不稳定。同时可以通过某个时
常大,可以得出相关结论。
对于响应时间,如果有两组数据,一组方差大一组方差小,并不一定说明方差大的
数据没有方差小的数据好,如果方差大的数据的平均值小于方差小的数据的平均值,有
可能说明方差大的数据是在响应时间较小的范围内波动,而方差小的数据则可能在响应
时间大的范围内波动。
相关公式如下:
1:检验一组数据的方差为某一个数值。
使用统计量:
2:检验两组数据的方差相等。
3:两种统计表合并成为一张表。
使用范围,这两张表拥有同一种横坐标,比如时间为横坐标,纵坐标各不相同。
它的理念是:当时间刻度变化的时候,这两张表的纵坐标分别对应不同的值,将这
两个值分别作为横坐标和纵坐标,这样就能更好的体现,这两张表中的纵坐标互相之间
的关系了。
《51 测试天地》四十四(上)
www.51testing.com
美人鱼和小暖暖都在认真的听着,记着笔记。
现在我们需要实际操作一下,这样可以加深印象, Lisiya 说。
有关性能测试的工具有很多种,比如 LoadRunner,Jmeter。
Lisiya 说:现在我们讲一下 Jmeter 的使用吧!因为 Jmeter 的深入研究要有待时日,
我们就先尝试着最简单的 Jmeter 的测试吧!万事都要一步一步来。
小暖暖和其他 5 条美人鱼说:好的。
1:安装 JMETER
2:设置 ....../jmeter/bin/user.properties 文件
增加语句:
proxy.cert.alias=anything
只有增加了这句语句才能使用代理服务器进行录制脚本
以下是普通的 Jmeter 使用方法
1、添加线程组
测试计划->添加->Threads(Users)->线程组
《51 测试天地》四十四(上)
www.51testing.com
2、配置线程组的数值
线程数:200,Ramp-up period(in second):10
循环次数:10
《51 测试天地》四十四(上)
www.51testing.com
3、添加 HTTP 代理服务器
工作台->添加->非测试元件->HTTP 代理服务器
《51 测试天地》四十四(上)
www.51testing.com
4、设置 HTTP 代理服务器的端口为 8080,这样就可以使用代理服务器端口号为 8080
的浏览器进行录制所需要的性能测试的部分
《51 测试天地》四十四(上)
www.51testing.com
5、添加响应时间图表
测试计划->添加->监听器->Response Time Graph
6、添加 Summary Report 图表
测试计划->添加->监听器->Summary Report
7、设置浏览器的代理服务器端口号为 8080
这里我们使用 Firefox 浏览器
《51 测试天地》四十四(上)
www.51testing.com
8、当以上都准备好之后,点击“工作台”->“HTTP 代理服务器”->“启动”按钮
9、打开 Firefox 浏览器,输入需要测试的网址,比如“http://bbs.****.com/search.php”,
《51 测试天地》四十四(上)
www.51testing.com
然后输入要搜索的内容,比如“22”, 点击“搜索”按钮。
10、停止 HTTP 代理服务器。
11、在 Jmeter 中删除多于的录制内容和多于的参数。直到最简化。
在这里,我们发现/search.php?mod=forum 的 http 请求中,所需要的参数只需要两个
《51 测试天地》四十四(上)
www.51testing.com
12、点击任意一个 report,然后点击“启动” 按钮就可以看到 report 的具体数值变化
比如,我点击 Summary report,然后点击“启动”的情况如下
13、下图是 Response Time 的图表样式
《51 测试天地》四十四(上)
www.51testing.com
14、查看响应内容,判断性能测试运行是否真正的能搜索出内容,如果返回结果和
真实情况的搜索的返回结果一致,则代表性能测试脚本录制正确。此时,我们可以在“查
看结果树”->“响应数据”中查看到返回的 html 的情况,因为查看到的 html 内容符合真实情
况,因此判定为是正确的。
《51 测试天地》四十四(上)
www.51testing.com
Lisiya 说,以上只是对于 Jmeter 的最基础的介绍,我们以后要多多学习 Jmeter
大家回答说,好的,这真的是非常有趣的学科!
拓展学习: http://www.atstudy.com/course/183
《Jmeter 性能测试》手把手实例教你如何运用 Jmeter 应对各种性能测试任务
http://www.atstudy.com/course/183
《51 测试天地》四十四(上)
www.51testing.com
一、例会的目的:
1) 加强组员分享意识
2) 同步项目整体情况,解决组内问题
3) 传达目标--打造一支测试精英队伍
二、内容甄选参考方法步骤:
1) 组员每个人写出自己想了解的议题,如限制至少 5 个
2) 统计出议题的票数
3) 深入了解每个人想了解议题的原因
4) 细化每个议题,直至内容可分享
5) 挑选出可分享的、对组员意义较大,且排名靠前的议题
6) 指派议题分享负责人
7) 分享排期
三、参考例会内容:
1) 技能分享
目的:相当于技能培训,至少每两周有一次本类分享,
? 服务端测试(单测、接口测试)
? 性能测试系列
测试人员例会会议议题制定规范
? 作者:陈
《51 测试天地》四十四(上)
www.51testing.com
? 自动化测试系列
? 随机测试思想
? 黑盒用例设计方法
? Appium 安卓自动化框架
? 浏览器性能评测方法
? Android 单测(框架、用例代码)
? 浏览器稳定性框架
? 浏览器白盒测试方法
2) 工作方法
目的:培养组员职业素养,本部分分享比较容易偏理论,要求必须与工作实际结合,
有实际的例子,对测试工作有帮助才能分享。
? 时间管理
? todo 管理
? 情绪管理
? 人际关系
? 提问技巧
3) 工具分享
目的:包括常用业界测试用具和自己写的工具,提升组员的工具意识。要求分享的
工具对测试工作有帮助。
? windbg 工具常用分析方法
? PM 工具使用方法
《51 测试天地》四十四(上)
www.51testing.com
? fiddler 工具
4) 读书分享
目的:培养组员读书习惯,这部分分享容易偏理论。要求包含以下几部分:书名、
内容简介、读后感、对大家的帮助。
5) 【例行】Bug 总结
目的:bug 总结分享,脑暴原因,避免以后大家犯同样的错误
6) 【例行】项目复盘结论公示
目的:不在例会上做复盘,但是复盘的有用的结论可以在例会上公示分享
7) 【例行】项目进度公示
目的:同步项目组目前的进度和未来的安排,提升组员的项目关心度
8) 【例行】组内新流程公示
目的:新流程同步给大家
9) 【例行】组内颁奖
目的:增强个人荣誉感。
四、可能存在的问题及解决方案
问题 1:议题内容过于庞大,模糊,不易分享,如“python 学习分享”
解决方案:
了解组员意愿集中程度,如果大部分人有需求,可以细化议题,排期分享;如果只
有一到两人想了解,就不用排到例会分享议题中,建议自学。
问题 2:分享内容不符合预期,较浅薄。
解决方案:可以在组员间做调查,如果一半以上人觉得没有收获,明确告知该分享
人,以后不用参与到知识分享。
问题 3:与项目任务冲突,导致无法按期分享
解决方案:可以与其他分享议题的同学协调排期,如果不能协调,顺延到下周分享
《51 测试天地》四十四(上)
www.51testing.com
性能测试流程
◆作者:曹承臻
一、背景:
当前所有同学做性能测试方法不一,没有统一的规范指导文档可以参考。
二、目的:
形成性能测试整个流程的指导规范,以后做性能测试的同学可以依据此规范做性能
三、具体流程:
(1)需求评估
目的:评估是否需要做性能测试。
? 需要做性能测试
新产品要上线,预估单台机器 QPS 峰值超过 100。
已经上线过的产品,由于接入了新的业务或者用户量增加,预估单台机器 QPS 峰值
超过 100。
? 不需要做性能测试
单台机器 QPS 峰值低于 50 的需求。
有相同产品实现逻辑的产品,且已经做过性能测试。
例如:假如一个请求,每次用户开启应用时都会发送到服务器,服务器则会返回给
客户端本账号在好友中的积分排名情况。从产品的角度认为,每次应用启动,都会触发
服务器查询一次数据库。这样会数据库会造成很大压力。而测试再了解了具体实现后发
现:针对每个用户机器码的排序数据是从 redis 服务器返回的,而 redis 服务器会每隔一小
时请求存储的

我要回帖

更多关于 去泰国学泰拳要多少钱 的文章

 

随机推荐