qileilove

blog已经转移至github,大家请访问 http://qaseven.github.io/

教你认识自动化测试工具QTP

初学测试自动化工具的一点感悟及教你认识自动化测试工具QTP
  初学自动化测试工具,总结了几点应该注意的重点问题:
  1、首先必须进行完善的用例设计和测试过程设计
  使用测试工具进行测试工作的第一步并不是录制脚本。而是应该在理解被测对象的基础上,进行用例设计和测试过程设计。用例设计包括用例数据、用例测试过程、预期结果等。然后将用例测试过程录制成测试脚本,将用例数据进行参数化。
  完成一项功能或多项相关功能的测试时,需要设计合理的测试过程。不同的测试场景使用独立的一项测试操作实现(表现为一个独立的测试脚本文件)。多项相关功能测试时,按设计的测试过程进行测试操作的组合(如使用QTP的操作调用)。这样,每一个测试场景使用不同的测试数据,且各个测试场景独立存在,但有有机地结合起来形成一个完整功能的测试。
  2、检查点是需要进行判断的
  初学者大多会按照教程设置各种检查点,但并不会看测试结果中检查点的结果。其实,许多检查点只表明了两种结果:“通过”或“失败”。
  关键的问题是:失败的理由、场景、状态等在结果中很难看出来。所以,在设置检查点后,还必须对检查点结果按照测试过程的业务逻辑进行判断,然后输出更为详细的结果。具体示例见我的上篇日志中的“ reporter.ReportEvent 1,"新增学生信息错误","信息存入数据库,但数据没有在保存后立即显示,数据编号:"+ DataTable("stu_ID", dtLocalSheet)”。
  此外,检查点的参数化至关重要,因为只有参数化检查点,才能真正体现系统运行过程中动态的变化!
  3、录制测试与编写测试脚本的目的是便于重复测试
  既然是为了重复测试,那么就必须认真考虑和设计每个测试活动的前置条件(如在什么样的数据环境下才能开始这个测试活动?)和后置条件(如:本测试活动所录入的数据是否需要保留?)。否则就会很容易出现问题(如:录入数据时关键字重复!)。
  4、测试工具不能解决所有问题
  许多初学者总希望测试工具能帮助他们解决所有问题。其实许多测试项目是必须靠手工完成的。如:界面布局的合理性、系统使用的方便性等。
  自动工具永远只是辅助手段!所以测试工作的关键还是对测试对象的理解、测试用例与测试过程的设计。有了完善的用例,不管是手工测试还是自动测试,都是可以很好地完成测试任务的。
  说到自动化测试,就不得不提大名鼎鼎的QTP了,Mercury QTP简称QTP,是一个先进的
  先进的自动化测试工具,它可以用于创建功能和回归测试。自动捕获、验证和重放用户的交互行为。
  QTP为每一个重要软件应用和环境提供功能和回归测试自动化的行业最佳解决方案,它是新一代自动化测试解决方案,采用了关键词驱动(Keyword-Driven)测试的理念,能完全简化测试的创建和维护工作。QTP关键词驱动方式独有之处在于,测试自动化专家可以通过一个整合的脚本和纠错环境,拥有对基础测试脚本和对象属性的完全访问权限,这些脚本和纠错环境与关键词视图(Keyword View)可以互为同步。
  QTP同时满足了技术型和非技术型用户的需求,让各个公司有能力部署更高质量的应用,同时部署的速度更快,费用更低,风险也更小。QTP和我们新的测试自动化系统Mercury Business Process Testing?的紧密结合,可以将非技术型的业务专家(SME, Subject-Matter Experts)引入质量流程,这一意义重大的引入可以将IT和业务更好地融合,最终建立起更出色的应用。
  有了该产品,您的QA部门可以获取多方面的优势:
  1.用最少的培训赋予整个小组创建成熟测试方案的能力。
  2.确保跨所有环境、数据包和业务流程的正确功能点。
  3.为开发人员全面记录和复制缺陷,使他们能更快地修复缺陷,满足最后上线期限。
  4.对不断变化的应用和环境展开便捷的回归测试。
  5.成为帮助整个机构实现高质量产品和服务、提高总收入和收益率的关键角色。
QTP是如何工作的
  QTP易于操作,即使是初级的测试人员也能在短时间内对其驾轻就熟。您可以使用无需脚本的关键词视图来表现测试的每个步骤,仅由此就可创建一个测试。您还可以通过QTP所集成的录制能力来捕获测试步骤。该产品用简单的英语以文档形式记录每个步骤,并通过活动屏幕将文档与一个集成截屏相结合。传统的脚本记录工具所生产的脚本不易修改,与此不同的是,QTP的关键词驱动方式能让您便捷地插入、修改、数据驱动(data-drive)和移除测试步骤。
  QTP可以自动引入检查点来验证应用的属性和功能点,比如确认输出量或检查链接的有效性。在关键词视图的每一步骤中,活动屏幕可显示被测应用在该步骤中的确切状态。您还可以为任意对象加入几种检查点,仅仅在活动屏幕中点击该对象,就可以验证该组件行为是否达到了期望值。
  然后您可以将测试数据输入数据表(Data Table),它拥有和Excel同样完善的功能特性,是一个集成的电子数据表格。您可以使用数据集并创建多种重复测试,无需编程就可以扩展测试案例的覆盖面。数据可以通过键入的方式输入或从数据库、数据表格或文本文档中导出。
  高级测试人员可以在专家视图(Expert View)中查看和修改他们的测试,在专家视图中显示了由QTP自动生成的基于行业标准的基本VBscrīpt语言。在专家视图中所做的任何改动将自动与关键词视图同步。
  一旦测试人员运行了一个脚本,TestFusion报告将显示测试运行各方面的信息,包括:高水平的结果纵览;一个可扩展的测试脚本树状视图(Tree View),其明确指出了应用错误的发生位置;被使用的测试数据;每个步骤的应用截屏,其中并标明了所有的差异;以及通过或未通过每个检查点的详细解释。您可以将TestFusion报告和QTP结合,从而与整个QA和开发小组分享这些报告。
  QTP处理一些应用的新版本问题。当一个被测应用发生变化时,比如把一个”Login”按钮被改名为”Sign in”,您可以在共享对象容器(Shared Object Repository)中做一次更新,接着此次更新将扩展到所有涉及这个对象的脚本。您可以将测试脚本公布给Mercury Quality Management,使其它的QA小组成员也可以使用您的测试脚本,从而减少了重复工作。
  通过与Business Process Testing的整合,在一个基于web的系统中,QTP被用于实现自动化操作,使非技术型用户可以便捷地在一个完全的无脚本环境中也能够建立起测试。
  QTP支持多种企业环境的功能测试,包括Windows、Web、.NET、 Java/J2EE、SAP、Siebel、Oracle、PeopleSoft、Visual Basic、ActiveX、Mainframe terminal emulators和Web services。
  Mercury功能测试
  那些在Mercury WinRunner

posted @ 2013-09-30 11:30 顺其自然EVO 阅读(394) | 评论 (0)编辑 收藏

新时代的测试工程师

 测试工程师在软件项目中把握着项目产品质量,具有最终项目能否发布的生杀大权,就这样一个重要的角色在实际情况中往往不受待见,却是为何?
  纵观国内测试工程师发展的过程来看,主要有以下几个原因:
  (1)起步晚:在国内软件行业发展的初期,没有专职测试的人员,所以测试工程师比开发工程师以及其产品等岗位的起步晚,在初期是可以没有的岗位。
  (2)起点低:发展到一定阶段以后,发现有一部分手工测试可以由单独的人员完成,但是对人员的要求没有开发那么高,所以最开始的测试人员的门槛低。
  (3)技术发展慢:测试技术的发展相对开发的技术发展要落后一个节拍,导致测试技术的发展比较慢,最开始都是功能测试,最近几年才开始性能,安全,大数据的测试。
  那么如何赢得众人尊重,重新树立新时达的测试工程师形象,个人认为得做到以下几点:
  1.写得了代码
  2.抓得住bug
  3.看得了产品
  4.懂得了用户
  写得了代码:
  这里所说的写得了代码,不仅仅是狭义上的编码,而是对于开发的技术的了解,能写得了代码,可以大大提高和测试人员最亲密的合作伙伴开发同学的相互理解,同时可以有更多的共同语言,能获得开发同学尊重,并且写得了代码就能够发现最深层次的bug。
  抓得住bug
  发现bug是测试人员的天职,但是功能的bug只是众多的bug中的冰山一角,而且发现bug应该是贯穿整个项目过程中,而不仅仅局限于测试阶段的bug,例如在设计阶段,可以发现系统设计的缺陷,如可能引起的性能,安全,或者可扩展性的问题。
  抓bug的技术手段和方法可以努力做到以下几点:
  自动化:自动化可以提高效率,减少人工的误差,另外自动化比较高端大气上档次。
  服务化:服务化可以让其他人使用,例如开发,产品;
  持续集成:持续集成可以提高利用率,减少再创造的成本。
  看得了产品
  看得了产品就是说可以看得见产品的发展趋势和产品的核心价值,这样可以理解产品的根本需求,把握测试的重点,在理解产品经理的基础上可以获得产品的更大的支持和尊重。
  懂得了用户
  这是个终极的目标,因为测试人员是用户在使用前最原始的用户,如果不能准确把握用户需求,那往往会在测试过程中因小失大,往往会因为某个小细节的纠结而失去产品推出的最好时机,没能够抓住用户。

posted @ 2013-09-30 11:30 顺其自然EVO 阅读(355) | 评论 (0)编辑 收藏

Java 理论与实践: 正确使用 volatile 变量 线程同步

 Java语言规范中指出:为了获得最佳速度,允许线程保存共享成员变量的私有拷贝,而且只当线程进入或者离开同步代码块时才与共享成员变量的原始值对比。
  这样当多个线程同时与某个对象交互时,就必须要注意到要让线程及时的得到共享成员变量的变化。
  而volatile关键字就是提示VM:对于这个成员变量不能保存它的私有拷贝,而应直接与共享成员变量交互。
  使用建议:在两个或者更多的线程访问的成员变量上使用volatile。当要访问的变量已在synchronized代码块中,或者为常量时,不必使用。
  由于使用volatile屏蔽掉了VM中必要的代码优化,所以在效率上比较低,因此一定在必要时才使用此关键字。
  Java的serialization提供了一种持久化对象实例的机制。当持久化对象时,可能有一个特殊的对象数据成员,我们不想
  用serialization机制来保存它。为了在一个特定对象的一个域上关闭serialization,可以在这个域前加上关键字transient。
  transient是Java语言的关键字,用来表示一个域不是该对象串行化的一部分。当一个对象被串行化的时候,transient型变量的值不包括在串行化的表示中,然而非transient型的变量是被包括进去的。
  注意static变量也是可以串行化的
  Java 语言中的 volatile 变量可以被看作是一种 “程度较轻的 synchronized”;与 synchronized 块相比,volatile 变量所需的编码较少,并且运行时开销也较少,但是它所能实现的功能也仅是 synchronized 的一部分。本文介绍了几种有效使用 volatile 变量的模式,并强调了几种不适合使用 volatile 变量的情形。
  锁提供了两种主要特性:互斥(mutual exclusion) 和可见性(visibility)。互斥即一次只允许一个线程持有某个特定的锁,因此可使用该特性实现对共享数据的协调访问协议,这样,一次就只有一个线程能够使用该共享数据。可见性要更加复杂一些,它必须确保释放锁之前对共享数据做出的更改对于随后获得该锁的另一个线程是可见的 —— 如果没有同步机制提供的这种可见性保证,线程看到的共享变量可能是修改前的值或不一致的值,这将引发许多严重问题。
  Volatile 变量
  Volatile 变量具有 synchronized 的可见性特性,但是不具备原子特性。这就是说线程能够自动发现 volatile 变量的最新值。Volatile 变量可用于提供线程安全,但是只能应用于非常有限的一组用例:多个变量之间或者某个变量的当前值与修改后值之间没有约束。因此,单独使用 volatile 还不足以实现计数器、互斥锁或任何具有与多个变量相关的不变式(Invariants)的类(例如 “start <=end”)。
  出于简易性或可伸缩性的考虑,您可能倾向于使用 volatile 变量而不是锁。当使用 volatile 变量而非锁时,某些习惯用法(idiom)更加易于编码和阅读。此外,volatile 变量不会像锁那样造成线程阻塞,因此也很少造成可伸缩性问题。在某些情况下,如果读操作远远大于写操作,volatile 变量还可以提供优于锁的性能优势。
  正确使用 volatile 变量的条件
  您只能在有限的一些情形下使用 volatile 变量替代锁。要使 volatile 变量提供理想的线程安全,必须同时满足下面两个条件:
  对变量的写操作不依赖于当前值。
  该变量没有包含在具有其他变量的不变式中。
  实际上,这些条件表明,可以被写入 volatile 变量的这些有效值独立于任何程序的状态,包括变量的当前状态。
  第一个条件的限制使 volatile 变量不能用作线程安全计数器。虽然增量操作(x++)看上去类似一个单独操作,实际上它是一个由读取-修改-写入操作序列组成的组合操作,必须以原子方式执行,而 volatile 不能提供必须的原子特性。实现正确的操作需要使 x 的值在操作期间保持不变,而 volatile 变量无法实现这点。(然而,如果将值调整为只从单个线程写入,那么可以忽略第一个条件。)
  大多数编程情形都会与这两个条件的其中之一冲突,使得 volatile 变量不能像 synchronized 那样普遍适用于实现线程安全。清单 1 显示了一个非线程安全的数值范围类。它包含了一个不变式 —— 下界总是小于或等于上界。
  清单 1. 非线程安全的数值范围类
@NotThreadSafe
public class NumberRange {
private int lower, upper;
public int getLower() { return lower; }
public int getUpper() { return upper; }
public void setLower(int value) {
if (value > upper)
throw new IllegalArgumentException(...);
lower = value;
}
public void setUpper(int value) {
if (value < lower)
throw new IllegalArgumentException(...);
upper = value;
}
}


 这种方式限制了范围的状态变量,因此将 lower 和 upper 字段定义为 volatile 类型不能够充分实现类的线程安全;从而仍然需要使用同步。否则,如果凑巧两个线程在同一时间使用不一致的值执行 setLower 和 setUpper 的话,则会使范围处于不一致的状态。例如,如果初始状态是 (0, 5),同一时间内,线程 A 调用 setLower(4) 并且线程 B 调用 setUpper(3),显然这两个操作交叉存入的值是不符合条件的,那么两个线程都会通过用于保护不变式的检查,使得最后的范围值是 (4, 3) —— 一个无效值。至于针对范围的其他操作,我们需要使 setLower() 和 setUpper() 操作原子化 —— 而将字段定义为 volatile 类型是无法实现这一目的的。
  性能考虑
  使用 volatile 变量的主要原因是其简易性:在某些情形下,使用 volatile 变量要比使用相应的锁简单得多。使用 volatile 变量次要原因是其性能:某些情况下,volatile 变量同步机制的性能要优于锁。
  很难做出准确、全面的评价,例如 “X 总是比 Y 快”,尤其是对 JVM 内在的操作而言。(例如,某些情况下 VM 也许能够完全删除锁机制,这使得我们难以抽象地比较 volatile和 synchronized 的开销。)就是说,在目前大多数的处理器架构上,volatile 读操作开销非常低 —— 几乎和非 volatile 读操作一样。而 volatile 写操作的开销要比非 volatile 写操作多很多,因为要保证可见性需要实现内存界定(Memory Fence),即便如此,volatile 的总开销仍然要比锁获取低。
  volatile 操作不会像锁一样造成阻塞,因此,在能够安全使用 volatile 的情况下,volatile 可以提供一些优于锁的可伸缩特性。如果读操作的次数要远远超过写操作,与锁相比,volatile 变量通常能够减少同步的性能开销。
  正确使用 volatile 的模式
  很多并发性专家事实上往往引导用户远离 volatile 变量,因为使用它们要比使用锁更加容易出错。然而,如果谨慎地遵循一些良好定义的模式,就能够在很多场合内安全地使用 volatile 变量。要始终牢记使用 volatile 的限制 —— 只有在状态真正独立于程序内其他内容时才能使用 volatile —— 这条规则能够避免将这些模式扩展到不安全的用例。
  模式 #1:状态标志
  也许实现 volatile 变量的规范使用仅仅是使用一个布尔状态标志,用于指示发生了一个重要的一次性事件,例如完成初始化或请求停机。
  很多应用程序包含了一种控制结构,形式为 “在还没有准备好停止程序时再执行一些工作”,如清单 2 所示:
  清单 2. 将 volatile 变量作为状态标志使用
volatile boolean shutdownRequested;
...
public void shutdown() { shutdownRequested = true; }
public void doWork() {
while (!shutdownRequested) {
// do stuff
}
}
  很可能会从循环外部调用 shutdown() 方法 —— 即在另一个线程中 —— 因此,需要执行某种同步来确保正确实现 shutdownRequested 变量的可见性。(可能会从 JMX 侦听程序、GUI 事件线程中的操作侦听程序、通过 RMI 、通过一个 Web 服务等调用)。然而,使用 synchronized 块编写循环要比使用清单 2 所示的 volatile 状态标志编写麻烦很多。由于 volatile 简化了编码,并且状态标志并不依赖于程序内任何其他状态,因此此处非常适合使用 volatile。
  这种类型的状态标记的一个公共特性是:通常只有一种状态转换;shutdownRequested 标志从 false 转换为 true,然后程序停止。这种模式可以扩展到来回转换的状态标志,但是只有在转换周期不被察觉的情况下才能扩展(从 false 到 true,再转换到 false)。此外,还需要某些原子状态转换机制,例如原子变量。
  模式 #2:一次性安全发布(one-time safe publication)
  缺乏同步会导致无法实现可见性,这使得确定何时写入对象引用而不是原语值变得更加困难。在缺乏同步的情况下,可能会遇到某个对象引用的更新值(由另一个线程写入)和该对象状态的旧值同时存在。(这就是造成著名的双重检查锁定(double-checked-locking)问题的根源,其中对象引用在没有同步的情况下进行读操作,产生的问题是您可能会看到一个更新的引用,但是仍然会通过该引用看到不完全构造的对象)。
  实现安全发布对象的一种技术就是将对象引用定义为 volatile 类型。清单 3 展示了一个示例,其中后台线程在启动阶段从数据库加载一些数据。其他代码在能够利用这些数据时,在使用之前将检查这些数据是否曾经发布过。
  清单 3. 将 volatile 变量用于一次性安全发布
public class BackgroundFloobleLoader {
public volatile Flooble theFlooble;
public void initInBackground() {
// do lots of stuff
theFlooble = new Flooble();  // this is the only write to theFlooble
}
}
public class SomeOtherClass {
public void doWork() {
while (true) {
// do some stuff...
// use the Flooble, but only if it is ready
if (floobleLoader.theFlooble != null)
doSomething(floobleLoader.theFlooble);
}
}
}

  如果 theFlooble 引用不是 volatile 类型,doWork() 中的代码在解除对 theFlooble 的引用时,将会得到一个不完全构造的 Flooble。
  该模式的一个必要条件是:被发布的对象必须是线程安全的,或者是有效的不可变对象(有效不可变意味着对象的状态在发布之后永远不会被修改)。volatile 类型的引用可以确保对象的发布形式的可见性,但是如果对象的状态在发布后将发生更改,那么就需要额外的同步。
  模式 #3:独立观察(independent observation)
  安全使用 volatile 的另一种简单模式是:定期 “发布” 观察结果供程序内部使用。例如,假设有一种环境传感器能够感觉环境温度。一个后台线程可能会每隔几秒读取一次该传感器,并更新包含当前文档的 volatile 变量。然后,其他线程可以读取这个变量,从而随时能够看到最新的温度值。
  使用该模式的另一种应用程序就是收集程序的统计信息。清单 4 展示了身份验证机制如何记忆最近一次登录的用户的名字。将反复使用 lastUser 引用来发布值,以供程序的其他部分使用。
  清单 4. 将 volatile 变量用于多个独立观察结果的发布
public class UserManager {
public volatile String lastUser;
public boolean authenticate(String user, String password) {
boolean valid = passwordIsValid(user, password);
if (valid) {
User u = new User();
activeUsers.add(u);
lastUser = user;
}
return valid;
}
}
  该模式是前面模式的扩展;将某个值发布以在程序内的其他地方使用,但是与一次性事件的发布不同,这是一系列独立事件。这个模式要求被发布的值是有效不可变的 —— 即值的状态在发布后不会更改。使用该值的代码需要清楚该值可能随时发生变化。
  模式 #4:“volatile bean” 模式
  volatile bean 模式适用于将 JavaBeans 作为“荣誉结构”使用的框架。在 volatile bean 模式中,JavaBean 被用作一组具有 getter 和/或 setter 方法 的独立属性的容器。volatile bean 模式的基本原理是:很多框架为易变数据的持有者(例如 HttpSession)提供了容器,但是放入这些容器中的对象必须是线程安全的。
  在 volatile bean 模式中,JavaBean 的所有数据成员都是 volatile 类型的,并且 getter 和 setter 方法必须非常普通 —— 除了获取或设置相应的属性外,不能包含任何逻辑。此外,对于对象引用的数据成员,引用的对象必须是有效不可变的。(这将禁止具有数组值的属性,因为当数组引用被声明为 volatile 时,只有引用而不是数组本身具有 volatile 语义)。对于任何 volatile 变量,不变式或约束都不能包含 JavaBean 属性。清单 5 中的示例展示了遵守 volatile bean 模式的 JavaBean:
  清单 5. 遵守 volatile bean 模式的 Person 对象
@ThreadSafe
public class Person {
private volatile String firstName;
private volatile String lastName;
private volatile int age;
public String getFirstName() { return firstName; }
public String getLastName() { return lastName; }
public int getAge() { return age; }
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public void setAge(int age) {
this.age = age;
}
}
  volatile 的高级模式
  前面几节介绍的模式涵盖了大部分的基本用例,在这些模式中使用 volatile 非常有用并且简单。这一节将介绍一种更加高级的模式,在该模式中,volatile 将提供性能或可伸缩性优势。
  volatile 应用的的高级模式非常脆弱。因此,必须对假设的条件仔细证明,并且这些模式被严格地封装了起来,因为即使非常小的更改也会损坏您的代码!同样,使用更高级的 volatile 用例的原因是它能够提升性能,确保在开始应用高级模式之前,真正确定需要实现这种性能获益。需要对这些模式进行权衡,放弃可读性或可维护性来换取可能的性能收益 —— 如果您不需要提升性能(或者不能够通过一个严格的测试程序证明您需要它),那么这很可能是一次糟糕的交易,因为您很可能会得不偿失,换来的东西要比放弃的东西价值更低。
  模式 #5:开销较低的读-写锁策略
  目前为止,您应该了解了 volatile 的功能还不足以实现计数器。因为 ++x 实际上是三种操作(读、添加、存储)的简单组合,如果多个线程凑巧试图同时对 volatile 计数器执行增量操作,那么它的更新值有可能会丢失。
  然而,如果读操作远远超过写操作,您可以结合使用内部锁和 volatile 变量来减少公共代码路径的开销。清单 6 中显示的线程安全的计数器使用 synchronized 确保增量操作是原子的,并使用 volatile 保证当前结果的可见性。如果更新不频繁的话,该方法可实现更好的性能,因为读路径的开销仅仅涉及 volatile 读操作,这通常要优于一个无竞争的锁获取的开销。
  清单 6. 结合使用 volatile 和 synchronized 实现 “开销较低的读-写锁”
  清单 6. 结合使用 volatile 和 synchronized 实现 “开销较低的读-写锁” 单 6. 结合使用 volatile 和 synchronized 实现 “开销较低的读-写锁”
@ThreadSafe
public class CheesyCounter {
// Employs the cheap read-write lock trick
// All mutative operations MUST be done with the 'this' lock held
@GuardedBy("this") private volatile int value;
public int getValue() { return value; }
public synchronized int increment() {
return value++;
}
}
  之所以将这种技术称之为 “开销较低的读-写锁” 是因为您使用了不同的同步机制进行读写操作。因为本例中的写操作违反了使用 volatile 的第一个条件,因此不能使用 volatile 安全地实现计数器 —— 您必须使用锁。然而,您可以在读操作中使用 volatile 确保当前值的可见性,因此可以使用锁进行所有变化的操作,使用 volatile 进行只读操作。其中,锁一次只允许一个线程访问值,volatile 允许多个线程执行读操作,因此当使用 volatile 保证读代码路径时,要比使用锁执行全部代码路径获得更高的共享度 —— 就像读-写操作一样。然而,要随时牢记这种模式的弱点:如果超越了该模式的最基本应用,结合这两个竞争的同步机制将变得非常困难。
  结束语
  与锁相比,Volatile 变量是一种非常简单但同时又非常脆弱的同步机制,它在某些情况下将提供优于锁的性能和伸缩性。如果严格遵循 volatile 的使用条件 —— 即变量真正独立于其他变量和自己以前的值 —— 在某些情况下可以使用 volatile 代替 synchronized 来简化代码。然而,使用 volatile 的代码往往比使用锁的代码更加容易出错。本文介绍的模式涵盖了可以使用 volatile 代替 synchronized 的最常见的一些用例。遵循这些模式(注意使用时不要超过各自的限制)可以帮助您安全地实现大多数用例,使用 volatile 变量获得更佳性能。

posted @ 2013-09-30 11:01 顺其自然EVO 阅读(496) | 评论 (0)编辑 收藏

activiti创建数据库表

 方法一:
    直接执行activiti-engine-x.jar 中 /org/activiti/db/create下的DDL语句脚本
  方法二:
  把activiti-engine的jar放到classpath下
  添加对应的数据库驱动
  把Activiti配置文件 (activiti.cfg.xml) 放到 classpath下, 指向你的数据库(参考数据库配置章节)
  执行 DbSchemaCreate 类的main方法
  例如:
  ProcessEngineConfiguration
  .createProcessEngineConfigurationFromResourceDefault()
  .setDatabaseSchemaUpdate(ProcessEngineConfigurationImpl.DB_SCHEMA_UPDATE_CREATE)
  .setJdbcUrl("jdbc:h2:tcp://localhost/activiti") --执行数据库
  .buildProcessEngine();

posted @ 2013-09-30 10:33 顺其自然EVO 阅读(1642) | 评论 (0)编辑 收藏

我的测试历程—QTP之狭义的数据驱动模型

 07年我参加了软件测试工程师培训课程(课程中包含自动测试工具,功能:QTP,性能:LR),QTP课程主要讲解了QTP的关键字视图相关的内容(专家视图部分没有涉及),培训完以后,我对QTP的认识是:QTP使用起来很简单,就是一个录制、回放(不通过就调试)、细化脚本、再回放(不通过就再调试)、出报告的过程,那时候对QTP的认识很肤浅,也和一些朋友一样对QTP产生过类似的质疑:QTP能满足实际项目包罗万象的需求吗?当时感觉QTP只能应用在主要流程的验证上,而且没有真正意义上做到测试的自动化(当然以上都是07年对QTP的认识)于是我停止了继续深入学习QTP……
  09年9月左右,由于项目人手少,测试时间又短,所以每次版本更新后,只对新增功能和相关模块进行测试,而比较稳定的模块只走一个正常流程(甚至时间太紧连正常流程也来不及走了),另外由于我所在项目和另外一个项目都是一个大项目的子项目,所以另外一个项目的修改也可能导致本项目的一些功能不可用,下面有个实际项目中遇到的例子:有一次另外那个项目修改了数据库结构,数据库中删除了一个字段,导致我这个项目的一些特别稳定的功能中查询该字段的所有地方都报“黄页”(当然这些地方都做了安全处理,只抛了个自定义的页面,没有把代码抛出来),当时吓出了一身“冷汗”,还好每次更新我都会挑一些没有修改模块进行抽查,这次运气好,刚好抽到了,俗话说:“吃一堑长一智”,就算完全没有修改的模块也应该验证一下,但是目前的时间和人力只够对新功能的测试,我又想到了QTP,于是我安装了QTP,将老功能的业务流程录制成脚本,每次更新后,跑一下流程,验证一下老功能是否可用,成功案例:有一次QTP回放当中发现2个地方报“黄页”,后来才知道是因为另外一个项目更新了WEBSERVICE,而我这个项目的那2个地方刚好要调用那个WEBSERVICE,所以会报错,由于这一次的经历让我忽然对QTP产生了兴趣,对QTP脚本进行了更深入的学习,从07年的完全自动录制到现在的手动写脚本,从脚本依赖对象库到脱离对象库,从求助别人到帮别人写实际项目的自动化测试脚本,从各个测试脚本相互独立,到自己编写自动化测试框架……2个月前自己写了个测试框架,实现了运行一个VBS脚本,就可以打开QTP(脱离对象库)并按照CASE优先级从高到低运行所有需要运行的CASE,运行结束自动将结果写入文件中……2个星期前重新设计框架提高脚本开发效率和简单易用性。
  下面写下现在我对QTP的看法:在没有接触自动化测试框架之前,我所有的脚本都是都是相互独立的,即:每个功能作为一个TESTCASE,这样就导致每次都要手动把每个脚本运行一遍,然后看报告,感觉自动化一点也不自动化,而且脚本的可重用性也很不好。于是我就在想,怎样才能做到真正意义上的自动化呢?可不可以通过运行一个驱动脚本打开QTP然后自动运行所有指定的脚本用例呢?后来在网上查了相关资料,开始自己搭建自动化测试框架:
  我的第一个框架:由依赖对象库到脱离对象库,由自动录制到手动编写测试脚本。这个框架思想是学习于51
  论坛中的《轻量级自动化测试框架》,只不过在此基础添加了一些功能,比如用例执行优先级。当时觉得这个框架很好用,全部使用描述性编程这样可以使用例不依赖对象库运行,提高了脚本的可移植性,但是随着对QTP认识的不断的深入,渐渐的发现描述性编程的弊端:脚本开发效率太低,同样开发一个测试脚本,完全使用描述性编程和自动录制+手动增强脚本相比,录制一个同样的功能,需要的时间大约3-4倍,甚至更长,因为使用描述性编程需要对对象的各个属性特别熟悉,另外完全使用描述性编程的调试效率也很低,使用哪些属性作为识别该对象的依据又需要一个判断过程,这样都会降低测试脚本的开发效率,还有描述性编程对编程基础有一定要求,所以我觉得脚本开发应该以自动录制+手动增强脚本为主,以描述性编程为辅。因为在有的项目中有些步骤可能通过自动录制是录制不到的,这时候描述性编程就起到很好的辅助作用。
  我的第二个框架:由脱离对象库到依赖对象库,由手动编写测试脚本到自动录制+手动增强脚本(以描述性编程为辅)。由于第一个框架的弊端,所以我在想怎样避免这个弊端,提高脚本开发效率,自动录制是开发脚本最快的一种方式,而且对脚本开发人员的要求很低,于是我开始把目光回归到QTP这一最简单最基本的功能上。开始设计一个属于我们“菜鸟”的测试框架。(其中借鉴了《QTP项目应用与进阶》中测试用例模板)
  这个框架(相对于第一个框架)的优点:1、降低人员素质的要求,使用例的脚本开发人员不需要懂得太多QTP方面的专业知识,只要掌握简单的录制回放过程和脚本增强就可以,这样避免有些人整天忙有些人“没事”做了,从而达到资源的充分利用。2、提高脚本开发效率。
  这个框架(相对于第一个框架)的缺点:调用外部ACTION相对复杂一点,需要明确知道该ACTION所在脚本的位置,不过这一点可以通过文档解决这个问题,制作一个 ACTION列表就可以了。2、对象+

 由于这个框架写在了“丫头”的毕业论文中,目前她还没答辩,为了避免不必要的麻烦,所以这里就不详细写了(大家看了附件的框架实例就应该能明白我的思路了)本实例是使用QTP10.0录制的,重点阐述的是一种思想,脚本中很多功能未加入。例如:自动加载插件的功能,不过大家可以自己加一下(QTP自动化对象模型参考中有加载插件的代码),另外QTP版本比较低的朋友可以自己录制下脚本替换掉Script文件夹下对应的脚本试下。若要设置脚本运行时QTP可见,可以将函数driver()中的qtapp.visible=False修改为qtapp.visible=True
  最后,如果哪位朋友有什么好的建议或觉得哪里需要改进,可以给我留言,如果有时间我会试着改进一下,另外写的不好的地方也请多多指正,谢谢!
  向大家推荐2本QTP相关的很不错书:
  《QTP项目应用与进阶》    E测工作室(风过无息、斐明哲、黄先容、韩柳、俞戴龙   化学工业出版社
  《QTP自动化测试实践》    陈能技      电子工业出版社
  第一本书我买了而且前段时间看了,感觉很不错,思路很清晰,而且包含编码规范等自动化以外的的知识,感觉写的蛮好的。
  第二本书最近才了解到这本书,不过没看过,朋友说很不错,正打算买呢,另外看了作者博客里的资料,感觉写的很好,所以就推荐大家看看,希望能对大家有所帮助,谢谢!
版权声明:本文由会员 feiyunkai 首发于51Testing软件测试论坛 [软件测试新手上路] 版块。
原创作品,转载时请务必以超链接形式标明本文原始出处、作者信息和本声明,否则将追究法律责任。
相关文章:
我的测试历程---用例设计思路(安装/卸载)

posted @ 2013-09-29 10:32 顺其自然EVO 阅读(277) | 评论 (0)编辑 收藏

WEB前端性能分析--工具篇

  在线网站类:
  WebPageTest
  说明:
  在线的站点性能评测网站,地址http://www.webpagetest.org/
  补充:
  其实这网站也是个开源项目,所以支持自己搭建一个内部的测试站点
  ShowSlow
  说明:
  showslow是yslow的数据收集与展示平台http://www.showslow.com/,它是一个开源的php项目,可以用来与firefox的yslow插件、page speed插件或者dynatrace通信,收集插件或程序所发送过来的信息并集中展示。只需要在dynatrace安装目录下进行一些设置,即可自动实现上传结果到showslow平台作为存档、分析及监控。
  浏览器插件类:
  FireBug
  这个不用说了,它可以对页面进行调试,可以记录所有网页的访问耗时,下载的资源等。
  Page Speed
  说明:
  基于firebug的web页面优化的评测工具,同时还有支持chrome的插件,因为是google产的。
  使用:
  直接打开FF的firebug或chrome的开发人员工具,切换到page speed标签,浏览一个网页然后点击分析即可,分析完成后会针对规则打出一个成绩,并告诉你哪些规则你没有符合。
  其评分规则27条规则:
  https://developers.google.com/speed/docs/best-practices/rules_intro
  对几个网站的分析结果如下:
  Google.cn 99分
  Baidu.com 98分
  360buy.com 98分
  Taobao.com 89分
  Dangdang.com 83分
  补充:
  其实这个更像是代码的白盒测试分析工具,因为其都是根据一定的规范来检测网页的优化程度,而不是实际的去监听和过滤页面访问所花费的时间。当然一个网页的加载时间和很多因素有关;比如网速,比如页面上的内容,不同的网站加载时间肯定是不一样的,这个就每一个用一个规则来确定一个怎么的网站应该要多长的加载时间了,因此这只是一个最佳实践规则和建议的检测工具;还有一点就是如果想看页面访问时间的细节,firebug和chrome的开发人员工具本身就已经有了。
  Speed Tracer
  说明:
  基于chrome的插件,同样是有google产的,这个是web前端页的性能记录和分析工具,同时还提供一个规则和建议的评测。
  使用:
  https://developers.google.com/web-toolkit/speedtracer/get-started
  补充:
  这个工具收集的东西主要是资源或事件消耗的时间,它会实时的记录某个页面的加载过程,并且一直跟踪所有的事件;在易用性方面数据可以到出来,还有可以根据时间轴来分析具体某端的性能规则和建议。
  Yslow
  说明:
  基于firebug的评测分析工具,yahoo产;和page speed类似工具,会给出页面的评分和优化说规则,同时会提供页面下载资源的统计分析功能,还提供了一些小工具,如js运行检测,图片的优化工具,未符合规则的资源有哪些等等。总的来说是page speed的增强版。
  Yslow优化建议23条规则:
  http://developer.yahoo.com/performance/rules.html
  各网站的评分:
  Google.cn 67分
  Baidu.com 94分
  360buy.com 77分
  Taobao.com 70分
  Dangdang.com 71分
独立程序类:
  DynaTrace Ajax Edition
  说明:
  基于IE,firefox的插件,对于FF需要版本支持,需要独立安装文件(50多M)。其可支持到函数级的度量分析,此外其它工具能支持的功能这个工具都支持的。
  DynaTrace优化建议规则:
  http://community.dynatrace.com/ext/ajax/PUB/Best+Practices+on+Web+Site+Performance+Optimization
  Fiddler
  说明:
  Microsoft的一款web调试工具,它会记录所有本地的http通信。同时支持ie插件版
  HttpAnalyzer
  说明:
  和fiddler原理一样的工具,不过功能比fiddler更加易用。同时支持ie,ff插件版,此外独立版程序提供http调试功能,写基于http通信的程序使用这个调试比较不错,之前写接口测试工具时就用的这个调试的。
  HttpWatch:
  说明:
  以前这个和httpanalyzer都用过,后来就只用后者了;今天突然发现放弃它的原因是它只支持插件版的,即只能在浏览器上使用,而且只能抓对应浏览器的http通信,且不支持http通信的调试;不过现在发现了一个比httpanalyzer好的就是它的页面加载用时的统计功能,是可以统计一个页面总用时什么的,所以这个工具更适合用于站点的页面性能分析。
  总结:
  这些个工具里有些类似,有些用处各不相同,有些事专门的web前端性能评测工具,有些并不是为了web前端性能而做的工具。总的来说就是要结合实际情况,综合这些个工具来用,需要分析什么情况就用什么工具。如果是通常意义上的web前端性能测试的话,可以选择一个固定的方案,比如:DynaTrace + showslow,前者获取非常丰富的数据,后者则在服务端专门展示这些数据,即方便使用又方便存储。如果要支持持续测试的话,可以写自动化的脚本来跑具体的页面,每次新版本都执行一次自动化测试即可。
相关文章:
web前端性能分析--实践篇

posted @ 2013-09-29 10:32 顺其自然EVO 阅读(474) | 评论 (0)编辑 收藏

loadrunner analysis设置axis 使曲线变得平滑

收集loadrunner测试结果的时候,默认的参考值往往不是0,这样会使tps或者response time的曲线看起来非常陡峭..
  如下图:
  我们可以设置axis,使曲线的参照点为0:
  在图像上单击右键---->Display Option----->advanced----axis
  左边axes选中 --left axis,右边选中minium,点change---->输入0,关闭.
  看看我的曲线图是不是平滑了不少:

posted @ 2013-09-29 10:23 顺其自然EVO 阅读(253) | 评论 (0)编辑 收藏

测试网站速度简单方法

 一:用ping命令简单测试网站的方法:
  Ping结果属于表示,bytes表示发送多少字节,time是时间,时间越小速度越快,
  TTL可以判断对方操作系统,TTL=119是XP系统,但TTL一般不准,
  服务器可以修改注册表更改TTL类型,更详细测速的办法,请多多搜索;
  最短时间、最长时间和平均时间(时间越短越好),这样你就能大致判断出网站的速度了;
  TTL的意思:
  TTL是IP协议包中的一个值,它告诉网络,数据包在网络中的时间是否太长而应被丢弃。
  有很多原因使包在一定时间内不能被传递到目的地。解决方法就是在一段时间后丢弃这个包,
  然后给发送者一个报文,由发送者决定是否要重发。TTL的初值通常是系统缺省值,
  是包头中的8位的域。TTL的最初设想是确定一个时间范围,超过此时间就把包丢弃。
  由于每个路由器都至少要把TTL域减一,TTL通常表示包在被丢弃前最多能经过的路由器个数。
  当记数到0时,路由器决定丢弃该包,并发送一个ICMP报文给最初的发送者。
  二:用tracert命令简单测试网站的方法:
  测试方法和ping命令类似,只是ping换成tracert www.你的网址.com, tracert就是用来检测从终端客户
  到你的服务器所在机房的“跳数”和响应时间,也就是测试出服务器与全国各地客户的连接速度,
  当到达任何一个网关的时候,tracert会进行三次测试,并把三次测试的结果以ms为单位显示,当然time时间越短越好。
  三:全方位的免费网站速度测试工具 — GTmetrix
  网址:http://gtmetrix.com
  四:比较哪个网站载入速度较快 — WhichLoadsFaster
  网址:http://whichloadsfaster.com/
  五:国内免费的网站速度测试平台 — WebKaka
  网址:http://www.webkaka.com

posted @ 2013-09-29 10:22 顺其自然EVO 阅读(366) | 评论 (0)编辑 收藏

测试人员总结应如何提高产品质量

 应我们总监要求,让我这个测试来写一篇关于 如何提高运营质量的文章,这不是为难我吗?
  第一,我不是运营,该怎么写运营质量呢?
  第二,我也不是项目经理,对整个项目产品把关?
  问过很多同学,回复百度,或者只是写一下 测试在整个运营中的工作及重要性和影响就行。
  无奈小公司,没有几个运营人员,产品上线后,用户有一些问题没有及时处理,我是兼测试和客服了。
  附件中是自己写的一个文档,记录在日志中,也算自己的工作收获了。
  刚才重新查看了下,上传的附件没有找到,不知道怎么回事,哎。
  如何提高产品运营质量
  要想提高产品运营质量,首先得提高产品质量,只有产品质量提高了,在产品推出使用中,才能减少运营事故的发生甚至避免发生,那么,该如何提高产品质量呢?
  1. 一个软件项目成功的关键因素:
  决定一个软件项目成败的关键因素有成本,时间,质量。提升软件质量,缩短测试周期。
  在整个项目过程中,各个角色对质量的理解也不同。对于用户来说,最重要的是满意的功能,好的用户体验;对于需求和设计来说,完整的需求文档,符合用户使用规范的文档等;对于开发人员来说,正确的代码是保证质量的前提,对自己的代码进行完整的测试;对于测试来说,好的质量是产品有最少的缺陷,满足用户的使用需求,有好的用户体验等等,不同的角色对于质量的要求不同。
  2.什么是软件质量
  用户对软件质量的评价,功能是否全面,运行速度、使用中是否有太多的错误(故障),软件不好改动(维护)等,如何保证软件质量是这个项目的关键,只有软件质量保证了,软件运营质量才能保证
  3.如何保证软件质量?
  项目一开始测试人员应该介入
  正确理解用户的需求
  制定标准和规范,团队统一执行
  审查软件开发活动
  测试源程序代码
  记录开发活动和软件产品的偏差
  记录所有不符合项,报告高级管理者
  3.1.理解客户的需求和要求
  在我们公司,用户产品的需求都是由产品部门提出的,测试、开发等各个部门可以一起参与讨论,产品需求提出后,形成文字或者用其他的形式(图片等)表达需求;之后对需求进行评审,输出最后确定的需求文档;如果在后期项目实施过程中需求有更改,及时沟通,以便开发和测试针对需求工作
  3.2.审查软件开发活动
  审查每个活动十分遵循软件开发过程规范,审查每个活动的输入条件是否都已经得到满足;审查活动的执行是否遵循规范;审查每个活动的输出是否都已经产生;
  需求的变更,开发文档相应的也发生变更,文档的及时更新,开发各个阶段的文档审查,代码审查等等,确保在开发阶段尽可能多的发现逻辑错误,这样修改bug的成本最低。

posted @ 2013-09-29 10:21 顺其自然EVO 阅读(417) | 评论 (0)编辑 收藏

java:递归取出List中的元素

 方法一:
....................
String hql = "select t.fsHostip, t.fiReserve1 from Thostip as t where 1 = 1";
List ls = dao.getHibernateTemplate().find(hql);
Iterator it = ls.iterator();
if(it.hasNext()){  // while 用这个的时候和下面的一样
Object[] obj = (Object[]) it.next();
String ip = (String) obj[0];
Integer rs = (Integer) obj[1];
System.out.println(ip +","+rs);
}
  方法二:
//   for(int i = 0; i < ls.size(); i++){
//    Object[] obj = (Object[]) ls.get(i);
//    String ip = (String)obj[0];
//    Integer rs = (Integer)obj[1];
//    System.out.println(ip +","+rs);
//   }

posted @ 2013-09-29 09:53 顺其自然EVO 阅读(261) | 评论 (0)编辑 收藏

仅列出标题
共394页: First 上一页 200 201 202 203 204 205 206 207 208 下一页 Last 
<2024年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

导航

统计

常用链接

留言簿(55)

随笔分类

随笔档案

文章分类

文章档案

搜索

最新评论

阅读排行榜

评论排行榜