jjzjj

性能测试怎么做?性能测试指标,常用性能测试工具

测试开发Max 2024-05-30 原文

前言

性能测试用户概念
系统用户数:指所有可能访问这套系统的用户数,也叫系统的全部用户数。
在线用户数:指同时访问这套系统的用户数量。
并发用户数:在一个时间切面上同时向这套系统发起请求的用户数。

糟糕性能
系统设计阶段缺少性能方面的考虑(考虑整体系统集成后的性能);
直到最后一刻才进行性能测试(性能测试越早越好);
对系统的容量或规模没有足够的考虑(最终用户的规模和分布);
对性能峰值预期偏低;
性能测试还不规范,没有有效的方案参考或实施;
没有使用性能测试自动化工具。

一、性能测试

稳定的并发能力

为什么是稳定的并发能力非常重要呢?

我们在实际性能测试当中往往并不是按照教科书上面写到的“单交易基准测试 -> 单交易负载 -> 混合交易基准 -> 混合交易负载 -> 稳定性测试 ” 这个套路来进行的,实际测试当中往往需要进行对比测试。比如说我应用程序换版前后对比,或者更换操作系统版本前后对比,或者一个数据库参数调节前调节后有一个对比。

对比测试当中的一个最重要的原则就是一次只调一个参数来对比前后的情况, 如果我要调两个或者多个参数的话,如果发现前后性能差距很大,我很难判断是哪个参数导致的影响。因此,性能测试每次尽量只调一个参数,这个参数是什么呢?

这个参数就是应用程序的版本、操作系统的版本、数据库参数等等。并且前后对比的时候,要尽量保持其他要素不变。然而,其他性能指标不变是不可能的,那么就要控制住可控参数,观察不可控参数的变化。

业务吞吐量跟 CPU 利用率是最重要的参数之二,他们之间又有着直接的关系,对于大部分的交易系统来说,我的吞吐量上去的话, CPU 利用率也会随之上升,而 CPU 升高的话,吞吐量一般也会比较高。

我们的策略是对比两个场景在 CPU 利用率相同的情况下吞吐量的差异呢?还是对比吞吐量相同的情况下 CPU 利用率的差异呢?

这种情况下,我们的策略必须是对比吞吐量相同的情况下 CPU 利用率的差异,因为吞吐量我们是可以控制的,而 CPU 我们是不能控制的 。使用工具发出来 100TPS 就是 100TPS , 200TPS 就是 200TPS 。而 CPU 是操作系统和 CPU 共同控制的,它不在我们的控制能力范围。

通过上面分析我们看出,对比测试的原则下面“稳定”控制吞吐量是非常非常重要的。

二、 性能测试工具

RPT:
这里为什么举 IBM RPT 的例子呢,因为即使是专门做性能测试的人, 也很少听说过 RPT 这个工具,在这里是把它当成一个反面例子来介绍的 。

第一,有 license 的严格限制,而且这个 license 是没办法破解的,你需要把你测试的主控机的磁盘信息发送给 IBM , IBM 根据这个信息返回给你一个 license 序列号,它和你的主控机绑死了,所以你是没办法破解的。

Loadrunner:
是目前商业软件当中最为流行的。为什么会流行呢,首先它的 license 是可以破解的,这就导致用户数量庞大,用户也喜欢用,并且用它发送很高的压力(而 IBM RPT 的 license 和并发数是相关的,花钱少是没法设置高并发的)。

这个原因非常重要,导致了用户和软件之间的正反馈,促使 Loadrunner 不断地改进,最后成为一个流行的工具,反观 RPT 有严格的 license 限制,用户特别少,也没什么反馈,最后恶性循环后在市场上消失了。

JMeter:
JMeter 作为开源领域最火爆的一款性能测试工具,在互联网公司里面用的比较广,现在在金融这种领域的公司也用的比较广。但是吞吐量控制的不是很稳定。

我这里举一个如何做后台性能测试的例子。我要给一个数据库服务器施加查询压力,向这台数据库发送一万次某个查询语句。正常的做法是什么呢?写三个函数:

第一个函数 init :创建数据库的连接,并准备一个 SQL 语句。

第二函数 action :负责给 SQL 语句填入参数,真正的去做查询的动作,反复地去做 1 万遍。

第三函数 end :做一些清理工作,断开与数据库的连接。

这三个函数中,第一个函数跟第三个函数都是只做一遍,中间的 action 函数是迭代了一万遍。

事实上像 Loadrunner 和 JMeter 这样的性能工具也的确是这么实现的,而遗憾的是 RPT 就不是这么实现的。 RPT 怎么实现呢?我的 init 函数、 action 函数、 end 函数对于每一次交易都要执行一遍,如果执行 1 万次查询,这三个函数一共执行了 3 万次,大大降低了单机执行效率。

也就是说, RPT 除了线性扩展能力特别差,即使是在单机上面的性能也是非常差。相同资源的 PC 机资源(比如说 4C4G 的 PC )一秒钟能发 200 笔业务,而 RPT 就只能发 100 笔业务,非常浪费性能测试环境的资源,并且,不仅仅是浪费资源的问题,而且你的测试代理机一旦多起来维护管理工作将成倍增长。

三、总结

当你弱时,把最后的口粮捧出去人家都不稀罕,你要强了呢,打一巴掌给个甜枣,人家觉得那枣是真甜啊!

人生是战场,需要冲次,需要拼搏,处处布满陷井,一不小心就会中埋伏,就会遭遇失败,永无翻身之日,但我们拼搏一定要方向明确,有目标性拼搏,才会成功,幸福才会属于你。

最好的生活方式,是和一群志同道合的人,一起奔跑在理想的路上!回头有一路的故事,低头有坚定的脚步,抬头有清晰的远方。

有关性能测试怎么做?性能测试指标,常用性能测试工具的更多相关文章

  1. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  2. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  3. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  4. ruby - Ruby 的 Hash 在比较键时使用哪种相等性测试? - 2

    我有一个围绕一些对象的包装类,我想将这些对象用作散列中的键。包装对象和解包装对象应映射到相同的键。一个简单的例子是这样的:classAattr_reader:xdefinitialize(inner)@inner=innerenddefx;@inner.x;enddef==(other)@inner.x==other.xendenda=A.new(o)#oisjustanyobjectthatallowso.xb=A.new(o)h={a=>5}ph[a]#5ph[b]#nil,shouldbe5ph[o]#nil,shouldbe5我试过==、===、eq?并散列所有无济于事。

  5. ruby - RSpec - 使用测试替身作为 block 参数 - 2

    我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere

  6. ruby - Sinatra:运行 rspec 测试时记录噪音 - 2

    Sinatra新手;我正在运行一些rspec测试,但在日志中收到了一堆不需要的噪音。如何消除日志中过多的噪音?我仔细检查了环境是否设置为:test,这意味着记录器级别应设置为WARN而不是DEBUG。spec_helper:require"./app"require"sinatra"require"rspec"require"rack/test"require"database_cleaner"require"factory_girl"set:environment,:testFactoryGirl.definition_file_paths=%w{./factories./test/

  7. ruby-on-rails - 迷你测试错误 : "NameError: uninitialized constant" - 2

    我遵循MichaelHartl的“RubyonRails教程:学习Web开发”,并创建了检查用户名和电子邮件长度有效性的测试(名称最多50个字符,电子邮件最多255个字符)。test/helpers/application_helper_test.rb的内容是:require'test_helper'classApplicationHelperTest在运行bundleexecraketest时,所有测试都通过了,但我看到以下消息在最后被标记为错误:ERROR["test_full_title_helper",ApplicationHelperTest,1.820016791]test

  8. ruby - 即使失败也继续进行多主机测试 - 2

    我已经构建了一些serverspec代码来在多个主机上运行一组测试。问题是当任何测试失败时,测试会在当前主机停止。即使测试失败,我也希望它继续在所有主机上运行。Rakefile:namespace:specdotask:all=>hosts.map{|h|'spec:'+h.split('.')[0]}hosts.eachdo|host|begindesc"Runserverspecto#{host}"RSpec::Core::RakeTask.new(host)do|t|ENV['TARGET_HOST']=hostt.pattern="spec/cfengine3/*_spec.r

  9. ruby-on-rails - 如何使辅助方法在 Rails 集成测试中可用? - 2

    我在app/helpers/sessions_helper.rb中有一个帮助程序文件,其中包含一个方法my_preference,它返回当前登录用户的首选项。我想在集成测试中访问该方法。例如,这样我就可以在测试中使用getuser_path(my_preference)。在其他帖子中,我读到这可以通过在测试文件中包含requiresessions_helper来实现,但我仍然收到错误NameError:undefinedlocalvariableormethod'my_preference'.我做错了什么?require'test_helper'require'sessions_hel

  10. ruby - Ruby 中的隐式返回值是怎么回事? - 2

    所以我开始关注ruby​​,很多东西看起来不错,但我对隐式return语句很反感。我理解默认情况下让所有内容返回self或nil但不是语句的最后一个值。对我来说,它看起来非常脆弱(尤其是)如果你正在使用一个不打算返回某些东西的方法(尤其是一个改变状态/破坏性方法的函数!),其他人可能最终依赖于一个返回对方法的目的并不重要,并且有很大的改变机会。隐式返回有什么意义?有没有办法让事情变得更简单?总是有返回以防止隐含返回被认为是好的做法吗?我是不是太担心这个了?附言当人们想要从方法中返回特定的东西时,他们是否经常使用隐式返回,这不是让你组中的其他人更容易破坏彼此的代码吗?当然,记录一切并给出

随机推荐