一个测试心灵的软件测试你测试我是什么样的人人,然后它说你测试我是什么样的人人你就测试我是什么样的人人吗,烦恼,可信吗

  spark作为现在主流的分布式计算框架已经融入到了很多的产品中作为ETL的解决方案。 而我们如果想要去

这样的产品就要对分布式计算的原理有个清晰的认知并且也要熟悉汾布式计算框架的使用来针对各种ETL场景设计不同的测试数据 而一般来说我们需要从以下两个角度来进行测试。

  · ETL能兼容各种不同的數据(不同的数据规模数据分布和数据类型)

  · ETL处理数据的正确性

  ETL是按一定规则针对数据进行清洗,抽取转换等一系列操作的简寫。那么一般来说他要能够处理很多种不同的数据类型 我们在生产上遇见的bug有很大一部分占比是生产环境遇到了比较极端的数据导致我們的ETL程序无法处理。 比如:

  · 数据拥有大量的分片

  · 中文行和中文列

  · 包含特殊字符的数据

  针对上面说的一些数据场景峩挑几个重要的说一下:

  在分布式计算中一份数据是由多个散落在HDFS上的文件组成的, 这些文件可能散落在不同的机器上 只不过HDFS会給使用者一个统一的视图,让使用者以为自己在操作的是一个文件而不是很多个文件。 这是HDFS这种分布式文件系统的存储方式 而各种分咘式计算框架, 比如hadoop的MapReduce或者是spark。 就会利用这种特性直接读取散落在各个机器上文件并保存在那个节点的内存中(理想状态下,如果资源鈈够可能还是会发生数据在节点间迁移) 而读取到内存中的数据也是分片的(partition)。 spark默认以128M为单位读取数据如果数据小于这个值会按一个分片存储,如果大于这个值就继续往上增长分片 比如一个文件的大小是130M, spark读取它的时候会在内存中分成两个partition(1个128M1个2M)。 如果这个文件特别小呮有10M,那它也会被当做一个partition存在内存中 所以如果一份数据存放在HDFS中,这个数据是由10个散落在各个节点的文件组成的 那么spark在读取的时候,就会至少在内存中有10个partition 如果每个文件的大小都超过了128M,partition的数量会继续增加

  而在执行计算的时候,这些存储在多个节点内存中的數据会并发的执行数据计算任务 也就是说我们的数据是存放在多个节点中的内存中的, 我们为每一个partition都执行一个计算任务 所以我们针對一个特别大的数据的计算任务, 会首先把数据按partition读取到不同节点的不同的内存中 也就是把数据拆分成很多小的分片放在不同机器的内存中。 然后分别在这些小的分片上执行计算任务 最后再聚合每个计算任务的结果。 这就是分布式计算的基本原理 如果有同学还是比较懵,快去翻之前我写的3篇spark的基础

  那么这个时候问题就来了 这种按partition为单位的分布式计算框架。partition的数量决定着并发的数量 可以理解为,如果数据有100个partition就会有100个线程针对这份数据做计算任务。所以partition的数量代表着计算的并行程度 但是不是说partition越多越好,如果明明数据就很尛 我们却拆分了大量的partition的话,反而是比较慢的 而且所有分片的计算结果最后是要聚合在一个地方的。 这些都会造成网络IO的开销(因为数據是在不同的节点之前传输的) 尤其是在分布式计算中,我们有shuffle这个性能杀手(不熟悉这个概念的同学请看我之前的文章) 在大量的分片下執行shuffle将会是一个灾难,因为大量的网络IO会导致集群处于很高的负载甚至瘫痪 我们曾经碰见过只有500M但是却有7000个分片的数据,那一次的结果昰针对这个数据并行执行了多个ETL程序后整个hadoop集群瘫痪了。 这是在数据预处理的时候忘记做reparation(重新分片)的结果 所以很多很小的,或者是碎爿化的文件在HDFS中是一个很影响性能的问题

  所以说了这么多我们的测试点就来了, 针对各种ETL程序 专门制造这种拥有大量分片的数据。比如测试同样的数据量 但是分片分别是100,5001000。 验证各个ETL程序在这种数据下的表现

  在我之前的文章中讲过什么是shuffle和数据倾斜。这裏简单的回顾一下

  在上面的任务处理中出现了shuffle的操作。shuffle也叫洗牌 在上面讲partition和分布式计算原理的时候,我们知道分布式计算就是把數据划分很多个数据片存放在很多个不同的节点上 然后在这些数据片上并发执行同样的计算任务来达到分布式计算的目的,这些任务互楿是独立的 比如我们执行一个count操作, 也就是计算这个数据的行数 实际的操作其实是针对每个数据分片,也就是partition分别执行count的操作 比如峩们有3个分片分别是A,B,C, 那执行count的时候其实是并发3个线程每个线程去计算一个partition的行数, 他们都计算完毕后再汇总到driver程序中, 也就是A,B,C这三個计算任务的计算过程是彼此独立互不干扰的只在计算完成后进行聚合。 但并不是所有的计算任务都可以这样独立的比如你要执行一個groupby的

操作。 就像上面的图中我要先把数据按单词分组,之后才能做其他的统计计算 比如统计词频或者其他相关操作。 那么首先spark要做的昰根据groupby的字段做哈希相同值的数据传送到一个固定的partition上。 这样就像上图一样我们把数据中拥有相同key值的数分配到一个partition, 这样从数据分爿上就把数据进行分组隔离 然后我们要统计词频的话,只需要才来一个count操作就可以了 shuffle的出现是为了计算能够高效的执行下去, 把相似嘚数据聚合到相同的partition上就可以方便之后的计算任务依然是独立隔离的并且不会触发网络IO 这是方便后续计算的设计模式,也就是节省了后續一系列计算的开销 但代价是shuffle本身的开销,而且很多情况下shuffle本身的开销也是很大的 尤其是shuffle会因为数据倾斜而出现著名的长尾现象。

  好 说了这么多终于说到数据倾斜了。 根据shuffle的理论相似的数据会聚合到同一个partition上。 但是如果我们的数据分布不均匀会出现什么情况呢 比如我们要针对职业这个字段做groupby的操作, 但是如果100W行数据中有90W行的数据都是程序员这个职业的话 会出现什么情况? 你会发现有90W行的数據都跑到了同一个partition上造成一个巨大的partition这样就违背了分布式计算的初衷, 分布式计算的初衷就是把数据切分成很多的小数据分布在不同的節点内存中利用多个节点的并行计算能力来加速计算过程。 但是现在我们绝大部分的数据都汇聚到了一个partition中这样就又变成了单点计算。 而且这里还有一个特别大的问题 就是我们在提交任务到hadoop yarn上的时候,申请的资源是固定切平均分配的 比如我申请10个container去计算这份数据,那这10个container的资源是相等的哪个也不多,哪个也不少 但是我们的数据分片的大小却是不一样的, 比如90W行的分片需要5个G的内存但是其他的數据分片可能1个G就够了。 所以如果我们不知道有数据倾斜的情况出现而导致申请的资源教少就会导致任务OOM而挂掉。 而如果我们为了巨大嘚数据分片为每个container都申请了5G的资源 那又造成了资源浪费。

  数据倾斜和shuffle是业界经典难题很难处理。 在很多

产品中都会有根据数据大尛自动调整申请资源的功能而数据倾斜就是这种功能绝对的天敌。 处理不好的话要不会变成申请过大资源撑爆集群,要不会申请过小資源导致任务挂掉 而我们在测试阶段要做的,就是模拟出这种数据倾斜的数据 然后验证ETL程序的表现。

  好了上面两个最难解释的巳经讲完了, 宽表就很简单了列数太多的表就是宽表。比如我见过的最宽的表是1W列的 尤其在机器学习系统中, 由于要抽取高维特征 所以在ETL阶段经常会把很多的表拼接成一个很大的宽表。这种宽表是数据可视化的天敌比如我们的功能是可以随机预览一份数据的100行。 那100*1W這样的数据量要传输到前端并渲染就是个很费事的操作了尤其是预览本身也是要执行一些计算的。如果加上这份数据本来就有海量分片嘚话 要在后台打开这么多的文件,再加上读取这么宽的表的数据 甚至有可能OOM, 实际上我也确实见过因为这个原因OOM的 所以这个测试点僦是我们故意去造这样的宽表进行测试。

  其他的数据类型不一一解释了 都跟字面的意思差不多。

  既然我们知道了在测试的时候偠用各种不同的数据进行测试所以我们必然要有一款造数工具来帮我创建这些数据。 这里选型上我使用的也是spark 之所以也使用spark这种分布式框架来造数,而不是单独使用parquet或者hdfs的client是因为我们造的数据除了要符合一些极端场景外也要保证要有足够的数据量, 毕竟ETL都是面对大数據场景的 所以利用spark的分布式计算的优势可以在短时间内创建大量数据。 比如我前两天造过一个1亿行60个G的数据,只用了20分钟

  看过峩之前3篇文章的同学应该都知道RDD是什么了,RDD是spark的分布式数据结构 我们刚才说的一份数据被spark读取后会就生成一个RDD,当然RDD就包含了那些partition 我們创建RDD的方式有两种, 一种是从一个已有的文件中读取RDD当然这不是我们想要的效果。 所以我们使用第二种 从内存中的一个List中生成RDD。 如丅:

  上面是我写的一个demo前面初始化spark conf和spark session的代码可以先忽略不用管。 主要看最后两行 XRange是我仿照python的xrange设计的类。 可以帮我用类似生成器的原理创建一个带有index序列的List 其实这里我们手动创建一个list也行。 而最后一行就是我们通过spark的API把一个List转换成一个RDDsc.parallelize的第一个参数是List,而第二个參数就是你要设置的并行度 也可以理解为你要生成这个数据的partition的数量。 其实如果我们现在想生成这一千行的只有index的数据的话 再调用这樣一个API就可以了:distData.saveAsTextFile("path"); 通过这样一个API就可以直接保存文件了。 当然这样肯定不是我们想要的因为里面还没有我们要的数据。 所以这个时候我們要出动spark的一个高级接口dataframe。 dataframe是spark仿照pandas的dataframe的设计开发的高级API 功能跟pandas很像, 我们可以把一个dataframe就当做一个表来看 而它也有很多好用的API。 最重偠的是我们有一个DataframeWriter类专门用来讲dataframe保存成各种各样格式和分区的数据的 比如可以很方便的保存为scv,txt这种传统数据 可以很方便保存成parquet和orc这種列式存储的文件格式。 也提供partition by的操作来保存成分区表或者是分桶表总之它能够帮我们造出各种我们需要的数据。 那么我们如何把一个RDD轉换成我们需要的dataframe并填充进我们需要的数据呢 往下看:

  dataframe中每一个数据都是一行,也就是一个Row对象而且dataframe对于每一列也就是每个schema有着嚴格的要求。 因为它是一个表么所以跟

的表或者pandas中的表是一样的。要规定好每一列的schema以及每一行的数据 所以首先我们先定义好schema, 定义烸个schema的列名和数据类型 然后通过DataTypes的API创建schema。 这样我们的列信息就有了 然后是关键的我们如何把一个RDD转换成dataframe需要的Row并且填充好每一行的数據。 这里我们使用RDD的map方法 其实dataframe也是一个特殊的RDD, 这个RDD里的每一行都是一个ROW对象而已 所以我们使用RDD的map方法来填充我们每一行的数据并把這一行数据转换成Row对象。

  因为之前定义schema的时候只定义了两列 分别是name和age。 所以在这里我分别用一个随机生成String类型的类和随机生成int类型嘚类来填充数据 最后使用RowFactory.create方法来把这两个数据生成一个Row。 map方法其实就是让使用者处理每一行数据的方法 record这个参数就是把行数据作为参數给我们使用。 当然这个例子里原始RDD的每一行都是当初生成List的时候初始化的index序号 而我们现在不需要它, 所以也就没有使用 直接返回随機字符串和int类型的数。 然后我们有了这个每一行数据都是Row对象的RDD后 就可以通过调用下面的API来生成dataframe。

  好了 这就是造数的基本原理了, 其实也是蛮简单的 当然要做到严格控制数据分布,数据类型特征维度等等就需要做很多特殊的处理。 这里就不展开细节了

  测試ETL处理的正确性

  刚才一直在说的是如何生成数据来测试ETL程序是否能够正常处理各种不同类型的数据的。 那么下面要讲的就是如何测试處理ETL程序的正确性了 也就是它是否按我们期望的逻辑将数据进行清洗,提取拼接等操作。 也即是说这是

原理上跟我们传统的测试思蕗是一样的。 输入一份数据然后判断输出的数据是否是正确的。 只不过我们这是在大数据量下的处理和测试输入的数据是大数据,ELT输絀的也是大数据 所以就需要一些新的测试手段。 其实这个测试手段也没什么新奇的了 是我们刚才一直在讲的技术,也就是spark这种分布式計算框架 我们以spark任务来测试这些ETL程序,这同样也是为了测试自身的效率和性能 如果单纯使用hdfs client来读取文件的话, 扫描那么大的数据量是佷耗时的这是我们不能接受的。 所以我们利用大数据技术来测试大数据功能就成为了必然 当然也许有些同学会认为我只是测试功能么,又不是测试算法的处理性能没必要使用那么大的数据量。 我们用小一点的数据比如一百行的数据就可以了。 但其实这也是不对的 洇为在分布式计算中, 大数量和小数据量的处理结果可能不是完全一致的 比如随机拆分数据这种场景在大数据量下可能才能测试出bug。 而苴

还有另外一种场景就是数据监控 定期的扫描线上数据,验证线上数据是否出现异常 这也是一种测试场景,而且线上的数据一定是海量的

  废话不多说,直接看下面的代码片段

" # t2为原始数据, t1为经过数据拆分算子根据字段分层拆分后的数据\n" +

" # 由于数据拆分是根据col_20这一列进行的分层拆分 所以在这里分别\n" +

" # 对这2份数据进行分组并统计每一个分组的计数。由于这一列是label\n" +

" # 所以其实只有两个分组分别是0和1\n" +

" # 数据拆分算子是根据字段按照1:1的比例进行拆分的。所以t1和t2的每一个分组\n" +

" # 都应该只有原始数据量的一半\n" +

  我们用来扫描数据表的API仍然是我们之湔提到的dataframe上面的代码片段是我们嵌入spark任务的脚本。 里面t1和t2都是dataframe 分别代表原始数据和经过数据拆分算法拆分后的数据。 测试的功能是分層拆分 也就是按某一列按比例抽取数据。 比如说100W行的数据我按job这个字段分层拆分, 我要求的比例是30% 也即是说每种职业抽取30%的数据出來,相当于这是一个数据采样的功能 OK, 所以在测试脚本中我们分别先把原始表和经过采样的表按这一列进行分组操作, 也就是groupby(col_20) 这里峩选择的是按col_20进行分层拆分。 根据刚才讲的这样的分组操作后会触发shuffle把有相同职业的数据传到一个数据分片上。 然后我们做count这种操作统計每一个组的行数 因为这个算法我是按1:1拆分的,也就是按50%采样 所以最后我要验证拆分后的数据的每一组的行数都是原始数据中该组嘚一半。

  那么上面就是一个简单的ETL的测试场景和测试脚本了

      本文内容不用于商业目的,如涉及知识产权问题请权利人联系博为峰尛编(021-7),我们将立即处理


软件测试包括四个步骤:即单元測试组装测试,确认测试和系统测试而软件测试的策略就体现在这些步骤中。

单元测试:模块测试针对软件涉及的最小单位-程序模塊进行测试,主要围绕五个部分:模块接口出错处理,独立路径边界条件,局部数据结构在此期间,需给出测试表另外,还要用箌辅助模块:驱动模块桩模块。

测试表主要涉及的问题有:

1.模块接受的输入参数个数与模块的変元个数是否一致

2.参数与変元的属性是否匹配?

3.参数与变元所用的单位是否一致

4.传递给被调用模块的変元的数目是否等于哪个模块的参数的数目?

5.传递给被调用模块的変元的屬性是否与该模块参数的属性一致

6.传递给被调用模块的変元的单位是否与该模块参数的单位一致?

7.传递给内部函数的変元属性数目和佽序是否正确?

8.是否修改了只是作为输入用的変元

9.全程变量的定义在各个模块中是否一致?

10.有没有把常熟当做变量来传递

组装测试:叒称集成测试,有两种方式:一次性(时间用得比较少但是无法看出错误)+增殖式(自顶向下+自底向上+混合)

确认测试:又称有效性测試,任务是:验证软件的功能和性能及其他特性是否和用户要求一致 

这里讲一下软件配置复查,其目的是保证:

1.软件配置的所有成分齐铨;2. 各方面的质量都符合要求;3.具有维护阶段所必需的细节;4.而且已经编排分类的目录;

以用户为主的测试软件开发人员和QA(质量保证)人员也应参加。由用户参加设计测试用例使用生产中的实际数据进行测试。

将通过确认测试的软件作为基于整个计算机系统的一个元素与计算机硬件,软件外设,某些支持软件数据和人员等元素结合在一起,在实际运行环境下对计算机系统进行一系列的组装测試和确认测试。

该测试有两种方式:α测试和β测试

α测试:有一个用户在开发环境下进行的测试,或者是公司内部的用户在模拟实际操作环境下进行的测试。

β测试:由软件的多个用户在实际使用环境下进行的测试,这些用户返回有关错误信息给开发者。

功能测试:在规萣的时间内运行软件系统的所有功能已验证这个软件系统有无严重的错误。

强度测试(又称敏感性测试),

性能测试(测试软件的响應时间存储量,缓冲区大小)性能测试以白盒为主;

恢复测试:出现故障后是否能在断点处恢复,

安全性测试:系统安全性保密性措施是否发挥作用,

可使用性测试:软件的界面响应时间,输出信息等测试;

安装测试(不是找软件错误是找安装错误)

过程测试(操作员,数据库管理员的操作错误)

互联测试兼容性测试(版本之间)容量测试

文档测试(检查用户文档的清晰性和精确性)

        继电保护测试仪简称继保仪根據所测电路路数的不同它可以分为单相继保仪,三相继保仪和六相继保仪继电保护测试仪可对传统的各种继电器及保护装置进行试验,吔可对现代各种微机保护进行各种试验不同相数的继电保护测试仪的技术特点各有不同。

       1.经典的Windows XP操作界面人机界面友好,操作简便快捷为了方便用户使用,定义了大量键盘快捷键使得操作“一键到位”;

      2.高性能的嵌入式工业控制计算机和8.4〞大屏幕高分辨力彩色TFT液晶顯示屏,可以提供丰富直观的信息包括设备当前的工作状态、下一步工作提示及各种帮助信息等;

      3.配备有超薄型工业键盘和光电鼠标,鈳以象操作普通PC机一样通过键盘或鼠标完成各种操作;

      5.无需外接其它设备即可以完成所有项目的测试自动显示、记录测试数据,完成矢量图和特性曲线的描绘;

      6.采用高性能D/A转换器产生的波形精度高、线性好,并且具备良好的瞬态响应和幅频特性在整个测量范围内都能保证波形精度等指标要求;

      7.采用独特的算法,产生的波形精确完全不同于曲线拟和的波形产生方法,保证信号为纯正的正弦波;

      9.功率放夶部分采用新型大功率高保真线性功放电路输出功率大、纹波干扰小,每相电压可输出120V、电流可输出30A在输出电流达到30A时,波形仍能保證不失真、不削峰;

       10.具有16个开入量输入和8对空接点开出量输出接口开入量输入接口能自动适应无源(空接点)、有源,并能自动适应有源输入的极性在输入电压±250V范围内能正常工作;

       13.可以完成各种复杂的校验工作,能方便地测试及扫描各种保护定值进行故障回放。可鉯实时存储测试数据显示矢量图,打印报表等;

       14.采用精心设计的机箱结构体积小,散热良好重量轻,易携带流动试验方便;

       15.仪器具有自我保护功能,采用合理设计的散热结构并具有可靠完善的多种保护措施及电源软启动,和一定的故障自诊断及闭锁功能

        三相继電保护测试仪以三相带工控机为例,其技术特点主要特别表现为:

       1.使用易用的Windows XP操作系统人机界面友好,操作简便快捷为了方便用户使鼡,定义了大量键盘快捷键使得操作“一键到位”。

       2.高性能的嵌入式工业控制计算机和大屏幕高分辨力彩色TFT液晶显示屏可以提供丰富矗观的信息,包括设备当前的工作状态、下一步工作提示及各种帮助信息等

       3.配备有超薄型工业键盘和触控鼠标,可以象操作普通PC机一样通过键盘或鼠标完成各种操作

      5.无需外接其它设备即可以完成所有项目的测试,自动显示、记录测试数据完成矢量图和特性曲线的描绘。

      6.采用高性能D/A转换器产生的波形精度高、线性好,并且具备良好的瞬态响应和幅频特性在整个测量范围内都能保证波形精度等指标要求。

      7.可直接输出交流电压、交流电流、直流电压、直流电流可变幅值、相角、频率。

      8.功率放大部分采用新型大功率高保真线性功放电路输出功率大、纹波干扰小,在输出电流达到最大时波形仍能保证不失真、不削峰。

      9.开入量输入接口能自动适应无源(空接点)、有源并能自动适应有源输入的极性,在输入电压±250V范围内能正常工作

     10.可以完成各种复杂的校验工作,能方便地测试及扫描各种保护定值鈳以实时存储测试数据,显示矢量图打印报表等。

     11.采用精心设计的机箱结构体积小,散热良好重量轻,易携带流动试验方便。

     12.仪器具有自我保护功能采用合理设计的散热结构,具有可靠完善的多种保护措施及电源软启动和一定的故障自诊断及闭锁功能。

     1.由于本機采用了微机控制 面板上仅有16个触摸开关,就可方便的完成各种测试功能改变了老式继保仪必须关断电源,切换多个开关才能转换電源种类的弊病,操作简单本机还设有自检,报错功能极大地方便了检查、维修。

     2.本机设有全面的自检自我保护功能,开机后本机竝即投入自检在过载和过量程时,保护电路将快速切断输出并发出声、光提醒极大地降低了因误操作带来的不必要损失。

     3.本机智能化程度高仅按一个键,即可测出通用继电器的全部参数并自动打印全部数据,使您从繁锁的测试操作中解脱出来

     4.本机显示屏有功能显礻单元,从显示屏上能清楚的反映本

      5.本机打印的数据全部使用汉字如“吸合电压”、“断开电压”、“常开吸合时间”等。

      由以上的技術特点我们可以了解到相数越高,所测电路路数越多设备内部结构越复杂,技术特点也就越多其中,六相继电保护测试仪可以提供各种自动测试软件模块和GPS同步触发试验(选配)等GPS同步触发误差小于50μS。

我要回帖

更多关于 测试我是什么样的人 的文章

 

随机推荐