起步于系统工程师,迈进入测试工程师,从起初的C/S系统到互联网时代的B/S系统,从事过电信增值业务、软交换、烟草OA、公安技侦和电子商务等行业的软件测试开发和管理多年,愿与大家共同分享共同交流,关注软件项目管理、测试团队管理、软件流程控制和软件性能测试及自动化测试技术。互联网时代,技术推动进步,欢迎人才推荐:jonas.wangl@alibaba-inc.com

发布新日志

  • Disktime

    2008-11-02 22:01:33

    Disktime要求在命令行输入diskperf -y
  • 对脚本进行参数化的好处

    2008-11-02 21:59:42

    可以总结几点:

    1:减少代码量。
    2:可以用不同的值来测试脚本的能力。
    参数化的过程:
    1:用参数替换脚本中的常量。
    2:为参数设置属性和数据源。
    注:只能参数化函数中的参数。并且也不是所有函数中的参数都能参数化。Lrd_stmt只能参数化mpcText
    lr_eval_string可以参数化不能用标准参数化的参数
    参数化CORBA或General_java Vsuer必须参数整个字符串。
    参数的格式要与所录制的脚本相一致,否则脚本可能不能正常运行。

  • 对web性能测试中的验证码问题

    2008-11-02 21:56:49


    现在越来越多的网站为了安全性或是防止Spam的侵害,采用了验证码的校验技术。

    简单地说,验证码就是在进行登录或是内容提交的时候,页面上会随机出现一个人工可识别,但机器不可识别的验证字符串(一般是采用背景、扭曲等方式产生的图片),要求登录或是提交内容时同时输入这个验证码。

    验证码可以有效防止对口令的刺探和所谓的网络推广软件带来的大量的Spam内容,目前已经被许多Internet或是Intranet应用接受为标准的实现方式。但对性能测试来说,这种验证码又带来了很大的问题。

    最突出的问题是,性能测试工具本身是自动化工具,由于这种验证码采用的是“防止自动化工具尝试”的方法,因此,在录制了脚本之后会发现,很难对脚本进行调整,以使其适应验证码验证的需要。已经不止一次有人提到这个问题,并询问有没有较好的解决方案。

    对这个问题,基本上可以考虑从三个途径来解决该问题:

    1、第一种方法,也是最容易想到的,在被测系统中暂时屏蔽验证功能,也就是说,临时修改应用,无论用户输入的是什么验证码,都认为是正确的。这种方法最容易实现,对测试结果也不会有太大的影响(当然,这种方式去掉了“验证验证码”这个环节,不过这个环节本来就很难成为系统性能瓶颈)。但这种方法有一个致命的问题:如果被测系统是一个实际已上线的系统,屏蔽验证功能会对已经在运行的业务造成非常大的安全性的风险,因此,对于已上线的系统来说,用这种方式就不合适了。

    2、第二种方法,在第一种方法的基础上稍微进行一些改进。第一种方法带来了很大的安全性问题,那么我们可以考虑,不取消验证,但在其中留一个后门,我们设定一个所谓的“万能验证码”,只要用户输入这个“万能验证码”,我们就验证通过,否则,还是按照原先的验证方式进行验证。这种方式仍然存在安全性的问题,但由于我们可以通过管理手段将“万能验证码”控制在一个小的范围内,而且只在性能测试期间保留这个小小的后门,相对第一种方法来说,在安全性方面已经有较大的改进了。

    3、如果安全性对应用来说真的是至关重要的,不容许有一丝一毫的闪失,那我们还可以用更进一步的方法来处理这个问题。一般的性能测试工具(MI的LR、Seague的Silk performer等)都能够调用外部的DLL或是组件接口,因此,可以考虑获得“验证码验证”部分的实现,写一个验证码获取的DLL,在测试脚本中进行调用即可。

       除了这三种方法以外,可能还会有其他的方法存在,也希望各位能提供一些其他的思路。在实践中,第二种方法用得比较多,对未上线系统系统的内部性能测试,有时候也用第一种方法。但要提醒的是,如果针对的是已上线系统,无论用哪种方法,测试完成后,都必须立刻将应用恢复,并对系统进行一次安全审计,以免在测试期间被他人入侵。第三种方法用得比较少,而且具体上还依赖于验证组件是否能提供这样的接口。

  • 2008年十大最流行病毒 你被命中多少

    2008-11-02 21:51:50

    2008年十大最流行病毒报告:2008年上半年,电脑病毒、木马的数量依然保持着高速增长,新病毒不断涌现,一些“老”病毒在大量下载器病毒的带动下也异常活跃。 与此同时,病毒、木马与安全软件之间的对抗日益加剧,以机器狗、磁碟机、AUTO木马群为代表的对抗型病毒已经成为广大用户电脑安全的主要威胁。  一、机器狗
      病毒名称:Trojan.Psw.Onlinegame.Dog
      病毒中文名:机器狗
      病毒类型:木马
      危险级别:★★★★
      影响平台:Win9X/2000/XP/NT/Me
      描述:机器狗病毒因最初的版本采用电子狗的照片做图标而被网民命名为“机器狗”,该病毒变种繁多,多表现为杀毒软件无法正常运行。该病毒的主要危害是充当病毒木马下载器,与AV终结者病毒相似,病毒通过修改注册表,让大多数流行的安全软件失效,然后疯狂下载各种盗号工具或黑客工具,给用户电脑带来严重的威胁。机器狗病毒直接操作磁盘以绕过系统文件完整性的检验,通过感染系统文件(比如explorer.exe,userinit.exe,winhlp32.exe等)达到隐蔽启动;通过底层技术穿透冰点,影子等还原系统软件导致大量网吧用户感染病毒,无法通过还原来保证系统的安全;通过修复SSDT(就是恢复安全软件对系统关键API的HOOK),映像挟持,进程操作等方法使得大量的安全软件失去作用;联网下载大量的盗号木马给广大网民的网络虚拟财产造成巨大威胁,部分机器狗变种还会下载ARP恶意攻击程序对所在局域网(或者服务器)进行ARP欺骗影响网络安全。
      二、磁碟机
      病毒名称:Trojan.Psw.Onlinegame.CD
      病毒中文名:磁碟机
      病毒类型:木马
      危险级别:★★★★★
      影响平台:Win9X/2000/XP/NT/Me
      简介:
      电脑感染“磁碟机”变种病毒后,症状表现为运行任意程序时系统经常性死机或长时间卡住不动,病毒会以加密感染的方式感染除系统盘外的其它所有分区内的EXE文件、网页文件、RAR和ZIP压缩包中的文件等。被感染的文件图标变为16位图标,图标变得模糊,类似马赛克状。病毒一旦发现带有符合安全工具软件相关的窗口名存在,就会强行将其关闭(发送洪水似垃圾消息)。在所有盘符下生成“autorun.inf”和病毒程序文件体,并且会实时检测保护这些文件。病毒会下载20余种木马病毒,用以窃取中毒电脑中有价值的隐私信息。病毒通过十余种方式实现自我保护和避免被杀毒软件查杀,其隐藏和自我保护技术超过机器狗。
      三、V终结者
      病毒名称:Trojan/Anti-AV
      病毒中文名:Av终结者
      病毒类型:木马
      危险级别:★★★★★
      影响平台:Win9X/2000/XP/NT/Me
      描述:“AV终结者”即"帕虫"是一系列反击杀毒软件,破坏系统安全模式、植入木马下载器的病毒,它指的是一批具备如下破坏性的病毒、木马和蠕虫。“AV终结者”名称中的“AV”即为英文“反病毒”(Anti-Virus)的缩写。它能破坏大量的杀毒软件和个人防火墙的正常监控和保护功能,导致用户电脑的安全性能下降,容易受到病毒的侵袭。同时它会下载并运行其他盗号病毒和恶意程序,严重威胁到用户的网络个人财产。此外,它还会造成电脑无法进入安全模式,并可通过可移动磁盘传播。目前该病毒已经衍生多个新变种,有可能在互联网上大范围传播。“AV终结者”设计中最恶毒的一点是,用户即使重装操作系统也无法解决问题:格式化系统盘重装后很容易被再次感染。用户格式化后,只要双击其他盘符,病毒将再次运行。“AV终结者”会使用户电脑的安全防御体系被彻底摧毁,安全性几乎为零。它还自动连接到某网站,下载数百种木马病毒及各类盗号木马、广告木马、风险程序,在用户电脑毫无抵抗力的情况下,鱼贯而来,用户的网银、网游、QQ账号密码以及机密文件都处于极度危险之中。
      四、网游窃贼
      病毒名称:Trojan/PSW.GamePass.Gen
      病毒中文名:网游大盗
      病毒类型:木马
      危险级别:★★★★
      影响平台:Win 9X/ME/NT/2000/XP/2003
      描述:Trojan/PSW.GamePass“网游大盗”是一个盗取网络游戏帐号的木马程序,会在被感染计算机系统的后台秘密监视用户运行的所有应用程序窗口标题,然后利用键盘钩子、内存截取或封包截取等技术盗取网络游戏玩家的游戏帐号、游戏密码、所在区服、角色等级、金钱数量、仓库密码等信息资料,并在后台将盗取的所有玩家信息资料发送到骇客指定的远程服务器站点上。致使网络游戏玩家的游戏帐号、装备物品、金钱等丢失,会给游戏玩家带去不同程度的损失。 “网游大盗”会通过在被感染计算机系统注册表中添加启动项的方式,来实现木马开机自启动。
      五、下载者
      病毒名称:w32.Troja.downloader
      中 文 名:下载者
      病毒类型:木马下载器
      危害等级:★★★★
      描述:该病毒为Windows平台下通过网络下载QQ木马、网游木或其它病毒的下载器病毒运行后将自己伪装成伪系统正常文件,并利用特殊技术将病毒代码注入到系统正常进程中,以绕过网络防火墙的监视。然后下载其它病毒。
    六、Rootkit  病毒名称:Rootkit.Agent.xd
      中 文 名:Rootkit
      病毒类型:病毒
      危害等级:★★★★★
      Rootkit基本是由几个独立程序组成,一个典型rootkit包括: 以太网嗅探器程序,用于获得网络上传输的用户名和密码等信息。 特洛伊木马程序,为攻击者提供后门。 隐藏攻击者目录和进程的程序。还包括一些日志清理工具,攻击者用其删除wtmp、utmp和lastlog等日志文件中有关自己行踪的条目。 复杂的rootkit还可以向攻击者提供telnet、shell和finger等服务。还包括一些用来清理/var/log和/var/adm目录中其 它文件的脚本。
      七、灰鸽子
      病毒名称:Backdoor/Huigezi
      病毒中文名:灰鸽子
      病毒类型:后门
      危险级别:★★★★
      影响平台:Win 9X/ME/NT/2000/XP/2003
      描述:Backdoor/Huigezi “灰鸽子”是后门家族的最新成员之一,采用Delphi语言编写,并经过加壳保护处理。“灰鸽子”运行后,会自我复制到被感染计算机系统的指定目录下,并重新命名保存(文件属性设置为:只读、隐藏、存档)。“灰鸽子”是一个反向连接远程控制后门程序,运行后会与骇客指定远程服务器地址进行TCP/IP网络通讯。中毒后的计算机会变成网络僵尸,骇客可以远程任意控制被感染的计算机,还可以窃取用户计算机里所有的机密信息资料等,会给用户带去不同程度的损失。“灰鸽子”会把自身注册为系统服务,以服务的方式来实现开机自启动运行。“灰鸽子”主安装程序执行完毕后,会自我删除。
      八、U盘病毒
      病毒名称:Checker/Autorun
      病毒中文名:U盘寄生虫
      病毒类型:蠕虫
      危险级别:★★★★
      一周感染量:18184台
      影响平台:Win 9X/ME/NT/2000/XP/2003
      描述:Checker/Autorun“U盘寄生虫”是一个利用U盘等移动存储设备进行自我传播的蠕虫病毒。“U盘寄生虫” 运行后,会自我复制到被感染计算机系统的指定目录下,并重新命名保存。“U盘寄生虫”会在被感染计算机系统中的所有磁盘根目录下创建“Autorun.inf”文件和蠕虫病毒主程序体,来实现用户双击盘符而启动运行“U盘寄生虫”蠕虫病毒主程序体的目的。“U盘寄生虫”还具有利用U盘、移动硬盘等移动存储设备进行自我传播的功能。“U盘寄生虫”运行时,可能会在被感染计算机系统中定时弹出恶意广告网页,或是下载其它恶意程序到被感染计算机系统中并调用安装运行,会给用户带去不同程度的损失。“U盘寄生虫” 会通过在被感染计算机系统注册表中添加启动项的方式,来实现蠕虫开机自启动。
      九、QQ大盗
      病毒名称:Trojan/Psw.Ala.QQpass
      病毒中文名:QQ大盗
      病毒类型:蠕虫
      危险级别:★★★★
      影响平台:Win 9X/ME/NT/2000/XP/2003
      描述:Trojan/PSW.QQPass“QQ大盗”是木马家族的最新成员之一,采用高级语言编写,并经过加壳保护处理。“QQ大盗”运行时,会在被感染计算机的后台搜索用户系统中有关QQ注册表项和程序文件的信息,然后强行删除用户计算机中的QQ医生程序“QQDoctorMain.exe”、“QQDoctor.exe”和“TSVulChk.dat”文件,从而来保护自身不被查杀。“QQ大盗”运行时,会在后台盗取计算机用户的QQ帐号、QQ密码、会员信息、ip地址、ip所属区域等信息资料,并且会在被感染计算机后台将窃取到的这些信息资料发送到骇客指定的远程服务器站点上或邮箱里,会给被感染计算机用户带去不同程度的损失。“QQ大盗”通过在注册表启动项中添加键的方式,来实现开机木马自启动。
      十、Flash漏洞攻击器
      病毒名称:Hack.Exploit.Swf.A
      病毒中文名:Flash漏洞攻击器
      病毒类型:蠕虫
      危害级别:★★★★
      一周感染量:1890453
      影响平台:Win 9X/ME/NT/2000/XP/2003
      这是一个黑客程序,可以破坏Flash插件的安全机制,使其它病毒获取系统权限,侵入用户电脑。目前每天有数十万台电脑被此病毒感染,危害十分严重。此病毒会被植入“挂马网站”中,用户浏览时就可能中毒。目前已截获的主要是木马下载器病毒,它们会从网上下载其它多种盗号木马,窃取流行网络游戏的账号和装备。
  • 运用加密技术保护Java源代码

    2008-11-02 21:50:21

    为什么要加密?   对于传统的C或C++之类的语言来说,要在Web上保护源代码是很容易的,只要不发布它就可以。遗憾的是,Java程序的源代码很容易被别人偷看。只要有一个反编译器,任何人都可以分析别人的代码。Java的灵活性使得源代码很容易被窃取,但与此同时,它也使通过加密保护代码变得相对容易,我们唯一需要了解的就是Java的ClassLoader对象。当然,在加密过程中,有关Java Cryptography Extension(JCE)的知识也是必不可少的。
      有几种技术可以“模糊”Java类文件,使得反编译器处理类文件的效果大打折扣。然而,修改反编译器使之能够处理这些经过模糊处理的类文件并不是什么难事,所以不能简单地依赖模糊技术来保证源代码的安全。
      我们可以用流行的加密工具加密应用,比如PGP(Pretty Good Privacy)或GPG(GNU Privacy Guard)。这时,最终用户在运行应用之前必须先进行解密。但解密之后,最终用户就有了一份不加密的类文件,这和事先不进行加密没有什么差别。
      Java运行时装入字节码的机制隐含地意味着可以对字节码进行修改。JVM每次装入类文件时都需要一个称为ClassLoader的对象,这个对象负责把新的类装入正在运行的JVM。JVM给ClassLoader一个包含了待装入类(比如java.lang.Object)名字的字符串,然后由ClassLoader负责找到类文件,装入原始数据,并把它转换成一个Class对象。
      我们可以通过定制ClassLoader,在类文件执行之前修改它。这种技术的应用非常广泛――在这里,它的用途是在类文件装入之时进行解密,因此可以看成是一种即时解密器。由于解密后的字节码文件永远不会保存到文件系统,所以窃密者很难得到解密后的代码。
      由于把原始字节码转换成Class对象的过程完全由系统负责,所以创建定制ClassLoader对象其实并不困难,只需先获得原始数据,接着就可以进行包含解密在内的任何转换。
      Java 2在一定程度上简化了定制ClassLoader的构建。在Java 2中,loadClass的缺省实现仍旧负责处理所有必需的步骤,但为了顾及各种定制的类装入过程,它还调用一个新的findClass方法。
      这为我们编写定制的ClassLoader提供了一条捷径,减少了麻烦:只需覆盖findClass,而不是覆盖loadClass。这种方法避免了重复所有装入器必需执行的公共步骤,因为这一切由loadClass负责。
      不过,本文的定制ClassLoader并不使用这种方法。原因很简单。如果由默认的ClassLoader先寻找经过加密的类文件,它可以找到;但由于类文件已经加密,所以它不会认可这个类文件,装入过程将失败。因此,我们必须自己实现loadClass,稍微增加了一些工作量。
      查看原文>>
      www.ibm.com/developerworks/cn/java/l-secureclass/
  • 初识验收测试管理工具FitNesse

    2008-11-02 21:47:54

    一、什么是Fitnesse?
    FitNesse 是一套软件开发协作工具
    FitNesse是帮助大家加强软件开发过程中的协作的工具。能够让客户、测试人员和开发人员了解软件要做成什么样,帮助建议软件最终是否达到了设计初衷。
    FitNesse 是一套软件测试工具.
    从另外一个角度看,FitNesse是一个轻量级的、开源的框架,能够帮助开发团队方便的定义验收测试(Acceptance Tests),通过在web页面上简单的输出和预计输出的表格就可实现,并且可以运行这些测试以确定是否通过。
    FitNesse 是 wiki.
    可以很方便的创建和编辑页面
    FitNesse 是一个web服务器.
    不用过多的安装配置,很方便使用。
    二、FitNesse的安装
    FitNesse需要Java1.4以上Java环境支持。你可以到SUN的官方网站去下载.
    设置系统环境变量: JAVA_HOME 到 java安装目录如:D:\Program Files\Java\jdk1.5.0_15\bin
    设置系统环境变量:classpath 到D:\Program Files\Java\jdk1.5.0_15\lib\dt.jar;D:\Program Files\Java\jdk1.5.0_15\lib\tool.jar
    下载FitNesse:
    http://fitnesse.org/FitNesse.DownLoad下载 "Full Distribution",并解压缩。
    启动
    如果http 的80端口没有被占用的话直接在dos状态下运行run.bat就可以了,我们做.net开发的一般80端口被iis占用了,这样我们在启动fitnesse的时候就要指定一个别的端口,如 run.bat -p 8008 ,这样就可以启动了。
    使用:
    启动浏览器,输入 http://localhost:8008 .OK,你应该已经能看到FitNesse的主界面了 .
  • IT项目团队内部成员管理

    2008-11-02 21:44:58

    团队成员选拔原则
     
      团队成员的选择是组建团队的第一步,也是决定这个团队是否能有效工作的关键因素,整个团队的未来业绩将直接取决于选拔到的成员的努力。在选拔过程前,可以先通过心理测评、专业考察、查阅档案等方式获取有关人员的可靠数据,包括专业能力、性格特征、个人经历、人际关系等方面,建立备选人员人才库。
     
      成员选择的基本原则除了要求具有基本的专业素质外,还要求具有较宽的专业知识面,对产品具有整体意识和系统集成的思想,并具有较强的合作精神。而团队领导则要求具有多专业的协调能力及处理团队与其他部门关系的能力,并能够营造好的团队文化。作为一个整体,团队的专业技能组合要达到必要的高度和广度,同时要求团队成员必须具有很好的人际关系能力,注意角色配置,以利于相互交流、彼此理解与通力合作。在挑选团队成员的过程中,既要考虑他们的性格、能力,更要遵循自愿的原则。团队成员还应该包括团队顾问或专题顾问,他们来自各职能组织部门,不直接参与产品的开发,但提供技术和知识上的支持。
     
      团队成员角色定位
     
      在形成团队时,首先根据任务的需要,确立团队成员的工作对象和工作方式,定义团队成员的工作对象和工作方式,定义团队成员的角色,形成各角色成员的来源、权利、义务及行为规则,确定各角色成员的选拔方式和评判标准,然后通过挑选和考评,并通过授权的方式形成整个工作团队,开始工作。团队成员的角色定位首先要根据团队的角色设计,主要考虑专业的需要,成员要从技术角度能够对团队做出贡献,要注意区分专才成员和通才成员,对于专业化越强的角色,越需要专才成员,对于系统集成工作,则通才更为适合。同时要在成员性格特征的基础上,应用团队角色理论,给成员一个合适的团队角色。
     
      团队成员职业发展和培训
     
      为增加团队的凝聚力和向心力,增强成员对团队的归属感和责任感,项目团队可以通过帮助成员设计职业发展方向,来帮助成员适应多方面的工作和未来发展的需要,同时使成员为自己的良好发展前景而不愿轻意离开团队。成员加入团队后,根据成员个人的条件和背景,由成员和项目经理共同协商,结合项目特点,研讨一套切实可行的个人职业生涯发展体系,协助成员开发其各种知识和技能,尤其是专业性知识和技能,为成员提供实现个人专长的契机。通过个人职业生涯发展计划,使每位成员对自己目前所拥有的技能、兴趣及价值观进行评估,接着考虑项目的变化需求,使自己的特长及发展方向符合团队的需求。通过团队为成员设计良好的个人发展计划和职业发展阶梯,就会促进团队和成员的发展,降低成员的流动率和流动倾向。对于那些看重学习和愿意获得新技能的成员,由项目团队提供培训机会,鼓励他们,以增加他们的满足感和责任感。
     
      项目经理的作用
     
      项目经理是团队的灵魂,是决定项目成功与否的关键人物,同时作为团队的领导者,他的管理素质、组织能力、知识结构、经验水平、领导艺术等都对团队管理的成败有着决定性的影响。在一个特定的项目中,项目经理要对项目实行全面的管理,包括制定计划、报告项目进展,控制反馈,组建团队,在不确定环境下对不确定性问题进行决策,在必要的时候进行谈判及解决冲突等。其中组建团队是项目经理的首要责任,一个项目要取得好的成绩,一个关键的要素就是项目经理应该具备把各方人才聚集在一起,组建一个有效的团队。在团队建设中,要确定项目所需人才,从各有关职能部门获得人才,定义成员任务和角色,把成员按任务组织起来形成一个高效的团队。要建立并使团队有效运行,项目经理需要起关键的作用。主要体现在整体的规划,组织,协调和控制等方面。
     
      (一)整体规划:计划安排项目工作,使各项目工作形成有机整体。
     
      (二)组织:同有关部门联络,选择并确定项目团队的职责。
     
      (三)协调:确定职能专业部门和其他项目参与者之间的分工,有效的调用项目团队和每个成员。
     
      (四)控制:监控进度,鉴别问题,并开创和调节正确的行为。
  • [论坛] 内存越界的现象的解决方法

    2008-11-02 21:41:27

    现象:     1 程序出现异常 异常的现象有很多,如:代码突然跑到不相干的地方去执行,访问异常,正常的变量操作也报错...
        原因:代码段紊乱,this指针被改变,指针指向的数据被改变
        2 程序按逻辑执行,但数据错误  如:变量内容突然消失
        原因:变量所在空间被其它操作误删除等
        3 其它莫名其妙的错误
        原因:
        越界的基本比较原因,如
        1 写越界:      向10个字节的数组写入了20个字节;内存操作越界,如char szText[10];memset(szText,0,30);
        2 错误的函数调用:   sprintf等fmt中的预定义和实际输入的变量数不一致,如sprintf(szData,\"Name:%d title:%s\",1)
        3 错误的调用方式:  用stdcall 的函数指针 调用pascall的函数
      
        检查方法:

        1 BoundChecker进行调试,BoundChecker在代码编译时加入了大量的附加处理,其中包括内存堆栈检测等,其实ms的debug模式也做了许多的类似操作,但debug模式下的一些代码行为,如初始化变量,和Release下的代码执行不同,所以用debug调试不是完美的方式
        2 类内部出现莫名其妙的错误时,查看 this 指针是否变化,方法是在调试的 \"查看\" 窗口 输入:this ;必要的时候进行手手工检查
        3 在调试的 \"查看\" 窗口 输入:@err,hr 看全局错误变量的内容,也许有提示
        4 注释掉部分代码,看是否错误还出现,注释的最佳方式是:二分法
        5 查看程序异常处的反汇编代码,分析原因
  • 【转】怎么做好一个好的测试经理?

    2008-11-02 21:39:34

    1.具有较好的人格魅力和亲和力:

    真正来说做到这一点非常难。这不仅要求测试经理有宽广的胸怀,良好的沟通能力和语言表达能力,还要求测试经理具有较强的应对能力。向上能把工作汇报的让领导满意,令领导信任。能把工作任务轻松, 无异意的下发给下属, 并让他们饱含工作热情共同协作去完成测试任务。如果您能够把扭转下属的思想,把要我测试,变成我要测试,我想你一定很强了。如果陌生的人一见到你,通过谈话就觉的你很强,都愿意和你交朋友,那你的人格魅力一定不错了,呵呵。

    2.
    最好具备较强的测试技术水平:

    一般来说,作为测试经理,在一个测试技术性的团队里,如果你有很强的技术,并且你的技术是最棒的,下属不能够搞定的问题,你都能够做的很好,即时有时候你凶了点,团队里的成员心底里都还是很敬佩你。如果你有技术,但是技术不高,你组内的技术高手一定是你的亲密战友,这个时候唯一的出路就是凝聚团队的力量,取长补短,也能够取得较高的效率。还有一点值得注意:在分派工作的时候,找一下组内的骨干,看看是否有新的或者好的处理办法,这样一来,避免在开会的时候遇到分工或者技术上的尴尬局面。但有的测试经理具备了很强的技术,整天对团队的成员都板副面孔,那你也很难做到人见人爱。唯有为人处事比较圆滑,待人真诚中肯、随和亲切,整天都是笑脸相迎,那呆在这样的团队里工作,一定很开心。所以要做到人见人爱的测试经理,较强的测试技术水平不能够忽视。

    3.
    乐意处理下属在项目中碰到的困难:

    在带领一个团队开展测试工作的时候,当你的下属碰到困难的时候,你更多的是给下属鼓励和安慰,帮助下属分析出现问题的原因。比如说一下:幸苦了干得不错慢慢来,没关系的!下属听了也很开心的,并且以后干活可能会很卖命,因为他的工作得到了领导的认可。或许该问题你也不一定解决得了,这时候你一定要挺身而出,协调测试团队的资源尽力帮他解决问题,久而久之,你的威信就树立起来了,之后就好办事了。

    4.
    勇于承担责任,把功劳推给测试团队:

    软件测试经理,作为一个中层经理。管理者一定要想管好下属,必须身先士卒以身作则,事事为先、严格要求自己,处处起到表率作用。示范的力量是惊人的,一旦通过表率在团队中树立起在员工中的威望。将会上下同心,大大提高团队的整体战斗力。常言到:得人心者得天下,做下属敬佩的领导,将使管理事半功倍。如果下属在测试项目中出现问题,上级领导怪罪下来,自己勇于承担,多检讨自己,少怪罪他人。始终用平和语气与下属沟通,最后一定要找出出现问题的真正原因。让出现问题的下属,自己过意不去,从心底里佩服你,想法补偿你。项目得到喜讯,比如:某个测试项目做的很好,领导表扬的时候,把功劳推给大家,很多时候,容易让人感动,让人佩服得五体头地哈哈。

    5.
    对下属多一些宽容和生活关心:

    特别是对下属不懂,自己懂得很精的地方,下属问的时候,一定要有耐心,给下属详细讲解。切忌:看不起下属。如果真是这样,你这个经理就很失败了。反正对下属,在很多地方,要多一些理解和包容,最好能和下属打成一片,当下属不认为你是领导的时候,你就真是领导了。如果做领导做到别人都当你是朋友,那你真的就成功了。
    还有一点就是要察言观色,随时发现和了解下属的困难,不管是工作方面,还是私人方面,都要关心。比如说:某个下属买了房子,准备装修,那他一定很关心装修方面的东西。如果你懂得很多,那和他交谈时,多一些这方面的话题,他也会很开心,觉的你这个人相当热心,并且也会觉的大家有共同语言,以后当你碰到问题的时候,他一定会鼎立帮助你,因为他认为你是他最信任的知己。也可以多在生活上关心下属。比如有项目要加班什么的,有时候陪陪下属加班呀,吃个午饭宵夜呀,聊点家常呀什么的,自己买单后,公司报销,效果真的不错哟!

    6.
    力争多给下属争取福利

    在公司条件允许的条件下,多给下属争取福利!但是做这件事的时候,一定要在公司利益和员工利益之前要平衡。若过分的给员工争取福利,会造成公司对你有意见,同样,过分的以公司利益为重,员工对你也会意见大!总之,每种情况都要有度,力所能及的事,一定不能放过。很多时候,为员工申请比较多的福利,即时没有成功或者工资变化不大,但是下属都看在眼里,还是很感激你的,因为他知道你已经尽力了,觉的你很够哥们,为你工作很值。

    7.
    多给下属锻炼机会,培养下属能力:

    作为测试经理不可能向测试工程师那样什么事情都自己做,并且事事都自己做也不现实。可以在不同的测试项目中,安排测试主管。然后对测试工作进行协调,参与测试中发现重大问题的讨论。这就要求测试经理懂得用人,懂得计划。在制定详细的测试计划的同时,自己把握测试项目中的关键点和时间表,给下属更多的实践机会,让下属做事更具有责任心和成就感。测试主管在做好测试项目的同时,又减少了测试经理的工作量,学到了不少东西,能力变强了,开心了,达到了上下级和谐共处的双丰收。

    8.
    多给下属精神鼓励,奖惩公私分明:

    很多时候,部门周例会上偶尔的一个口头表扬,更会让下属铭记于心,因为他觉的很有面子,很体面,也许他会再接再厉,给自己创造机会,争取后面再受表扬。下属也乐开了,工作也更加努力、拼命了,效果相当明显。并且奖赏要公私分明,不能有所偏袒,更不能让部门的人觉得你搞私人关系,力争做到一视同仁,对事不对人,也许你就成功了一半。但是,对于工作做的比较差的下属,也要私下单独谈心,帮助找出原因,给他打气,并鼓励他继续努力工作。

    9.
    知人善用,用人之长,合理分工:

    现在很多公司的测试工程师,都是网上外招的,分别来自不同的行业和不同的工作岗位,他们有着不同的专业知识和行业、业务背景。这就要求测试经理,对每个人的长处非常了解,将合适的人安排到合适的工作岗位上,用人之长,避人之短,合理分工,争取达到双赢。

    10.
    较强的行业和业务知识背景:

    测试经理作为一个部门的Leader必须对相关的产品和行业的知识背景了如指掌,要不然下属做了什么,怎么做的,正确与否,你都没法判断。一般来说,在某个行业待3年左右,做了几年的测试,那你对这个行业就非常了解。即使你不参加项目的测试,你问很多的问题,下属也不敢乱讲,毕竟你了解很多。再比如说:某些税务的项目,很多的业务知识,你不是很了解,那也没法做,还有一些隐含的行业需求,没有35年的行业背景,更是没法发掘出来,到了客户缺陷才被发现,你就太被动了。当然,如果时间允许的话,你也可以介入部分模块的测试,这样虽然你测试不是很多,往往会发现很多问题,检验检验下属测试成果。

    11.
    多给下属讲解一些职业发展方面的东西:

    从我带过的团队成员来说,一般干了34年测试的测试工程师,大部分的测试工程师,对自己的职业生涯都很迷茫,没有完整的规划。由于大部分都是做黑盒测试,技术含量较低,抱怨时常是有的。尤其在这个关键的节骨眼上,对他们的心里辅导和安慰非常必要。多给他们展望一些测试的前景,经常组织测试职业发展的方向类似的讨论会,让大家有一个稳定的心,认真干活,而不是时时刻刻在寻找机会,想立马跳槽。

     

  • web测试环(UNIX)Log日志整理

    2008-11-02 21:37:36

    LOG日志的介绍

     

     

    1、  在看log之前,首先需要了解每个log文件要记录什么信息:比如, performance.log是一个查看性能的log日志,而search-velocity.log则是一个查看页面信息的日志;由于每个projectlog文件都有其特定性,所以在看log之前需要先清楚每个log文件代表什么信息;

     

    2、  Log信息问几种级别:OFFFATALERRORWARNINFODEBUGALL;但是平时一般只用四种:DEBUGINFOWARNERROR;前三个级别的信息一般是在程序员用来调试的信息,而第四种(error)级别是日志信息里级别最高的,ERROR级别信息的产生分两种;一种是程序出错,一种只是程序员用来调试输出;一般在日志文件中,ERROR级别的信息是需要特别关注的;而在性能监控的日志文件里,则不需要特别去关注ERROR级别的信息,而是去关注操作带来的时间瓶颈

     

    3、  下面以一个应用工程为例讲讲;

     

    4、  如某个应用常用的日志文件分为两块:系统级(sys)和用户级(user),这一步是分成两个目录保存,/sys/user;我们主要关注系统级的日志信息,用户级的日志信息只是关注用户在系统中的行为,一般不需要去关注;而sys级的常用日志一般也分为两块:功能性的日志和关注性能方面的日志:

    功能性的日志一般为:

                             i.              dal.log:      用来记录数据层程序执行sql的信息,可以看到sql语句以及执行的情况,该日志不会产生error级别的信息;

                           ii.              velocity.log:  用来记录页面的信息;

                          iii.              webx.log:    该日志记录系统运行期间发生的信息,该日志记录的都是java类运行发生的信息,当程序出错后,首要查看的是该日志;

    性能方面的日志:

                         iv.              performance.log:记录aodao类运行时间,由什么请求发起,属于性能监控;

                           v.              webx-filter.log  用来记录每个ie请求的信息,以及该请求从开始到结束所经过的各个请求以及每个请求所开销的时间,属于性能监控;

                         vi.              hacking.log:      是记录用户修改登陆信息的日志;

     

      功能性的日志一般需要关注的是ERROR级别的日志信息,除dal.log外,因为dal.log是没有信息级别表识的,它只是打印sql执行的语句;但如果在webx.logvelocity.log日志中发现ERROR级别的信息,那肯定就是程序出错,需要返馈给程序员,由程序员去修改程序;下面对以上的日志举例进行讲解。

     

    4、一般每条日志信息包含了几大要素:

    a)         发生的时间;

    b)        信息级别;

    c)        执行什么操作,如果出错,则有出错的异常类型;

    d)        调试的输出信息,如出错,则有出错的提示;

    e)         如出错,相关出错的地方,在做什么动作的时候发生,具体出错在哪一行;

        操作步骤:

    确定要查看什么功能,打开相应的日志文件,先查看是否有ERROR级别的信息;

    然后确认该error信息的时间是否是要查询的操作时间,看是否是在该操作时间段内发生的;

    以上两点都符合的话,则进行下一步,举例分析ERROR发生的原因;

     

    5、举例说明:

           功能性的日志

    velocity.log:该日志是用来记录页面信息的;当页面运行时,页面的信息会被记录在该日志中,页面出错首先看这份文件,然后再看webx.log确定是页面出错还是环境或配置或程序出错;

           如:2007-08-06 15:02:20,335 ERROR VelocityService.aso - ResourceManager : unable to find resource 'macros.vm' in any resource loader.

           分析:

    发生的时间,2007-08-06 15:02:20

    信息级别,ERROR,表明是出错信息;

    出错的提示:unable to find resource 'macros.vm' in any resource loader

               根据出错提示可得出系统找不到macros.vm,该摸板没有被载入,据此就可以把这信息反馈给功能负责者或程序员,让他去改正这一bug

    但是页面的出错有时候并不能完全确定是页面或摸板出的错,也有可能是业务层或数据层出的错,比如页面出现505错误,这个时候就需要看Webx.log

     

    Webx.log: 一般环境、程序、配置出错,都看这份文件;

    2007-08-06 15:03:59,567 [] ERROR service.ServiceManager - Service BeanFactoryService failed to initialize

    com.alibaba.service.ServiceInitializationException: Failed to initialize BeanFactory

    at com.alibaba.service.spring.DefaultBeanFactoryService.init(DefaultBeanFactoryService.java:84)

           at com.alibaba.service.GenericService.init(GenericService.java:26)

           at com.alibaba.service.DefaultServiceManager.initService(DefaultServiceManager.java:458)

           at com.alibaba.service.DefaultServiceManager.getService(DefaultServiceManager.java:829)

           at com.alibaba.service.DefaultServiceManager.getService(DefaultServiceManager.java:801)

           at com.alibaba.service.DefaultServiceManager.initAll(DefaultServiceManager.java:186)

           at com.alibaba.service.context.SingletonServiceManagerLoader.getInstance(SingletonServiceManagerLoader.java:72)

                  ……………………

       分析:

    发生的时间,2007-08-06 15:03:59

    信息级别,ERROR,表明是出错信息;

    出错的异常类型:ServiceInitializationException

    出错的提示:Failed to initialize BeanFactory,初始化BeanFactory失败;

    相关类的出错的地方,在做什么动作的时候发生,具体出错在哪一行;

    如:at com.alibaba.service.GenericService.init(GenericService.java:26),表明是在执行GenericService.java的方法init时出错,在GenericService.java类的第26行;

     

     dal.log:从该日志信息,主要能打印出整个sql语句;该日志信息是没有显示信息级别的,目的只是为了打印出整个执行的sql语句;

           如:2007-08-02 17:40:40,573 DEBUG sql.Connection - {conn-100003} Preparing Statement:              select        sum(case when STATUS='published' and GMT_EXPIRE>sysdate then 1 else 0 end) total_count,     sum(case when STATUS='member expired' or (STATUS = 'published' AND GMT_EXPIRE < SYSDATE) then 1 else 0 end) expired_count    from offer     where member_id=?       

    从这条信息中能看到,发生的时间,执行的完整的sql

     

    性能监控的日志

    performance.log:从该日志信息能看到AODAOjava类在发生请求时,执行的时间;

    如:2007-08-02 17:40:40,581 INFO  - Call interface com.alibaba.exodus2.biz.dal.daointerface.OfferDAO.getOfferTotalAndExpiredCountByMemberId() take 8 ms. - [/ims/my_alitalk_info.htm?member_id=alipff]

    分析:

           发生的时间:2007-08-02 17:40:40

        信息级别:  INFO

          类:com.alibaba.exodus2.biz.dal.daointerface.OfferDAO

           该类执行的方法:getOfferTotalAndExpiredCountByMemberId()

           执行该方法花费的时间:8 ms

           执行该方法的请求:/ims/my_alitalk_info.htm?member_id=alipff

    根据以上的这些信息,就能够确定出这个请求在执行java类的方法时花了多少时间?在监控java类性能上可以查看该信息;

     

     

    webx-filter.log:该信息用来查看发起一次请求,所经过那些请求,以及每个请求所花费的时间,用来性能监控;

     

    如:2007-08-02 18:05:18,906 INFO  timer.TimerFilter - Started processing request: GET /offer/select_page.htm?needsignin=1

    2007-08-02 18:05:19,575 INFO  timer.TimerFilter - Response of GET /offer/select_page.htm?needsignin=1 returned in 657ms

    Detail: 0 [657ms, 100%] - process HTTP request

            +---0 [0ms] - Preparing request context: BufferedRequestContextImpl(14723050)

            +---0 [0ms] - Preparing request context: LazyCommitRequestContextImpl(19925149)

            +---0 [0ms] - Preparing request context: ParserRequestContextImpl(8754866)

            +---0 [1ms, 0%, 0%] - Preparing request context: SessionRequestContextImpl(6861740)

            +---1 [6ms, 1%, 1%] - Preparing request context: SetLocaleRequestContextImpl(32252426)

            |   `---1 [6ms (5ms), 100%, 1%] - Decoding cookie for session object

            |       `---1 [1ms, 17%, 0%] - Decrypting cookie for session object

            +---7 [1ms, 0%, 0%] - Preparing request context: RewriteRequestContextImpl(5203636)

            +---8 [0ms] - Preparing request context: RemoteAddrRequestContextImpl(14670479)

            +---8 [0ms] - Preparing request context: ChinaRunData(8789037)

            +---8 [16ms, 2%, 2%] - before request

            +---24 [625ms (84ms), 95%, 95%] - handle request

            |   +---94 [289ms (52ms), 46%, 44%] - load and execute screen module: SelectPage (template: screen/selectPage.vm)

            |   |   +---145 [94ms, 33%, 14%] - Dispatch and process command: offerBaseAO

            |   |   `---240 [143ms (119ms), 49%, 22%] - render velocity template: /screen/selectPage.vm

            |   |       +---327 [11ms (4ms), 8%, 2%] - load and execute control module: TemplateControl (template: control/post/style.vm)

            |   |       |   `---331 [7ms, 64%, 1%] - render velocity template: /control/post/style.vm

            |   |       `---363 [13ms, 9%, 2%] - load and execute control module: TemplateControl (template: control/excelpost/uploadExcelModule.vm)

            |   |           `---363 [13ms, 100%, 2%] - render velocity template: /control/excelpost/uploadExcelModule.vm

            |   `---397 [252ms, 40%, 38%] - load and execute layout module: TemplateLayout

            |       `---397 [252ms (128ms), 100%, 38%] - render velocity template: /layout/myalibaba.vm

            |           +---453 [21ms (9ms), 8%, 3%] - load and execute control module: home:TemplateControl (template: control/share/meta.vm)

            |           |   `---462 [12ms, 57%, 2%] - render velocity template: /control/share/meta.vm

            |           +---494 [5ms, 2%, 1%] - load and execute control module: home:TemplateControl (template: control/common/style/myalibaba.vm)

            |           |   `---494 [5ms, 100%, 1%] - render velocity template: /control/common/style/myalibaba.vm

            |           +---508 [2ms, 1%, 0%] - load and execute control module: TemplateControl (template: control/excelpost/uploadExcelDiv.vm)

            |           |   `---508 [2ms, 100%, 0%] - render velocity template: /control/excelpost/uploadExcelDiv.vm

            |           +---524 [3ms, 1%, 0%] - load and execute control module: home:TemplateControl (template: control/common/top/top.vm)

            |           |   `---524 [3ms, 100%, 0%] - render velocity template: /control/common/top/top.vm

            |           +---542 [83ms, 33%, 13%] - load and execute control module: home:TemplateControl (template: control/common/menu/myalibabaLeftMenu.vm)

            |           |   `---542 [83ms (30ms), 100%, 13%] - render velocity template: /control/common/menu/myalibabaLeftMenu.vm

            |           |       `---572 [53ms, 64%, 8%] - load and execute control module: home:TemplateControl (template: control/common/style/menuArray.vm)

            |           |           `---572 [53ms, 100%, 8%] - render velocity template: /control/common/style/menuArray.vm

            |           `---639 [10ms (1ms), 4%, 2%] - load and execute control module: home:TemplateControl (template: control/common/bottom/bottom.vm)

            |               `---640 [9ms, 90%, 1%] - render velocity template: /control/common/bottom/bottom.vm

            +---649 [2ms, 0%, 0%] - after request

            +---651 [0ms] - Committing request context: ChinaRunData(8789037)

            +---651 [0ms] - Committing request context: RemoteAddrRequestContextImpl(14670479)

            +---651 [0ms] - Committing request context: RewriteRequestContextImpl(5203636)

            +---651 [0ms] - Committing request context: SetLocaleRequestContextImpl(32252426)

            +---651 [5ms (2ms), 1%, 1%] - Committing request context: SessionRequestContextImpl(6861740)

            |   `---652 [3ms, 60%, 0%] - Encoding cookie for session object

            |       `---655 [0ms] - Encrypting cookie for session object

  • Mobile Linux组织融合背后的故事

    2008-11-02 21:34:18

    有近半年没有写关于mobile linux方面的博文了,主要原因就是LiPS Forum和LiMo Foundation的融合过程中作为内部人员的言论限制。亲历了LiPS Forum的创立、发展和结束,以及与LiMo Foundation的谈判,直到最近全面参与LiMo Foundation的工作,其中有很多东西与大家分享,以弥补这长期静默的“罪过”。    法国电信Orange作为LiPS Forum的发起公司其实一直没有放弃加入LiMo Foundation的努力,刚开始的时候LiMo Foundation的创始成员(NTT DoCoMo,Vodafone,Motorola,NEC/Panasonic等)中有人明确不希望Orange成为一员,这当然是出于竞争的考虑。然而,在发展了一段时间以后,发现不但是不能够击垮LiPS Forum,而且在时间表上还有落后的危险。这时候,实用主义的精神发挥了作用,由Foundation办公室出面提出了让法国电信Orange加入LiMo Foundation 并追认为创始会员,这离LiMo成立已经相隔1年半之久了。当然这不是没有条件的,法国电信Orange必须离开LiPS Forum,这个结果也就相当于直接解体了LiPS Forum。在那个时候我个人是极力反对的,原因就是LiMo Foundation的组织和工作进展都与我们的认识相左,存在极大风险。然而,随着法国电信内部的争论的升级,最后集团决策层会议上决定加入LiMo,但是没有人提及相应的附加条件。我们并没有放弃为LiPS Forum其它成员争取更多的利益,经过几轮谈判,终于所有的LiPS Forum成员都争取到了LiMo Foundation的会员资格,要知道LiMo的会员费比LiPS Forum贵6倍。
        这一个过程尽管作为LiPS Forum的创始人,我个人会有一些失落感,但是看看结果,还是一个双赢的局面。首先,法国电信Orange从Mobile Linux的门外汉,到世界上主要支持的Mobile Linux的运营商,仅仅耗时4年,费用相对其它公司来说也就1/10,然而先后成为LiPS Forum和LiMo Foundation的创始成员、董事会成员,成功的推动Linux在手机上的标准化,并有可能在欧洲首推运营商定制Linux手机。其次,LiPS Forum的成员他们往往没有机会被那些所谓的巨头认可,但是由于他们的重要作用和已经取得的成果(LiPS的标准及其实现),成为LiMo Foundation的成员,尤其得到关注。最后, LiMo Foundation尽管巨头云集,但是还是前途未卜,只有消灭潜在威胁、广聚人气才能为成功争取时间,而且,LiPS的融合使得成员数量增加近一倍,成为独一无二的Mobile Linux组织。
        从这个融合之中,我们也发现了行业中的普遍问题。首先是缺乏反垄断意识,尽管每个大公司都有一流律师,但是在这个融合过程中,还是有人犯了低级的错误,并且有可能将LiMo Foundation陷入法律纠纷中去。简单说来,在美国和欧洲的法律下,一个组织通过给与某些条件给另一个组织的主要成员,以达到消灭那个组织减少竞争为目的的行为,就有可能触犯了反垄断法。读者可以想像,在两个组织的讨论中,那么多的邮件交互,是不是漏洞也很多呀。其次是趋炎附势、人云亦云,我惊人的发现,很多大公司在加入LiMo这个投资巨大的组织前,并没有什么仔细研究,就是老板们见个面就定下来了,加入以后为了面子和位子的问题,又要处处硬上,为的就是自圆其说。我们还是要引以为鉴,希望不要再犯同样的错误。

     

  • LR脚本的调试详细介绍

    2008-11-02 21:32:44

    沉浮于LR很多天了,以前一直在WR分论坛漂。看到大家提出很多问题,不过发现大家的脚本大都已录制为主,而且经常有提出录制的脚本回放有问题,其实很多问题很好解决,LR提供了很多手段调试和优化我们的脚本。  1.设置断点
      相信大家都不陌生,LR也是可以设置断点的,在需要设置断点的语句前按F9快捷键,断点就设置好了,程序运行到断点语句后会暂停,这时我们可以用F10单步调试程序.
      2.打开EXtended Log
      只是设置断点是不够的,我们还得知道具体发生了什么事情,Log告诉了我们一切,默认的Log是standard Log,这时远远不够的.我们要extended log,打开路径为runtime settings-->log-->extended log.把parameter substitution和data returned by server和advanced trace大家根据需要勾选吧.
      3.注释掉多余的语句
      很多回放时出错的脚本都是因为多余的语句.因为LR在录制的时候,LR生成的语句很多不是我们想要的,这里结合几个网友的问题说说,曾有网友问:回放脚本的时
    候socket出错,提示: Error : socket0 - Address already in use. Error code: 10048.而且非常坚持说脚本不会有问题,因为脚本直接录制后回放,什么都没改,是不会出错的.拿到脚本一看,有一条语句lrs_create_socket,建立了socket0,但是之后没有任何socket0的语句,可以判断出该语句是无效的,注释掉,问题解决。所以大家不要过分相信LR了,它生成的语句也是有很多BUG的。
      经常有朋友们问到,log文件在哪看,特别是controll执行后,怎么看log。这里一一说明一下:
      (1)在vgen中,我们必须写输出函数输出信息,将我们所想要了解的信息用函数输出,主要有这么几个函数输出信息:lr_output_message,lr_error_message,lr_log_message。这些函数请参阅help-->function reference.
      其次,我们要在runtime settings中设置,勾选always send messages,具体的做法是:runtime settings--->log-->always send messages,这样我们才能写出Log,在我们的脚本所在的文件夹中,有两个文件很重要,mdrv.log.txt和output.txt文件,lr_log_message只会把信息输到mdrv.log文件中,而lr_output_message则会写进以上两个文件。
      (2)在controller中,很多朋友都会想知道多次迭代,参数是否正确的导入了呢,我们依旧查看log,我们在执行结束后,查看结果目录的Log文件夹,如果是负载生成器运行的话,则在tmp目录。不过,还想提醒朋友们,在controller我们也要设置runtime settings才行,而且每个用户组的runtime settings,设置的方法是:在controller的design标签页中,右下角的部分有runtime settings按钮,我们点击它,设置的方法与在vgen中一样的。
  • 性能测试工具tptp使用

    2008-11-02 21:30:39

    程序在实际应用当中,大数据量时对系统本身的影响是一个不得不面对的问题。  什么是tptp
      Eclipse Test and Performance Tools Platform(TPTP)用它可以监测运行的并发线程数据、内存的使用情况等,是不款非常不错的性能测试工具,它是eclipse官方的一款插件项目.可以进行程序执行时间的统计分析、内存的监控、对象调用的分析等。
      环境
      本次用的tptp版本是4.4.0.2是当时比较稳定的版本,再多说一句,本想下载tptp的4.4.1 但是下载所有eclipse官方所有依赖的插件运行后一直都启动不了agent controller(tptp依赖的一个非常重要的服务项目),所以请大家注意,我是浪费了整两天时间也没搞懂为什么启动不了,所以用了 4.4.0.2.
      jdk1.6
      Business Intelligence and Reporting Tools (BIRT) 2.2.2
      tptp.platform.runtime-TPTP-4.4.0.2
      tptp.trace.runtime-TPTP-4.4.0.2
      Data Tools Platform (DTP) 1.5.2
      Graphics Editor Framework (GEF) 3.3.2
      Eclipse Web Tools Platform (WTP) 2.0.2
      Eclipse Modeling Framework (EMF and XSD) 2.3.2
      eclipse3.3.2
      以上是我的运行环境供大家参考,还可下载许多tptp相关的插件工具,具体的网址是:http://www.eclipse.org/tptp/home/downloads/?ver=4.4.1
      注意相关的工具可能也有他依赖的插件工具.
      运行tptp
      安装tptp后启动eclipse将出现如下界面:



      如果你的eclipse工具栏的位置将出现profile按钮(上图红色标记的按钮)说明tptp安装成功.
      如果想测试你的程序,右键点击类文件选择Profile as--->Java Application将打开如下界面:



      在打开此界面过程中系统进程中将多一个ACServer服务项,这也是tptp所依赖的一个非常重要的服务,在tptp4.4之前的版本agent controller(ACServer服务)是需要用户手动打开此服务,agent controller可以在tptp的网站下载,注意要下载与你系统相符的agent controller版本,tptp4.4不需要另外下载agent controller tptp自动启动agent controller,此服务的默认的端口为10002,使用时要查看端口是否被占用,再看上图,如果你的jdk是1.5可以选择jre1.5,如果jdk1.6需要选择jre1.5 or new来运行tptp,如果成功eclipse将改变为Profile and Logging透视图,如下图:

      左侧将出现统计项,双击此项在右侧出现统计信息,如果eclipse中安装有mdt-uml工具插件,当右键点击统计项时会出现uml统计项,将出现uml的序列图.
      此上只是tptp的基本应用,仅供参考,tptp的配置及应用还有很多,并且也可以测试web工程的应用,如果有兴趣大家可以去eclipse网站查看资料.
  • 五种最值得学习的JAVA开发技术

    2008-11-02 21:28:40

    Carlos Perez(著名的Java技术人员)最近发表了他认为值得在2008学习五种的JAVA技术,它们是: OSGi(基于Java的动态模型规范) OSGi(Open Service Gateway Initiative)指OSGi Alliance组织制定的一个基于Java语言的服务 (业务)规范——OSGi服务平台(Service Platform)。 该规范和核心部分是一个框架 ,其中定义了应用程序的生命周期模式和服务注册。这个框架实现了一个优雅、完整和动态的组件模型。应用程序(称为bundle)无需重新引导可以被远程安装、启动、升级和卸载(其中Java包/类的管理被详细定义)。API中还定义了运行远程下载管理政策的生命周期管理。服务注册允许bundles去检测新服务和取消的服务,然后相应配合。 Java内容仓库,最早于2002年2月由JCP发布 JCP(Java Community Process) 是一个开放的国际组织,主要由Java开发者以及被授权者组成,职能是发展和更新 Java技术规范、参考实现(RI)、技术兼容包(TCK)。JCP维护的规范包括J2ME、J2SE、J2EE,XML,OSS,JAIN等。组织成员可以提交JCR(Java SpECification RequESts),通过特定程序以后,进入到下一版本的规范里面。 Google Web Toolkit(最早发布于2006年5月) GWT(Google Web Toolkit) 是 Google 推出的一个开发 Ajax 应用的框架,它支持用 Java 开发和调试 Ajax 应用。 Groovy(最早发布于2004年5月) Groovy是一种面向对象的程序设计语言,作为Java程序设计语言的一种可选替代品,并增加了Python,Ruby和Smalltalk中的一些特性。 云计算(用于虚拟服务器的设计理念,或无需EJB的分布式计算) “云计算”的英文即Cloud Computing。自谷歌发展起来之后,极大规模的服务器集中在一起,统一管理,形成了“云雾计算”(“Cloud Computing”)的物质基础。“云雾计算”是社会计算能力的大集中,也是所谓“SaaS”的客观基础。 有趣的是,其中有几种技术已经成熟,或者说是“老”了,并且正在其被推荐应用的项目中有成熟的应用。当然,这五种技术都很有价值。OSGi是 Eclipse的建模系统,Goovry因其正式的规范说明和频繁的改进版发布赢得支持。GWT也算是成熟稳定,云雾计算正在受到更为广泛市场的接受。 JRC和云雾计算是最近才被广泛接受的技术,但是厂商正在利用竞争和商业关系猎取支持来发布相关的产品(比如GridGain,Gigaspaces,和Terracotta),而有的厂商还正在对此进行策划(TSS计划在TSSJS2008发布JCR相关的声明)。
  • 解析StressMark压力测试工具

    2008-11-02 21:25:21

    StressMark测试软件是一个使用Visual C++编写的,开放源代码的测试工具,可以完成服务程序及重要算法的功能和性能测试,其最主要的功能是模拟多线程或多客户端的自动化压力测试。
     
           我们可以利用StressMark软件完成的典型测试任务包括:

           1. 在多线程环境下测试一个软件模块、一段关键算法是否可以正确运行,即代码是否是多线程安全的。 

           2. 测试一个软件模块、一段关键算法在并发执行时的效率,如每个线程的平均执行时间等。
     
           3. 模拟一个服务程序的多个客户端,测试该服务程序对并发请求的响应是否正确。
     
           4. 模拟一个服务程序的多个客户端,测试该服务程序在并发请求的情况下,对每个客户请求的响应效率。
     
           5. 使用一台或多台高配置的测试计算机(多CPU,大内存),每台计算机上运行一套StressMark,每套StressMark模拟多个客户线程,以此测试服务程序在大压力情况下的响应能力,这一方法甚至可以测出服务程序支持的并发数上限。
     
           因为StressMark软件的源代码是完全开放的,基于这套源代码,你完全可以改造出符合你的特定需求的自动测试程序,使StressMark可以完成更多的测试任务。
    测试包:用户根据特定测试需求制订的,包含一个或多个不同测试用例及其配置方式的描述性大纲。
     
           测试用例:指对一项特定的测试任务的描述,包括测试目标,输入数据,测试方法,实现代码等。在 StressMark 中,测试用例对应于一段具体的待测试代码,该测试代码由测试者提供,并被嵌入到 StressMark 工程中。测试时,可以对一个测试用例起多个测试客户(线程)同时运行,也就是说,一个测试用例同时可以有多个运行实例。还可以对特定的测试用例指定测试次数,即指定在该测试用例的每个实例中,重复执行多少次测试代码。根据需要,用户也可以指定每两次重复之间的时间间隔。

           测试客户:或称测试线程。指测试时某特定测试用例的一个具体的实例。该实例以线程方式运行,并与该测试用例的其他实例同时启动。用户可以在测试包中为每个测试用例配置测试客户(线程)的数目。
     
           测试次数:某特定测试用例的每一个测试客户(线程)中,待测试代码的重复执行次数。用户可以在测试包中为每个测试用例配置测试次数。
     
           间隔时间:某特定测试用例的每一个测试客户(线程)中,待测试代码两次重复执行之间的间隔时间。单位是毫秒。间隔时间可以在测试包中指定。
  • 关于提高Java水平十大技术

    2008-11-02 21:20:32

    1、XML 在十种技术中,最重要的一种技术我想应该非XML莫属。这里不仅仅指XML规范本身,还包括一系列有关的基于XML的语言:主要有XHTML,XSLT,XSL,DTDs,XML Schema(XSD),XPath,XQuery和SOAP.如果你现在还对XML一无所知,那么赶快狂补吧!XML是包含类似于HTML标签的一个文本文件,在这个文件中定义了一个树型结构来描述它所保存的数据。 XML最大的优点是你既可以在这个文本文件中存储结构化数据,也可以在其中存储非结构化数据——也就是说,它能包含和描述“粗糙的”文档数据,就象它描述“规则的”表格数据一样。 XHTML是目前编写HTML的首选方法;因为XHTML本身就是格式良好的XML,与通常畸形的HTML文档相比, XHTML格式文档更容易处理。 XSLT和XSL是对XML文档进行转换的语言。它们可以将XML文档转换成各种格式,比如另一个文本文件、PDF文件、HTML文件、逗号分割的文件,或者转换成其它的XML文档。 DTDs 和XML Schema用来描述XML文件所包含的数据内容的类型,使你不用编写定制的代码就能对XML文档的内容进行“有效性”检查,使内容强行遵守给出的规则。 XPath 和 XQuery是查询语言,用它们可以从XML文档中吸取单个的数据项或者数据项列表。XQuery的功能特别强大,因为它对XPath查询进行了扩展。实际上,XQuery和XML的关系就像SQL之于关系数据库一样。 SOAP是Web services间进行通讯的标准协议。你不必知道SOAP协议的所有细节,但是你应该熟悉其常用规则及其工作原理,这样你才能使用它。 2、Web Services Web服务是XML流行后的直接产物。因为XML可以描述数据和对象,XML大纲可以保证XML文档数据的有效性,因为XML的基于文本的规范,因而XML文档极其适合于作为一种跨平台通讯标准的基本格式。如果你还没有接触过Web服务,那么过不了多久你肯定会碰到它,所以必须熟练掌握Web服务,最好是精通它,因为它是迄今为止应用程序间跨不同种类机器、语言、平台和位置通讯的最简单的一种方式。不管你需不需要它,Web服务都会是将来互用性的主要趋势。 XML工作组的John Bosak曾说过:“XML使得Java有事可做”,那么,我们也可以说,Web服务使得所有语言都有事可做。Web服务让运行在大型机上的COBOL应用程序与运行在手持设备上的应用程序相互沟通;让Java小应用与。NET服务器相互通讯,让桌面应用与Web服务器进行无缝交互,不但为商业数据处理,同时也为商业功能提供了方便的实现——并且这种实现与语言、平台、和位置无关。 3、面向对象编程 许多程序员仍然认为OOP乃技术的象牙之塔,但是细细想一下过去十年里在面向对象领域里占据过统治地位的开发语言之后,你就不会这么认为了,OOP理念从Smalltalk开始,然后蔓延到C++和Pascal(Delphi),到Java成为真正的主流,几年之后,VB.NET 和 C#的出现可以说是OOP发展到了登峰造极的地步。虽然使用这些语言不必了解OOP的概念,但如果你缺乏一些OOP的基本知识和方法,我想你很难在逐渐疲软的就业市场中找到工作。 4、Java,C++C#,VB.NET 如果你热衷于技术,并且热爱编程,那么我想你应该轻松玩转这些高级语言,我说的玩转并不一定要你成为超级编程高手。而是能看懂用这些语言编写的代码即可。如果你还有精力用它们编码那就更好了。其实这种机会甚少。但是看代码的机会很多,学习编程的最有效的一种方式就是看源代码——浩如烟海的源代码中很多都不是用你所钟爱的开发语言编写的。 在过去的几年里,各个语言功能的发展基本上都差不多。现在你完全可以用VB.NET来写Windows服务、Web应用或者命令行程序。即使你只用其中的一种语言写程序。我认为也完全有必要学习另外一种语言,使自己能阅读和理解它们现有的例子代码,并且能将一种语言编写的代码转换成你首选的编程语言代码。这里列出的四种语言可谓是一个强大的开发语言工具箱,如果你掌握了它们,毫无疑问你一定是一个众人仰慕的高手。这里我要声明一下:那就是我并没有要忽略和排除其它的高级语言,如:FORTRAN、COBOL、APL、ADA、Perl和Lisp等等,根据你所从事的领域不同,应该选择适合的语言和工具。 5、Javascrīpt Java 和Javascrīpt两者的名字尽管很类似,但它们之间并没有什么关系。为什么一种脚本语言会如此重要,以至于将它列入十种关键技术之一呢?仔细想一下就知道了,目前所有主流的浏览器都使用Javascrīpt.如果你要编写Web应用程序,那么Javascrīpt不可或缺。此外,Javascrīpt还能作为一种服务器端的脚本语言,如将它嵌入在ASP、ASP.NET中,或者嵌入XSLT来扩展功能。目前Javascrīpt在Mozilla/Netscape中是激活基于XUL界面的首选语言,它派生出了Actionscrīpt,成为Flash MX应用的编程语言。还有就是Javascrīpt极有可能成为未来新设备的脚本语言以及主流应用的宏语言。 相比之下,VBscrīpt虽然在微软的产品中得到很好的支持,但从长远来看,没有迹象表明它会有美好前途。微软自己都趋向于用Javascrīpt(或者用由Javascrīpt派生的Jscrīpt)来编写其客户端脚本代码。因此,如果你要选择脚本语言,非Javascrīpt莫属。
       6、Regular Expressions 从所周知,关系数据库的查询使用SQL,搜索XML文档用XPath 和XQuery,而正则表达式则用来搜索纯文本。例如,你可以用一个命令来查找或删除HTML格式文件中的注释内容。大家都用过“IndexOf”、“InStr”以及“Like”这些内建在Javascrīpt或VB中的文本搜索函数,这些函数虽然很容易使用,但是它们的功能却无法与正则表达式同日而语——现在每一种主流的开发语言都提供对正则表达式的存取。尽管有人认为正则表达式本身的读写艰涩难懂,但毕竟它的功能强大,使用它的领域也越来越多。 7、Design Patterns 就像OOP通过创建和分类对象来简化编程一样,设计模式将普通的对象交互分类成指定的模型,这是一个从一般到具体的过程。OOP的成分使用得越多,设计模式就显得越有用武之地。所以你必须理解它们,跟上其总体理论的发展。 8、Flash MX 当你需要比HTML和CSS所能提供的更多的客户端图形和编程能力时,Flash是最佳选择。在Flash中编程比用Java小应用或者。NET代码来得快得多,也容易得多。 在最新版本中(MX),Flash不仅可以画图和进行动画打包,它还是个高度的可编程应用环境。具备强大的与SOAP Web服务沟通的能力,可以调用运行在远端服务器上的ColdFusion、Java或.NET代码。可以说Flash几乎无处不在,包括手持设备、置顶盒、甚至是新的平板电脑,你到处都可以见到它的身影,所以使用它实际上可以扩展和延伸你的应用程序使用领域。 9、Linux/Windows 这是当今PCs机操作系统的两大阵容,如果你想在计算机行业里混,就一定要熟悉它们。对于Linux,最好能自己安装,配置,下载它的图形用户界面以及一些应用程序。自己安装Apache并会编写Web应用程序。要清醒地认识到这个世界除了Windows之外,还有Linux的存在。并且这种局面将会长期存在。反过来,如果你是一个死忠的Linux开发者,不要再继续对Windows的憎恶,要相互学习,取长补短,看看Windows有什么好的东东可以采纳。记住Windows仍然是桌面之王。 谁也说不准你们公司什么时候会决定从Linux转向Windows,或者从Windows转向Linux.谁也说不准什么时候你会跳槽跑到另外一个使用不同平台的公司上班——或者即便不跳槽,也有可能在不同平台上开始另外一个杀手级项目——所以最好在每个平台上都积累一些经验,而不要在一棵树上吊死。 10、SQL 尽管SQL在当今众多的技术中已不是什么新东西,而且在未来的十年里它的作用很有可能被削弱,甚至整个被淘汰,但它仍然是一种基本技能——别看它是一种基本技能,至今仍有许多开发人员不懂什么是SQL或对它了解不多。不要指望基于图形用户界面的SQL构造器会帮你的忙,还是自己亲手写SQL查询吧,确定你掌握了SQL的基本语法。现在理解了SQL,不仅对以后学习XQuery有所裨益,而且可以使你很快找到简化或改进当前开发项目的途径。 结束语: 其实,不管技术的发展趋势如何,每个人最重要的一个技能是好奇心。敢于面对挑战,在你目前或未来的工作中,新语言或新技术可能很重要,也可能不怎么重要,你所学习的东西并不一定非要针对你的工作。不要怕失败,任何新的技术对初学者来说都是困难的。大多数的失败都可以归咎于本身急功近利,希望速成。俗话说——千里之行,始于足下,应该脚踏实地,一步一个脚印地往前走。不要让时间来左右你行动,而是要利用时间来关注、研究、测试新的开发技术和工具。
  • LR中自动显示函数语法

    2008-11-02 21:14:59

    Auto show function syntax:语句完全打出后,再打(可自动显示函数的用法(参数及回值类型)。
    Auto complete word:打出函数第一小段再加_(可自动显示函数列表)
  • LR算当前时间

    2008-11-02 20:47:38

    Action()
    {
    typedef long time_t; 
    time_t t; 
    
         /* Get system time and display as number and string */ 
    
         lr_message("Time in seconds since 1/1/70: %ld\n", time(&t)); 
    
         lr_message("Formatted time and date: %s", ctime(&t)); 
    
    return 0;
    }
  • 【转】LoadRunner下Dll的调用

    2008-11-02 20:41:41

       一个LR下DLL调用的例子,很不错的。

       场景介绍
        最近在做类似于QQ的通信工具的性能测试时发现了一些问题,现总结出来与大家分享一下。希望大家在使用LoadRunner时不仅仅停在只是录制/播放脚本,而全面提升脚本的编程技术,解决复杂场景。
        本次测试中碰到的问题是这样的,在消息的传送过程中遇到了DEC加密的过程,LoadRunner录制到的全是加密的消息,比如我录制了某一个用户的登陆,发送消息,退出,但由于是加密的,只能单个用户使用,但如果我想并发多少个用户就存在很多问题,最直接的一个问题就是用户名是加密的,密码是加密的,当然你可以说让程序那里注掉加密的代码进行明码的测试,当然也是一种办法。但程序组提出了要使用更真实的方法来模拟,这时就必需使用下面介绍的方法。
         一开始是直接把API移植到LoadRunner中来,不过由于加密算法异常复杂,有几层循环,而脚本是解释执行的,进行一次加密运算可能需要好几分钟,当然在脚本里可以把脚本本身运行的时间去掉,但这样做显然没有直接调用DLL来的效率高。由于程序组比较忙,所以无法提供DLL给测试,所以测试组完成了DLL的编写,并在LoadRunner中调用成功,高效的完成了用户信息加密,参数关联,成功的完成了测试。

    动态链接库的编写
        在Visual C++6.0开发环境下,打开FileNewProject选项,可以选择Win32 Dynamic-Link Library建立一个空的DLL工程。
    1.Win32 Dynamic-Link Library方式创建Non-MFC DLL动态链接库
        每一个DLL必须有一个入口点,这就象我们用C编写的应用程序一样,必须有一个WINMAIN函数一样。在Non-MFC DLL中DllMain是一个缺省的入口函数,你不需要编写自己的DLL入口函数,用这个缺省的入口函数就能使动态链接库被调用时得到正确的初始化。如果应用程序的DLL需要分配额外的内存或资源时,或者说需要对每个进程或线程初始化和清除操作时,需要在相应的DLL工程的.CPP文件中对DllMain()函数按照下面的格式书写。
     
    BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
    {
        switch( ul_reason_for_call )
        {
            case DLL_PROCESS_ATTACH:
                break;
            case DLL_THREAD_ATTACH:
                break;
            case DLL_THREAD_DETACH:
                break;
            case DLL_PROCESS_DETACH:
                break;
            default:
                break;
         }
        return TRUE;
    }
      
        参数中,hMoudle是动态库被调用时所传递来的一个指向自己的句柄(实际上,它是指向_DGROUP段的一个选择符);ul_reason_for_call是一个说明动态库被调原因的标志,当进程或线程装入或卸载动态链接库的时候,操作系统调用入口函数,并说明动态链接库被调用的原因,它所有的可能值为:DLL_PROCESS_ATTACH: 进程被调用、DLL_THREAD_ATTACH: 线程被调用、DLL_PROCESS_DETACH: 进程被停止、DLL_THREAD_DETACH: 线程被停止;lpReserved为保留参数。到此为止,DLL的入口函数已经写了,剩下部分的实现也不难,你可以在DLL工程中加入你所想要输出的函数或变量了。

         我们已经知道DLL是包含若干个函数的库文件,应用程序使用DLL中的函数之前,应该先导出这些函数,以便供给应用程序使用。要导出这些函数有两种方法,一是在定义函数时使用导出关键字_declspec(dllexport),另外一种方法是在创建DLL文件时使用模块定义文件.Def。需要读者注意的是在使用第一种方法的时候,不能使用DEF文件。下面通过两个例子来说明如何使用这两种方法创建DLL文件。

        1)使用导出函数关键字_declspec(dllexport)创建MyDll.dll,该动态链接库中有两个函数,分别用来实现得到两个数的最大和最小数。在MyDll.h和MyDLL.cpp文件中分别输入如下原代码:
     
    //MyDLL.h
    extern "C" _declspec(dllexport) int desinit(int mode);
    extern "C" _declspec(dllexport) void desdone(void);
    extern "C" _declspec(dllexport) void des_setkey(char *subkey, char *key);
    extern "C" _declspec(dllexport) void endes(char *block, char *subkey);
    extern "C" _declspec(dllexport) void dedes(char *block, char *subkey);
    //MyDll.cpp
    #include"MyDll.h"
    //这里我用了比较大小的函数代替了我要实现的函数
    int desinit(int a, int b)
    {
        if(a>="b)return" a;
        else
            return b;
    }


    int desdone(int a, int b)
    {
        if(a>="b)return" b;
        else
            return a;
    }
        该动态链接库编译成功后,打开MyDll工程中的debug目录,可以看到MyDll.dll、MyDll.lib两个文件。LIB文件中包含DLL文件名和DLL文件中的函数名等,该LIB文件只是对应该DLL文件的"映像文件",与DLL文件中,LIB文件的长度要小的多,在进行隐式链接DLL时要用到它。读者可能已经注意到在MyDll.h中有关键字"extern C",它可以使其他编程语言访问你编写的DLL中的函数。

    LoadRunner调用动态链接库
        上面完成动态链接库开发后,下面就介绍动态链接库如何被LoadRunner进行调用,其实也是很简单的。在LoadRunner中的DLL调用有局部调用与全局调用,下面介绍局部调用。
        首先把你编译的DLL放在脚本路径下面,这里是MyDll.dll,MyDll.lib.然后在Action中使用lr_load_dll("MYDll.dll"),此函数可以把DLL加载进来,让你调用DLL里面的函数,而DLL中的运算是编译级的,所以效率极高,代码样例如下:
    #include "lrs.h"
    Action()
    {
            //
            int nRet = 6;
            char srckey[129];
            memset(srckey, 'a', 128);
            lr_message(lr_eval_string(srckey));
            lr_load_dll("MyDLL.dll");
            nRet = desinit(5,8);
            lr_message("比较的结果为%d",nRet);
        return 0;
    }
    运行结果
            比较的结果为8

            全局的动态链接库的调用则需要修改mdrv.dat,路径在LoadRunner的安装目录下面(LoadRunner/dat directory);在里面修改如例:
    [WinSock]
    ExtPriorityType="protocol"
    WINNT_EXT_LIBS="wsrun32.dll"
    WIN95_EXT_LIBS="wsrun32.dll"
    LINUX_EXT_LIBS="liblrs.so"
    SOLARIS_EXT_LIBS="liblrs.so"
    HPUX_EXT_LIBS="liblrs.sl"
    AIX_EXT_LIBS="liblrs.so"
    LibCfgFunc="winsock_exten_conf"
    UtilityExt="lrun_api"
    ExtMessageQueue="0"
    ExtCmdLineOverwrite="-WinInet" No
    ExtCmdLineConc="-UsingWinInet" No
    WINNT_DLLS="user_dll1.dll," user_dll2.dll, ...
    //最后一行是加载你需要的DLL


        这样你就可以在LR中随意的调用程序员写的API函数,进行一些复杂的数据加密,准备的一些操作,进行复杂的测试。同时如果你觉的有大量高复杂的运算也可以放在DLL中进行封装,以提高效率。

  • atol类型转换字符串转成整型

    2008-11-02 20:33:11

    Action()
    {
    char a[512];
    lr_output_message("value:%s",lr_eval_string("{param1}"));
    sprintf(a,"value=%ld",atol(lr_eval_string("{param1}"))+1);
    lr_output_message("value:%s",a);
    return 0;
    }
    atoi是转回来
1427/8<12345678>