区块链实质上就是一个分布式系统软件。因此,在质量管理上,系统软件和分布式系统是区块链测试的两个大方向。目前业界主要有公有链、联盟链以及私有链三种模式,不管哪种运转模式,对于区块链这种底层平台软件,测试过程应至少需包含四大块内容,分别为功能、性能、可靠性和安全性,下面从这四个角度讨论区块链平台的一些测试思路。
节点能由管理者操作加入或者退出区块链网络,而不影响业务的正常运行,以及扩容新增节点。长期使用的软件,一般都会迭代更新,区块链节点也应能够进行升级,包括灰度升级能力,升级后业务正常运行。
通常在环境条件正常时,以上连接都能顺利进行,并且通过网络连接命令和日志信息能查询对应结果。
而真正考验连接的健壮性是在异常环境下系统的应对能力,以及环境恢复正常之后,连接能否也恢复正常,而不用去重启进程。
影响连接的因素包括区块链系统本身和外部环境对连接的影响:
我们需要验证的是,这种共识机制能否按预期算法完成从交易触发到数据落盘,以及在容错和容灾范围内依然正常工作。实际上就是在共识的某个阶段遇到问题,它的应对机制是否可行,而不是卡在那或者直接系统崩溃。区块链平台上线前,对其使用的共识算法需要做严格的测试验证,涉及功能、安全、易用性等各方面。
在测试共识算法前,需要清楚共识内部主要流程,才能对每一步骤构造场景进行相应测试。
平台支持的合约语言丰富:通用的solidity合约、预编译合约
合约的使用和管理:
合约的功能点验证(solidity语言):
可以从账户状态和存储介质对区块链的存储进行功能正确性和稳定性测试。可以将账户状态模型和存储介质引擎进行组合测试。
可采用混沌模型测试,各场景进行组合,验证每个节点存储稳定且数据正确,在落盘成功的基础上还要保证节点间数据都一致。
在区块链系统中,兼容性主要考虑两大块,自身兼容和周边兼容。
还需考虑灰度升级的情况,即节点有新老版本共存这种模式下需要测试验证的场景会较多,所有的功能特性在新老节点上都应操作验证一遍。
接口的测试重点在输入稳定输出正确,多关注边界,外部对节点的访问能持续不断连。
接口测试采用自动化是比较简单的,同时模拟接口在一定压力访问下,客户端对节点发送交易,链上共识能否保持正常。
常见的治理方式有数据导出、数据导入、数据裁剪等。
数据裁剪后所有上层业务需保证继续正常运行,包括已部署的合约业务和新部署的合约,都能正常调用,同时节点自身的退网、入网、同步、兼容性等各种特性都不受影响。
被裁剪的数据虽然不在链上,但链上业务运行过程还是可能会用到,因此涉及到这部分数据的测试场景也需要全覆盖验证
对于区块链来说,重点关注的是它处理交易的性能,从客户端发起交易,签名,到节点打包、共识,最后数据落盘,这一完整过程系统的性能。
性能压测可以达到两个目的,一是压出系统的性能,还一个是通过压测发现代码的一些bug,比如cpu、内存等硬件没有发现瓶颈,但是性能确一直上不去,这可能就是代码实现的逻辑有问题了。在性能数据基础上,继续加大交易并发量,就能对系统做进行压力测试,验证其他指标。在性能数据基础上,适当减少交易并发量,也能对系统进行稳定性测试。

对于不同的性能指标,几点思考:
实际中,网络规模越大,需要达成共识的节点越多,达成共识的进度,越慢,吞吐量(TPS)就越低。
区块越大,可扩展性越大,吞吐量可能发生抖动,大概率是变低。
区块链系统涉及的安全包括很多方面,从连接到共识、从算法到隐私保护,都和安全息息相关,安全措施覆盖的越全面,系统被攻击的概率越低,运行更稳健。区块链是由节点组成,而对于非法节点的加入,平台是否提供了证书网络准入机制或者黑白名单特性,解决非法连接和入网问题。链上大量的数据或者各种类型的表,需要提供权限管理机制给不同用户授予不同操作权限,包括部署合约及发送交易。
而对于加密算法,需要考虑能否支持国密算法,以及在隐私保护中,同态加密和群环签名是都具备。落盘数据能否进行加密,而不影响系统的正常运行,包括在多群组中,数据是否隔离等,以上都是作为一个区块链底层平台需要覆盖到的安全措施。
在区块链质量体系的构建过程中,可靠性是最重要的内容之一,需要投入大量的资源去模拟各种可能的场景,完成可靠性验证。
因为区块链是个分布式的系统软件,一个节点的正常不代表整个系统正常。 既然是一个分布式的软件,测试过程也需要融入分布式思想,而不能停留在中心化软件上。某个节点在同步,其他节点可能在共识,包括节点所在机器环境也可能随时发生变化,在场景模拟的过程,需要将软件、硬件以及区块链自身操作进行各种组合验证,称为混沌测试。
常用的混沌测试工具有操作系统自带的iptables、tc、 wondershaper 等,可用于模拟机器间连接、端口是否可用、丢包、带宽控制,或者使用开源工具ChaosBlade也能完成以上模拟,包括cpu、内存等使用率。在结合前面章节讨论的节点连接、共识、同步等特性测试方法,进行各种混合测试。区块链的边界比较模糊,而混沌测试法正是通过模拟的方式,让系统尽可能运行在边界处,就比如PBFT共识算法,四节点的网络,让其中三个正常运行,剩下的一个节点进程停止,比同时让四个节点都正常跑着,进行场景模拟会更容易发现一些边界问题。所有场景模拟过程,可同时进行一些压力测试,保证时刻有交易在链上处理。
参考文献:
区块链如何测试?
区块链如何测试?_zhusongziye的博客-CSDN博客_区块链测试
区块链怎么测试
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当
我有一个围绕一些对象的包装类,我想将这些对象用作散列中的键。包装对象和解包装对象应映射到相同的键。一个简单的例子是这样的: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?并散列所有无济于事。
我有一些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
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/
我遵循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
我已经构建了一些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
我在app/helpers/sessions_helper.rb中有一个帮助程序文件,其中包含一个方法my_preference,它返回当前登录用户的首选项。我想在集成测试中访问该方法。例如,这样我就可以在测试中使用getuser_path(my_preference)。在其他帖子中,我读到这可以通过在测试文件中包含requiresessions_helper来实现,但我仍然收到错误NameError:undefinedlocalvariableormethod'my_preference'.我做错了什么?require'test_helper'require'sessions_hel
只是想确保我理解了事情。据我目前收集到的信息,Cucumber只是一个“包装器”,或者是一种通过将事物分类为功能和步骤来组织测试的好方法,其中实际的单元测试处于步骤阶段。它允许您根据事物的工作方式组织您的测试。对吗? 最佳答案 有点。它是一种组织测试的方式,但不仅如此。它的行为就像最初的Rails集成测试一样,但更易于使用。这里最大的好处是您的session在整个Scenario中保持透明。关于Cucumber的另一件事是您(应该)从使用您的代码的浏览器或客户端的角度进行测试。如果您愿意,您可以使用步骤来构建对象和设置状态,但通常您
我有:When/^(?:|I)follow"([^"]*)"(?:within"([^"]*)")?$/do|link,selector|with_scope(selector)doclick_link(link)endend我打电话的地方:Background:GivenIamanexistingadminuserWhenIfollow"CLIENTS"我的HTML是这样的:CLIENTS我一直收到这个错误:.F-.F--U-----U(::)failedsteps(::)nolinkwithtitle,idortext'CLIENTS'found(Capybara::Element