发布新日志

  • 有效的用例编写规则

    2007-12-05 17:27:20

    1.1 为什么要使用用例

    用例提供了一种用于构建故事的半形式框架;

    在每个用例和所有描述层次中,用例都描述了错误情况的系统需求;

    虽然本质上是一种功能分解技术,但用例已经成为面向对象软件开发的一个流行元素;

    用例提供了可以在其上处理其他项目信息的骨架:

    项目经理根据用例进行估计和发布进度;

    数据及业务规则制定人员可以把自己的需求和所需用例联系起来;

    用户界面设计人员可以进行设计,并将其与相关用例联系起来;

    测试人员可以根据用例中描述的成功和失败情况构建测试场景(测试用例);

    1.2 编写用例容易出现的问题
    用户界面太多,用户界面应属于设计范畴,鼠标、按键等内容不应出现在用例中;
    较低目标层次上的用例太多,无法展示系统将会给其最终用户提供什么功能;
    使用用例表示非行为信息,性能需求、业务规则等不要在用例中描述;
    太冗长,最好在3~9步;
    目标实现不完整,尤其是错误处理;
    句子片断,主、谓、宾尽量完整;
    1.3 为什么使用用例模式语言
    描述了用例的质量标志及其编写过程,提供了能够经受时间考验的用例改进建议;在评审用例初稿和改进其质量的过程中,这个工具能起到很大作用。
    1.4 什么是模式
    模式是质量标志和策略;
    1.5 使用模式语言时错误观念

    模式提供了一个关于其自身和模式内容的完整方法;只起补充作用
    使用模式肯定会成功;
    模式为老问题提供了新的解决方案;只是经常出现的问题的通用可靠方案
    模式适用于所有情况;仅是处于某种上下文中的问题的解决方案
    1.6 模式组织

    模式分类
    子类

    开发模式

    团队组织 :判断和改进用例团队组织方式的质量的模式;

    过程 :判断和改进团队用来创建用例的方法质量的模式;

    编辑 :随着潜在需求的变化和编写人员知识的增加,判断和改进单个用例的质量;

    结构模式

    用例集 :判断和改进用例集质量的模式;

    用例 :判断和改进单个用力质量的模式;

    场景和步骤 :判断和改进用力场景以及这些场景中的步骤质量的模式;

    用例关系 :判断和改进集合中用例之间的结构关系质量的模式;

    1.7 用例的读者和编写者
    有两组不同的认阅读和使用用例:(1)最终用户或业务专家;(2)程序员。
    用例编写组必须包括:
    至少一位具有编程背景的认,以获得描述所要求的准确性和精度;
    至少一位熟知业务规则的认;
    至少一位熟知在实际中如何使用系统的认;
    1.7 用例的读者和编写者

    有两组不同的认阅读和使用用例:(1)最终用户或业务专家;(2)程序员。
    用例编写组必须包括:
    至少一位具有编程背景的认,以获得描述所要求的准确性和精度;
    至少一位熟知业务规则的认;
    至少一位熟知在实际中如何使用系统的认;
    第二章 团队

    2.1 SmallWritingTeam

    原因:
    用例要求具有不同观点和专业知识的人编写;
    将一大组人聚集在一起是困难的;
    理论上,在用例上投入的人越多,就能越快的完成用例编写工作
    大的团队会变得低效;
    大型编写团队可能会通过集体讨论的形式开发用例,添加许多不必要的特性;
    所以:
    一个由2人或3人组成的团队足够小,容易交流和达成一致;

    可以使用几个SmallWritingTeam,但应当制定一位用例设计师,以保证所有用例与愿景一致。
    最终目的是使过程保持在可管理状态,大的团队将在管理上投入更多的精力。
    2.2 ParticipatingAudience
    没有涉众提供的信息和反馈,就不能满足他们的需要;尽可能使客户和内部涉众积极参与用例开发过程。
    2.3 BalancedTeam
    由一些个性相似、意见相同的个人组成的团队开发用例,可能会得到一组缺乏创见、范围狭窄的用例,这种用例不能满足每个人的需要。
    因此,为小组配备具有不同专长的人员,以维护开发过程中涉众的利益,确保团队中包括开发人员和最终用户。
    最大好处是使编写人员在用例中使用常见的、可理解的术语。
    第三章 过程
    编写好的用例是极其个性化的,每个人都有他自己的风格,每个组织都有根据自己的文化和业务需要做事情的方式,因此,没有创建用例的通用过程。

    3.1 BreadthBeforeDepth
    原因:
    需求收集是一个发现过程,用例编写是一个迭代过程;
    人们很早就开始编写用例的细节;
    人们浪费了精力或陷入了太多的细节,通常都会失去重点,无法描述所有可能的扩展条件;

    从早期获得概述是有益的;
    最初编写的细节越多,在了解系统后必须进行的改变也就越多;
    所以:
    通过首先开发用例的概述来保存精力,然后逐步增加细节,并行开发一组相关用例。

    完成概述用例后,随着对系统了解的增多,不断提高用例精度,避免突然开发完所有用例或一次只开发一个用例的倾向。
    3.2 SpiralDevelopment(螺旋式开发)

    原因:
    理解系统的行为可能会花掉大量时间,要求渐进式分析;
    拖延是昂贵的。要尽快完成用例的编写;
    对需求进行分析后,需求很可能会发生变化;
    需求成本的错误是昂贵的;
    所以:
    以一种迭代的,宽度优先的方式开发用例,每次迭代都会提高用例集的准确性和精度。
    基本过程:
    从简单的东西开始,如一个参与者/用例列表;
    简要描述用力主场景,即高层用例,以包含用例的主要范围;
    扩展摘要的子集,并填充细节;
    评审并调整;
    3.3 MultipleForms
    不同的项目需要不同程度的形式化,每个人对模板都有不同的偏好,要求每个人都使用相同的用例模板只会起到相反的作用。
    原因:
    每个人的个性、经验和经受的锻炼不同,每个开发组织都有其特有的人员、历史和文化;
    不同的项目有不同的需要;
    不同的编写团队需要不同程度的规范和严格度;
    在组织中使用公共的编写形式有助于交流;
    在同一个项目上使用不同的模板不是一个好主意;
    因此:根据项目相关的风险性、项目特点,和所涉及到的人员选择用例的编写格式,并在该项目的开发过程中的组织内部使用。
    3.4 TowTireReview(评审)

    许多人都可能需要评审用例,这是一件昂贵耗时的事情。
    原因:
    对于验证和确认编写及内容来说,评审是必要的;
    涉众在用例上有一种既得利益;
    使每个人参与编写过程非常昂贵、麻烦并且缓慢;
    如果仅由一个小的编写组进行评审,就不会考虑所有涉众的利益;
    评审可能是昂贵的、乏味的、耗时的。
    所以:

    进行两种类型的评审:第一种是由较小的内部小组进行的评审,可能要重复进行很多次;第二种是由整个团队进行的评审,可能只进行一次。

    3.5 QuittingTime
    开发一个超出了涉众和开发人员需要的用例模型不仅浪费资源,而且会拖延项目进度。
    原因:
    忽视重要需求的巨大恐惧使构建人员和涉众延长了需求收集活动;
    大多数人可以用一种合理的模糊性工作,即不言自明;
    详细讲述谎言并不能使他们更为精确;
    所以:
    在用例完整并且符合参与者的需要后,停止开发用例;
    用例模型完整性的检验:完整、可读、逻辑上正确、对开发人员足够详细。
    是否识别了所有的参与者和目标并将其编成了文档?
    客户及其代表是否承认用例集是完整的,而且每个用例都是可读的和正确的?
    设计人员是否能够实现这些用例?
    3.6 WriterLicense
    小的格式差别并不重要,解决了所有系统问题后,及时还存在一些格式问题,也可以停止编写;

  • 性能测试及性能调整概述

    2007-12-05 13:28:09

    明确了具体的性能要求后,可以开始进行测试,确定应用程序是否满足这些要求。性能测试假定应用程序稳定、可靠地运行。因此,在测试中消除尽可能多的变数很重要。例如,代码中的错误可以导致出现性能问题,甚至掩盖性能问题。要精确地比较不同性能测试的结果,应用程序必须正确地工作。如果调整过程修改了组件的实现,则重新测试应用程序的功能尤其重要。应用程序必须通过功能性测试后才可以测试性能。除了应用程序更改外,硬件、网络通信量、软件配置、系统服务等诸多方面也会发生意外的更改。控制应用程序更改很重要。

    测量性能

    要正确地调整性能,必须准确完整地记录每次测试的结果并进行维护。记录应包括:

    • 精确的系统配置,尤其是与前几次测试的不同之处
    • 原始数据和性能监视工具计算的结果

    这些记录不仅指示应用程序是否达到性能目标,而且有助于识别未来性能问题的潜在原因。

    性能调整是与性能管理相关的主要活动。当性能降到最基本的水平时,性能调整由查找和消除瓶颈组成,瓶颈是在服务器中的某个硬件或软件接近其容量限制时发生和显示出来的情况。

    在开始性能调整循环之前,必须做一些准备工作,为正在进行的性能调整活动建立框架。您应该:

    • 识别约束 - 站点的业务实例确定优先级,而优先级又设立边界。约束(如可维护性和预算限制)在寻求更高的性能方面是不可改变的因素。必须将寻求性能提高的努力集中在不受约束的因素上。
    • 指定负载 - 这涉及确定站点的客户端需要哪些服务,以及对这些服务的需求程度。用于指定负载的最常用度量标准是客户端数目、客户端思考时间以及负载分布状况;其中客户 端思考时间是指客户端接收到答复到后面提交新请求之间的时间量,负载分布状况包括稳定或波动负载、平均负载和峰值负载。
    • 设置性能目标 - 性能目标必须明确,包括识别用于调整的度量标准及其对应的基准值。总的系统吞吐量和响应时间是用于测量性能的两个常用度量标准。识别性能度量标准后,必须为每个度量标准建立可计量的基准值与合理的基准值。
      注意   由于性能和容量的关系如此密切,因此您识别的约束、负载和目标也适用于容量规划。

    建立了性能调整的边界和期望值后,可以开始调整循环,这是一系列重复的受控性能试验。

    调整循环

    重复以下所示的四个调整循环阶段,直到获得在开始调整过程前建立的性能目标。

    调整循环

    收集

    收集阶段是任何调整操作的起点。在此阶段,只是使用为系统特定部分选择的性能计数器集合来收集数据。这些计数器可用于网络、服务器或后端数据库

    不论调整的是系统的哪一部分,都需要根据基准测量来比较性能改变。需要建立系统空闲以及系统执行特定任务时的系统行为模式。因此,可以使用第一遍数据收集来建立系统行为值的基准集。基准建立在系统的行为令人满意时应该看到的典型计数器值。

    注意   基准性能是一个主观的标准:必须设置适合于工作环境且能最好地反映系统工作负荷和服务需求的基准。

    分析

    收集了调整选定系统部分所需的性能数据后,需要对这些数据进行分析以确定瓶颈。记住,性能数字仅具有指示性,它并不一定就可以确定实际的瓶颈在哪 里,因为一个性能问题可能由多个原因所致。某个系统组件的问题是由另一系统组件的问题导致的,这种情况也很普遍。内存不足是这种情况的最好示例,它表现为 磁盘和处理器使用的增加。

    以下几点来自“Microsoft Windows 2000 资源工具包”,提供了解释计数器值和消除可能导致设置不适当的调整目标值的错误数据或误导数据的指南。

    • 监视名称相同的进程 — 监视某个实例而没有监视另一个实例的异乎寻常大的值。有时,系统监视器将多个实例的组合值报告为单个实例的值,这就错误地报告了同名进程的不同实例的数据。可通过按进程标识符对进程进行跟踪来解决此问题。
    • 监视多个线程 - 当监视多个线程而其中一个线程停止时,一个线程的数据可能似乎被报告成了另一个线程的数据。这是由于线程的编号方式所导致的。可通过将进程线程的线程标识符包含在日志或显示中来解决此问题。为此,请使用“线程/线程 ID”计数器。
    • 数据值中的不连续峰值 - 不必太重视数据中偶尔的峰值。这些峰值可能是由于进程的启动,并不是该进程随时间改变的计数器值的准确反映。尤其是平均计数器可以导致峰值随时间停留的效果。
    • 监视一段延长的时期 - 建议使用图形代替报告或直方图,因为后两种视图仅显示最后的值和平均值。结果,当查找峰值时,可能得不到这些值的准确反映。
    • 排除启动事件 - 除非有特殊的原因需要将启动事件包含在数据中,否则排除这些事件,因为它们产生的临时性高峰值往往歪曲了整体性能结果。
    • 零值或缺少的数据 - 调查所有出现的零值或缺少的数据。这些零值或缺少的数据会妨碍建立有意义的基准。

    配置

    收集了数据并完成结果分析后,可以确定系统的哪部分最适合进行配置更改,然后实现此更改。

    实现更改的最重要规则是:一次仅实现一个配置更改。看起来与单个组件相关的问题可能是由涉及多个组件的瓶颈导致的。因此,分别处理每个问题很重要。如果同时进行多个更改,将不可能准确地评定每次更改的影响。

    测试

    实现了配置更改后,必须完成适当级别的测试,确定更改对调整的系统所产生的影响。在这一点上,这是确定更改是否有如下影响的问题:

    • 性能提高 - 更改提高了性能吗?如果是,提高了多少?
    • 性能下降 - 更改在其他位置导致了瓶颈吗?
    • 对性能没有影响 - 更改对性能到底有何显著的影响?

    如果幸运,性能提高到预期的水平,这时便可以退出。如果不是这样,则必须重新逐步进行调整循环。

    提示   可以从监视日志文件(可导出到 Microsoft Excel)和事件日志中获取测试所产生的监视结果。

    测试时务必要:

    • 检查用于测试的应用程序的正确性和性能,查找内存泄漏和不正常的客户端请求响应延迟。
    • 确保所有测试都正常进行。
    • 确保可以使用相同的事务混合和相同的客户端生成相同的负载来重复所有测试。
    • 文档更改和结果。

    在每遍测试中,运行一系列完全相同的性能测试;否则,无法分辨不同的结果是由于测试中的改动还是应用程序更改造成的。使尽可能多的性能测试操作自动进行有助于消除因操作者造成的差异。

    其他表面上是良性的因素影响性能测试的结果,如应用程序在测试开始前运行的时间。正如冷的汽车引擎与热引擎的性能不同,长时间运行的应用程序由于内存碎片这样的因素,其性能可能与刚启动的应用程序不同。

    定义性能测试

    性 能测试期间,测量和记录性能目标中指定的度量标准值。达到全部性能度量标准(如思考时间、事务混合等)很重要。在这些约束下,测试应尽可能实际。例如,对 应用程序进行测试,确定它在许多客户端同时访问它时的性能。多线程测试应用程序可以用可复制的方式模拟多个客户端,每个线程表示一个客户端。如果应用程序 访问数据库,则数据库应包含实际数目的记录,并且测试应使用数据项的随机(但有效)值。如果测试数据库太小,数据库服务器的缓存效果将产生不符合实际情况 的测试结果。如果输入或访问数据的方式不符合实际情况,则结果也可能不符合实际情况。例如,在主键上按字母顺序创建新数据是不太可能的。

    通常,测试装置必须接受用户指定的输入参数,如事务混合、思考时间、客户端数目等。然而,测试装置本身可以规定创建实际的随机数据的规则。

    创建了驱动应用程序的测试装置后,应该将所有运行测试的不变条件记入文档。最起码,这些条件应包括运行测试装置所需的输入参数。另外,应将如何设置 运行测试的数据库记入文档。说明中应指定数据库不应包含前一遍测试所做的更改。说明中还应指定用于测试的计算机配置。在不同于应用程序所在的另一台计算机 上运行测试装置,因为这样设置更接近生产环境。

    确定基准性能

    确定了性能目标并制定了性能测试后,运行一次测试以建立基准。验证环境与生产环境越相似,应用程序部署后的性能令人满意的可能性就越大。因此,一开始有一个符合实际情况的验证环境很重要。

    幸运的话,基准性能将符合性能目标,并且应用程序不需要任何调整。但更可能的情况是,基准性能不令人满意。然而,记录初始测试环境和基准结果可以为调整工作提供坚实的基础。

    压力测试

    压 力测试是性能测试的一种专门形式,它与其他工程领域的破坏性测试相似。压力测试的目的是使应用程序产生故障,通过增加处理负载使其超过性能的降低,直到由 于资源饱和或发生错误而使应用程序开始出问题。压力测试有助于揭示细微的错误,这些错误本来要到部署应用程序时才会被发现。由于此类错误通常是因设计缺陷 所致,压力测试应该早在开发阶段便在应用程序的每个区域上开始进行。在其源头修复这些细微的错误,而不是忽视这些错误,直到它们可能在应用程序中的其他位 置表现出症状时才修复它们。

    解决性能问题

    通常可将性能问题归结于不止一个因素。因此,查找性能恶化的解决方案与进行科学实验极为相似。科学实验传统上遵循一个分六步进行的过程,包括观察、初步假设、预测、测试、控制和结论。结论由该过程积累的最佳证据集合所支持的假设组成。可以遵循同样的过程来解决性能问题。

    当观察到 ASP 应用程序的性能比期望的低时,您假定 ASPProcessorThreadMax 元数据库属性设置得太低。当“ASP 排队请求”性能计数器上下移动,并且处理器的运行效率低于 50% 时,可能会发生这种情况。您预测增加 ASPProcessorThreadMax 元数据库属性的数值可以提高性能。

    活动线程设置现在已经变成控件。一次仅进行一个设置更改,直到观察到满意的性能改变。如果在几次调整 ASPProcessorThreadMax 元数据库属性之后获得了更令人满意的性能,则结论是某个属性设置与所有当前变量(所需内存的总量、正在运行的应用程序数、已升级的软件等)组合,可提供最 佳服务器性能。变量中的任何更改就会形成进一步的实验。

  • 性能测试之场景设计思想

    2007-12-05 10:22:17

     前段时间有幸收到珠海X公司性能题目,呵呵,以下是对公司产品性能测试的总结。个人认为有关性能测试场景问题,其实更佳着重于对性能测试目的考究。

      验证测试是用于验证在特定的场景、时间、压力、环境和操作方式下系统能够正常的运行,服务器、应用系统和网络环境等软硬件设施还能否良好的支撑这些情况下用户的使用。验证性测试主要针对有明确的压力目标和预期结果,验证系统在这种压力下的各方面反映能够达到预期结果。

      主要分以下几种:

      压力测试:已知系统高峰期使用人数,验证各事务在最大并发数(通过高峰期人数换算)下事务响应时间能够达到客户要求。系统各性能指标在这种压力下是否还在正常数值之内。系统是否会因这样的压力导致不良反应(如:宕机、应用异常中止等)。

      Ramp Up 增量设计:如并发用户为75人,系统注册用户为1500人,以5%-7%作为并发用户参考值。一般以每15s加载5人的方式进行增压设计,该数值主要参考测试加压机性能,建议Run几次。以事务通过率与错误率衡量实际加载方式。

      Ramp Up增量设计目标: 寻找已增量方式加压系统性能瓶颈位置,抓住出现的性能拐点时机,一般常用参考Hits点击率与吞吐量、CPU、内存使用情况综合判断。模拟高峰期使用人数,如早晨的登录,下班后的退出,工资发送时的消息系统等。

      另一种极限模拟方式,可视为在峰值压力情况下同时点击事务操作的系统极限操作指标。 加压方式不变,在各脚本事务点中设置同集合点名称(如:lr_rendzvous("same");)在场景设计中,使用事务点集合策略。以同时达到集合 点百分率为标准,同时释放所有正在Run的Vuser。

       稳定性测试:已知系统高峰期使用人数、各事务 操作频率等。设计综合测试场景,测试时将每个场景按照一定人数比率一起运行,模拟用户使用数年的情况。并监控在测试中,系统各性能指标在这种压力下是否能 保持正常数值。事务响应时间是否会出现波动或随测试时间增涨而增加。系统是否会在测试期间内发生如宕机、应用中止等异常情况。

      根据上述测试中,各事务条件下出现性能拐点的位置,已确定稳定性测试并发用户人数。仍然根据实际测试服务器(加压机、应用服务器、数据服务器三方性能),估算最终并发用户人数。

      场景设计思想:从稳定性测试场景的设计意义,应分多种情况考虑:

      针对同一个场景为例,以下以公文附件上传为例简要分析场景设计思想:

      1)场景一:已压力测试环境下性能拐点的并发用户为设计测试场景,目的验证极限压力情况下测试服务器各性能指标。

      2)场景二:根据压力测试环境中CPU、内存等指标选取服务器所能承受最大压力的50%来确定并发用户数。

      测试方法:采用1)Ramp Up-Load all Vusers simultaneously

      2)Duration-Run Indefinitely

      3)在Sechedule-勾选Initalize all Vusers before Run

       容错性测试:通过模拟一些非正常情况(如:服 务器突然断电、网络时断时续、服务器硬盘空间不足等),验证系统在发生这些情况时是否能够有自动处理机制以保障系统的正常运行或恢复运行措施。如有HA (自动容灾系统),还可以专门针对这些自动保护系统进行另外的测试。验证其能否有效触发保护措施。

       问题排除性测试:通过原有案例或经验判断,针对系统中曾经发生问题或怀疑存在隐患的模块进行验证测试。验证这些模块是否还会发生同样的性能问题。如:上传附件模块的内存泄露问题、地址本模块优化、开启Tivoli性能监控对OA系统性能的影响等等。

      测评测试是用于获取系统的关键性能指标点,而进行的相关测试。主要是针对预先没有明确的预期测试结果,而是要通过测试获取在特定压力场景下的性能指标(如:事务响应时间、最大并发用户数等)。

       评测事务交易时间:为获取某事务在特定压力下的响应时间而进行的测试活动。通过模拟已知客户高峰期的各压力值或预期所能承受的压力值,获取事务在这种压力下的响应时间。

       评测事务最大并发用户数:为获取某事务在特定系统环境下所能承受的最大并发用户数而进行的测试活动。通过模拟真实环境或直接采用真实环境,评测在这种环境下事务所能承受的最大并发用户数。判定标准阈值需预先定义(如响应时间,CPU占用率,内存占用率,已出现点击率峰值,已出现吞吐量峰值等)。

       评测系统最大并发用户数:为获取整个系统所能 够承受的最大并发用户数而进行的的测试活动。通过预先分析项目各主要模块的使用比率和频率,定义各事务在综合场景中所占的比率,以比率方式分配各事务并发 用户数。模拟真实环境或直接采用真实环境,评测在这种环境下系统所能承受的最大并发用户数。判定标准阀值预先定义(如响应时间,CPU占用率,内存占用 率,已出现点击率峰值,已出现吞吐量峰值等)。取值标准以木桶法则为准(并发数最小的事务为整个系统的并发数)。

       评测不同数据库数据量对性能的影响:针对不同数据库数据量的测试,将测试结果进行对比,分析发现数据库中各表的数据量对事务性能的影响。得以预先判断系统长时间运行后,或某些模块客户要求数据量较大时可能存在的隐患。

      问题定位测试在通过以上测试或用户实际操作已经发现系统中的性能问题或怀疑已存在性能问题。需通过响应的测试场景重现问题或定义问题。如有可能,可以直接找出引起性能问题所在的代码或模块。

      该类测试主要还是通过测试出问题的脚本场景,并可以增加发现和检测的工具,如开启Tivoli性能监控、开启HeapDump输出、Linux资源监控命令等。并在场景运行过程中辅以手工测试

  • web 性能测试小结

    2007-12-05 10:10:35

    PHP site:
    PHP 的性能,和PHP 优化(Zend Optimizer),加速(Zend Engine v2.1.0)有很大影响.
    对Moodle 进行压力测试, 没有加速下, 10 并发(No thinking time),CPU 占用就开始增加到 95%, 到100 并发, 响应时间接近10s.
    加速后, 100 并发,响应时间在几百毫秒.CPU 状况良好.
     
    性能的关键影响要素:
    1. 干净的环境
       性能测试对机器性能有一定要求, 且没有其他应用, 以免引起干扰. 对CPU, Memory的监控比较准确.
    2. 启动方式
       瞬间启动和逐步启动, 是有区别的, 为了数据更准确, 应该采用逐步加压的方式. 比如我们用JMeter 做性能测试, 100 个线程, ramp up period是在一秒内启动,还是100秒内启动? 大多数情况下, 我们是100秒来启动, 数据更接近真实.
    3. 思考时间
       人工操作, 大概的延时在2秒左右. 做性能测试时, 思考时间的不同设置,对结果有很大影响. 为了测试数据更接近真实情况,我们通常会设置思考时间, 该时间的设置和应用有关, 如果网站本身业务简单, 响应非常快, 人的习惯是点击速度也会加快, 而本来响应较慢的情况下,做下个动作的间隔,也会相应增加, 可以设置的长一点. 我们通常会设置1~2 秒.
    4. 测试脚本
       一个网站有很多页面, 采取哪些页面来做压力测试呢? 抽取benchmark,  也就是抽取用户操作的主要动作, 形成脚本. 可以选择几大业务主线, 进行录制. 然后再做整理, 删除一些零散页面.
    5. 测试时间
       压力测试进入稳定期, 通常需要一定的时间, 因此不应少于半小时. 持续两小时为佳.
    6. 测试记录
       测试开始就要做好记录准备, 需要观察哪些信息? 比如CPU 到80%以上, 响应时间超出2s,错误率超出5%, 就已经基本到达极限, 再测下去的意义不大.
    比较简单的案例, 后面用Loadrunner 再做个测试分析.
  • QTP识别和操作对象的原理(转)

    2007-12-04 15:58:40

    一、QTP识别对象的原理(by yabest, http://yabest.net

    QTP里的对象有两个概念,一个是Test Object(简称TO),一个是Runtime Object(简称RO)。
    这两个概念从字面上不大好理解,也容易混淆。
    但从实际作用上来看,应该说TO就是是仓库文件里定义的仓库对象,RO是被测试软件的实际对象。

    QTP识别对象,一般是要求先在对象仓库文件里定义仓库对象,里面存有实际对象的特征属性的值。
    然后在运行的时候,QTP会根据脚本里的对象名字,在对象仓库里找到对应的仓库对象,
    接着根据仓库对象的特征属性描述,在被测试软件里搜索找到相匹配的实际对象,最后就可以对实际对象进行操作了。

    仓库对象TO一般在录制/编写脚本时加入仓库文件,它不仅可以在录制编写时进行修改,
    也可以在运行过程中进行动态修改,以匹配实际对象。

    和TO、RO相关的几个函数有:

    GetTOProperty():取得仓库对象的某个属性的值
    GetTOProperties():取得仓库对象的所有属性的值
    SetTOProperty():设置仓库对象的某个属性的值

    GetROProperty():取得实际对象的某个属性的值


    理解了TO的含义,你就可以自由的用SetTOProperty()定义TO,以灵活的操作RO

    比如有个测试任务,窗口上有很多待检查的记录,每条记录右边都有一个Check按钮,用来检查各条记录。
    记录个数不定,所以Check按钮个数也就不定,只有一个Edit显示记录个数。
    我们要对每条记录进行检查,也就是要点击每个Check按钮。
    但是Check按钮个数不定,不好录制,而且个数可能也很多(上百个),即使能一一录制,那也很麻烦。

    那我有一个好办法,只录制一个按钮对象,它设有两个特征属性 label=OK, index=0
    然后用下面的脚本,就可以完成测试

    buttonNum = CInt(JavaWindow("Test").JavaEdit("Record Num").GetROProperty("value"))
    For buttonIndex = 0 to buttonNum - 1
      JavaWindow("Test").JavaButton("Check").SetTOProperty("index", buttonIndex)
      JavaWindow("Test").JavaButton("Check").Click
    Next


    或者窗口上有New、Modify、Delete、Check等好几个按钮,要把这几个按钮一一按过去
    我在对象仓库里只设置一个按钮对象AnyButton,label特征属性值填任意值,然后用下面脚本执行测试

    JavaWindow("Test").JavaButton("AnyButton").SetTOProperty("label", "New")
    JavaWindow("Test").JavaButton("AnyButton").Click

    JavaWindow("Test").JavaButton("AnyButton").SetTOProperty("label", "Modify")
    JavaWindow("Test").JavaButton("AnyButton").Click

    JavaWindow("Test").JavaButton("AnyButton").SetTOProperty("label", "Delete")
    JavaWindow("Test").JavaButton("AnyButton").Click

    JavaWindow("Test").JavaButton("AnyButton").SetTOProperty("label", "Check")
    JavaWindow("Test").JavaButton("AnyButton").Click

    另外,QTP还支持脚本描述的方法来定义和访问对象,即不需要在仓库里定义,也能访问和操作实际对象
    ( Written by yabest,http://yabest.net

    如上面两个任务,可以如下实现

    1. 不需要在仓库里定义Check按钮对象,直接用下面脚本来实现测试

    buttonNum = CInt(JavaWindow("Test").JavaEdit("Record Num").GetROProperty("value"))
    For buttonIndex = 0 to buttonNum - 1
      JavaWindow("Test").JavaButton("label:=Check", "index:="+CStr(buttonIndex)).Click
    Next

    2. 不需要在仓库里定义New、Modify、Delete、Check按钮对象,直接用下面脚本来实现测试

    JavaWindow("Test").JavaButton("label:=New").Click
    JavaWindow("Test").JavaButton("label:=Modify").Click
    JavaWindow("Test").JavaButton("label:=Delete").Click
    JavaWindow("Test").JavaButton("label:=Check").Click



    二、QTP操作对象的原理(by yabest, http://yabest.net

    QTP为用户提供了两种操作对象的接口,一种就是对象的封装接口,另一种是对象的自身接口。

    对象的自身接口是对象控件本身的接口,只要做过软件开发,使用过控件的人应该很清楚。
    对象的封装接口是QTP为对象封装的另一层接口,它是QTP通过调用对象的自身接口来实现的。


    两种接口的脚本书写格式的差别在于:
      自身接口需要在对象名后面加object再加属性名或方法名,
      封装接口就不用在对象名后面加object。

    具体格式如下:
      对实际对象的操作:
          对象.object.自身属性
          对象.object.自身方法()
          对象.GetROProperty("封装属性")
          对象.封装方法()

      对仓库对象的操作:
          对象.GetTOProperty("封装属性")
          对象.GetTOProperties()      ’获取所有封装属性的值
          对象.SetTOProperty("封装属性", "封装属性值")

    比如操作JavaEdit对象,通过QTP封装的封装接口,脚本如下:
      设置JavaEdit的内容:
         JavaDialog("Add NE").JavaEdit("NE Name").Set "NE1"
      读取JavaEdit的内容:
         msgbox JavaDialog("Add NE").JavaEdit("NE Name").GetROProperty("value")

    如果通过JavaEdit的自身接口,脚本如下:
      设置JavaEdit的内容:
         JavaDialog("Add NE").JavaEdit("NE Name").object.setText("NE1")
      读取JavaEdit的内容:
         Msgbox JavaDialog("Add NE").JavaEdit("NE Name").object.getText()

    QTP执行JavaEdit().Set语句时,是通过执行JavaEdit().object.setText()来实现的。
    QTP执行JavaEdit().GetROProperty("value"),是通过执行JavaEdit().object.getText()来实现的。
    JavaEdit对象的封装接口Set()和GetROProperty("value"),是QTP封装JavaEdit对象的自身接口setText()和getText()而得来的。

    对象的封装接口是QTP使用的缺省接口,我们录制出来的脚本都是使用封装接口,大家用的也都是封装接口。
    但是封装接口不如自身接口丰富,因为QTP只是封装了部分常用的自身接口嘛。
    所以我们在需要时,可以绕过封装接口,直接调用对象的自身接口。
    不过有些自身接口不够稳定,在实践中偶尔会出现问题,但是概率很少。
    封装接口有相应功能的话,就尽量用封装接口吧!
    ( Written by yabest,http://yabest.net

    理解了封装接口和自身接口的原理,我们就可以更加灵活的操作对象了。

    但是我们怎么知道对象都有哪些封装接口和自身接口呢?
    其实很简单,用对象查看器(Object Spy)查看对象,在查看窗口里有列出这些接口,包括属性和方法。
    窗口中间有选择栏让你选择Run-time Object或者Test Object,
    当你选择Runtime Object时,它显示的就是对象的自身接口(自身的属性和方法)
    当你选择Test Object时,它显示的就是对象的封装接口(封装的属性和方法)

    (注意:GetROProperty访问的是实际对象的封装接口,GetTOProperty访问的是仓库对象的封装接口,
                两者访问的都是对象的封装接口,即Object Spy窗口里选Test Object时显示的属性。
                不要以为GetROProperty访问的是自身接口,即Object Spy窗口里选Run-time Object时显示的属性。
                QTP里的Test Object/Run-time Object的概念太容易让人混淆了!
                它既用来区分仓库对象和实际对象,又用来区分对象的封装接口和自身接口。



    明白了这些,你还等什么呢?快拿起对象查看器,看看对象都有哪些封装接口和自身接口,肆意的操作它,玩弄它吧!

    比如执行
      JavaDialog("Add NE").JavaEdit("NE Name").object.setVisible(false)
    哈哈,你的JavaEdit对象就当场消失不见了!!!

    你可以拿这个做恶作剧,指着这个窗口逼问开发人员,JavaEdit对象哪去了?
    开发人员肯定瞪大眼睛看着这个窗口,当场翘掉!!!sdlkfj3
  • web测试之url测试

    2007-12-04 15:32:03

    我们平时在对url进行测试的时候可能不知道采用什么方法测试,可能点点链接指定页面出现就ok了,其实这个是远远不够的,我说说我平时测试常用的一些方法,供大家参考。当然也欢迎大家说大家的一些测试的方法加以补充,将url测试尽可能覆盖全。

    1.修改url中的get参数
            要对url进行测试首先要对url的组成搞成明白,正所谓知己知彼方能百战不殆,废话少说,比如一下url http://www.javathinker.org/main.jsp?bc=showessay.jsp&id=703 
            前面部分我就不用多解释了,做web的人应该都知道其含义,我就说说?后面的部分,其实这部分是客户端向服务器请求的参数,一般get请求会将参数放在 url中,这时我们就必须注意了,我们试图修改这些参数看能否从服务获得相应的内容,如果服务端没有做相应的处理,用户可能就会通过该方式获得一些其他用户的保密信息(这算是所谓的安全性测试吗?哈哈);
           
    2.是否存在孤立的页面,这个测试可使用一些辅助的工具,比如:Link checker等;
           
    3.链接是否能到达指定的页面,这个测试属于最基本的测试,这个主要注意:点击链接在本页面打开,点击在新页面打开(比如页面主流程中的帮助链接,点击後就应该在新页面打开而不会影响当前的操作流程);
           
    4.涉及到一些安全性选择的登录还要在url中校验http和https协议请求是否正常;
           
    5.涉及到埋点等功能的url测试,还要注意点击的方式,比如单击,右键打开,直接输入url等方式请求(有些js处理的时候可能仅仅调用onclick事件)
           
    6.错误url请求页面的出错页面校验,比如url参数错误是否会给用户一个比较友好的错误提示页面等。
  • 需求测试的checklist文件(转)

    2007-12-04 13:49:37

    序号

    内容

    满足/正确

    问题

    描述

    1

    是否描述系统的所有输入,包括输入源、准确性、取值范围和出现频率?

     

     

    2

    是否描述系统的所有输出,包括输出的目标、准确性、取值范围、出现频率和格式?

     

     

    3

    是否描述所有(主要)的报表格式?

     

     

    4

    是否描述所有硬件和软件的外部接口?

     

     

    5

    是否描述所有的通信接口,包括握手协议、差错检测和通信协议?

     

     

    6

    从用户的角度来看,是否描述了对所有必要操作的预计响应时间?

     

     

    7

    是否对时间方面问题进行考虑,如处理时间、数据传输和系统的吞吐量?

     

     

    8

    是否描述用户想要完成的所有(主要)任务?

     

     

    9

    是否每个任务都描述了所使用的数据及产生的数据?

     

     

    10

    是否描述了安全级别?

     

     

    11

    是否描述了系统的可靠性,包括软件产生故障的后果、故障后重要数据的保护、错误检测和恢复?

     

     

    12

    是否描述了可接受的折中原则,如健壮性和正确性之间的选择?

     

     

    13

    是否详细说明了(最大)内存容量河(最大)存储容量?

     

     

    14

    是否详细说明了(最大)存储容量?

     

     

    15

    是否详细说明了系统的可维护性,包括适应操作环境变化的能力、与其它软件的接口、精确性、性能和附加的可以预知的性能?

     

     

    16

    有些信息只有到开发时才能获得,是否对这些信息不完全的领域进行描述?

     

     

    17

    你是否对需求的某些部分感到不满意?是否有些部分不可能实现,但为了取悦客户或上司而放在需求之中?

     

     

    18

    是否用用户语言,站在用户角度上来写需求?用户这样认为吗?

     

     

    19

    是否所有的需求都避免与其它的需求发生冲突?

     

     

    20

    需求是否避免了对设计的详细说明?

     

     

    21

    对需求的描述是否一致?是否有的需求说明很详细,有的需求说明很粗?

     

     

    22

    需求是否足够清晰,以至可以转交给一个独立小组来实现,并能够被理解?

     

     

    23

    每个条款都是描述问题及解决问题吗?每个条款都能被追溯到问题的源泉?

     

     

    24

    每个需求是可测试的吗?是否可以通过独立的测试来决定需求是否被满足?

     

     

    25

    对需求的变更描述是否包括变更发生的可能性?

     

     

  • 软件测试常用的功能测试方法

    2007-12-03 14:36:39

    功能测试就是对产品的各功能进行验证,根据功能测试用例,逐项测试,检查产品是否达到用户要求的功能。针对Web系统的常用测试方法如下:

      1. 页面链接检查:每一个链接是否都有对应的页面,并且页面之间切换正确。

      2. 相关性检查:删除/增加一项会不会对其他项产生影响,如果产生影响,这些影响是否都正确。

      3. 检查按钮的功能是否正确:如update、cancel、delete、save等功能是否正确。

      4. 字符串长度检查:输入超出需求所说明的字符串长度的内容,看系统是否检查字符串长度,会不会出错。

      5. 字符类型检查:在应该输入指定类型的内容的地方输入其他类型的内容(如在应该输入整型的地方输入其他字符类型),看系统是否检查字符类型,会否报错。

      6. 标点符号检查:输入内容包括各种标点符号,特别是空格、各种引号、回车键。看系统处理是否正确。

      7. 中文字符处理:在可以输入中文的系统输入中文,看会否出现乱码或出错。

      8. 检查带出信息的完整性:在查看信息和update信息时,查看所填写的信息是不是全部带出,带出信息和添加的是否一致。

      9. 信息重复:在一些需要命名,且名字应该唯一的信息输入重复的名字或ID,看系统有没有处理,会否报错,重名包括是否区分大小写,以及在输入内容的前后输入空格,系统是否作出正确处理。
          
           10. 检查删除功能:在一些可以一次删除多个信息的地方,不选择任何信息,按”delete”,看系统如何处理,会否出错;然后选择一个和多个信息,进行删除,看是否正确处理。

      11. 检查添加和修改是否一致:检查添加和修改信息的要求是否一致,例如添加要求必填的项,修改也应该必填;添加规定为整型的项,修改也必须为整型。

      12. 检查修改重名:修改时把不能重名的项改为已存在的内容,看会否处理,报错。同时,也要注意,会不会报和自己重名的错。

      13. 重复提交表单:一条已经成功提交的纪录,back后再提交,看看系统是否做了处理。

      14. 检查多次使用back键的情况:在有back的地方,back,回到原来页面,再back,重复多次,看会否出错。

      15. search检查:在有search功能的地方输入系统存在和不存在的内容,看search结果是否正确。如果可以输入多个search条件,可以同时添加合理和不合理的条件,看系统处理是否正确。

      16. 输入信息位置:注意在光标停留的地方输入信息时,光标和所输入的信息会否跳到别的地方。

      17. 上传下载文件检查:上传下载文件的功能是否实现,上传文件是否能打开。对上传文件的格式有何规定,系统是否有解释信息,并检查系统是否能够做到。

      18. 必填项检查:应该填写的项没有填写时系统是否都做了处理,对必填项是否有提示信息,如在必填项前加*

      19. 快捷键检查:是否支持常用快捷键,如Ctrl+C Ctrl+V Backspace等,对一些不允许输入信息的字段,如选人,选日期对快捷方式是否也做了限制。

      20. 回车键检查:在输入结束后直接按回车键,看系统处理如何,会否报错。
  • 10大负面测试用例

    2007-12-03 14:23:06

    当前位置: 首页» 测试技术» 测试用例设计» 10大负面测试用例
    文章出处:blog.csdn.net / 作者: / 发布时间:2007-11-02 / 阅读次数:75次
    负面测试(Negative testing)是相对于正面测试(Positive testing)而言的。它们也是测试设计时的两个非常重要的划分。简单点说,正面测试就是测试系统是否完成了它应该完成的工作;而负面测试就是测试系统是否不执行它不应该完成的操作。形象一点,正面测试就象一个毕恭毕敬的小学生,老师叫我做什么,我就做什么;而负面测试就象一个调皮捣蛋的孩子,你叫我这样做,我偏不这样做,而且和你对着干。开发人员也是最讨厌修改此类bug的。
    正面测试主要根据需求,功能说明书,设计文档等相关参考文档来执行测试,而负面测试则主要根据错误猜测,逆向思维来测试系统,一定程序上的的依赖测试人员的经验积累。
    执行负面测试时,不单单要测试系统是否处理了用户的异常操作,还要检查系统对于这些异常操作是否给予了正确的错误提示。它是系统对用户进行继续正确操作的指引。
    简言之负面测试的三部曲就是:
    1. 检查程序中的屏幕或页面是否给出了清晰且充分的提示或约束;
    2. 测试系统是否处理了用户的异常操作;
    3. 检查系统的错误提示是否清晰且充分。
     
     
    负面测试用例被设计于用软件未意欲被使用的方式测试软件,它也应该是测试工作的一部分。以下就是在设计测试工作量时你应该考虑的10大负面测试用例。
    1.植入的单引号。大多数基于SQL的数据库系统在用户存储包含一个单引号的信息时会出现问题,例如John's car。每一个可以接受文字数字型数据条目的屏幕都要试试输入包含一个或多个单引号的文本。
    Kiki补充】其实不只是单引号,基本上测试人员应该测试所有的特殊字符和空/空格(单纯的空格和文本前后的空格)。单引号,逗号,/<>(对于web的应用程序)都是很容易引发错误的。在开发早期测试组就可以建议开发组写一个通用的函数来处理这些特殊字符,然后在处理用户的输入时套用这个函数就可以避免此类错误了。
     
    2.必需输入的数据条目。功能说明书上应该清楚的指出屏幕上必须输入数据条目的字段。测试屏幕上每一个被说明为必须输入的字段以保证它强制要求你在字段中输入数据。
    Kiki补充】对于强制输入的字段,在屏幕上最好有些标识以说明其为必须输入的字段。一般在字段前或后用红色的*号表示。测试时必须要检查有标识的字段是否和功能说明书或其他参考文档一致,错误信息提示是否正确,强制输入的字段是否真的必须输入。
     
    3.字段类型测试。功能说明书上应该清楚的指出要求特定数据输入要求(日期字段,数字字段,电话号码,邮编等等)的字段。测试屏幕上每一个被指出有特定类型的字段以保证你输入了基于字段类型的符合正确格式的数据(数字型字段应该不允许字符或特殊字符,日期型的字段应该允许输入一个正确的日期等等)
    Kiki补充】其实这里还有一个字段格式和字段内容的测试。有些字段对输入的格式有要求,这些字段的格式一般在屏幕上也有相应的提示。所以在测试时需要测试提示的格式是否合理(和功能说明书或其他参考文档相一致)以及系统是否正确识别输入的格式。有些字段对字段的内容有限制,如常见的用户名,不能包含特殊字符,首字不能未数字等要求。所以在测试时需要测试提示的格式是否合理(和功能说明书或其他参考文档相一致)还有不符合内容要求的数据输入时系统是否正确的处理。
     
    4.字段长度测试。功能说明书上应该清楚的指出可以在字段中输入的字符数(例如,first name必须是50个或更少的字符)。写测试用例以保证你只可以输入特定的字符数。防止用户输入比允许范围更多的字符比因用户已输入过多的字符而给出的错误信息更加的文雅些。
    Kiki补充】一般对于限制长度的字段,现在开发大多采用限制输入的方法(设置字段的长度)来处理。所以测试时需要测试限制的长度是否合理(和功能说明书或其他参考文档相一致),对于没有限制长度的字段,要测试无穷输入时是否出错,有问题报bug时建议开发人员根据需要限制长度。
     
    5.数字型的边界测试对于数字型的字段,测试上下边界是非常重要的。例如,如果你正在计算某个账户的利息时,你永远不会输入一个负的利息数给应该赢取利息的账户。因此,你应该尝试用负数测试。同样,如果功能说明书上要求字段在某一个特定的范围(如从10~50),你就应该尝试输入9或51,它应该给出一个得体的信息表示失败。
     
    6.数字的约束测试。大多数数据库系统和编程语言允许数字条目被识别为整数或长整数。通常,整数的范围是从-32,767~32,767,长整数的范围从-2,147,483,648~2,147,483,647。对于那些没有特定边界限制的数字数据条目,用这些限制测试以确保不会出现数字的溢出错误。
    Kiki补充】小数型的数字字段同样也需要格外的测试。一般对于未指出数字类型的字段,尝试输入负整数,负小数,0,正整数,正小数进行测试。
    不管是哪种数据库系统,对于数字一般都有多种数字类型。所以测试人员一定要测试的全面。
     
    7.日期边界测试。对于日期型的字段,测试上下边界是很重要的。例如,如果你正在检查一个出生日期的字段,很大可能出生日期不能早于150年前。同样,出生日期应该不是将来的某一天。
    Kiki补充】一般来说,每种数据库系统的日期都有个范围,如SQL Server最小日期是175311日,所以如果是输入型的日期字段同样也应该测试早于1753的日期。
     
    8。日期的有效性。对于日期字段,确保不允许无效的日期是很重要的(04/31/2007是一个无效的日期)。测试用例也应该检查闰年(每个第4年和第400年是一个闰年)。
     
    9。web会话测试。很多的web应用程序依赖浏览器的会话来追踪已登录的用户,应用程序的设置等等。应用程序的大多数屏幕不被设计为没有首次登录就可以被运行。应用程序应该确保在打开应用程序的某一页面之前会话里有一个有效的登录。
     
    10.性能的改变。当发布产品的最新版本时,应该有一套运行于识别屏幕(列出信息的屏幕,add/update/delete数据的屏幕等等)速度的性能测试。测试包里应该包括比较先前版本和现有版本性能统计值的测试用例。这个可以帮助识别那些可以证明是随着对现有版本的代码变更而引起的潜在的性能问题。
     
    Kiki补充】从第一条到第八条是我们在测试字段时常常需要做的测试,一般的测试人员都不陌生。第九条在测试web应用程序中会作为检查应用程序的安全性而做的一项测试。而第十条估计很多公司都不会将它考虑到测试的范畴中,一般最多也就是在测试用例中添加校验某一个操作是否在系统允许的响应时间里,很少去做这样的比较,除了一些有针对性的性能测试。
  • QTP基础代码

    2007-12-03 14:14:15

    文章出处:51testing论坛 / 作者:未知 / 发布时间:2006-07-26 / 阅读次数:1363次

           这两周我开始学习QTP测试我们的web服务了;大体的软件使用操作流程是懂了,但具体实施起来特别是代码的组织及函数应用还有一些困难,因为自己只会vb没学习vbscrīpt,所以想和大家交流一下代码等一些基础知识;呵呵,一起学习,加强记忆与应用。

     

    1 生产随机数列
    第一种方法
    randomize'更新反回的数据
    funcation rand(k,n)
    n="int((k-1)*rnd+1) rand=n
    end funcation
    第二种方法
    n="randomnumber.value(1,255)

    2  当运行到表中的某一行,自动导出表中的所有数据
    row=datatable.getcurrentrow
    if row="5" then
      datatable.export("d:\data.xml")
    end if

     

    3 参数化密码
    webedit("txtpass").setsecure"sdsdf...."
    如果参数化密码,可以直接在数据表中写入未加密的密码,它会自动识别,即不用把setsecure改为set

     

    4 如果弹出对话框就获取上面提示信息并与表中的信息对比,不统一证明弹出的提示出错,主要用来验证
    if browser("web_name").dialog("dialog_name").exist(1) then'如果不出现="false     error_message=browser("web_name").dialog("diaglog_name").static("用户密码错误!".getRoproperty("text")
       if error_message<>(datatable.value("error_info"))then
             msgbox(error_message)
          end if
         browser("web_name").dialog("diaglog_name").close
      end if
    这里我总结了两点技巧:
      一是:对于dialog中,虽然提示信息对象名称是"用户密码错误",但如果信息对象名称是“该用户不存在”,不用更改会自动识别,我想主要是录制第一遍时,“用户密码错误”只是让运行时能找到这个控制,而不管它是什么内容,因为在对象仓库中,text不是决定该对象的属性
         二是:如果对于提示信息比较长的,可以用mid(error_message,n,m)取一部份特征提示信息进行验证,这样我想可以节省处理时间,又可以避免长度以及空格等字符的处理

     

    5  datatable.value("num")只在global形式下的一种省略形式;完整形式是:
    datatable.value("num",dtlocalsheet)
    -----向某一列的单元格赋值:
    datatable.value("column_name",dtlocalsheet)="nanjing"
    -----取得某一行具体值:
    datatable.setcurrentrow(n)
    msgbox(datatable.getsheet("global").getparameter("column_name").Rawvalue)
    或者kk=datatable.Rawvalue("column_name","action1")
    ----在run-time时,动态添加表格与数据
    kk=datatable.addsheet("sheet_name").addparameter("column_name","value").name;

     

    7   wintreeview一些操作
    选择一个条目:wintreeview.select(item)'根是0
    根的名称:wintreeview.getitem(0)

     

    8   数据库检查点模块:
    sub database_check
    set con="createobject(""adodb.connection")
    con.open "Descrīption="IBM_ODBC;DRIVER=SQL" Server;SERVER="IBM;UID=sa;""&_
                     "PWD="123456;APP=Quick" Test Pro;WSID="IBM;DATABASE=IBM_table""
    'access方式:con.open "DRIVER="{Microsoft" Access Driver (*.mdb)};DBQ="d:\test.mdb""
    'Orocle方式:con.open "DRIVER="{Oracle" in OraHome92};SERVER="CESHI;UID=CND_TEST;PWD=CND;DBQ=CESHI;DBA=W;APA=T;

    EXC=F;XSM=Default;FEN=T;QTO=T;FRC=10;FDL=10;LOB=T;RST=T;GDE=F;FRL=Lo;BA

    M=IfAllSuccessful;MTS=F;MDI=Me;CSR=F;FWC=F;PFC=10;TLO=O;""
    set record="createobject(""adodb.recordset")
    sql="select*from ibm_one_table"
    record.open sql,con
    DO
    if(record("ibm_table_column")="kai")then'//查找表格中有多少kai
    num=num+1;
    end if
    record.movenext
    loop until record.eof="true record.close
    set record="nothing con.close
    set con="nothing end sub

     

    9   换行符
    vbcr----chr(13)回车符// vblf----chr(10)换行符
        vbcrlf----chr(13)+chr(10)结合//type(chr(13)就相当于按了一上键盘上的enter

     

    10  Run from step有两种方式:
    在Keyword View模式会从本步骤运行到所有action结束
    在expert view模式仅会将本action运行结束

     

    11  由于对象属性原因,无法识别对象
    -----对于对象属性是变化的,可以参数化/或者用正则表达式
    -----报匹配多个对象错误,可以spy查看对象,添加一个该对象另一个唯一标识属性
    -----有时可以删除对象的变化的属性来解决识别问题
    ------对于多个完全相同的对象,可以采用添加index,location,createtime等特殊属性来识别
      (index:按照程序源码,绘制对象的先后标识对象,所以与其它相同对象是相互依赖,当其它对象发生
      变化后,原先的所有对象index属性要发生变化,开始是0;如index:="0;         location:根据对象的位置进行确定,从上到下,从左到右;
      CreateTime:按照对象被浏览器打开的先后标识对象)
    ------另外换一种思维方式,采取等效的方法;比如用键盘代替鼠标或用操作系统本身特性去解决问题

     

    12  对系统文件的操作
    -------从系统的文件中获取信息及删除文件
      get_file_infor("c:\she.mpg")
       function get_file_infor(url)
        dim fso,f
        set fso="createobject(""scrīpting.filesystemobject")
        set f="fso.getfile(url)"
        f.name:f.size:f.type:f.datacreated'///获取文件信息
        fso.deletefile(url)'/////删除文件
       end function
    --------获取文件夹里所有文件信息
    get_folder_infor("c:\kai")
    function get_folder_infor(folder)
    dim fso,f,f1,n
    set fso="createobject(""scrīpting,filesystemobject")
    set f="fso.getfolder(folder) set fc="f.files for each f1 in fc
    select case f1.name
    case"kai.mpg","she.mpg","dd.mp3"'//检查文件夹里是否含有这些文件
    end select
    next
    end function

     

    13   等待某个对象出现方法
    y="......waitproperty(""visible",true,10000)

     

    14   防程序中断方法
    On error resume next
    On error goto handle

     

    15  数组的应用:
    name="array(1,2,""aa","bb")
    name(2)="aa"

     

    16  正则表达式应用模板
    进行日期YYYY-MM-DD的格式检查 :
    Function RegExpTest(patrn, strng)
      Dim regEx, Match, Matches      ' Create variable.
      Set regEx = New RegExp         ' Create a regular expression.
      regEx.Pattern = patrn         ' Set pattern.
      regEx.IgnoreCase = True         ' Set case insensitivity.
      regEx.Global = True         ' Set global applicability.
      Set Matches = regEx.Execute(strng)   ' Execute search.
      For Each Match in Matches      ' Iterate Matches collection.
        RetStr = RetStr & "Match found at position "
        RetStr = RetStr & Match.FirstIndex & ". Match Value is '"
        RetStr = RetStr & Match.Value & "'." & vbCRLF
      Next
      RegExpTest = RetStr
    End Function
    date_pattern="^((((19|20)(([02468][048])|([13579][26]))-02-29))|((20[0-9][0-9])|(19[0-9][0-9]))-((((0[1-9])|(1[0-2]))-((0[1-9])|(1\d)|(2[0-8])))|((((0[13578])|(1[02]))-31)|(((01,3-9])|(1[0-2]))-(29|30)))))$"
    result_message=RegExpTest(date_pattern, inputbox("请你输入要检查的时间:"))'用其它正则表达式更改此处
    Select case result_message
    Case ""
             msgbox("你输入的日期格式与标准不匹配")
    case else  MsgBox(result_message)
    end select

     

    17   返回一个字符串在另一字符串中的位置
    instr(string1,string2)

     

    18   有时回放出现找不到对象时,可能不是由于你的代码问题,而是由于你的操作系统等设置问题;
    举例说明1:
    比如:你录制一个选择磁盘中的文件动作
    会录制为:
    .winlistview("  ").drap 46,99
    .winlistview("  ").draponitem "she.mp3"
    下次录制的时候,如果你的系统文件改为不显示扩展名,下次执行的时候,QTP就找不到she.mp3,只能找到she;
    举例说明2:
    有时由于不同操作系统以及不同的ie,导致有些窗口不能识别,比如在2000下弹出的网页对话框的标题是:
    “web对话框",而在2003上是”网页对话框"

     

    19  "is+*"类型function
    isarray'是否是数组
    isconnected'判断QTP是否连接到TD
    isdate'是否是合法的日期类型
    isempty'判断是否初始化
    isNull'判断是否为空值
    isNumeric'判断是否是数字型
    isobject'判断是否一个功能对象
    isready'判断设备是否准备就绪
    isRootFolder'是否是根目录

     

    20 Action之间的参数传递
    例如:在Action1中,有如下代码:
    out_str="This is out_string"
    RunAction "Action2",oneIteration,out_str
    在Acton2中,在其step->Action Properties中的,input参数栏,加入out_str后,
    msgbox(parameter("out_str")),就能正确显示参数了 

     

    21 Wscrīpt.Shell的一些应用
    set WshShell ="CreateObject(""Wscrīpt.Shell")
    WshShell.SendKeys "{ENTER}"     '模拟键盘进行操作
    WshShell.AppActivate "Calculator"             '启动应用程序

     

    22 获取对象属性名称用法:
    GetRoProperty----从应用程序界面上获取对象属性(即,是脚本运行时,获取的对象动态属性值)例如:获取对象库中index属性值,似乎只能用GetToProperty,因为应用程序界面上对象没有该属性,只是QTP为识别该对象创立的描述属性;
    GetToproperty----从对象库中描述对象的属性,静态值
    GetToProperties----获取用于标识对象的属性集;对于这个集合,有count等属性方法

     

    23 FireEvent的使用可以对一个对象进行更复杂的操作
    如:FireEvent("onfocus")   '使一个控件获取焦点
         FireEvent("ondblclick")  '实现双击/也可以在事件设定中针对该对象事件响应  

     

    24 模板的应用
    -----新建一个文本,输入一些新建Action时常包含的信息,然后保存为ActionTemplate.MST文件,
     并复制到QTP/dat目录下;这样每次新建action都会包含固定的信息了;
    例如:
    '-------------------脚本说明---------------
    '产品版本:      __Build(  )
    '测试员:
    '编写日期:
    '测试功能:
    '脚本类型:
    '被测试对象初始状态:
    '进展程度:
    '基本思路:
    '主要功能函数:
    '历史修改:
    '没解决的问题:
    '--------------------脚本内容-------------

     

    25 在对象库中,两个对象有时不能通过更改属性或命名来达到两个对象完全一致的替换;
    在web-mod项目中,我在对象库里添加了一个自动含有index标识属性的对象,然后每次通过SetToproperty来改变
    index值,对对象进行数据驱动,使其操作另一个对象,但脚本始终操作原先index属性值的对象;后来,把该对象
    删除掉,重新添加一个不自动含有index标识属性的该类对象,然后,手工添加,index标识属性,后来脚本能正常工作了,可见两次的对象属性完全一致,但形成方式不一样,导致的结果往往也不一样;

     

    26 childobject的应用
    childobject可以返回界面上满足条件的对象集合,而且与对象库里是否有这些对象无关,这就可以简化对象库;
    返回的对象集合的count方法可以返回对象个数,这就可以通过下标对单个对象进行操作;在出现index标识对象时
    可以进行运用
    如:Set m_WinCheck="Descrīption.Create()       m_WinCheck("nativeclass").Value="Button"
          set All_WinCheck="Window(""").Dialog("").Childobject(m_WinCheck)
          n="All_WinCheck.Count()      for i="0" to n-1
          All_WinCheck(i).Set "ON"
         next

    --以上是一些简单基础内容及我的经验心得,欢迎大家贴一些特色代码或具体应用的核心代码,谢谢

  • Selenium备忘

    2007-11-12 15:56:32

    作者 johnsonchen 目标文章 项目日志 - 2006-09-13


        最近的项目准备用Selenium作一部分的Regression Test。在SpringSide里参考了一下,又下了个Selenium IDE玩玩,觉得还蛮容易上手,基本上不需要手动写测试代码。
        但实操起来时面对各种复杂的页面情况遇到不少麻烦。感觉Selenium 的offical documentation写的比较high level, 最后找了个though works的ppt,算得上比较全面易懂。匆匆翻译了一下,供后来者参考。


    一、 格式
    1. Test Case 格式

       Title  
     命令(Command)   目标(Target)   值(Value)
     命令(Command)  目标(Target)    (&nbsp;)
     判断(Assertion)   期望值(Expected)   实际值(Actual)


    2. Test Suites 格式

     Title
     TestCase1.html
     TestCase2.html
     TestCase3.html

    二、 Commands (命令)

    • Action
      对当前状态进行操作
      失败时,停止测试
    • Assertion
      校验是否有产生正确的值
    • Element Locators
      指定HTML中的某元素
    • Patterns
      用于模式匹配

    1. Element Locators (元素定位器)

    • id=id
      id locator 指定HTML中的唯一id的元素 
    •  name=name
      name locator指定 HTML中相同name的元素中的第一个元素
    •  identifier=id
      identifier locator 首先查找HTML是否存在该id的元素, 若不存在,查找第一个该name的元素 
    • dom=javascrīptExpression
      dom locator用Javascrīpt表达式来定位HTML中的元素,注意必须要以”document”开头
      例如:
      dom=document.forms[‘myForm’].myDropdown
      dom=document.images[56]
    •  xpath=xpathExpression
      xpath locator用 XPath 表达式来定位HTML中的元素,必须注意要以”//”开头
      例如:
      xpath=//img[@alt=’The image alt text’]
      xpath=//table[@id=’table1’]//tr[4]/td[2]
    •  link=textPattern
      link locator 用link来选择HTML中的连接或锚元素
      例如:
      link=The link text
    • 在没有locator前序的情况下 Without a locator prefix, Selenium uses:
      如果以”document.”开头,则默认是使用 dom locator,如果是以“//”开头,则默认使用xpath locator,其余情况均认作identifier locator

    2. String Matching Patterns (字符串匹配模式)

    • glob:patthern
      glob模式,用通配符”*”代表任意长度字符,“?”代表一个字符
    • regexp:regexp
      正则表达式模式,用Javascrīpt正则表达式的形式匹配字符串
    • exact:string
      精确匹配模式,精确匹配整个字符串,不能用通配符
    • 在没有指定字符串匹配前序的时候,selenium 默认使用golb 匹配模式

    3. Select Option Specifiers (Select选项指定器)

    • label=labelPattern
      通过匹配选项中的文本指定选项
      例如:label=regexp:^[Oo]ther
    • value=valuePattern
      通过匹配选项中的值指定选项
      例如:value=other
    • id=id
      通过匹配选项的id指定选项
      例如: id=option1
    • index=index
      通过匹配选项的序号指定选项,序号从0开始
      例如:index=2
    • 在没有选项选择前序的情况下,默认是匹配选项的文本

    三、 Actions
    描述了用户所会作出的操作。
    Action 有两种形式: action和actionAndWait, action会立即执行,而actionAndWait会假设需要较长时间才能得到该action的相响,而作出等待,open则是会自动处理等待时间。

    • click
      click(elementLocator)
      - 点击连接,按钮,复选和单选框
      - 如果点击后需要等待响应,则用”clickAndWait”
      - 如果是需要经过Javascrīpt的alert或confirm对话框后才能继续操作,则需要调用verify或assert来告诉Selenium你期望对对话框进行什么操作。
       click  aCheckbox  
       clickAndWait  submitButton  
       clickAndWait   anyLink  

    • open
      open(url)

      - 在浏览器中打开URL,可以接受相对和绝对路径两种形式
      - 注意:该URL必须在与浏览器相同的安全限定范围之内
       open   /mypage  
       open  http://localhost/   

    • type
       type(inputLocator, value)
      - 模拟人手的输入过程,往指定的input中输入值
      - 也适合给复选和单选框赋值
      - 在这个例子中,则只是给钩选了的复选框赋值,注意,而不是改写其文本
       type  nameField   John Smith
       typeAndWait   textBoxThatSubmitsOnChange  newValue

    • select
      select(dropDownLocator, optionSpecifier)
      - 根据optionSpecifier选项选择器来选择一个下拉菜单选项
      - 如果有多于一个选择器的时候,如在用通配符模式,如”f*b*”,或者超过一个选项有相同的文本或值,则会选择第一个匹配到的值
       select    dropDown   Australian Dollars
       select    dropDown   index=0
       selectAndWait   currencySelector   value=AUD
       selectAndWait   currencySelector   label=Auslian D*rs

    •  goBack,close
      goBack()
      模拟点击浏览器的后退按钮
      close()
      模拟点击浏览器关闭按钮
    • selectWindow
      select(windowId)
      - 选择一个弹出窗口
      - 当选中那个窗口的时候,所有的命令将会转移到那窗口中执行
       selectWindow   myPopupWindow  
       selectWindow  null  

    • pause
      pause(millisenconds)
      - 根据指定时间暂停Selenium脚本执行
      - 常用在调试脚本或等待服务器段响应时
       pause   5000  
       pause   2000  

    • fireEvent
       fireEvent(elementLocatore,evenName)
      模拟页面元素事件被激活的处理动作
       fireEvent   textField focus 
       fireEvent  dropDown  blur

    • waitForCondition
      waitForCondition(JavascrīptSnippet,time)

      - 在限定时间内,等待一段Javascrīpt代码返回true值,超时则停止等待
       waitForCondition   var value=selenium.getText("foo"); value.match(/bar/);  3000

    • waitForValue
      waitForValue(inputLocator, value)
      - 等待某input(如hidden input)被赋予某值,
      - 会轮流检测该值,所以要注意如果该值长时间一直不赋予该input该值的话,可能会导致阻塞
       waitForValue  finishIndication isfinished 
           

    • store,stroreValue
      store(valueToStore, variablename)
      保存一个值到变量里。
      该值可以由自其他变量组合而成或通过Javascrīpt表达式赋值给变量
       store   Mr John Smith  fullname
       store   ${title} ${firstname} ${suname}  fullname
       store   javascrīpt{Math.round(Math.PI*100)/100}  PI
       storeValue  inputLocator  variableName

      把指定的input中的值保存到变量中
       storeValue   userName  userID 
       type   userName   ${userID}

    • storeText, storeAttribute
      storeText(elementLocator, variablename)
      把指定元素的文本值赋予给变量
       storeText   currentDate   expectedStartDate
       verifyValue   startDate   ${expectedStartDate}

      storeAttribute(elementLocator@attributeName,variableName)
      把指定元素的属性的值赋予给变量
       storeAttribute  input1@class    classOfInput1
       verifyAttribute   input2@class   ${classOfInput1}

    • chooseCancel.., answer..
      chooseCancelOnNextConfirmation()
      - 当下次Javascrīpt弹出confirm对话框的时候,让selenium选择Cancel
      - 如果没有该命令时,遇到confirm对话框Selenium默认返回true,如手动选择OK按钮一样
       chooseCancelOnNextConfirmation      

      - 如果已经运行过该命令,当下一次又有confirm对话框出现时,也会同样地再次选择Cancel
      answerOnNextPrompt(answerString)
      - 在下次Javascrīpt弹出prompt提示框时,赋予其anweerString的值,并选择确定
       answerOnNextPrompt   Kangaroo   

    四、 Assertions
    允许用户去检查当前状态。两种模式: Assert 和 Verify, 当Assert失败,则退出测试;当Verify失败,测试会继续运行。

    • assertLocation, assertTitle
      assertLocation(relativeLocation)
      判断当前是在正确的页面
       verifyLocation   /mypage  
       assertLocation   /mypage  

    • assertTitle(titlePattern)
      检查当前页面的title是否正确
       verifyTitle   My Page   
       assertTitle   My Page   

    • assertValue
      assertValue(inputLocator, valuePattern)
      - 检查input的值
      - 对于 checkbox或radio,如果已选择,则值为”on”,反之为”off”
       verifyValue   nameField   John Smith
       assertValue   document.forms[2].nameField  John Smith

    • assertSelected, assertSelectedOptions
      assertSelected(selectLocator, optionSpecifier)
      检查select的下拉菜单中选中的选型是否和optionSpecifer(Select选择选项器)的选项相同
       verifySelected   dropdown2   John Smith
       verifySelected   dorpdown2   value=js*123
       assertSelected   document.forms[2].dropDown  label=J*Smith
       assertSelected   document.forms[2].dropDown   index=0

    • assertSelectOptions(selectLocator, optionLabelList)
      - 检查下拉菜单中的选项的文本是否和optionLabelList相同
      - optionLabelList是以逗号分割的一个字符串
       verifySelectOptions   dropdown2   John Smith,Dave Bird
       assertSelectOptions   document.forms[2].dropdown  Smith,J,Bird,D

    • assertText
      assertText(elementLocator,textPattern)
      - 检查指定元素的文本
      - 只对有包含文本的元素生效
      - 对于Mozilla类型的浏览器,用textContent取元素的文本,对于IE类型的浏览器,用innerText取元素文本
       verifyText   statusMessage   Successful
       assertText   //div[@id='foo']//h1  Successful

       
    • assertTextPresent, assertAttribute
      assertTextPresent(text)
      检查在当前给用户显示的页面上是否有出现指定的文本
       verifyTextPresent   You are now logged in   
       assertTextPresent   You are now logged in   

    • assertAttribute(elementLocator@attributeName, ValuePattern)
      检查当前指定元素的属性的值
       verifyAttribute  txt1@class  bigAndBlod
       assertAttribute   document.images[0]@alt  alt-text
       verifyAttribute   //img[@id='foo']/alt   alt-text

    • assertTextPresent, etc.
      assertTextPresent(text)
      assertTextNotPresent(text)
      assertElementPresent(elementLocator)
       verifyElementPresent   submitButton   
       assertElementPresent   //img[@alt='foo']   
      assertElementNotPresent(elementLocator)
    • assertTable
      assertTable(cellAddress, valuePattern)
      - 检查table里的某个cell中的值
      - cellAddress的语法是tableName.row.column, 注意行列序号都是从0开始
       verifyTable   myTable.1.6  Submitted
       assertTable   results0.2   13

       
    • assertVisible, nonVisible
      assertVisible(elementLocator)
      - 检查指定的元素是否可视的
      - 隐藏一个元素可以用设置css的‘visibility’属性为’hidden’,也可以设置‘display’属性为‘none’
       verfyVisible   postcode   
       assertVisible   postcode   

    • assertNotVisible(elementLocator)
       verfyNotVisible   postcode   
       assertNotVisible   postcode   

    • Editable, non-editable
      assertEditable(inputLocator)
      检查指定的input是否可以编辑
       verifyEditable   shape   
       assertEditable   colour   

    • assertNotEditable(inputLocator)
      检查指定的input是否不可以编辑
    • assertAlert
      assertAlert(messagePattern)
      - 检查Javascrīpt是否有产生带指定message的alert对话框
      - alert产生的顺序必须与检查的顺序一致
      - 检查alert时会产生与手动点击’OK’按钮一样的效果。如果一个alert产生了,而你却没有去检查它,selenium会在下个action中报错。
      - 注意:Selenium 不支持 Javascrīpt 在onload()事件时 调用alert();在这种情况下,Selenium需要你自己手动来点击OK.
    • assertConfirmation
      assertConfirmation(messagePattern)
      - 检查Javascrīpt是否有产生带指定message的confirmation对话框和alert情况一样,confirmation对话框也必须在它们产生的时候进行检查
      - 默认情况下,Selenium会让confirm() 返回true, 相当于手动点击Ok按钮的效果。你能够通过chooseCancelOnNextConfirmation命令让confirm()返回false.同样地,如果一个cofirmation对话框出现了,但你却没有检查的话,Selenium将会在下个action中报错
      - 注意:在Selenium的环境下,confirmation对话框框将不会再出现弹出显式对话框
      - 注意:Selenium不支持在onload()事件时调用confirmation对话框,在这种情况下,会出现显示confirmatioin对话框,并需要你自己手动点击。
    •  assertPrompt
      assertPrompt(messagePattern)
      - 检查Javascrīpt是否有产生带指定message的Prompt对话框
      - 你检查的prompt的顺序Prompt对话框产生的顺序必须相同
      - 必须在verifyPrompt之前调用answerOnNextPrompt命令
      - 如果prompt对话框出现了但你却没有检查,则Selenium会在下个action中报错
       answerOnNextPrompt   Joe   
       click   id=delegate   
       verifyPrompt   Delegate to who?   


    五、 Parameters and Variables
    参数和变量的声明范围由简单的赋值到Javascrīpt表达式赋值。
    Store,storeValue 和storeText 为下次访问保存值。
    在Selenium内部是用一个叫storeVars的map来保存变量名。

    • Variable Substitution 变量替换
      提供了一个简单的方法去访问变量,语法 ${xxx}
       store    Mr   title
       storeValue   nameField   surname
       store    ${title} ${suname}  fullname
       type   textElement   Full name is: ${fullname}

    •  Javascrīpt Evaluation Javascrīpt赋值
      你能用Javascrīpt来构建任何你所需要的值。
      这个参数是以javascrīpt开头,语法是 javascrīpt{‘with a trailing’}。
      可以通过Javascrīpt表达式给某元素赋值。
      store   javascrīpt{'merchant'+(new Date()).getTime()}   merchantId
       type  textElement   javascrīpt{storedVars['merchantId'].toUpperCase()}

    • Generating Unique values 产生唯一值.  
      问题:你需要唯一的用户名
      解决办法: 基于时间来产生用户名,如’fred’+(new Date().getTime())
  • Selenium Reference

    2007-11-12 14:06:18

    Concepts

    A command is what tells Selenium what to do. Selenium commands come in three 'flavors': Actions, Accessors and Assertions. Each command call is one line in the test table of the form:

    command target value

    Actions are commands that generally manipulate the state of the application. They do things like "click this link" and "select that option". If an Action fails, or has an error, the execution of the current test is stopped.

    Many Actions can be called with the "AndWait" suffix, e.g. "clickAndWait". This suffix tells Selenium that the action will cause the browser to make a call to the server, and that Selenium should wait for a new page to load.

    Accessors examine the state of the application and store the results in variables, e.g. "storeTitle". They are also used to automatically generate Assertions.

    Assertions are like Accessors, but they verify that the state of the application conforms to what is expected. Examples include "make sure the page title is X" and "verify that this checkbox is checked".

    All Selenium Assertions can be used in 3 modes: "assert", "verify", and "waitFor". For example, you can "assertText", "verifyText" and "waitForText". When an "assert" fails, the test is aborted. When a "verify" fails, the test will continue execution, logging the failure. This allows a single "assert" to ensure that the application is on the correct page, followed by a bunch of "verify" assertions to test form field values, labels, etc.

    "waitFor" commands wait for some condition to become true (which can be useful for testing Ajax applications). They will succeed immediately if the condition is already true. However, they will fail and halt the test if the condition does not become true within the current timeout setting (see the setTimeout action below).

    Element Locators tell Selenium which HTML element a command refers to. Many commands require an Element Locator as the "target" attribute. Examples of Element Locators include "elementId" and "document.forms[0].element". These are described more clearly in the next section.

    Patterns are used for various reasons, e.g. to specify the expected value of an input field, or identify a select option. Selenium supports various types of pattern, including regular-expressions, all of which are described in more detail below.

    Defines an object that runs Selenium commands.

    Element Locators

    Element Locators tell Selenium which HTML element a command refers to. The format of a locator is:

    locatorType=argument

    We support the following strategies for locating elements:

    identifier=id
    Select the element with the specified @id attribute. If no match is found, select the first element whose @name attribute is id. (This is normally the default; see below.)
    id=id
    Select the element with the specified @id attribute.
    name=name
    Select the first element with the specified @name attribute.
    • username
    • name=username
    The name may optionally be followed by one or more element-filters, separated from the name by whitespace. If the filterType is not specified, value is assumed.
    • name=flavour value=chocolate
    dom=javascrīptExpression
    Find an element using Javascrīpt traversal of the HTML Document Object Model. DOM locators must begin with "document.".
    • dom=document.forms['myForm'].myDropdown
    • dom=document.images[56]
    xpath=xpathExpression
    Locate an element using an XPath expression.
    • xpath=//img[@alt='The image alt text']
    • xpath=//table[@id='table1']//tr[4]/td[2]
    link=textPattern
    Select the link (anchor) element which contains text matching the specified pattern.
    • link=The link text
    css=cssSelectorSyntax
    Select the element using css selectors. Please refer to CSS2 selectors, CSS3 selectors for more information. You can also check the TestCssLocators test in the selenium test suite for an example of usage, which is included in the downloaded selenium core package.
    • css=a[href="#id3"]
    • css=span#firstChild + span
    Currently the css selector locator supports all css1, css2 and css3 selectors except namespace in css3, some pseudo classes(:nth-of-type, :nth-last-of-type, :first-of-type, :last-of-type, :only-of-type, :visited, :hover, :active, :focus, :indeterminate) and pseudo elements(::first-line, ::first-letter, ::selection, ::before, ::after).

    Without an explicit locator prefix, Selenium uses the following default strategies:

    • dom, for locators starting with "document."
    • xpath, for locators starting with "//"
    • identifier, otherwise

    Element Filters

    Element filters can be used with a locator to refine a list of candidate elements. They are currently used only in the 'name' element-locator.

    Filters look much like locators, ie.

    filterType=argument

    Supported element-filters are:

    value=valuePattern

    Matches elements based on their values. This is particularly useful for refining a list of similarly-named toggle-buttons.

    index=index

    Selects a single element based on its position in the list (offset from zero).

    String-match Patterns

    Various Pattern syntaxes are available for matching string values:

    glob:pattern
    Match a string against a "glob" (aka "wildmat") pattern. "Glob" is a kind of limited regular-expression syntax typically used in command-line shells. In a glob pattern, "*" represents any sequence of characters, and "?" represents any single character. Glob patterns match against the entire string.
    regexp:regexp
    Match a string using a regular-expression. The full power of Javascrīpt regular-expressions is available.
    exact:string
    Match a string exactly, verbatim, without any of that fancy wildcard stuff.

    If no pattern prefix is specified, Selenium assumes that it's a "glob" pattern.

    Selenium Actions

    addSelection ( locator,optionLocator )
    Add a selection to the set of selected options in a multi-select element using an option locator. @see #doSelect for details of option locators

    Arguments:

    • locator - an element locator identifying a multi-select box
    • optionLocator - an option locator (a label by default)

    answerOnNextPrompt ( answer )
    Instructs Selenium to return the specified answer string in response to the next Javascrīpt prompt [window.prompt()].

    Arguments:

    • answer - the answer to give in response to the prompt pop-up

    check ( locator )
    Check a toggle-button (checkbox/radio)

    Arguments:


    chooseCancelOnNextConfirmation ( )
    By default, Selenium's overridden window.confirm() function will return true, as if the user had manually clicked OK. After running this command, the next call to confirm() will return false, as if the user had clicked Cancel.
    click ( locator )
    Clicks on a link, button, checkbox or radio button. If the click action causes a new page to load (like a link usually does), call waitForPageToLoad.

    Arguments:

    • locator - an element locator

    clickAt ( locator,coordString )
    Clicks on a link, button, checkbox or radio button. If the click action causes a new page to load (like a link usually does), call waitForPageToLoad. Beware of http://jira.openqa.org/browse/SEL-280, which will lead some event handlers to get null event arguments. Read the bug for more details, including a workaround.

    Arguments:

    • locator - an element locator
    • coordString - specifies the x,y position (i.e. - 10,20) of the mouse event relative to the element returned by the locator.

    close ( )
    Simulates the user clicking the "close" button in the titlebar of a popup window or tab.
    createCookie ( nameValuePair,optionsString )
    Create a new cookie whose path and domain are same with those of current page under test, unless you specified a path for this cookie explicitly.

    Arguments:

    • nameValuePair - name and value of the cookie in a format "name=value"
    • optionsString - options for the cookie. Currently supported options include 'path' and 'max_age'. the optionsString's format is "path=/path/, max_age=60". The order of options are irrelevant, the unit of the value of 'max_age' is second.

    deleteCookie ( name,path )
    Delete a named cookie with specified path.

    Arguments:

    • name - the name of the cookie to be deleted
    • path - the path property of the cookie to be deleted

    dragdrop ( locator,movementsString )
    Drags an element a certain distance and then drops it Beware of http://jira.openqa.org/browse/SEL-280, which will lead some event handlers to get null event arguments. Read the bug for more details, including a workaround.

    Arguments:

    • locator - an element locator
    • movementsString - offset in pixels from the current location to which the element should be moved, e.g., "+70,-300"

    fireEvent ( locator,eventName )
    Explicitly simulate an event, to trigger the corresponding "onevent" handler.

    Arguments:

    • locator - an element locator
    • eventName - the event name, e.g. "focus" or "blur"

    goBack ( )
    Simulates the user clicking the "back" button on their browser.
    keyDown ( locator,keySequence )
    Simulates a user pressing a key (without releasing it yet).

    Arguments:

    • locator - an element locator
    • keySequence - Either be a string("\" followed by the numeric keycode of the key to be pressed, normally the ASCII value of that key), or a single character. For example: "w", "\119".

    keyPress ( locator,keySequence )
    Simulates a user pressing and releasing a key.

    Arguments:

    • locator - an element locator
    • keySequence - Either be a string("\" followed by the numeric keycode of the key to be pressed, normally the ASCII value of that key), or a single character. For example: "w", "\119".

    keyUp ( locator,keySequence )
    Simulates a user releasing a key.

    Arguments:

    • locator - an element locator
    • keySequence - Either be a string("\" followed by the numeric keycode of the key to be pressed, normally the ASCII value of that key), or a single character. For example: "w", "\119".

    mouseDown ( locator )
    Simulates a user pressing the mouse button (without releasing it yet) on the specified element.

    Arguments:


    mouseDownAt ( locator,coordString )
    Simulates a user pressing the mouse button (without releasing it yet) on the specified element. Beware of http://jira.openqa.org/browse/SEL-280, which will lead some event handlers to get null event arguments. Read the bug for more details, including a workaround.

    Arguments:

    • locator - an element locator
    • coordString - specifies the x,y position (i.e. - 10,20) of the mouse event relative to the element returned by the locator.

    mouseMove ( locator )
    Simulates a user pressing the mouse button (without releasing it yet) on the specified element.

    Arguments:


    mouseMoveAt ( locator,coordString )
    Simulates a user pressing the mouse button (without releasing it yet) on the specified element. Beware of http://jira.openqa.org/browse/SEL-280, which will lead some event handlers to get null event arguments. Read the bug for more details, including a workaround.

    Arguments:

    • locator - an element locator
    • coordString - specifies the x,y position (i.e. - 10,20) of the mouse event relative to the element returned by the locator.

    mouseOut ( locator )
    Simulates a user moving the mouse pointer away from the specified element.

    Arguments:


    mouseOver ( locator )
    Simulates a user hovering a mouse over the specified element.

    Arguments:


    mouseUp ( locator )
    Simulates a user pressing the mouse button (without releasing it yet) on the specified element.

    Arguments:


    mouseUpAt ( locator,coordString )
    Simulates a user pressing the mouse button (without releasing it yet) on the specified element. Beware of http://jira.openqa.org/browse/SEL-280, which will lead some event handlers to get null event arguments. Read the bug for more details, including a workaround.

    Arguments:

    • locator - an element locator
    • coordString - specifies the x,y position (i.e. - 10,20) of the mouse event relative to the element returned by the locator.

    open ( url )
    Opens an URL in the test frame. This accepts both relative and absolute URLs. The "open" command waits for the page to load before proceeding, ie. the "AndWait" suffix is implicit. Note: The URL must be on the same domain as the runner HTML due to security restrictions in the browser (Same Origin Policy). If you need to open an URL on another domain, use the Selenium Server to start a new browser session on that domain.

    Arguments:

    • url - the URL to open; may be relative or absolute

    refresh ( )
    Simulates the user clicking the "Refresh" button on their browser.
    removeSelection ( locator,optionLocator )
    Remove a selection from the set of selected options in a multi-select element using an option locator. @see #doSelect for details of option locators

    Arguments:

    • locator - an element locator identifying a multi-select box
    • optionLocator - an option locator (a label by default)

    select ( selectLocator,optionLocator )
    Select an option from a drop-down using an option locator.

    Option locators provide different ways of specifying options of an HTML Select element (e.g. for selecting a specific option, or for asserting that the selected option satisfies a specification). There are several forms of Select Option Locator.

    label=labelPattern
    matches options based on their labels, i.e. the visible text. (This is the default.)
    • label=regexp:^[Oo]ther
    value=valuePattern
    matches options based on their values.
    • value=other
    id=id
    matches options based on their ids.
    • id=option1
    index=index
    matches an option based on its index (offset from zero).
    • index=2

    If no option locator prefix is provided, the default behaviour is to match on label.

    Arguments:

    • selectLocator - an element locator identifying a drop-down menu
    • optionLocator - an option locator (a label by default)

    selectFrame ( locator )
    Selects a frame within the current window. (You may invoke this command multiple times to select nested frames.) To select the parent frame, use "relative=parent" as a locator; to select the top frame, use "relative=top".

    You may also use a DOM expression to identify the frame you want directly, like this: dom=frames["main"].frames["subframe"]

    Arguments:


    selectWindow ( windowID )
    Selects a popup window; once a popup window has been selected, all commands go to that window. To select the main window again, use "null" as the target.

    Arguments:

    • windowID - the Javascrīpt window ID of the window to select

    setContext ( context,logLevelThreshold )
    Writes a message to the status bar and adds a note to the browser-side log.

    If logLevelThreshold is specified, set the threshold for logging to that level (debug, info, warn, error).

    (Note that the browser-side logs will not be sent back to the server, and are invisible to the Client Driver.)

    Arguments:

    • context - the message to be sent to the browser
    • logLevelThreshold - one of "debug", "info", "warn", "error", sets the threshold for browser-side logging

    setCursorPosition ( locator,position )
    Moves the text cursor to the specified position in the given input element or textarea. This method will fail if the specified element isn't an input element or textarea.

    Arguments:

    • locator - an element locator pointing to an input element or textarea
    • position - the numerical position of the cursor in the field; position should be 0 to move the position to the beginning of the field. You can also set the cursor to -1 to move it to the end of the field.

    setTimeout ( timeout )
    Specifies the amount of time that Selenium will wait for actions to complete.

    Actions that require waiting include "open" and the "waitFor*" actions.

    The default timeout is 30 seconds.

    Arguments:

    • timeout - a timeout in milliseconds, after which the action will return with an error

    submit ( formLocator )
    Submit the specified form. This is particularly useful for forms without submit buttons, e.g. single-input "Search" forms.

    Arguments:


    type ( locator,value )
    Sets the value of an input field, as though you typed it in.

    Can also be used to set the value of combo boxes, check boxes, etc. In these cases, value should be the value of the option selected, not the visible text.

    Arguments:


    uncheck ( locator )
    Uncheck a toggle-button (checkbox/radio)

    Arguments:


    waitForCondition ( scrīpt,timeout )
    Runs the specified Javascrīpt snippet repeatedly until it evaluates to "true". The snippet may have multiple lines, but only the result of the last line will be considered.

    Note that, by default, the snippet will be run in the runner's test window, not in the window of your application. To get the window of your application, you can use the Javascrīpt snippet selenium.browserbot.getCurrentWindow(), and then run your Javascrīpt in there

    Arguments:

    • scrīpt - the Javascrīpt snippet to run
    • timeout - a timeout in milliseconds, after which this command will return with an error

    waitForPageToLoad ( timeout )
    Waits for a new page to load.

    You can use this command instead of the "AndWait" suffixes, "clickAndWait", "selectAndWait", "typeAndWait" etc. (which are only available in the JS API).

    Selenium constantly keeps track of new pages loading, and sets a "newPageLoaded" flag when it first notices a page load. Running any other Selenium command after turns the flag to false. Hence, if you want to wait for a page to load, you must wait immediately after a Selenium command that caused a page-load.

    Arguments:

    • timeout - a timeout in milliseconds, after which this command will return with an error

    waitForPopUp ( windowID,timeout )
    Waits for a popup window to appear and load up.

    Arguments:

    • windowID - the Javascrīpt window ID of the window that will appear
    • timeout - a timeout in milliseconds, after which the action will return with an error

    windowFocus ( windowName )
    Gives focus to a window

    Arguments:

    • windowName - name of the window to be given focus

    windowMaximize ( windowName )
    Resize window to take up the entire screen

    Arguments:

    • windowName - name of the window to be enlarged

    Selenium Accessors

    storeAlert ( variableName )
    Retrieves the message of a Javascrīpt alert generated during the previous action, or fail if there were no alerts.

    Getting an alert has the same effect as manually clicking OK. If an alert is generated but you do not get/verify it, the next Selenium action will fail.

    NOTE: under Selenium, Javascrīpt alerts will NOT pop up a visible alert dialog.

    NOTE: Selenium does NOT support Javascrīpt alerts that are generated in a page's onload() event handler. In this case a visible dialog WILL be generated and Selenium will hang until someone manually clicks OK.

    Returns:
    The message of the most recent Javascrīpt alert

    Related Assertions, automatically generated:


    storeAllButtons ( variableName )
    Returns the IDs of all buttons on the page.

    If a given button has no ID, it will appear as "" in this array.

    Returns:
    the IDs of all buttons on the page

    Related Assertions, automatically generated:


    storeAllFields ( variableName )
    Returns the IDs of all input fields on the page.

    If a given field has no ID, it will appear as "" in this array.

    Returns:
    the IDs of all field on the page

    Related Assertions, automatically generated:


    storeAllLinks ( variableName )
    Returns the IDs of all links on the page.

    If a given link has no ID, it will appear as "" in this array.

    Returns:
    the IDs of all links on the page

    Related Assertions, automatically generated:


    storeAllWindowIds ( variableName )
    Returns the IDs of all windows that the browser knows about.

    Returns:
    the IDs of all windows that the browser knows about.

    Related Assertions, automatically generated:


    storeAllWindowNames ( variableName )
    Returns the names of all windows that the browser knows about.

    Returns:
    the names of all windows that the browser knows about.

    Related Assertions, automatically generated:

    • assertAllWindowNames ( pattern )
    • assertNotAllWindowNames ( pattern )
    • verifyAllWindowNames ( pattern )
    • verifyNotAllWindowNames ( pattern )
    • waitForAllWindowNames ( pattern )
    • waitForNotAllWindowNames ( pattern )

    storeAllWindowTitles ( variableName )
    Returns the titles of all windows that the browser knows about.

    Returns:
    the titles of all windows that the browser knows about.

    Related Assertions, automatically generated:

    • assertAllWindowTitles ( pattern )
    • assertNotAllWindowTitles ( pattern )
    • verifyAllWindowTitles ( pattern )
    • verifyNotAllWindowTitles ( pattern )
    • waitForAllWindowTitles ( pattern )
    • waitForNotAllWindowTitles ( pattern )

    storeAttribute ( attributeLocator, variableName )
    Gets the value of an element attribute. Beware of http://jira.openqa.org/browse/SEL-280, which will lead some event handlers to get null event arguments. Read the bug for more details, including a workaround.

    Arguments:

    • attributeLocator - an element locator followed by an
    • variableName - the name of a variable in which the result is to be stored.

    Returns:
    the value of the specified attribute

    Related Assertions, automatically generated:

    • assertAttribute ( attributeLocator, pattern )
    • assertNotAttribute ( attributeLocator, pattern )
    • verifyAttribute ( attributeLocator, pattern )
    • verifyNotAttribute ( attributeLocator, pattern )
    • waitForAttribute ( attributeLocator, pattern )
    • waitForNotAttribute ( attributeLocator, pattern )

    storeAttributeFromAllWindows ( attributeName, variableName )
    Returns every instance of some attribute from all known windows.

    Arguments:

    • attributeName - name of an attribute on the windows
    • variableName - the name of a variable in which the result is to be stored.

    Returns:
    the set of values of this attribute from all known windows.

    Related Assertions, automatically generated:

    • assertAttributeFromAllWindows ( attributeName, pattern )
    • assertNotAttributeFromAllWindows ( attributeName, pattern )
    • verifyAttributeFromAllWindows ( attributeName, pattern )
    • verifyNotAttributeFromAllWindows ( attributeName, pattern )
    • waitForAttributeFromAllWindows ( attributeName, pattern )
    • waitForNotAttributeFromAllWindows ( attributeName, pattern )

    storeBodyText ( variableName )
    Gets the entire text of the page.

    Returns:
    the entire text of the page

    Related Assertions, automatically generated:


    storeConfirmation ( variableName )
    Retrieves the message of a Javascrīpt confirmation dialog generated during the previous action.

    By default, the confirm function will return true, having the same effect as manually clicking OK. This can be changed by prior execution of the chooseCancelOnNextConfirmation command. If an confirmation is generated but you do not get/verify it, the next Selenium action will fail.

    NOTE: under Selenium, Javascrīpt confirmations will NOT pop up a visible dialog.

    NOTE: Selenium does NOT support Javascrīpt confirmations that are generated in a page's onload() event handler. In this case a visible dialog WILL be generated and Selenium will hang until you manually click OK.

    Returns:
    the message of the most recent Javascrīpt confirmation dialog

    Related Assertions, automatically generated:


    storeCookie ( variableName )
    Return all cookies of the current page under test.

    Returns:
    all cookies of the current page under test

    Related Assertions, automatically generated:


    storeCursorPosition ( locator, variableName )
    Retrieves the text cursor position in the given input element or textarea; beware, this may not work perfectly on all browsers.

    Specifically, if the cursor/selection has been cleared by Javascrīpt, this command will tend to return the position of the last location of the cursor, even though the cursor is now gone from the page. This is filed as SEL-243.

    This method will fail if the specified element isn't an input element or textarea, or there is no cursor in the element.

    Arguments:

    • locator - an element locator pointing to an input element or textarea
    • variableName - the name of a variable in which the result is to be stored.

    Returns:
    the numerical position of the cursor in the field

    Related Assertions, automatically generated:

    • assertCursorPosition ( locator, pattern )
    • assertNotCursorPosition ( locator, pattern )
    • verifyCursorPosition ( locator, pattern )
    • verifyNotCursorPosition ( locator, pattern )
    • waitForCursorPosition ( locator, pattern )
    • waitForNotCursorPosition ( locator, pattern )

    storeElementHeight ( locator, variableName )
    Retrieves the height of an element

    Arguments:

    • locator - an element locator pointing to an element
    • variableName - the name of a variable in which the result is to be stored.

    Returns:
    height of an element in pixels

    Related Assertions, automatically generated:

    • assertElementHeight ( locator, pattern )
    • assertNotElementHeight ( locator, pattern )
    • verifyElementHeight ( locator, pattern )
    • verifyNotElementHeight ( locator, pattern )
    • waitForElementHeight ( locator, pattern )
    • waitForNotElementHeight ( locator, pattern )

    storeElementIndex ( locator, variableName )
    Get the relative index of an element to its parent (starting from 0). The comment node and empty text node will be ignored.

    Arguments:

    • locator - an element locator pointing to an element
    • variableName - the name of a variable in which the result is to be stored.

    Returns:
    of relative index of the element to its parent (starting from 0)

    Related Assertions, automatically generated:

    • assertElementIndex ( locator, pattern )
    • assertNotElementIndex ( locator, pattern )
    • verifyElementIndex ( locator, pattern )
    • verifyNotElementIndex ( locator, pattern )
    • waitForElementIndex ( locator, pattern )
    • waitForNotElementIndex ( locator, pattern )

    storeElementPositionLeft ( locator, variableName )
    Retrieves the horizontal position of an element

    Arguments:

    • locator - an element locator pointing to an element OR an element itself
    • variableName - the name of a variable in which the result is to be stored.

    Returns:
    of pixels from the edge of the frame.

    Related Assertions, automatically generated:

    • assertElementPositionLeft ( locator, pattern )
    • assertNotElementPositionLeft ( locator, pattern )
    • verifyElementPositionLeft ( locator, pattern )
    • verifyNotElementPositionLeft ( locator, pattern )
    • waitForElementPositionLeft ( locator, pattern )
    • waitForNotElementPositionLeft ( locator, pattern )

    storeElementPositionTop ( locator, variableName )
    Retrieves the vertical position of an element

    Arguments:

    • locator - an element locator pointing to an element OR an element itself
    • variableName - the name of a variable in which the result is to be stored.

    Returns:
    of pixels from the edge of the frame.

    Related Assertions, automatically generated:

    • assertElementPositionTop ( locator, pattern )
    • assertNotElementPositionTop ( locator, pattern )
    • verifyElementPositionTop ( locator, pattern )
    • verifyNotElementPositionTop ( locator, pattern )
    • waitForElementPositionTop ( locator, pattern )
    • waitForNotElementPositionTop ( locator, pattern )

    storeElementWidth ( locator, variableName )
    Retrieves the width of an element

    Arguments:

    • locator - an element locator pointing to an element
    • variableName - the name of a variable in which the result is to be stored.

    Returns:
    width of an element in pixels

    Related Assertions, automatically generated:

    • assertElementWidth ( locator, pattern )
    • assertNotElementWidth ( locator, pattern )
    • verifyElementWidth ( locator, pattern )
    • verifyNotElementWidth ( locator, pattern )
    • waitForElementWidth ( locator, pattern )
    • waitForNotElementWidth ( locator, pattern )

    storeEval ( scrīpt, variableName )
    Gets the result of evaluating the specified Javascrīpt snippet. The snippet may have multiple lines, but only the result of the last line will be returned.

    Note that, by default, the snippet will run in the context of the "selenium" object itself, so this will refer to the Selenium object, and window will refer to the top-level runner test window, not the window of your application.

    If you need a reference to the window of your application, you can refer to this.browserbot.getCurrentWindow() and if you need to use a locator to refer to a single element in your application page, you can use this.page().findElement("foo") where "foo" is your locator.

    Arguments:

    • scrīpt - the Javascrīpt snippet to run
    • variableName - the name of a variable in which the result is to be stored.

    Returns:
    the results of evaluating the snippet

    Related Assertions, automatically generated:


    storeExpression ( expression, variableName )
    Returns the specified expression.

    This is useful because of Javascrīpt preprocessing. It is used to generate commands like assertExpression and waitForExpression.

    Arguments:

    • expression - the value to return
    • variableName - the name of a variable in which the result is to be stored.

    Returns:
    the value passed in

    Related Assertions, automatically generated:

    • assertExpression ( expression, pattern )
    • assertNotExpression ( expression, pattern )
    • verifyExpression ( expression, pattern )
    • verifyNotExpression ( expression, pattern )
    • waitForExpression ( expression, pattern )
    • waitForNotExpression ( expression, pattern )

    storeHtmlSource ( variableName )
    Returns the entire HTML source between the opening and closing "html" tags.

    Returns:
    the entire HTML source

    Related Assertions, automatically generated:


    storeLocation ( variableName )
    Gets the absolute URL of the current page.

    Returns:
    the absolute URL of the current page

    Related Assertions, automatically generated:


    storeLogMessages ( variableName )
    Return the contents of the log.

    This is a placeholder intended to make the code generator make this API available to clients. The selenium server will intercept this call, however, and return its recordkeeping of log messages since the last call to this API. Thus this code in Javascrīpt will never be called.

    The reason I opted for a servercentric solution is to be able to support multiple frames served from different domains, which would break a centralized Javascrīpt logging mechanism under some conditions.

    Returns:
    all log messages seen since the last call to this API

    Related Assertions, automatically generated:


    storePrompt ( variableName )
    Retrieves the message of a Javascrīpt question prompt dialog generated during the previous action.

    Successful handling of the prompt requires prior execution of the answerOnNextPrompt command. If a prompt is generated but you do not get/verify it, the next Selenium action will fail.

    NOTE: under Selenium, Javascrīpt prompts will NOT pop up a visible dialog.

    NOTE: Selenium does NOT support Javascrīpt prompts that are generated in a page's onload() event handler. In this case a visible dialog WILL be generated and Selenium will hang until someone manually clicks OK.

    Returns:
    the message of the most recent Javascrīpt question prompt

    Related Assertions, automatically generated:


    storeSelectedId ( selectLocator, variableName )
    Gets option element ID for selected option in the specified select element.

    Arguments:

    • selectLocator - an element locator identifying a drop-down menu
    • variableName - the name of a variable in which the result is to be stored.

    Returns:
    the selected option ID in the specified select drop-down

    Related Assertions, automatically generated:

    • assertSelectedId ( selectLocator, pattern )
    • assertNotSelectedId ( selectLocator, pattern )
    • verifySelectedId ( selectLocator, pattern )
    • verifyNotSelectedId ( selectLocator, pattern )
    • waitForSelectedId ( selectLocator, pattern )
    • waitForNotSelectedId ( selectLocator, pattern )

    storeSelectedIds ( selectLocator, variableName )
    Gets all option element IDs for selected options in the specified select or multi-select element.

    Arguments:

    • selectLocator - an element locator identifying a drop-down menu
    • variableName - the name of a variable in which the result is to be stored.

    Returns:
    an array of all selected option IDs in the specified select drop-down

    Related Assertions, automatically generated:

    • assertSelectedIds ( selectLocator, pattern )
    • assertNotSelectedIds ( selectLocator, pattern )
    • verifySelectedIds ( selectLocator, pattern )
    • verifyNotSelectedIds ( selectLocator, pattern )
    • waitForSelectedIds ( selectLocator, pattern )
    • waitForNotSelectedIds ( selectLocator, pattern )

    storeSelectedIndex ( selectLocator, variableName )
    Gets option index (option number, starting at 0) for selected option in the specified select element.

    Arguments:

    • selectLocator - an element locator identifying a drop-down menu
    • variableName - the name of a variable in which the result is to be stored.

    Returns:
    the selected option index in the specified select drop-down

    Related Assertions, automatically generated:

    • assertSelectedIndex ( selectLocator, pattern )
    • assertNotSelectedIndex ( selectLocator, pattern )
    • verifySelectedIndex ( selectLocator, pattern )
    • verifyNotSelectedIndex ( selectLocator, pattern )
    • waitForSelectedIndex ( selectLocator, pattern )
    • waitForNotSelectedIndex ( selectLocator, pattern )

    storeSelectedIndexes ( selectLocator, variableName )
    Gets all option indexes (option number, starting at 0) for selected options in the specified select or multi-select element.

    Arguments:

    • selectLocator - an element locator identifying a drop-down menu
    • variableName - the name of a variable in which the result is to be stored.

    Returns:
    an array of all selected option indexes in the specified select drop-down

    Related Assertions, automatically generated:

    • assertSelectedIndexes ( selectLocator, pattern )
    • assertNotSelectedIndexes ( selectLocator, pattern )
    • verifySelectedIndexes ( selectLocator, pattern )
    • verifyNotSelectedIndexes ( selectLocator, pattern )
    • waitForSelectedIndexes ( selectLocator, pattern )
    • waitForNotSelectedIndexes ( selectLocator, pattern )

    storeSelectedLabel ( selectLocator, variableName )
    Gets option label (visible text) for selected option in the specified select element.

    Arguments:

    • selectLocator - an element locator identifying a drop-down menu
    • variableName - the name of a variable in which the result is to be stored.

    Returns
  • Selenium IDE(转)

    2007-11-12 13:46:47

    The IDE used to record scrīpts is currently only available in Firefox.

    1.1 Installing the IDE

     

    The Selenium IDE is an extension that needs to be installed before use.

    To install the IDE follow the steps outlined below:

    Step 1: Launch Firefox.

     

     

     

     

     

     

     

     

     

     

     


    Step 2: Drag and drop the Selenium IDE xpi file into the browser window

    Step 3: Wait until the Install Now button is activated on the Software Installation dialog that appears

    Step 4: Click Install Now. The extension will be installed by the browser

    Step 5: In order to activate the extension, you need to restart Firefox

     

    The Selenium IDE should now be installed


    1.2 Starting the IDE

     

    By clicking Tools => Selenium IDE.

    This will start the IDE in a new window.

    1.3 A Quick Overview of the Selenium IDE

     

    The main features of the IDE are outlined below:

    a.      Base URL

    The base URL is the starting point for your scrīpts.

     

    b.      Record & Player Toolbar

    Allows you to play, pause and record scrīpts. You can also step through a scrīpt one command at a time using the Step button.

     

    c.      Mode Selection Bar

    Three modes are available and control the speed at which the scrīpt is played back.

     

    d.      Command Window

    Hold a list of commands that have been recorded or are to be played back.

     

    1.4 Recording a scrīpt

     

    Recording a new scrīpt using the IDE is fairly straight forward.

    The basic steps involved when recording a scrīpt are:

    1.       Start the IDE

    2.       Make sure the record button is activated

    3.       Enter the web site address into the web browser

    4.       Perform required tasks

    5.       Stop scrīpt

    6.       Playback

     

    A Newly Recorded Selenium scrīpt

     

     

    1.5 Saving Your scrīpts

     

    You can save your scrīpt by going to File => Save Test in the menu bar or by pressing CTRL + S.

     

    1.6 Breakpoints

     

    Breakpoints are points in your scrīpt where execution will stop. You will need to manually restart the test in order to continue. Breakpoints are helpful when debugging scrīpts and when writing complex scrīpts that require a lot of attention to detail.

    To set a breakpoint, you can do one of two things:

    One:

    ·    Select the command on which you like to set the breakpoint

    ·    Right click and select Toggle Breakpoint

    Two:

    ·    Select the command on which you like to set the breakpoint

    ·    Press B to set the breakpoint

     

    To remove a breakpoint, simply repeat the process used to set the breakpoint. With breakpoints set in your scrīpt, you will need to manually step over these points using either the pause/resume button or the step button. Both are located on the Record & Playback Toolbar.

     

    1.7 Using Variables

     

    Variables can be set for use within your scrīpts. You would normally declare your variable list at the beginning of your scrīpt to allow them to be used everywhere throughout the scrīpt. Variables need to follow a basic format.

     

    Variable Examples:

    store

    tasec

    siteURL

    store

    wbxadmin

    siteAdmin

    store

    pass

    sa_password

     

    The store command notifies Selenium that you intend to declare a variable for use within your scrīpt. The next item is the value that will be stored in the variable. The final item is the name you wish to give the variable. All variables must follow this format in order to be declared correctly.

     

    You can then access the variables above using the following values within your scrīpt:

    ${siteURL}

    ${siteAdmin}

    ${sa_password}

     

    1.8 Set Assertions

    We need to set assertions in the scrīpts to check current status. There are two modules: Assert and Verify. When Assert fails, it will exit the test. When Verify fails, test will be continued.

  • 球场交易与换工作

    2007-10-23 10:40:31

       1 不要说是因为没有得到应得的报酬而要求交易。当一个百万富翁跑到大家面前哭穷的时候,试问会有几个人真正在意?

       不要说是因为没有得到相应的薪水而换工作

      2 不要让别人知道你到底有多么的想离开。你必须保持沉默,如果你叫嚣着说出非走不可的话,那最直接的结果就是丧失了球迷和队友们的同情。

       离职前不要让别人知道你想离开

      3 不要相信媒体。跟媒体打交道的时候,别在你自己认为双方的交谈只是非正式的就可以乱说话,你需要再三考虑。媒体只会让你的交易要求变得更加复杂,并爆出一些虚假的流言。

        不要相信别人的话

      4 不要背弃你的队友。当你想要离开的时候,可不能把整支球队都出卖掉。最坏的说法,就是你想离开只是因为球队缺乏竞争力,这样你可能中的新队友们会认为你是一个喜欢背后伤人的阴险之徒。

        不要说你同事的不是(任何时候)

      5 另外一个不应该被牵扯到的人就是主教练。几乎所有的主教练都是和球队的球星站在同一个战壕里的,无论如何你也要尊重他们的权威,即使他们确实没有能力为球队带来好成绩。

        走的时候不要抱怨任何人

      6 不要公开表示你想要去哪座城市。那些为了你的离去而伤心欲绝的球迷们,你不应该用这样的方式疏远他们。

        不要让别人知道你想(要)去新公司

      7 把你的家庭和生意完全的分离开。这一条往往容易被人们忽略,不要让你的家人或者朋友给媒体抓到话柄,要自己把握好生意,你不能让人看上去只是一个被妈妈看护着的乖儿子。

        把家庭和工作分开

      8 告诉你的经纪人,做好经济人工作,别去当小喇叭。让他在于外界隔绝的情况下进行谈判。有时候虽然你保持了沉默,但一个多嘴的经纪人同样能够让你看上去无助而且贪婪。

       告诉你的朋友,不要说你新工作的事

      9 无论发生什么,都不要用缺席比赛、训练或球队活动的方式来达到交易的目的。作为球员,就必须尊重比赛(其实这才是最重要的一条)。

       还没有离职时,做好自己应该做的事情

      10 要记住总有些人是希望你被交易的。

       有些人希望你离职

  • 性能测试测试分析-简要篇(转)

    2007-10-10 18:10:30

    分析原则:

    具体问题具体分析(这是由于不同的应用系统,不同的测试目的,不同的性能关注点)

    查找瓶颈时按以下顺序,由易到难。

        服务器硬件瓶颈-〉网络瓶颈(对局域网,可以不考虑)-〉服务器操作系统瓶颈(参数配置)-〉中间件瓶颈(参数配置,数据库web服务器等)-〉应用瓶颈(SQL语句、数据库设计、业务逻辑、算法等)

        注:以上过程并不是每个分析中都需要的,要根据测试目的和要求来确定分析的深度。对一些要求低的,我们分析到应用系统在将来大的负载压力(并发用户数、数据量)下,系统的硬件瓶颈在哪儿就够了。

    分段排除法 很有效

    分析的信息来源:

    •1 根据场景运行过程中的错误提示信息

    •2 根据测试结果收集到的监控指标数据

    一.错误提示分析

    分析实例:

    1 •Error: Failed to connect to server “10.10.10.30:8080″: [10060] Connection

    •Error: timed out Error: Server “10.10.10.30″ has shut down the connection prematurely

    分析:

    •A、应用服务死掉。

    (小用户时:程序上的问题。程序上处理数据库的问题)

    •B、应用服务没有死

    (应用服务参数设置问题)

        例:在许多客户端连接Weblogic应用服务器被拒绝,而在服务器端没有错误显示,则有可能是Weblogic中的server元素的AcceptBacklog属性值设得过低。如果连接时收到connection refused消息,说明应提高该值,每次增加25

    •C、数据库的连接

    (1、在应用服务的性能参数可能太小了 2、数据库启动的最大连接数(跟硬件的内存有关))

    2 Error: Page download timeout (120 seconds) has expired

    分析:可能是以下原因造成

    •A、应用服务参数设置太大导致服务器的瓶颈

    •B、页面中图片太多

    •C、在程序处理表的时候检查字段太大多

    二.监控指标数据分析

    1.最大并发用户数:

    应用系统在当前环境(硬件环境、网络环境、软件环境(参数配置))下能承受的最大并发用户数。

        在方案运行中,如果出现了大于3个用户的业务操作失败,或出现了服务器shutdown的情况,则说明在当前环境下,系统承受不了当前并发用户的负载压力,那么最大并发用户数就是前一个没有出现这种现象的并发用户数。

        如果测得的最大并发用户数到达了性能要求,且各服务器资源情况良好,业务操作响应时间也达到了用户要求,那么OK。否则,再根据各服务器的资源情况和业务操作响应时间进一步分析原因所在。

    2.业务操作响应时间:

        • 分析方案运行情况应从平均事务响应时间图和事务性能摘要图开始。使用事务性能摘要图,可以确定在方案执行期间响应时间过长的事务。

    细分事务并分析每个页面组件的性能。查看过长的事务响应时间是由哪些页面组件引起的?问题是否与网络或服务器有关?

    如果服务器耗时过长,请使用相应的服务器图确定有问题的服务器度量并查明服务器性能下降的原因。如果网络耗时过长,请使用网络监视器图确定导致性能瓶颈的网络问题

    3.服务器资源监控指标:

    内存:

    1 UNIX资源监控中指标内存页交换速率(Paging rate),如果该值偶尔走高,表明当时有线程竞争内存。如果持续很高,则内存可能是瓶颈。也可能是内存访问命中率低。

    2 Windows资源监控中,如果Process\Private Bytes计数器和Process\Working Set计数器的值在长时间内持续升高,同时Memory\Available bytes计数器的值持续降低,则很可能存在内存泄漏。

    内存资源成为系统性能的瓶颈的征兆:

    很高的换页率(high pageout rate);

    进程进入不活动状态;

    交换区所有磁盘的活动次数可高;

    可高的全局系统CPU利用率

    内存不够出错(out of memory errors)

    处理器:

    1 UNIX资源监控(Windows操作系统同理)中指标CPU占用率(CPU utilization),如果该值持续超过95%,表明瓶颈是CPU。可以考虑增加一个处理器或换一个更快的处理器。如果服务器专用于SQL Server,可接受的最大上限是80-85% 

    合理使用的范围在60%70%

    2 Windows资源监控中,如果System\Processor Queue Length大于2,而处理器利用率(Processor Time)一直很低,则存在着处理器阻塞。

    CPU资源成为系统性能的瓶颈的征兆

    很慢的响应时间(slow response time) 

    CPU空闲时间为零(zero percent idle CPU) 

    过高的用户占用CPU时间(high percent user CPU) 

    过高的系统占用CPU时间(high percent system CPU) 

    长时间的有很长的运行进程队列(large run queue size sustained over time)

    磁盘I/O

    1 UNIX资源监控(Windows操作系统同理)中指标磁盘交换率(Disk rate),如果该参数值一直很高,表明I/O有问题。可考虑更换更快的硬盘系统。

    2 Windows资源监控中,如果 Disk TimeAvg.Disk Queue Length的值很高,而Page Reads/sec页面读取操作速率很低,则可能存在磁盘瓶径。

    I/O资源成为系统性能的瓶颈的征兆 :

    过高的磁盘利用率(high disk utilization) 

    太长的磁盘等待队列(large disk queue length) 

    等待磁盘I/O的时间所占的百分率太高(large percentage of time waiting for disk I/O) 

    太高的物理I/O速率:large physical I/O rate(not sufficient in itself) 

    过低的缓存命中率(low buffer cache hit ratio(not sufficient in itself)) 

    太长的运行进程队列,但CPU却空闲(large run queue with idle CPU)

    4.数据库服务器:

    SQL Server数据库:

    1 SQLServer资源监控中指标缓存点击率(Cache Hit Ratio),该值越高越好。如果持续低于80%,应考虑增加内存。

    2 如果Full Scans/sec(全表扫描/秒)计数器显示的值比12高,则应分析你的查询以确定是否确实需要全表扫描,以及SQL查询是否可以被优化。 

    3 Number of Deadlocks/sec(死锁的数量/):死锁对应用程序的可伸缩性非常有害,并且会导致恶劣的用户体验。该计数器的值必须为0

    4 Lock Requests/sec(锁请求/),通过优化查询来减少读取次数,可以减少该计数器的值。

    Oracle数据库:

    1 如果自由内存接近于0而且库快存或数据字典快存的命中率小于0.90,那么需要增加SHARED_POOL_SIZE的大小。

    快存(共享SQL区)和数据字典快存的命中率: 

    select(sum(pins-reloads))/sum(pins) from v$librarycache; 

    select(sum(gets-getmisses))/sum(gets) from v$rowcache; 

    自由内存: select * from v$sgastat where name=’free memory’; 

    2 如果数据的缓存命中率小于0.90,那么需要加大DB_BLOCK_BUFFERS参数的值(单位:块)。

    缓冲区高速缓存命中率:

    select name,value from v$sysstat where name in (’db block gets’,

    ‘consistent gets’,'physical reads’) ;

    Hit Ratio = 1-(physical reads / ( db block gets + consistent gets))

    3 如果日志缓冲区申请的值较大,则应加大LOG_BUFFER参数的值。

    日志缓冲区的申请情况 :

    select name,value from v$sysstat where name = ‘redo log space requests’ ;

    4 如果内存排序命中率小于0.95,则应加大SORT_AREA_SIZE以避免磁盘排序。

    内存排序命中率 :

    select round((100*b.value)/decode((a.value+b.value), 0, 1, (a.value+b.value)), 2)from v$sysstat a, v$sysstat b where a.name=’sorts (disk)’ and b.name=’sorts (memory)’

    注:上述SQL ServerOracle数据库分析,只是一些简单、基本的分析,特别是Oracle数据库的分析和优化,是一门专门的技术,进一步的分析可查相关资料。

     

  • 各种排序算法java实现

    2007-10-10 16:26:08

    插入排序:

    public class InsertSort implements SortUtil.Sort{

        public void sort(int[] data) {
            int temp;
            for(int i=1;i<data.length;i++){
                for(int j=i;(j>0)&&(data[j]<data[j-1]);j--){
                    SortUtil.swap(data,j,j-1);
                }
            }       
        }

    }
    冒泡排序:

    public class BubbleSort implements SortUtil.Sort{

        public void sort(int[] data) {
            int temp;
            for(int i=0;i<data.length;i++){
                for(int j=data.length-1;j>i;j--){
                    if(data[j]<data[j-1]){
                        SortUtil.swap(data,j,j-1);
                    }
                }
            }
        }

    }

    选择排序:

    public class SelectionSort implements SortUtil.Sort {
        public void sort(int[] data) {
            int temp;
            for (int i = 0; i < data.length; i++) {
                int lowIndex = i;
                for (int j = data.length - 1; j > i; j--) {
                    if (data[j] < data[lowIndex]) {
                        lowIndex = j;
                    }
                }
                SortUtil.swap(data,i,lowIndex);
            }
        }

    }

    Shell排序:

    public class ShellSort implements SortUtil.Sort{
        public void sort(int[] data) {
            for(int i=data.length/2;i>2;i/=2){
                for(int j=0;j<i;j++){
                    insertSort(data,j,i);
                }
            }
            insertSort(data,0,1);
        }

        private void insertSort(int[] data, int start, int inc) {
            int temp;
            for(int i=start+inc;i<data.length;i+=inc){
                for(int j=i;(j>=inc)&&(data[j]<data[j-inc]);j-=inc){
                    SortUtil.swap(data,j,j-inc);
                }
            }
        }

    }

    快速排序:

    public class QuickSort implements SortUtil.Sort{

        public void sort(int[] data) {
            quickSort(data,0,data.length-1);       
        }
        private void quickSort(int[] data,int i,int j){
            int pivotIndex=(i+j)/2;
            //swap
            SortUtil.swap(data,pivotIndex,j);
           
            int k=partition(data,i-1,j,data[j]);
            SortUtil.swap(data,k,j);
            if((k-i)>1) quickSort(data,i,k-1);
            if((j-k)>1) quickSort(data,k+1,j);
           
        }
       
        private int partition(int[] data, int l, int r,int pivot) {
            do{
               while(data[++l]<pivot);
               while((r!=0)&&data[--r]>pivot);
               SortUtil.swap(data,l,r);
            }
            while(l<r);
            SortUtil.swap(data,l,r);       
            return l;
        }

    }
    改进后的快速排序:


    public class ImprovedQuickSort implements SortUtil.Sort {

        private static int MAX_STACK_SIZE=4096;
        private static int THRESHOLD=10;
      
        public void sort(int[] data) {
            int[] stack=new int[MAX_STACK_SIZE];
           
            int top=-1;
            int pivot;
            int pivotIndex,l,r;
           
            stack[++top]=0;
            stack[++top]=data.length-1;
           
            while(top>0){
                int j=stack[top--];
                int i=stack[top--];
               
                pivotIndex=(i+j)/2;
                pivot=data[pivotIndex];
               
                SortUtil.swap(data,pivotIndex,j);
               
                //partition
                l=i-1;
                r=j;
                do{
                    while(data[++l]<pivot);
                    while((r!=0)&&(data[--r]>pivot));
                    SortUtil.swap(data,l,r);
                }
                while(l<r);
                SortUtil.swap(data,l,r);
                SortUtil.swap(data,l,j);
               
                if((l-i)>THRESHOLD){
                    stack[++top]=i;
                    stack[++top]=l-1;
                }
                if((j-l)>THRESHOLD){
                    stack[++top]=l+1;
                    stack[++top]=j;
                }
               
            }
            //new InsertSort().sort(data);
            insertSort(data);
        }
        /**
         * @param data
         */
        private void insertSort(int[] data) {
            int temp;
            for(int i=1;i<data.length;i++){
                for(int j=i;(j>0)&&(data[j]<data[j-1]);j--){
                    SortUtil.swap(data,j,j-1);
                }
            }      
        }

    }

    归并排序:

    package org.rut.util.algorithm.support;

    import org.rut.util.algorithm.SortUtil;

    /**
     * @author treeroot
     * @since 2006-2-2
     * @version 1.0
     */
    public class MergeSort implements SortUtil.Sort{

        /* (non-Javadoc)
         * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
         */
        public void sort(int[] data) {
            int[] temp=new int[data.length];
            mergeSort(data,temp,0,data.length-1);
        }
       
        private void mergeSort(int[] data,int[] temp,int l,int r){
            int mid=(l+r)/2;
            if(l==r) return ;
            mergeSort(data,temp,l,mid);
            mergeSort(data,temp,mid+1,r);
            for(int i=l;i<=r;i++){
                temp[i]=data[i];
            }
            int i1=l;
            int i2=mid+1;
            for(int cur=l;cur<=r;cur++){
                if(i1==mid+1)
                    data[cur]=temp[i2++];
                else if(i2>r)
                    data[cur]=temp[i1++];
                else if(temp[i1]<temp[i2])
                    data[cur]=temp[i1++];
                else
                    data[cur]=temp[i2++];           
            }
        }

    }

    改进后的归并排序:

    package org.rut.util.algorithm.support;

    import org.rut.util.algorithm.SortUtil;

    /**
     * @author treeroot
     * @since 2006-2-2
     * @version 1.0
     */
    public class ImprovedMergeSort implements SortUtil.Sort {

        private static final int THRESHOLD = 10;

        /*
         * (non-Javadoc)
         *
         * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
         */
        public void sort(int[] data) {
            int[] temp=new int[data.length];
            mergeSort(data,temp,0,data.length-1);
        }

        private void mergeSort(int[] data, int[] temp, int l, int r) {
            int i, j, k;
            int mid = (l + r) / 2;
            if (l == r)
                return;
            if ((mid - l) >= THRESHOLD)
                mergeSort(data, temp, l, mid);
            else
                insertSort(data, l, mid - l + 1);
            if ((r - mid) > THRESHOLD)
                mergeSort(data, temp, mid + 1, r);
            else
                insertSort(data, mid + 1, r - mid);

            for (i = l; i <= mid; i++) {
                temp[i] = data[i];
            }
            for (j = 1; j <= r - mid; j++) {
                temp[r - j + 1] = data[j + mid];
            }
            int a = temp[l];
            int b = temp[r];
            for (i = l, j = r, k = l; k <= r; k++) {
                if (a < b) {
                    data[k] = temp[i++];
                    a = temp[i];
                } else {
                    data[k] = temp[j--];
                    b = temp[j];
                }
            }
        }

        /**
         * @param data
         * @param l
         * @param i
         */
        private void insertSort(int[] data, int start, int len) {
            for(int i=start+1;i<start+len;i++){
                for(int j=i;(j>start) && data[j]<data[j-1];j--){
                    SortUtil.swap(data,j,j-1);
                }
            }
        }

    }
    堆排序:

    package org.rut.util.algorithm.support;

    import org.rut.util.algorithm.SortUtil;

    /**
     * @author treeroot
     * @since 2006-2-2
     * @version 1.0
     */
    public class HeapSort implements SortUtil.Sort{

        /* (non-Javadoc)
         * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
         */
        public void sort(int[] data) {
            MaxHeap h=new MaxHeap();
            h.init(data);
            for(int i=0;i<data.length;i++)
                h.remove();
            System.arraycopy(h.queue,1,data,0,data.length);
        }


         private static class MaxHeap{
            
           
            void init(int[] data){
                this.queue=new int[data.length+1];
                for(int i=0;i<data.length;i++){
                    queue[++size]=data[i];
                    fixUp(size);
                }
            }
            
            private int size=0;

            private int[] queue;
                   
            public int get() {
                return queue[1];
            }

            public void remove() {
                SortUtil.swap(queue,1,size--);
                fixDown(1);
            }
            //fixdown
            private void fixDown(int k) {
                int j;
                while ((j = k << 1) <= size) {
                    if (j < size && queue[j]<queue[j+1])
                        j++;
                    if (queue[k]>queue[j]) //不用交换
                        break;
                    SortUtil.swap(queue,j,k);
                    k = j;
                }
            }
            private void fixUp(int k) {
                while (k > 1) {
                    int j = k >> 1;
                    if (queue[j]>queue[k])
                        break;
                    SortUtil.swap(queue,j,k);
                    k = j;
                }
            }

        }

    }

     

    SortUtil:

    package org.rut.util.algorithm;

    import org.rut.util.algorithm.support.BubbleSort;
    import org.rut.util.algorithm.support.HeapSort;
    import org.rut.util.algorithm.support.ImprovedMergeSort;
    import org.rut.util.algorithm.support.ImprovedQuickSort;
    import org.rut.util.algorithm.support.InsertSort;
    import org.rut.util.algorithm.support.MergeSort;
    import org.rut.util.algorithm.support.QuickSort;
    import org.rut.util.algorithm.support.SelectionSort;
    import org.rut.util.algorithm.support.ShellSort;

    /**
     * @author treeroot
     * @since 2006-2-2
     * @version 1.0
     */
    public class SortUtil {
        public final static int INSERT = 1;

        public final static int BUBBLE = 2;

        public final static int SELECTION = 3;

        public final static int SHELL = 4;

        public final static int QUICK = 5;

        public final static int IMPROVED_QUICK = 6;

        public final static int MERGE = 7;

        public final static int IMPROVED_MERGE = 8;

        public final static int HEAP = 9;

        public static void sort(int[] data) {
            sort(data, IMPROVED_QUICK);
        }
        private static String[] name={
                "insert","bubble","selection","shell","quick","improved_quick","merge","improved_merge","heap"
        };
       
        private static Sort[] impl=new Sort[]{
                new InsertSort(),
                new BubbleSort(),
                new SelectionSort(),
                new ShellSort(),
                new QuickSort(),
                new ImprovedQuickSort(),
                new MergeSort(),
                new ImprovedMergeSort(),
                new HeapSort()
        };

        public static String toString(int algorithm){
            return name[algorithm-1];
        }
       
        public static void sort(int[] data, int algorithm) {
            impl[algorithm-1].sort(data);
        }

        public static interface Sort {
            public void sort(int[] data);
        }

        public static void swap(int[] data, int i, int j) {
            int temp = data[i];
            data[i] = data[j];
            data[j] = temp;
        }
    }

     
     

  • 生活小常识

    2007-10-10 16:16:19

    1 、巧用牙膏6:若有小面积皮肤损伤或烧伤、烫伤,抹上少许牙膏,可立即止血止痛,也可防止感染,疗效颇佳。

    2 、巧除纱窗油腻3:可将洗衣粉、吸烟剩下的烟头一起放在水里,待溶解后,拿来擦玻璃窗、纱窗,效果均不错。 

    3 、将虾仁放入碗内,加一点精盐、食用碱粉,用手抓搓一会儿后用清水浸泡,然后再用清水洗净,这样能使炒出的虾仁透明如水晶,爽嫩可口。

    4 、和饺子面的窍门1:1斤面粉里掺入6个蛋清,使面里蛋白质增加,包的饺子下锅后蛋白质会很快凝固收缩,饺子起锅后收水快,不易粘连

    5 、将残茶叶浸入水中数天后,浇在植物根部,可促进植物生长;把残茶叶晒干,放到厕所或沟渠里燃熏,可消除恶臭,具有驱除蚊蝇的功能。

    6 、夹生饭重煮法:如果是米饭夹生,可用筷子在饭内扎些直通锅底的孔,洒入少许黄酒重焖,若只表面夹生,只要将表层翻到中间再焖即可。 

    7 、烹调蔬菜时如果必须要焯,焯好菜的水最好尽量利用。如做水饺的菜,焯好的水可适量放在肉馅里,这样即保存营养,又使水饺馅味美有汤。

    8 、炒鸡蛋的窍门:将鸡蛋打入碗中,加入少许温水搅拌均匀,倒入油锅里炒,炒时往锅里滴少许酒,这样炒出的鸡蛋蓬松、鲜嫩、可口。 

    9 、如何使用砂锅1:新买来的砂锅第一次使用时,最好用来熬粥,或者用它煮一煮浓淘米水,以堵塞砂锅的微细孔隙,防止渗水。 

    10 、巧用十三香”:炖肉时用陈皮,香味浓郁;吃牛羊肉加白芷,可除膻增鲜;自制香肠用肉桂,味道鲜美;熏肉熏鸡用丁香,回味无穷。

    11 、和饺子面的窍门2:面要和的略硬一点,和好后放在盆里盖严密封,饧10-15分钟,等面中麦胶蛋白吸水膨胀,充分形成面筋后再包饺子

    12 、香菜是一种伞形花科类植物,富含香精油,香气浓郁,但香精油极易挥发,且经不起长时间加热,香菜最好在食用前加入,以保留其香气。

    13 、当进行高温洗涤或干衣程序时,不可碰触机门玻璃,以免烫伤。拿出烘干的衣物时,要小心衣物上的金属部分,如拉链、纽扣等,以免烫伤。

    14 、如果衣领和袖口较脏,可将衣物先放进溶有洗衣粉的温水中浸泡15-20分钟,再进行正常洗涤,就能洗干净。 

    15 、如何使用砂锅2:用砂锅熬汤、炖肉时,要先往砂锅里放水,再把砂锅置于火上,先用文火,再用旺火。 

    16 、烹调蔬菜时,加点菱粉类淀粉,使汤变得稠浓,不但可使烹调出的蔬菜美味可口,而且由于淀粉含谷胱甘肽,对维生素有保护作用。

    17 、米饭若烧糊了,赶紧将火关掉,在米饭上面放一块面包皮,盖上锅盖,5分钟后,面包皮即可把糊味吸收。 

    18 、洗衣粉用量:若衣服不太脏或洗涤时泡沫过多,则要减少洗衣粉用量。避免洗衣粉使用过量,不仅省钱而且保护环境,可令洗衣机更耐用。 

    19 、煮饺子时要添足水,待水开后加入2%的食盐,溶解后再下饺子,能增加面筋的韧性,饺子不会粘皮、粘底,饺子的色泽会变白,汤清饺香。 

    20 、许多人爱吃青菜却不爱喝菜汤,事实上,烧菜时,大部分维生素已溶解在菜汤里。比如小白菜炒好后,会有70%的维生素C溶解在菜汤里。 

    21 、白袜子若发黄了,可用洗衣粉溶液浸泡30分钟后再进行洗涤。对于衣服上的奶渍捎孟匆路劢形圩赵ご恚缓笤俳姓O吹印?nbsp;

    22 、如何使用砂锅3:从火上端下砂锅时,一定要放在干燥的木板或草垫上,切不要放在瓷砖或水泥地面上。 

    23 、烧荤菜时,在加了酒后,再加点醋,菜就会变得香喷喷的。烧豆芽之类的素菜时,适当加点醋,味道好营养也好,因为醋对维生素有保护作用

    24 、面包能消除衣服油迹:用餐时,衣服如果被油迹所染,可用新鲜白面包轻轻摩擦,油迹即可消除。 

    25 、用残茶叶擦洗木、竹桌椅,可使之更为光洁。把残茶叶晒干,铺撒在潮湿处,能够去潮;残茶叶晒干后,还可装入枕套充当枕芯,非常柔软。

    26 、饺子煮熟以后,先用笊篱把饺子捞出,随即放入温开水中浸涮一下,然后再装盘,饺子就不会互相粘在一起了。

    27 、炒鲜虾的窍门:炒鲜虾之前,可先将虾用浸泡桂皮的沸水冲烫一下,然后再炒,这样炒出来的虾,味道更鲜美。 

    28 、蔬菜尽可能做到现炒现吃,避免长时间保温和多次加热。另外,为使菜梗易熟,可在快炒后加少许水闷熟。

    29 、面包能消除地毯污迹:家中的小块地毯如果脏了,可用热面包渣擦拭,然后将其挂在阴凉处,24小时后,污迹即可除净。

    30 、男子剃须时,可用牙膏代替肥皂,由于牙膏不含游离碱,不仅对皮肤无刺激,而且泡沫丰富,气味清香,使人有清凉舒爽之感。

    31 、风油精的妙用(1:在电风扇的叶子上洒上几滴风油精,随着风叶的不停转动,可使满室清香,而且有驱赶蚊子的效用。

    32 、刷油漆前,先在双手上抹层面霜,刷过油漆后把奶油涂于沾有油漆的皮肤上,用干布擦拭,再用香皂清洗,就能把附着于皮肤上的油漆除掉。

    33 、豆腐一般都会有一股卤水味。豆腐下锅前,如果先在开水中浸泡10多分钟,便可除去卤水味,这样做出的豆腐不但口感好,而且味美香甜。 

    34 、煮鸡蛋时,可先将鸡蛋放入冷水中浸泡一会,再放入热水里煮,这样煮好的鸡蛋蛋壳不破裂,且易于剥掉。

    35 、手表受磁,会影响走时准确。消除方法很简单,只要找一个未受磁的铁环,将表放在环中,慢慢穿来穿去,几分钟后,手表就会退磁复原。

    36 、豆腐性偏寒,平素有胃寒者,如食用豆腐后有胸闷、反胃等现象,则不宜食用;易腹泻、腹胀脾虚者,也不宜多食豆腐。

    37 、牙膏也有洁肤功能!洗澡时用牙膏代替浴皂搓身去污,既有明显的洁肤功能,还能使浴后浑身凉爽,而且还有预防痱子的作用。

    38 、用微波炉做菜时,首先要用调料将原料浸透。这是因为微波烹任过程快,若不浸润透很难入味,且葱、姜、蒜等增香的作用也难以发挥。

    39 、葡萄汁送服降压药效果好!用葡萄汁代替白开水送服降压药,能使血压降得平稳,且不会出现血压忽高忽低的现象。

    40 、煮饭不宜用生水。因为自来水中含有氯气,在烧饭过程中,它会破坏粮食中所含的维生素B1,若用开水煮饭,维生素B1可免受损失。 

    41 、砧板防裂小窍门:买回新砧板后,在砧板上下两面及周边涂上食用油,待油吸干后再涂,涂三四遍,油干后即可使用,这样砧板便会经久耐用 

    42 、风油精的妙用(2:洗澡时,在水中加入数滴风油精,浴后会有浑身清凉舒爽感觉,还有防治痱子、防蚊叮咬、祛除汗臭的作用。

    43 、炸馒头片时,先将馒头片在冷水里浸一下,然后再入锅炸,这样炸好的馒头片焦黄酥脆,既好吃又省油。

    44 、做菜或做汤时,如果做咸了,可拿一个洗净的土豆切成两半放入汤里煮几分钟,这样,汤就能由咸变淡了。

    45 、舒缓眼部疲劳小窍门:用水浸泡药用小米草或母菊花,然后将毛巾浸湿,敷于眼部1015分钟,可有效舒缓眼部疲劳。 

    46 、夏日天气炎热,身上容易长痱子,可用温水将长有痱子的部位洗净,涂擦一层牙膏,痱子不久即可消失。

    47 、室内厕所即使冲洗得再干净,也常会留下一股臭味,只要在厕所内放置一小杯香醋,臭味便会消失。其有效期为六、七天,可每周换一次。

    48 、如果用陈米做米饭,淘过米之后,可在往米中加水的同时,加入1/41/5啤酒,这样蒸出来的米饭香甜,且有光泽,如同新米一样。 

    49 、煮饺子时,饺子皮和馅中的水溶性营养素除因受热小部分损失之外,大部分都溶解在汤里,所以,吃水饺最好把汤也喝掉。

    50 、热水泡双手可治偏头痛。把双手浸入热水中,水量以浸过手腕为宜,并不断地加热水,以保持水温。半小时后,痛感即可减轻,甚至完全消失
    51
    、忌食鲜黄花菜!因为鲜黄花菜内含秋水仙碱有毒物质,食用后会导致恶心、腹泻等。而加工后的干黄花菜已将秋水仙碱溶出,食用则不会中毒 

    52 、风油精的妙用(3:在点燃的蚊香上洒几滴风油精,蚊香放出的烟气不会呛,而且清香扑鼻,驱蚊效果也会更佳。

    53 、在洗碗水中放几片柠檬皮和橘子皮,或滴几滴醋,能消除碗碟等餐具上的异味。同时,它还能使硬水软化,同时增加瓷器的光泽感。

    54 、皮肤小面积擦伤会导致局部肿胀,这时可在伤口处涂些牙膏,不仅具有止痛、止血、减轻肿胀的功效,还有防止伤口化脓的作用。

    55 、烤肉防焦小窍门:烤肉时,可在烤箱里放一只盛有水的器皿,因为器皿中的水可随烤箱内温度的升高而变成水蒸气,防止烤肉焦糊。 

    56 、巧洗带鱼:带鱼身上的腥味和油腻较大,用清水很难洗净,可把带鱼先放在碱水中泡一下,再用清水洗,就会很容易洗净,而且无腥味。 

    57 、芥末煮水洗脚可降血压。将80芥末面放在洗脚盆里,加半盆水搅匀,用炉火煮开,稍凉后洗脚。每天早晚1次,1天后血压就可下降。 

    58 、煮排骨时放点醋,可使排骨中的钙、磷、铁等矿物质溶解出来,利于吸收,营养价值更高。此外,醋还可以防止食物中的维生素被破坏。

    59 、巧剥蒜皮:将蒜用温水泡3-5分钟捞出,用手一搓,蒜皮即可脱落。如需一次剥好多蒜,可将蒜摊在案板上,用刀轻轻拍打即可脱去蒜皮。

    60 、蚊香定时熄灭法:用一个铁夹子,用时夹在蚊香所需要的长度上,当蚊香烧到铁夹夹的地方时,就会熄灭,既不影响睡眠,也可节约蚊香。 

    61 、面包与饼干不宜一起存放。面包含水分较多,饼干一般则是干而脆,两者如果存放在一起,就会使面包变硬,饼干也会因受潮失去酥脆感。

    62 、烧糖醋鱼块及其它需放醋的菜肴时,最好在即将起锅时再放醋,这样能充分保持醋味,若放的过早,醋就会在烹调过程中蒸发掉而使醋味大减

    63 、梨可防晒!常食梨能使肌肤保持弹性,不起皱纹。梨中含有丰富的维生素E,对太阳光的暴晒能起到防护作用。 

    64 、各种染发剂在室温或炎热的天气中,均会失去部分功能或改变色泽。若放在冰箱中保存,可长期保持其原有的功能,不会变质。

    65 、冷冻食品解冻法1:肉类:适宜在室温下自然解冻,在水中解冻会使营养流失;家禽:宜在水中解冻,但未去内脏的最好在室温下自然解冻。 

    66 、彩电不能自行接地线,如果接地线,一旦电源插头接反时,会使机内地线与电源的火线接通而使机架等部件带电,这样会有触电的危险。

    67 、揭胶纸、胶带的妙法:贴在墙上的胶纸或胶带,如果生硬去揭,会损坏物件,可用蒸汽熨斗熨一下,就能很容易揭去了。 

    68 、皮鞋霉斑清除法:皮鞋放久了发霉时,可用软布蘸酒精加水(1:1)溶液进行擦拭,然后放在通风处晾干。对发霉的皮包也可如此处理。

    69 、巧制肉馅:将要做馅的肉放入冰箱冷冻,待完全冻实后取出,用擦菜板擦肉,很容易就能擦把冻肉成细条,之后,只需用刀剁几下就可以了。 

    70 、皱褶身份证复原法:将身份证放在桌上,上面盖一两层纸,用熨斗隔纸熨烫(温度不易过高),熨好一面再熨另一面,即可使之平展如初。 

    71 、电吹风治疗肩周炎!用电吹风以适当距离对准患者肩部用热风吹约10分钟,每天两次,3周可愈。若先在患者肩部擦上药酒再吹,效果更佳 

    72 、煮肉的时候,如果想使汤味鲜美,应该把肉放入冷水中慢慢地煮;如果想使肉味鲜美,则应该把肉放在热水里煮。

    73 、宝石戒指如何清洗?可用棉棒在氧化镁和氨水混合物,或花露水、甘油中沾湿,擦洗宝石和框架,然后用绒布擦亮即可。

    74 、芦笋可减肥!芦笋能提高人体的基础代谢,促进人体内热量的消耗,并有很强的脱水能力,因此,多吃新鲜芦笋能变得苗条。

    75 、如何让蜡烛不流泪?生日蜡烛用之前先放到冰箱的冷冻室里冷冻24小时,再插到蛋糕上,点燃后就没有烛油流下而弄脏蛋糕了。 

    76 、夏天甲鱼易被蚊子叮咬而死亡,但如果将甲鱼养在冰箱冷藏的果盘盒内,既可防止蚊子叮咬,又可延长甲鱼的存活时间。

    77 、冷冻食品解冻法2:鱼类:宜在5%40-50度食盐水中解冻;蛋品:可装在不透水的金属容器中,将容器浸在20度的水中迅速解冻 

    78 、茶叶与食糖、糖果不宜一起存放。茶叶易吸潮,而食糖、糖果却恰恰含水分多,这两类物品存放在一起,就会使茶叶因受潮而发霉或变味。

    79 、洗涤面粉袋时不要在水中搓洗,可将面袋放在清水中泡1-2天,待发酵后,面粉会从面袋上自动脱落,这时再用清水漂洗,即可干净如初。 

    80 、茶叶受潮不要晒!夏季茶叶容易受潮,若把受潮的茶叶放到太阳下晒就会走味。可用铁锅慢火炒至水气消失,晾干后密封保存,可保持其原味

    81 、牛仔裤穿时间长了就会褪色。可以把新买来的牛仔裤放入浓盐水中浸泡12小时后,再用清水洗净,以后再洗涤时就不会褪色了。 

    82 、丝瓜治慢性喉炎。用丝瓜绞汁或将丝瓜藤切断,让其汁自然滴出,放入碗内,上锅蒸熟,再加适量冰糖饮用,就能有效治疗慢性喉炎。

    83 、有的人吃药总是把药片掰开吃,以为药片小了利于吞咽。其实药片掰开后变成尖的,反而不利于下咽,还易划伤食道,所以药片不要掰开吃。

    84 、指甲油长久不脱落法:涂指甲油之前,先用棉花蘸点醋把指甲擦干净,等醋干后再涂指甲油,这样指甲油就不容易脱落了。 

    85 、识别手机的窍门:正版手机机身号码,外包装号码,从手机上调出的号码三号一致。在验钞机下,进网许可标签右下角显示CMII字样。 

    86 、巧切松花蛋:用刀切松花蛋,蛋黄会粘在刀上,可用丝线将松花蛋割开,既均匀又不粘蛋黄。将刀在热水中烫一下再切,也能切的整齐漂亮。 

    87 、不能用茶叶煮鸡蛋!因为茶叶中除含有生物碱外,还有多种酸化物质,这些化合物与鸡蛋中的铁元素结合,对胃有刺激作用,不利于消化吸收

    88 、瓜果的清洗:食用前,先将瓜果在盐水中浸泡20-30分钟,可去除瓜果表皮残存的农药或寄生虫卵,且盐水还有杀灭某些病菌的作用。

    89 、高压锅烹调火候:高压锅烹调时间从限压阀首次出气算起。鸡1千克加水2千克18分钟可脱骨;排骨1千克加水2千克20分钟可脱骨

    90 、巧选茶叶:看匀度,将茶叶倒入茶盘里,手拿茶盘向一定方向旋转数圈,使不同形状的茶叶分出层次中段茶越多,表明匀度越好。 

    91 、洋葱防衰老。洋葱对人体的结缔组织和关节有益。洋葱不仅能提供人体需要的许多养分,还含有微量元素硒,因此,多食洋葱能够预防衰老。

    92 、巧除家电缝隙的灰尘:家用电器的缝隙里常常会积藏很多灰尘,且用布不宜擦净,可将废旧的毛笔用来清除缝隙里的灰尘,非常方便。 

    93 、首饰收藏与保养的窍门:轻拿轻放,避免碰撞与磨擦;避免受高温和酸、碱溶液接触;经常检查,防止宝石脱落;及时取下收藏和清洗保存。 

    94 、牛奶渍鱼格外香!把收拾好的鱼放到牛奶里泡一下,取出后裹一层干面粉,再入热油锅中炸制,其味道格外香美。

    95 、鉴别珍珠的窍门:将珍珠放在阴暗处,闪闪发光的是上等珍珠;珍珠表面的清洁度和颜色决定珍珠的价值;珍珠越大、越圆越有价值。 

    96 、大枣巧去皮:将干的大枣用清水浸泡3小时,然后放入锅中煮沸,待大枣完全泡开发胖时,将其捞起剥皮,很容易就能剥掉。

    97 、巧选茶叶:看茶叶松紧,紧而重实的质量好,粗而松弛、细而碎的质量差;看净度,茶叶中有较多茶梗、叶柄、茶籽及杂质的质量差。 

    98 、空腹不宜吃柿子。如果空腹吃大量未加工或未去皮的柿子,而胃里的游离酸含量又较高时,就会凝结成块,形成柿石,引起肚子疼、呕吐等。

    99 、巧洗铁锅油垢:炒菜锅用久了,锅上积存的油垢很难清除掉,如果将新鲜的梨皮放在锅里加水煮一会儿,油垢就很容易清除了。 

    100 、瓶子上的塑料瓶盖有时因拧得太紧而打不开,此时可将整个瓶子放入冰箱中(冬季可放在室外)冷冻一会儿,然后再拧,很容易就能拧开。
    101
    、豆腐可用来美容!每天早晨起床后,用豆腐一块,放在掌心,用以摩擦面部几分钟,坚持一个月,面部肌肤就会变得白嫩滋润。 

    102 、高压锅烹调火候:牛肉1千克加水2千克17分钟即可将肉煮烂;大米1500加水1千克9分钟即可煮熟。

    103 、拉链的保养:拉链不能拉得太急、太猛;不能崩得太紧;保持干燥,防止和酸、碱东西接触;拉链发涩,可涂点蜡,轻轻拉几下,即可。

    104 、巧选茶叶:看色泽,绿茶翠绿有光的质量好;红茶褐色带油润的质量好;若绿茶含较多白毫,红茶含较多橙***芽头,均为高级茶。 

    105 、海参的贮藏:将海参晒得干透,装入双层食品塑料袋中,加几头蒜,然后扎紧袋口,悬挂在高处,不会变质生虫。

    106 、在灯下挂一把香葱,或用纱袋装几根葱段,各种小虫都不会飞来。蚊子最怕橘红色光,用橘红色玻璃纸或绸布套在灯泡上,蚊子就不会靠近了 

    107 、在房间里放上几盒开盖的风油精、清凉油,或在墙上涂点薄荷可驱蚊。在室内栽一两株西红柿,西红柿枝叶发出的气味会把蚊子赶走。 

    108 、碱水去鲜桃毛!在清水中放入少许食用碱,将鲜桃放入浸泡3分钟,搅动几下,桃毛便会自动脱落,清洗几下毛就没有了,很方便!

    109 、白背心穿久了会出现黑斑,可取鲜姜2两捣烂放锅内加1斤水煮沸,稍凉后倒入洗衣盆,浸泡白背心十分钟,再反复揉搓几遍,黑斑即可消除

    110 、切肥肉的窍门:切肥肉时,可先将肥肉蘸一下凉水,然后放在案板上,一边切一边洒点凉水,这样切着省力,肥肉也不会滑动,且不易粘案板

    111 、抽烟或长时间使用深色指甲油会使指甲变色,可每天用半个新鲜柠檬擦拭,连续擦上两周即可除去污渍。 

    112 、减少洗衣粉泡沫的窍门:往洗涤液中加少量肥皂粉,泡沫会显著减少。若用洗衣机洗衣,可在洗衣缸里放一杯醋,洗衣粉泡沫就会消失。

    113 、在服用四环素类药物时,不宜吃豆腐,因豆腐中含有较多钙,用盐卤做的石膏中含有较多镁,四环素遇到钙、镁会发生反应,降低杀菌效果。 

    114 、丸子、松肉的配料比例:在烹饪丸子或松肉菜肴时,只要是按50肉、10淀粉的比例调料,就能使松肉松酥、丸子软嫩。

    115 、巧除领带上的皱纹。打皱了的领带,不用熨斗烫也能变得既平整又漂亮,只要把领带卷在啤酒瓶上,第二天再用时,原来的皱纹就消除了。 

    116 、取适量红糖放口中含十分钟后刷牙2-3分钟,漱口。再用盐碱水(清水掺食盐、食碱各50)刷牙2分钟。每日2次,1周后烟垢可脱落

    117 、将废药瓶上的橡皮盖子搜集起来,按纵横交错位置,一排排钉在一块长方形木板上(钉子须钉在盖子凹陷处),就成为一块很实用的搓衣板。 

    118 、使衣物香气袭人:用完的香水瓶、化妆水瓶等不要立即扔掉,把它们的盖打开,放在衣箱或衣柜里,会使衣物变得香气袭人。

    119 、咸肉放时间长了会有一股辛辣味,在煮咸肉时放一个白萝卜,然后再烹调,辛辣味即可除去。若咸肉仅表面有异味,用水加少量醋清洗即可。 

    120 、手表内不小心进水,可用一种叫硅胶的颗粒状物质与手表一起放入密闭的容器内,数小时后取出,表中的积水即可消失。硅胶可反复使用。 

    121 、擀面条时,如果一时找不到擀面杖,可用空玻璃瓶代替。用灌有热水的瓶子擀面条,还可以使硬面变软。 

    122 、用洁厕灵当疏通剂:隔三差五地将适量洁厕灵倒入马桶,盖上马桶盖闷一会儿,再用水冲洗,能保持马桶通畅。

    123 、被蚊虫叮咬后可将热水瓶盖子(取自约90度水温的热水瓶)放在患处摩擦2-3秒钟,然后拿起,连续2-3次,瘙痒即会消失。 

    124 、将待熟的香蕉放入冰箱内贮存,能使香蕉在较长时间内保鲜,即使外皮变色,里面也一样新鲜如初。 

    125 、巧用84消毒液:洗衣时,白色纯棉织物易被其他衣服染色,可将被染衣服泡到稀释后的84消毒液中,利用其脱色性,还您衣服的本来面目 

    126 、用墩布拖地很沉,且容易腰酸背疼,地面也要很长时间才干。用旧毛巾当抹布擦地,干净、干得快、省时间,用旧化纤料效果更好。 

    127 、喝烫过的白酒对人体有益。因白酒中的醛对人体损害较大,只要把酒烫热一些,就可使大部分醛挥发掉,这样对人身体的危害就会少一些。 

    128 、巧用废瓶盖洁墙壁。将几只小瓶盖钉在小木板上,即成一个小铁刷,用它可刮去贴在墙壁上的纸张和鞋底上的泥土等,用途很广。 

    129 、当你非常口渴而家中又无凉开水时,可把装有热水的杯子放入冷水中浸泡,然后在冷水中撒上一把盐,这样能加速开水的冷却。 

    130 、写钢笔字时,如写了错别字,抹点牙膏,一擦就净。圆珠笔芯写字不流利时,将笔头插进吸过香烟的过滤嘴中转一转即可。

    131 、如果你身边只有温开水而又想喝到浓郁的香茶,可在温开水中放少许白糖或红糖,搅拌溶解,然后放入茶叶,5分钟后,你便能如愿以偿。

    132 、将废弃无用的橡皮盖子用双面胶固定在房门的后面,可防止门在开关时与墙的碰撞,能起到保护房门的作用。 

    133 、将西瓜浸入15%的盐水中3-5日,捞出揩干,再用西瓜蔓叶中挤出的水汁涂一遍,密封于聚乙稀塑料袋内,放入地窖,可使西瓜保鲜半年

    134 、鉴别宝石的窍门:将宝石放在衬物上让日光照射,穿透宝石的光线在衬物上呈现金星样子的为真品。若是假宝石,衬物上会呈现一块黑影

    135 、怎样烧鱼鱼不碎?1烧鱼之前,先将鱼下油锅炸一下。如烧鱼块,应裹一层薄薄的淀粉再炸。炸时注意油温宜高不宜低。

    136 、怎样烧鱼鱼不碎?2烧鱼时汤以刚没过鱼为宜,待汤烧开后,要改用小火煨焖至汤浓放香时即可,煨焖时要少翻动鱼,可将锅端起轻轻晃动。

    137 、鸡肉与芹菜同食会伤元气;牛肉与栗子同食后会呕吐;兔肉与芹菜同食会伤头发;蟹与柿子同食会中毒;洋葱与蜂蜜同食会伤眼睛。 

    138 、戳伤手指的救护窍门:用冷湿布冷却患处,用厚纸作夹板固定受伤手指,再用绷带包扎好。普通扭伤或脱位,可自行将患处整复好,恢复原状

    139 、面粉能洗净葡萄!葡萄去蒂放在水盆里,加入适量面粉,用手轻搅几下,然后将浑浊的面粉水倒掉,用清水冲净即可。 

    140 、车船行驶途中,将鲜姜片随时放在鼻孔下面闻,使辛辣味吸入鼻中,可以防晕车;将姜片贴在肚脐上,用伤湿止痛膏固定好,有相同效果。 

    141 、旅途中处理脚泡的方法:先用热水烫脚十分钟,用消过毒的针刺破脚泡,使泡内液体流出、排干,再将脚泡部位消毒。忌剪去泡皮,以防感染

    142 、旅途中小腿抽筋的防治:扳脚法:取坐姿,一手用力压迫痉挛的腿肚肌肉,一手抓住足趾向后扳脚,使足部背曲,再活动一下,即可缓解。

    143 、旅途中遭遇雷雨时,千万不要在巨石、悬崖下和山洞口躲避,电流从这些地方通过时会产生电弧,击伤避雨者。若山洞很深,可躲在里面 

    144 、受潮软化的饼干放入冰箱冷藏几天,即可恢复原状;切洋葱等蔬菜时,可将其去皮放入冰箱冷冻室存放数小时后再切,就不会刺眼流泪了。 

    145 、酿酒用的葡萄皮有丰富的抗氧化剂,经常适量饮点红酒,能增加好的胆固醇,减少血管硬化。 

    146 、熬粥加碱的做法是不科学的,加碱熬出来的粥虽然显得粘稠、滑口,但粥内的一些重要的营养成分大部分都被破坏了,因此,熬粥不宜加碱。 

    147 、治疗风湿症的窍门:生姜皮晒干研末,装入瓶内储存备用。每次取姜皮末半茶匙冲酒(低度白酒)饮服,可缓解症状。

    148 、吃羊肉有助于保持健美体形,羊肉是理想的肉碱来源,这种和氨基酸类似的物质能帮助细胞掉人体多余的脂肪。 

    149 、炒青菜脆嫩法:在炒黄瓜、莴笋等青菜时,洗净切好后,撒少许盐拌合,腌渍几分钟,控去水分后再炒,能保持脆嫩清鲜。

    150 、鱼刺卡喉的救治窍门1:吞咽橙皮。鱼刺卡喉时,可剥取橙皮,块窄一点,含着慢慢咽下,可化解鱼刺。

    151 、鱼刺卡喉的救治窍门2:用维生素C软化。细小鱼刺卡喉,可取维生素C一片,含服慢慢咽下,数分钟后,鱼刺就会软化清除。 

    152 、皮肤粗糙者可将醋与甘油以5:1比例调和涂抹面部,每日坚持,会使皮肤变细嫩。在洗脸水中加一汤匙醋洗脸,也有美容功效。

    153 、晾晒衣服要诀1:衣服最好不要在阳光下曝晒,应在阴凉通风处晾至半干时,再放到较弱的太阳光下晒干,以保护衣服的色泽和穿着寿命。

    154 、晾晒衣服要诀2:晾晒衣服不可拧得太干,应带水晾晒,并用手将衣服的襟、领、袖等处拉平,这样晾晒干的衣服会保持平整,不起皱褶。

    155 、西红柿、黄瓜不宜放冰箱储存。将西红柿、黄瓜放入冰箱存放,其表皮会呈现水浸状态,从而失去它们特有的风味,乃至变质腐败,不能食用 

    156 、常吃苹果可防治口腔疾病,因为苹果的纤维质能清除牙龈中的污垢。但有一点需注意,吃完苹果后应漱口,以防龋齿的发生。 

    157 、巧除室内怪味:室内通风不畅时,经常有碳酸怪味,可在灯泡上滴几滴香水或花露水,待遇热后慢慢散发出香味,室内就清香扑鼻了。

    158 、炒洋葱宜放面粉、酒。切好的洋葱蘸点干面粉,炒熟后色泽金黄,质地脆嫩,味美可口。炒洋葱时,加少许白葡萄酒,不易炒焦。 

    159 、巧除软刺:仙人掌之类的植物软刺扎进皮肤时,可用伤湿止痛膏贴在扎刺的部位,在灯泡下烘烤一会儿,然后快速将其揭去,刺就会被拔出。

    160 、巧识香油是否掺假1:看颜色。颜色淡红或红中带黄为正品。机榨香油比小磨香油颜色淡。如颜色黑红或深黄,则可能掺进了棉籽油或菜籽油

    161 、熬粥防溢妙法:熬粥时,稍不注意便会溢锅。如果往锅里加5-6滴植物油或动物油,就可避免粥汁溢锅了。

    162 、报纸油墨味可驱虫。在放衣服的箱子底上铺一层报纸,再放入衣物(最好使深色衣物贴着报纸),这样可使衣物免遭虫咬,报纸每半年换一次 

    163 、巧识香油是否掺假2:看变化。香油在日光下清晰透明,如掺进凉水,在光照下则不透明,如果掺水过多,香油还会分层并容易沉淀变质。

    164 、旧邮票出现黄斑后,可将少许盐放在热牛奶中化开,然后把邮票放在冷却的奶液中浸泡2小时后取出,再用清水冲净、晾干,黄斑即可消除。

    165 、白萝卜美容:将白萝卜切碎捣烂取汁,加入适量清水,用来洗脸,长期坚持,可以使皮肤变得清爽润滑。 

    166 、拔丝糖汁的熬制:在熬制做拔丝菜用的糖汁时,加入同大米粒差不多大小的明矾,就能延长凝结时间,并使糖丝拉得更长。

    167 、变质葡萄糖粉是好肥料。变质的葡萄糖粉捣碎撒入花盆土四周,三日后黄叶就会变绿,长势茂盛。其适用于吊兰、刺梅、万年青、龟背竹等。 

    168 、电动剃须刀可修整衣裤。毛料衣裤、毛衣等穿久了会起很多小球,很不美观,可用电动剃须刀像剃胡须一样将衣服剃一遍,衣服即可平整如新 

    169 、巧治气管炎:将蜂蜜和白酒(多少根据自己的酒量大小而定)掺在一起,用火烧热,凉后喝下,每天1-2次,坚持喝一个月,即可见效。 

    170 、防衣物褪色二法:洗涤深色棉织物时加适量醋,可防止其褪色,且光泽如新;新买的有色花布第一次下水时,加盐浸泡十分钟可防止布料褪色。

    171 、身上有伤口流血时,可立即在伤口上撒些白糖,因为白糖能减少伤口局部的水分,抑制细菌的繁殖,有助于伤口收敛愈合。 

    172 、吃过大蒜后,喝杯牛奶,可消除大蒜遗留在口中的异味。抽屉、壁橱、衣箱里有霉味时,在里面放块肥皂,即可去除。 

    173 、巧选羽绒服1:一般以选含绒量多的为好。可将羽绒服放在案子上,用手拍打,蓬松度越高说明绒质越好,含绒量也越多。

    174 、巧选羽绒服2:全棉防绒布表面有一层蜡质,耐热性强,但耐磨性差;防绒尼龙绸面料耐磨耐穿,但怕烫怕晒。选购涤棉面料的羽绒服较好。

    175 、珍珠不佩戴时,先用弱碱性的肥皂水洗涤一下,再用清水充分冲洗,然后用洁净软布将其擦净、阴干,放在丝绒盒内,置于避晒、防潮处保存 

    176 、发面加盐好!面发酵得好坏是制作馒头、包子等各类主食的关键,发面时可加入少量食盐,这样发出的面气泡多,蒸出的主食松软可口。 

    177 、根据美国国家药典规定,药品一旦开罐,罐内所附的棉花和干燥剂,就必须立刻丢弃,否则它们会因吸附水气,成为药罐内的一项污染源! 

    178 、化妆时,先把微湿的化妆绵放到冰箱里,几分钟后把冰凉的海绵拍在抹好粉底的肌肤上,你会觉得肌肤格外清爽,彩妆也显得特别清新 

    179 、蜂蜜能洁齿。蜂蜜含有类似溶菌酶的成分,对各种致病病菌有较强的杀菌和抑菌能力,经常食用蜂蜜并注意口腔卫生,能预防龋齿的发生。 

    180 、在粮食中放少量干海带,可吸收粮食中水分,防止其生虫发霉,海带用后会变湿,可晾干后再次放入,仍保持吸湿和杀菌能力,且不影响食用
    181
    、电视机或电脑着火时,先拔掉插头或关上总开关,再用毯状物扑灭火焰。切勿用水或灭火器救火,因机体内可能仍有残余电力,会引致电击。 

    182 、画眼线的小技巧:要画好一双细致的眼线,可以先把手肘固定在桌上,然后平放一块小镜子,让双眼朝下望向镜子,就可以放心描画眼线了。

    183 、糕点的保存:保存糕点时,可在贮藏糕点的密封容器里加1片新鲜的面包,当面包发硬时,再及时更换一块新鲜的,这样糕点能保鲜较长时间

    184 、日光灯管使用数月后会两端发黑,照明度降低。这时把灯管取下,颠倒一下其两端接触极,日光灯管的寿命就可延长一倍,还可提高照明度 

    185 、圆珠笔油弄到手上很难洗掉,可用酒精棉球(也可用白酒)放在手上被污染处,圆珠笔油很快就被吸附,再用清水冲洗即能洗净。 

    186 、要防止毛线衣缩水,洗涤时水温不要超过30度,用中性肥皂片或洗涤剂洗涤,过最后一遍水时加少许食醋,,能有效保持毛衣的弹性和光泽 

    187 、浴室用电注意事项:宜用12伏低压电源,用防潮照明灯,里面的任何电气设备都要有足够高度(2米以上),以保证不会有人误触电源 

    188 、识别优质酱油:摇晃瓶子看沿瓶壁流下的速度快慢,优质酱油浓度高流动慢;瓶底无沉淀物;颜色呈红褐色、棕褐色、有光泽而发乌。

    189 、米饭做好后,挑些比较软、温热的揉成团,放在面部轻揉,直到米饭团变得油腻污黑,然后用清水洗掉,这样可使皮肤呼吸通畅,减少皱纹。 

    190 、珍珠的保养:不宜在阳光下曝晒,少与香水、油脂以及强酸强碱等化学物质接触,防止珍珠失光、褪色。佩戴时要常用洁净的软布擦抹。

    191 、识别优质酱油:打开后未触及瓶口就可闻到浓香,劣质的则香气少或有异味;优质酱油品尝起来味道鲜美,咸甜适口,醇厚柔和,口味绵长。

    192 、活窍门:心绞痛病人的急救:让患者保持最舒适坐姿,头部垫起;如随身携带药品则给患者用药;松开紧身的衣服使其呼吸通畅;安慰患者。

    193 、将一头大蒜切成薄片,与三百毫升凉开水一起装入密封容器内6-7小时,然后加入三十克碎冰糖,每天早晚漱口一次,可防感冒。

    194 、购买保暖内衣应选内外表层均用40支以上全棉的产品,用手轻抖不出现沙沙声,手感柔顺无异物感,有优良回弹性,最好选知名品牌。 

    195 、自来水刚煮沸就关火对健康不利,煮沸3-5分钟再熄火,烧出来的开水亚硝酸盐和氯化物等有毒物质含量都处于最低值,最适合饮用。

    196 、电毯失火时应先拔掉插头,然后向床泼水灭火,切勿揭起床单,否则空气进入,冒烟的床容易着火。如情势严重,则立即通知消防队。 

    197 、巧煮牛肉:在头天晚上将牛肉涂上一层芥末,第二天洗净后加少许醋煮;或用纱布包一小撮茶叶与牛肉同煮,都可使牛肉易熟快烂。

    198 、西红柿可治病,每天生食1-2个鲜熟西红柿可防癌,每早吃1-2个鲜熟西红柿蘸白糖可降血压,西红柿汁和西瓜汁各半杯混饮,可退烧。

    199 、煤气中毒的急救:迅速打开门窗使空气流通;尽可能把中毒者转移至通风处,同时注意保暖;保证呼吸道通畅,及时给氧,必要时做人工呼吸

    200 、专家建议冬天多吃红辣椒、胡萝卜、西红柿、洋葱、山楂等红颜色食品,可预防感冒;每天喝一杯酸奶、一碗鸡汤也有预防感冒的作用。

    201 、巧刮鱼鳞:将鱼装一较大塑料袋里,放到案板上,用刀背反复拍打鱼体两面的鳞,然后将勺伸入袋内轻轻地刮,鱼鳞即可刮净,且不外溅。

    202 、鲜蛋与生姜、洋葱不能混放,生姜和洋葱有强烈气味,易透进蛋壳上的小气孔,使鲜蛋变质。粮食与水果混放,则水果易干瘪、粮食易霉变。 

    203 、巧煮面条:煮面时在水面加一汤匙油,面条就不会沾了,还能防止面汤起泡沫溢出锅外。 

    204 、买肉常识:看肉色,新鲜肉肥肉乳白,瘦肉粉红。如肥肉发黄或肉呈黑紫色有淤血,不能要。含瘦肉精的肉则特别鲜亮,色泽红艳。

    205 、煮挂面时不要等水沸再下,当锅底有小气泡往上冒时就可下面,搅几下盖锅煮沸,适量加冷水,再盖锅煮沸即熟。这样煮出的面,面柔而汤清 

    206 、毛巾科学消毒法:将毛巾先用开水煮沸10分钟左右,再用肥皂洗涤,然后用清水充分洗净,最后将毛巾折叠好放入微波炉中,加热5分钟。 

    207 、将白菜帮叶切斜片,锅内油热后放花椒10粒左右,炸黑后放白菜,紧跟将一小酒杯米醋入锅,翻炒后勾淀粉少许,此菜有助防流感。

    208 、亮光可以帮助你早起,在床头准备一盏明灯,闹钟一响就打开,坚持下去,有一天你会发现,每天起床后你都会精神奕奕。 

    209 9种让你笑容绽放的食物:芹菜、乳酪、绿茶、洋葱、香菇、芥末、无糖口香糖、薄荷、水;常食这些食物可消除口臭、防止蛀牙。

    210 、背阴客厅的:补充人工光源。厅内色调统一,忌沉闷。选白榉、枫木饰面哑光漆家具并合理摆放。地面砖宜亮色,如浅米***光面的 

    211 、识别假蜂蜜:在蜂蜜中加入少量冷开水,也可滴几滴碘酒或酒精,如滴入物呈紫、绿或红褐色的,就是假蜂蜜。

    212 、头皮屑过多可通过饮食改善。多吃碱性食物如水果、蔬菜、蜂蜜等;多吃含维生素B2B6食物,如动物肝、肾、心、奶类、蛋黄、麦胚等 

    213 、挑选瓷器餐具时,用食指在瓷器上轻轻拍弹,如发出清脆的罄一般的声响,表明瓷器胚胎细腻、烧制好,如拍弹声发哑,则有破损或瓷胚质劣 

    214 、枕头应有一定弹性,但过强也不好,头部不断受到外加的弹力作用,易产生肌肉疲劳和损伤。如弹簧枕、气枕等,都不能算是有利健康的枕头 

    215 、鉴别香油:纯正香油色泽透明鲜亮,不纯香油有混浊物。冰箱中低温存放24小时后,纯正香油保持晶莹剔透液体状,不纯香油则有明显结晶 

    216 、表面多刺、多斑、釉质不够均匀甚至有裂纹的陶瓷品,其釉中所含铅易溢出,不宜做餐具。瓷器粘合剂大多含铅高,瓷器补过后也不宜做餐具 

    217 、冬季当心低热烫伤!热水袋内水温不要太热,热力表面不要直接贴近皮肤。糖尿病人或末梢感觉神经迟钝者及婴幼儿最好不用热水袋取暖

    218 、挑选熟透的西红柿,将柿肉挖出,搅拌均匀,敷在眼睛上,约十分钟后用湿毛巾擦掉。此法可淡化黑眼圈,同时还可延缓眼周皮肤的老化。 

    219 、苹果的另类疗效:治疗头痛!头痛时,把苹果磨成泥状,涂在纱布上,贴在头痛部位,头痛症状可减轻。 

    220 、减少电脑伤害策略:连续工作1小时后应休息十分钟左右。室内光线要适宜,且保持通风干爽。注意正确的操作姿势。保持皮肤清洁。

    221 、苹果的另类疗效:消除口臭!用苹果汁刷牙,可消除口臭,还可保持牙齿洁白,但切记刷完后要再用牙膏刷一遍牙。

    222 、用大号针头的废旧注射器,把胶水或其他无色、无腐蚀、流动性较好的粘合剂,均匀适量注入西服的气泡处,再熨干、熨平,西服会挺括如初 

    223 、开启干白葡萄酒的软木瓶塞:将酒瓶握手中,用瓶底轻撞墙壁,木塞会慢慢向外顶,当顶出近一半时,停,待瓶中气泡消失后,木塞一拔即起

    224 、仰卧位是护送急症病人的常用体位。如病人处于昏迷状态,还应将其头部偏向一侧,以免咽喉部分泌物或呕吐物吸入气管,引起窒息。 

    225 、毛巾常洗且每隔一段时间用肥皂、洗衣粉或碱液煮沸数分钟,可防发硬。煮沸时毛巾应全部浸水中,以免与空气接触发生氧化而降低柔软度 

    226 、将急症病人护送医院时,心力衰竭或支气管哮喘病人适用坐位;一侧肺炎、气胸、胸腔积液病人适用侧卧位,且歪向患侧,有利保持呼吸功能 

    227 、袋装牛奶冬季或冰箱放置后,其油脂会凝结附着在袋壁上,不易刮下,可在煮之前将其放暖气片上或火炉旁预热片刻,油脂即溶。 

  • SQL语句常用汇总(转)

    2007-10-10 15:10:37

    添加、删除、修改使用db.Execute(Sql)命令执行操作 
    ╔--------------------╗ 
    ☆ 数据记录筛选 ☆ 
    ╚--------------------╝ 
    注意:单双引号的用法可能有误(没有测式) 

    Sql = "Select Distinct 字段名 From 数据表" 
    Distinct函数,查询数据库存表内不重复的记录 

    Sql = "Select Count(*) From 数据表 where 字段名1>#18:0:0# and 字段名1< #19:00# " 
    count函数,查询数库表内有多少条记录,“字段名1”是指同一字段 
    例: 
    set rs=conn.execute("select count(id) as idnum from news") 
    response.write rs("idnum") 

    sql="select * from 数据表 where 字段名 between 值1 and 值2" 
    Sql="select * from 数据表 where 字段名 between #2003-8-10# and #2003-8-12#" 
    在日期类数值为2003-8-10 19:55:08 的字段里查找2003-8-10至2003-8-12的所有记录,而不管是几点几分。 

    select * from tb_name where datetime between #2003-8-10# and #2003-8-12# 
    字段里面的数据格式为:2003-8-10 19:55:08,通过sql查出2003-8-10至2003-8-12的所有纪录,而不管是几点几分。 

    Sql="select * from 数据表 where 字段名=字段值 order by 字段名 [desc]" 

    Sql="select * from 数据表 where 字段名 like '%字段值%' order by 字段名 [desc]" 
    模糊查询 

    Sql="select top 10 * from 数据表 where 字段名 order by 字段名 [desc]" 
    查找数据库中前10记录 

    Sql="select top n * form 数据表 order by newid()" 
    随机取出数据库中的若干条记录的方法 
    top n,n就是要取出的记录数 

    Sql="select * from 数据表 where 字段名 in ('值1','值2','值3')" 

    ╔--------------------╗ 
    ☆ 添加数据记录 ☆ 
    ╚--------------------╝ 
    sql="insert into 数据表 (字段1,字段2,字段3 …) valuess (值1,值2,值3 …)" 

    sql="insert into 数据表 valuess (值1,值2,值3 …)" 
    不指定具体字段名表示将按照数据表中字段的顺序,依次添加 

    sql="insert into 目标数据表 select * from 源数据表" 
    把源数据表的记录添加到目标数据表 

    ╔--------------------╗ 
    ☆ 更新数据记录 ☆ 
    ╚--------------------╝ 
    Sql="update 数据表 set 字段名=字段值 where 条件表达式" 

    Sql="update 数据表 set 字段1=值1,字段2=值2 …… 字段n=值n where 条件表达式" 

    Sql="update 数据表 set 字段1=值1,字段2=值2 …… 字段n=值n " 
    没有条件则更新整个数据表中的指定字段值 

    ╔--------------------╗ 
    ☆ 删除数据记录 ☆ 
    ╚--------------------╝ 
    Sql="delete from 数据表 where 条件表达式" 

    Sql="delete from 数据表" 
    没有条件将删除数据表中所有记录) 

    ╔--------------------------╗ 
    ☆ 数据记录统计函数 ☆ 
    ╚--------------------------╝ 
    AVG(字段名) 得出一个表格栏平均值 
    COUNT(*|字段名) 对数据行数的统计或对某一栏有值的数据行数统计 
    MAX(字段名) 取得一个表格栏最大的值 
    MIN(字段名) 取得一个表格栏最小的值 
    SUM(字段名) 把数据栏的值相加 

    引用以上函数的方法: 
    sql="select sum(字段名) as 别名 from 数据表 where 条件表达式" 
    set rs=conn.excute(sql) 
    用 rs("别名") 获取统的计值,其它函数运用同上。 

    ╔-----------------------------╗ 
    ☆ 数据表的建立和删除 ☆ 
    ╚-----------------------------╝ 
    CREATE TABLE 数据表名称(字段1 类型1(长度),字段2 类型2(长度) …… ) 
    例:CREATE TABLE tab01(name varchar(50),datetime default now()) 
    DROP TABLE 数据表名称 (永久性删除一个数据表) 

    ╔--------------------------╗ 
    ☆ 记录集对象的方法 ☆ 
    ╚--------------------------╝ 
    rs.movenext 将记录指针从当前的位置向下移一行 
    rs.moveprevious 将记录指针从当前的位置向上移一行 
    rs.movefirst 将记录指针移到数据表第一行 
    rs.movelast 将记录指针移到数据表最后一行 
    rs.absoluteposition=N 将记录指针移到数据表第N行 
    rs.absolutepage=N 将记录指针移到第N页的第一行 
    rs.pagesize=N 设置每页为N条记录 
    rs.pagecount 根据 pagesize 的设置返回总页数 
    rs.recordcount 返回记录总数 
    rs.bof 返回记录指针是否超出数据表首端,true表示是,false为否 
    rs.eof 返回记录指针是否超出数据表末端,true表示是,false为否 
    rs.delete 删除当前记录,但记录指针不会向下移动 
    rs.addnew 添加记录到数据表末端 
    rs.update 更新数据表记录
  • 经典SQL语句

    2007-10-10 15:05:04

    为了大家更容易理解我举出的SQL语句,本文假定已经建立了一个学生成绩管理数据库,全文均以学生成绩的管理为例来描述。

      1.在查询结果中显示列名:

      a.用as关键字:select name as '姓名' from students order by age

      b.直接表示:select name '姓名' from students order by age

      2.精确查找:

      a.用in限定范围:select * from students where native in ('湖南', '四川')

      b.between...and:select * from students where age between 20 and 30

      c.“=”:select * from students where name = '李山'

      d.like:select * from students where name like '李%' (注意查询条件中有“%”,则说明是部分匹配,而且还有先后信息在里面,即查找以“李”开头的匹配项。所以若查询有“李”的所有对象,应该命令:'%李%';若是第二个字为李,则应为'_李%'或'_李'或'_李_'。)

      e.[]匹配检查符:select * from courses where cno like '[AC]%' (表示或的关系,与"in(...)"类似,而且"[]"可以表示范围,如:select * from courses where cno like '[A-C]%')

      3.对于时间类型变量的处理

      a.smalldatetime:直接按照字符串处理的方式进行处理,例如:
    select * from students where birth > = '1980-1-1' and birth <= '1980-12-31'

      4.集函数

      a.count()求和,如:select count(*) from students (求学生总人数)

      b.avg(列)求平均,如:select avg(mark) from grades where cno=’B2’

      c.max(列)和min(列),求最大与最小

      5.分组group

      常用于统计时,如分组查总数:

      select gender,count(sno)

      from students

      group by gender

      (查看男女学生各有多少)

      注意:从哪种角度分组就从哪列"group by"

      对于多重分组,只需将分组规则罗列。比如查询各届各专业的男女同学人数 ,那么分组规则有:届别(grade)、专业(mno)和性别(gender),所以有"group by grade, mno, gender"

      select grade, mno, gender, count(*)

      from students

      group by grade, mno, gender

      通常group还和having联用,比如查询1门课以上不及格的学生,则按学号(sno)分类有:

      select sno,count(*) from grades

      where mark<60

      group by sno

      having count(*)>1

      6.UNION联合

      合并查询结果,如:

      SELECT * FROM students

      WHERE name like ‘张%’

      UNION [ALL]

      SELECT * FROM students

      WHERE name like ‘李%’

      7.多表查询

      a.内连接

      select g.sno,s.name,c.coursename

      from grades g JOIN students s ON g.sno=s.sno

      JOIN courses c ON g.cno=c.cno

      (注意可以引用别名)

      b.外连接

      b1.左连接

      select courses.cno,max(coursename),count(sno)

      from courses LEFT JOIN grades ON courses.cno=grades.cno

      group by courses.cno

      左连接特点:显示全部左边表中的所有项目,即使其中有些项中的数据未填写完全。

      左外连接返回那些存在于左表而右表中却没有的行,再加上内连接的行。

      b2.右连接

      与左连接类似

      b3.全连接

      select sno,name,major

      from students FULL JOIN majors ON students.mno=majors.mno

      两边表中的内容全部显示

      c.自身连接

      select c1.cno,c1.coursename,c1.pno,c2.coursename

      from courses c1,courses c2 where c1.pno=c2.cno

      采用别名解决问题。

      d.交叉连接

      select lastname+firstname from lastname CROSS JOIN firstanme

      相当于做笛卡儿积

     8.嵌套查询

      a.用关键字IN,如查询李山的同乡:

      select * from students

      where native in (select native from students where name=’ 李山’)

      b.使用关键字EXIST,比如,下面两句是等价的:

      select * from students

      where sno in (select sno from grades where cno=’B2’)

      select * from students where exists

      (select * from grades where

      grades.sno=students.sno AND cno=’B2’)

      9.关于排序order

      a.对于排序order,有两种方法:asc升序和desc降序

      b.对于排序order,可以按照查询条件中的某项排列,而且这项可用数字表示,如:

      select sno,count(*) ,avg(mark) from grades

      group by sno

      having avg(mark)>85

      order by 3

      10.其他

      a.对于有空格的识别名称,应该用"[]"括住。

      b.对于某列中没有数据的特定查询可以用null判断,如select sno,courseno from grades where mark IS NULL

      c.注意区分在嵌套查询中使用的any与all的区别,any相当于逻辑运算“||”而all则相当于逻辑运算“&&”

      d.注意在做否定意义的查询是小心进入陷阱:

      如,没有选修‘B2’课程的学生 :

      select students.*

      from students, grades

      where students.sno=grades.sno

      AND grades.cno <> ’B2’

      上面的查询方式是错误的,正确方式见下方:

      select * from students

      where not exists (select * from grades

      where grades.sno=students.sno AND cno='B2')

      11.关于有难度多重嵌套查询的解决思想:

      如,选修了全部课程的学生:

      select *

      from students

      where not exists ( select *

      from courses 

      where NOT EXISTS

      (select *

      from grades

      where sno=students.sno

      AND cno=courses.cno))

  • SQL语句大全(转)

    2007-10-10 15:02:17

    一、基础

    1、说明:创建数据库
    Create DATABASE database-name
    2、说明:删除数据库
    drop database dbname
    3、说明:备份sql server
    --- 创建 备份数据的 device
    USE master
    EXEC sp_addumpdevice 'disk', 'testBack', 'c:\mssql7backup\MyNwind_1.dat'
    --- 开始 备份
    BACKUP DATABASE pubs TO testBack
    4、说明:创建新表
    create table tabname(col1 type1 [not null] [primary key],col2 type2 [not null],..)
    根据已有的表创建新表:
    A:create table tab_new like tab_old (使用旧表创建新表)
    B:create table tab_new as select col1,col2… from tab_old definition only
    5、说明:删除新表
    drop table tabname
    6、说明:增加一个列
    Alter table tabname add column col type
    注:列增加后将不能删除。DB2中列加上后数据类型也不能改变,唯一能改变的是增加varchar类型的长度。
    7、说明:添加主键: Alter table tabname add primary key(col)
    说明:删除主键: Alter table tabname drop primary key(col)
    8、说明:创建索引:create [unique] index idxname on tabname(col….)
    删除索引:drop index idxname
    注:索引是不可更改的,想更改必须删除重新建。
    9、说明:创建视图:create view viewname as select statement
    删除视图:drop view viewname
    10、说明:几个简单的基本的sql语句
    选择:select * from table1 where 范围
    插入:insert into table1(field1,field2) values(value1,value2)
    删除:delete from table1 where 范围
    更新:update table1 set field1=value1 where 范围
    查找:select * from table1 where field1 like ’%value1%’ ---like的语法很精妙,查资料!
    排序:select * from table1 order by field1,field2 [desc]
    总数:select count as totalcount from table1
    求和:select sum(field1) as sumvalue from table1
    平均:select avg(field1) as avgvalue from table1
    最大:select max(field1) as maxvalue from table1
    最小:select min(field1) as minvalue from table1
    11、说明:几个高级查询运算词
    A: UNION 运算符
    UNION 运算符通过组合其他两个结果表(例如 TABLE1 和 TABLE2)并消去表中任何重复行而派生出一个结果表。当 ALL 随 UNION 一起使用时(即 UNION ALL),不消除重复行。两种情况下,派生表的每一行不是来自 TABLE1 就是来自 TABLE2。
    B: EXCEPT 运算符
    EXCEPT 运算符通过包括所有在 TABLE1 中但不在 TABLE2 中的行并消除所有重复行而派生出一个结果表。当 ALL 随 EXCEPT 一起使用时 (EXCEPT ALL),不消除重复行。
    C: INTERSECT 运算符
    INTERSECT 运算符通过只包括 TABLE1 和 TABLE2 中都有的行并消除所有重复行而派生出一个结果表。当 ALL 随 INTERSECT 一起使用时 (INTERSECT ALL),不消除重复行。
    注:使用运算词的几个查询结果行必须是一致的。
    12、说明:使用外连接
    A、left outer join:
    左外连接(左连接):结果集几包括连接表的匹配行,也包括左连接表的所有行。
    SQL: select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c
    B:right outer join:
    右外连接(右连接):结果集既包括连接表的匹配连接行,也包括右连接表的所有行。
    C:full outer join:
    全外连接:不仅包括符号连接表的匹配行,还包括两个连接表中的所有记录。

    二、提升

    1、说明:复制表(只复制结构,源表名:a 新表名:b) (Access可用)
    法一:select * into b from a where 1<>1
    法二:select top 0 * into b from a
    2、说明:拷贝表(拷贝数据,源表名:a 目标表名:b) (Access可用)
    insert into b(a, b, c) select d,e,f from b;

    3、说明:跨数据库之间表的拷贝(具体数据使用绝对路径) (Access可用)
    insert into b(a, b, c) select d,e,f from b in ‘具体数据库’ where 条件
    例子:..from b in '"&Server.MapPath("."&"\data.mdb" &"' where..

    4、说明:子查询(表名1:a 表名2:b)
    select a,b,c from a where a IN (select d from b  或者: select a,b,c from a where a IN (1,2,3)

    5、说明:显示文章、提交人和最后回复时间
    select a.title,a.username,b.adddate from table a,(select max(adddate) adddate from table where table.title=a.title) b

    6、说明:外连接查询(表名1:a 表名2:b)
    select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c

    7、说明:在线视图查询(表名1:a
    select * from (Select a,b,c FROM a) T where t.a > 1;

    8、说明:between的用法,between限制查询数据范围时包括了边界值,not between不包括
    select * from table1 where time between time1 and time2
    select a,b,c, from table1 where a not between 数值1 and 数值2

    9、说明:in 的使用方法
    select * from table1 where a [not] in (‘值1’,’值2’,’值4’,’值6’)

    10、说明:两张关联表,删除主表中已经在副表中没有的信息
    delete from table1 where not exists ( select * from table2 where table1.field1=table2.field1

    11、说明:四表联查问题:
    select * from a left inner join b on a.a=b.b right inner join c on a.a=c.c inner join d on a.a=d.d where .....

    12、说明:日程安排提前五分钟提醒
    SQL: select * from 日程安排 where datediff('minute',f开始时间,getdate())>5

    13、说明:一条sql 语句搞定数据库分页
    select top 10 b.* from (select top 20 主键字段,排序字段 from 表名 order by 排序字段 desc) a,表名 b where b.主键字段 = a.主键字段 order by a.排序字段

    14、说明:前10条记录
    select top 10 * form table1 where 范围

    15、说明:选择在每一组b值相同的数据中对应的a最大的记录的所有信息(类似这样的用法可以用于论坛每月排行榜,每月热销产品分析,按科目成绩排名,等等.)
    select a,b,c from tablename ta where a=(select max(a) from tablename tb where tb.b=ta.b)

    16、说明:包括所有在 TableA 中但不在 TableB和TableC 中的行并消除所有重复行而派生出一个结果表
    (select a from tableA  except (select a from tableB) except (select a from tableC)

    17、说明:随机取出10条数据
    select top 10 * from tablename order by newid()

    18、说明:随机选择记录
    select newid()

    19、说明:删除重复记录
    Delete from tablename where id not in (select max(id) from tablename group by col1,col2,...)

    20、说明:列出数据库里所有的表名
    select name from sysobjects where type='U'

    21、说明:列出表里的所有的
    select name from syscolumns where id=object_id('TableName')

    22、说明:列示type、vender、pcs字段,以type字段排列,case可以方便地实现多重选择,类似select 中的case。
    select type,sum(case vender when 'A' then pcs else 0 end),sum(case vender when 'C' then pcs else 0 end),sum(case vender when 'B' then pcs else 0 end) FROM tablename group by type
    显示结果:
    type vender pcs
    电脑 A 1
    电脑 A 1
    光盘 B 2
    光盘 A 2
    手机 B 3
    手机 C 3

    23、说明:初始化表table1

    TRUNCATE TABLE table1

    24、说明:选择从10到15的记录
    select top 5 * from (select top 15 * from table order by id asc) table_别名 order by id desc

    三、技巧

    1、1=1,1=2的使用,在SQL语句组合时用的较多

    “where 1=1” 是表示选择全部  “where 1=2”全部不选,
    如:
    if @strWhere !='
    begin
    set @strSQL = 'select count(*) as Total from [' + @tblName + '] where ' + @strWhere
    end
    else
    begin
    set @strSQL = 'select count(*) as Total from [' + @tblName + ']'
    end

    我们可以直接写成
    set @strSQL = 'select count(*) as Total from [' + @tblName + '] where 1=1 安定 '+ @strWhere

    2、收缩数据库
    --重建索引
    DBCC REINDEX
    DBCC INDEXDEFRAG
    --收缩数据和日志
    DBCC SHRINKDB
    DBCC SHRINKFILE

    3、压缩数据库
    dbcc shrinkdatabase(dbname)

    4、转移数据库给新用户以已存在用户权限
    exec sp_change_users_login 'update_one','newname','oldname'
    go

    5、检查备份集
    RESTORE VERIFYONLY from disk='E:\dvbbs.bak'

    6、修复数据库
    Alter DATABASE [dvbbs] SET SINGLE_USER
    GO
    DBCC CHECKDB('dvbbs',repair_allow_data_loss) WITH TABLOCK
    GO
    Alter DATABASE [dvbbs] SET MULTI_USER
    GO

    7、日志清除
    SET NOCOUNT ON
    DECLARE @LogicalFileName sysname,
            @MaxMinutes INT,
            @NewSize INT


    USE    tablename            -- 要操作的数据库名
    Select  @LogicalFileName = 'tablename_log',  -- 日志文件名
    @MaxMinutes = 10,              -- Limit on time allowed to wrap log.
            @NewSize = 1                  -- 你想设定的日志文件的大小(M)

    -- Setup / initialize
    DECLARE @OriginalSize int
    Select @OriginalSize = size
      FROM sysfiles
      Where name = @LogicalFileName
    Select 'Original Size of ' + db_name() + ' LOG is ' +
            CONVERT(VARCHAR(30),@OriginalSize) + ' 8K pages or ' +
            CONVERT(VARCHAR(30),(@OriginalSize*8/1024)) + 'MB'
      FROM sysfiles
      Where name = @LogicalFileName
    Create TABLE DummyTrans
      (DummyColumn char (8000) not null)


    DECLARE @Counter  INT,
            @StartTime DATETIME,
            @TruncLog  VARCHAR(255)
    Select  @StartTime = GETDATE(),
            @TruncLog = 'BACKUP LOG ' + db_name() + ' WITH TRUNCATE_ONLY'

    DBCC SHRINKFILE (@LogicalFileName, @NewSize)
    EXEC (@TruncLog)
    -- Wrap the log if necessary.
    WHILE    @MaxMinutes > DATEDIFF (mi, @StartTime, GETDATE()) -- time has not expired
          AND @OriginalSize = (Select size FROM sysfiles Where name = @LogicalFileName)
          AND (@OriginalSize * 8 /1024) > @NewSize
      BEGIN -- Outer loop.
        Select @Counter = 0
        WHILE  ((@Counter < @OriginalSize / 16) AND (@Counter < 50000))
          BEGIN -- update
            Insert DummyTrans VALUES ('Fill Log')
            Delete DummyTrans
            Select @Counter = @Counter + 1
          END
        EXEC (@TruncLog)
      END
    Select 'Final Size of ' + db_name() + ' LOG is ' +
            CONVERT(VARCHAR(30),size) + ' 8K pages or ' +
            CONVERT(VARCHAR(30),(size*8/1024)) + 'MB'
      FROM sysfiles
      Where name = @LogicalFileName
    Drop TABLE DummyTrans
    SET NOCOUNT OFF

    8、说明:更改某个表
    exec sp_changeobjectowner 'tablename','dbo'

    9、存储更改全部表

    Create PROCEDURE dbo.User_ChangeObjectOwnerBatch
    @OldOwner as NVARCHAR(128),
    @NewOwner as NVARCHAR(128)
    AS

    DECLARE @Name  as NVARCHAR(128)
    DECLARE @Owner  as NVARCHAR(128)
    DECLARE @OwnerName  as NVARCHAR(128)

    DECLARE curObject CURSOR FOR
    select 'Name'  = name,
      'Owner'  = user_name(uid)
    from sysobjects
    where user_name(uid)=@OldOwner
    order by name

    OPEN  curObject
    FETCH NEXT FROM curObject INTO @Name, @Owner
    WHILE(@@FETCH_STATUS=0)
    BEGIN
    if @Owner=@OldOwner
    begin
      set @OwnerName = @OldOwner + '.' + rtrim(@Name)
      exec sp_changeobjectowner @OwnerName, @NewOwner
    end
    -- select @name,@NewOwner,@OldOwner

    FETCH NEXT FROM curObject INTO @Name, @Owner
    END

    close curObject
    deallocate curObject
    GO


    10、SQL SERVER中直接循环写入数据
    declare @i int
    set @i=1
    while @i<30
    begin
      insert into test (userid) values(@i)
      set @i=@i+1
    end 

562/3<123>