测试交流天地

发布新日志

  • 检测父级树内容,并赋值“产品”

    2013-12-03 01:45:12

    检测父级树内容,并赋值“产品”
    Sub Requirements_Req_AfterPost
      On Error Resume Next
      'dim ra
      if (left(Req_Fields.Field("RQ_REQ_PATH").Value,3) ="AAF"or left(Req_Fields.Field("RQ_REQ_PATH").Value,3) ="AAB")and Req_Fields.Field("RQ_REQ_PRODUCT").Value="" then
         Req_Fields.Field("RQ_REQ_PRODUCT").Value= "餐饮"
      end if
      if (left(Req_Fields.Field("RQ_REQ_PATH").Value,3) ="AAG"or left(Req_Fields.Field("RQ_REQ_PATH").Value,3) ="AAA")and Req_Fields.Field("RQ_REQ_PRODUCT").Value="" then
         Req_Fields.Field("RQ_REQ_PRODUCT").Value= "餐饮"
     ' else
      ' ra= Req_Fields.Field("RQ_REQ_PATH").Value
      ' msgbox ra
      end if
      On Error GoTo 0
    End Sub
  • 转-在Windows下实现SVN邮件自动通知

    2013-03-26 10:05:34

     

    昨天装了一下SVN,对自动化脚本进行版本控制,看到SVN可以实现邮件自动通知,所以今天也想试一下。在网上搜了一些资料,照着安装,现在实现了。所以现在想写一篇日志让后来的新手对SVN邮件自动通知有个参考。

    以下是我参考goldpicker进行的配置:
    配置前提:安装了.NET2.0 框架
    1.将SvnNotify.rar下载到本地并解压到任何位置,比如我这里解压到F:\SvnNotify

    2.对SvnNotify.exe.config这个文件进行配置(在解压文件中),配置如下:
    <configuration>
      <appSettings>
        <!-- SVNBasePath is the full path of svn path with the "\" -->
        <add key="SVNBasePath" value=" C:\Program Files\Subversion\bin\"/>
        <!-- {0}表示SVN仓库 -->
        <add key="NotifySubject" value="SVN REPOS {0} CHANGED"/>
        <add key="UseSsl" value="false" />
      </appSettings>
      <system.net>
        <mailSettings>
          <smtp from="xxx" deliveryMethod="Network">
            <network host="yyy" port="25" userName="zzz" password="ppp" defaultCredentials="false"/>
          </smtp>
        </mailSettings>
      </system.net>
    </configuration>
    参数说明
    SVNBasePath 表示SV程序BIN目录 比如这里的目录就是 C:\Program Files\Subversion\bin\
    NotifySubject 表示邮件主题的模板,可以任意定义,且程序将用仓库来替换{0}
    UseSsl 表示是不是用SSL进行连接
    xxx 表示发件人的邮件地址
    yyy 表示发件服务器的地址
    zzz 表示发件服务器需要登录时的用户
    ppp 表示登录的密码
    如果公司的服务器不需要认证,ZZZ,PPP也可以设置为空

    几个参数配置完成后,存盘退出即可。

    3.到版本库的HOOK目录下新建post-commit.bat或post-commit.cmd,内容如下:

    set REPOS=%1
    set REV=%2
    F:\SvnNotify\svnnotify.exe -repos "%REPOS%" -r %REV% -to xxx@gmail.com
    exit 0
    注意 上面的文件内容中F:\SvnNotify\svnnotify.exe是布署的程序完整路径repos指版本库的路径 –r值版本号 最后是收件人的Email地址,通常是一个邮件组的地址,当然你可以用,进行隔开来实现发送给多人。

    4.进行你可以进行测试
    你可以直接双击post-commit.bat文件,然后看是否可以接受到邮件。如果没有接受到,建议你到DOS下进行调试。

    5.何时会自动发送邮件通知?
    当版本库的内容发生改变时,SVN就会自动运行post-commit.bat这个文件来实现邮件的自动通知。

    以上信息希望对大家有一点帮助!
    http://bbs.51testing.com/thread-101033-1-1.html
    [ 本帖最后由 lantianwei 于 2007-12-16 18:12 编辑 ]

    SVNNotify.rar (4.11 KB)

  • ALM 11.50 Patch 01 - 11.50.886.01发布了

    2012-08-09 11:08:16

    好消息惠普ALM 11.50——刚刚发布了补丁01 - 11.50.886.01。这个补丁包括一组修复和改进。

  • 转:一个小公司老板的日常管理,希望能让创业的朋友学到

    2012-03-10 13:52:51

    转:一个小公司老板的日常管理,希望能让创业的朋友学到

    日常管理书看得不少,讲座也听了一些,但那些IBM,HP等大公司放之四海皆准的管理方法到自己公司却用不上。本人在深感烦恼的同时,将日常遇到的问题和处理方法写出来与各位一起探讨,没准比教科书上的方法更为实用。
      首先介绍下我公司:百人左右,成立十多年,年销售额几千万,问题几百个。
      1. 小公司如何留住骨干:(难,给股份不如给提成)
      这些年物价上涨,费用上涨,公司利润却未涨多少。每个员工都希望工资大幅增加,但估计90%以上小公司无法做到这点。有时我这当老板的恨不得将公司门一关,自己拿着资金炒股或炒房,图个清净。虽说近几年由于给每个员工上5险1金,人均费用每月增加几百元,但员工并不领情,员工只算每月到手多少钱,至于公司的支出与己无关。
      既然无法让所有人都满意,我就只满足公司20%的骨干。
      首先发展骨干员工入股:我将公司股份买一送一,半价销售给骨干员工,五年内退股只退还本金,五年以上退股我三倍赎回。每年拿出利润的60%分红。反正有钱大家赚,但股东一旦做了对不起公司的事,加倍惩罚,由股金中扣除。这招还真好使,在近5年里没有一个股东离职,而且公司重点岗位都有股东,省了我不少精力。
      为什么不白送骨干员工股份?其实我并不是在乎钱,主要是白给的东西别人不珍惜,而且入股的钱又可作为押金,以防股东做出格的事,再说员工入股的钱不出5年即可通过分红收回,不投入哪来的产出啊。

    2.关于授权 (授权是必须的,不然再小的公司,事情却总是一大堆)
      记得公司刚有十几个人的时候,全公司我最忙,经常同时接两三个销售电话,还得安排送货,结账,进货,每天来得最早,走得最晚。一次我弟弟到公司,看了半天,发表感慨说:“哥我怎么觉得你在养活公司所有人哪?”我当时还挺自豪。结果公司四五年也发展不大,一直十几个人,而且公司员工感觉备受压抑,无发展空间。后来终于明白该放权就得放权,哪怕员工只能做到你的70%。有时候真着急啊,明明能谈下的客户销售人员就是差那么一点谈不下来,恨不得立刻自己冲上去,该忍还得忍,要不手下员工如何进步。
      小公司发展过程中15人是个坎,50人是个坎,200人又是个坎,管理方法不改进,一般无法进一步发展。老板事事亲力亲为的公司,很难过15人。一个人能力强,可直接管理七八个人,能力一般,则只能直接领导四五个人。各个国家效率最高的部门就是军队,看看军队的组织结构:一个班十一二个人,除班长外还有一个副班长,三个班一个排,三个排一个连,以此类推。团长管一千多人,可能只认识其中百十来人。团长看见某个士兵有问题,绝对不会骂士兵,他只会骂士兵所在营的营长,营长则再骂连长,一级管理一级,最后班长把该士兵剥皮了事。所以军队尽管有千军万马,依然能做到令行禁止。
      现在客户找我买东西,我经常说:“哎呀真对比起,价格我不知道,我给您介绍个销售人员,我让他跟您联系吧。”
    3.有的钱不能省 (小公司初期用记账公司是明智之选)
      刚创业时也就一两个人,自己销售,进货,维修,跑银行。当时没有注册资金,借朋友的营业执照。自己到外面学习了几个月会计就开始瞎做报表。月底到税务局报税,报表一交,专管员看了两眼,开始问问题。问的问题我根本不明白,更别说回答了。专管员一脸不高兴,问:“你懂不懂?”。我陪着笑脸:“不懂,不懂。”“不懂你来干嘛。换个懂的来。”“好,好,下次一定换个懂的来。”下个月我又瞎做了张报表去税务局报税。专管员显然对我又印象:“怎么又你来了?”我只好顺嘴胡编:“会计怀孕来不了,只好我来。”。“!” 。第二天我就找了个会计公司,一月300元钱,以后再不自己跑税务局了。一直到公司十几个人,我仍然让会计公司做账,公司只有一个出纳,没有专职会计和库管。随后几年业务开展的不错,没少挣钱,可年底公司帐上资金却没增多少。后来我发现公司只要一过十个人,老板一人根本看不过来,整个公司就像个筛子一样,到处都是洞,能剩下钱才怪。指望公司员工都是焦裕禄和雷锋,门都没有,哪怕提成给员工70%,他还会惦记剩下的30%,傻瓜才不贪污。只有制度健全,让心数不正的人无懈可击,才能管好公司。感谢我现在的会计,工作极为负责。下辈子再办公司,公司只要有4个人,一定是一个老板,一个会计,一个出纳,一个库管,打死再不省那点钱了。
    4.隔行不挣钱 赞成
      这句话放在90%的公司身上是对的,当然,如果您觉得自己是那剩下的10%,也不妨一试。
      一般公司只要能坚持个三五年,挣了点钱,老板就开始琢磨再干点什么。大部分人总觉得自己的行业不如别人的行业挣钱,很不幸,我就是其中一个(我觉得自己的经历整个可编个小企业错误大全)。上世纪末,脑袋一热,开了个饭馆,从此厄运开始了。当初本人觉得自己销售方面颇有天赋,开饭馆肯定没问题。谁知这该死的饭馆光有销售根本不行,做的不好吃别人最多只来一次。本人不好吃喝,也没耐心和大厨琢磨新菜。而且开饭馆不光进货结账,卫生防疫,工商公共安全专家样样要跟上,起早贪黑累的要死,跟开公司不一个路数,本人实在没耐心,找了个公司部门经理去负责,管得一塌糊涂,半年赔了几十万,关门了事。现在谁再跟我提开饭馆我跟谁急,去饭馆吃饭行,别的一概免谈。
      如各位有兴趣要开饭馆,一定先想明白以下几点:
      A: 你是否能起早贪黑吃得了苦
      B: 如是接别人转让的饭馆搞明白上家为何转让(不可只听一面之辞,一定在该饭馆蹲两天)
      C: 饭馆租金,人员开销等费用核到每天每张桌子是多少钱,饭馆定位,面向什么层次客户,一天能翻几次台,平均每桌消费多少,毛利率多少,是否能赚回来(一定要掰着手指头算好,不行连脚趾头一块上,否则赔死你)。
      D: 附近的工商,卫生,公共安全专家,地痞流氓你是否搞得定。
      E: 停车问题。
      F: 找大厨。找着后如何管理,是后厨承包还是流水提成?
      G: 你老婆是否愿意做采购或找个向你老婆一样对你忠心的人做采购。
      H: 饭馆服务员可得管吃管住,而且工资近期增长很快,预算要留出富裕。计算不好你就只能剥削你自己外加你爸你妈你老婆。
      I:……还有N多问题自己想吧。
      据我的经验,饭馆和美容美发都不好干,只要看看报纸上转让信息就知道,基本就这两个行业。
      另:本人的副业还曾有过服装,节电设备等,都没挣到钱。
    本人比较惭愧,从未在大公司待过,也未系统地接受过管理培训。刚毕业时虽进入大部委工作两年,可惜职务太低,没学到真谛。一说起管理,总感觉别人讲得头头是道,就好像武侠小说里的名门正派,而自己则是街头打群架的小混混出身,没有理论,只有教训。有时感觉成功是不可以复制的而错误则是可以重复的。比如大家就算知晓了微软运行的每一个步骤也不可能成为另一个比尔盖茨,但若有人像我原来一样不重视财务管理十有八九公司在钱财上会有损失。
      在随后一段时间内,我会把自己的经验教训逐步列出,想到哪写哪吧。不过各位新创业的朋友读过我的文章后估计还会犯同样的错误,只是希望大家犯的错误小点,过程短点,毕竟在岸上看过一百遍游泳教学片下水后还得喝点水。

    5.关于招聘 (这个有一定道理,现在人难招)
      这些年没少招聘,几年前最多时我一下午面试五六十人。刚开始没有经验,每回招人都找最好的,工资一千多的售后服务岗位经常招名牌大学本科生,英语过四级。后来发现,招来人根本留不住。本来简单工作的岗位中专生完全能够胜任,找个本科生双方都不合适,只是在写公司简介时方便吹牛。另外面试时应聘人员说的话不可全信,有时对方刚失去工作后比较失落,为得到新工作,他们什么都敢承诺。某次公司招聘商务,岗位工资定为两千左右,一个女孩投简历面试,本科学历,3年工作经验,上份工作工资在两千五,我问她这次工资比上份工作工资低,能否接受。她毫不犹豫表示没问题。由于她比较适合商务职位,我就录用了她。半个月后,前任商务和她交接完离职后第二天她也离职,理由居然是工资低,搞得公司非常被动。再次招聘我招了个原工资一千五百元的女孩,现在还在该岗位,不但干得好,而且对工资也很满意。大部分人对待新工作职位及待遇都是只能上不能下,能上能下的人太少了,Dengxp应该算一个。
      招人的经验是:宁可漏过一千,不可错招一个(源于历史上某个著名人物语录)。据我的经验,公司招聘如低一档用人,高一档发工资效果比较好(也就是招三流的人才,干二流的工作,发一流的工资。当然,以上一流三流都是相对的)。招聘时应不嫌麻烦,仔细核对应聘人员身份。去年我公司连续发生两起新员工携款潜逃事件,打电话找人时对方有恃无恐:反正我应聘时的身份证学历证家庭住址都是假的,几千块钱pol.ice都不管。别说pol.ice还真不管。现在招聘,本地人公司都一一核实,外地人一律要有本地人担保,弄虚作假者一概不要。从此再无类似情况发生。
      对于下岗职工我个人有一定偏见。大部分下岗职工,特别是岁数稍大的国营单位下岗职工基本上牢骚满腹,觉得社会对他不公,而且把不满情绪及原单位的种种不良习气都带到新公司,觉得公司给他什么福利都是应该的,别人都欠他的,很难融入新公司,踏实肯干的占少一部分。大概私营企业不适合下岗职工吧。此外亲戚朋友能少用就少用吧,这个话题以后我还将涉及。
    6.老板尽量唱红脸
      每天公司里总有很多事发生,有的应该表扬,有的应该批评。批评和表扬到底该由谁来执行呢?
      刚干公司时,找不着当老板的感觉,平素又最烦管人,所以员工有什么问题我很少说。结果公司员工自由散漫,谁也不服谁,工作无法开展。后来觉得再这样下去实在不行,于是开始板起脸管人,这下新的问题又出来了,公司里几乎所有的矛盾都集中到我和公司员工之间,经常有员工当面与我理论是非曲直,这老板当的真郁闷,而我又实在不想当一个声色俱厉的管理者。后来与日本企业接触多了,发现不少奥秘。日本公司总经理很少骂公司普通员工,对公司底层员工可和蔼了,但他经常当着员工的面训斥公司中层干部,而普通员工犯错误则由该员工的直接领导负责处理,当然月底发工资时总经理心里可不含糊,这样公司不仅管理得井井有条,而且员工心里也比较平衡。
      他山之石可以工玉,说干就干,咱公司不大,好歹也有几个主管。于是开会明确职责,谁的手下出问题谁自己处理,别什么问题都往我这推。平常我一般只表扬好人好事,鼓励为主,而主管自身犯错时我也很少当众批评,通常是私下交流。时间不长,公司管理顺畅了,我在公司里的形象也大为改观,员工更尊敬我了。
      有时觉得,老板对于公司有点像古代皇帝对于国家。如果皇帝很贤明而大臣很昏庸,老百姓通常觉得国家还是有希望的,大不了清君侧,换个大臣了事。而如果皇帝很昏庸,则老百姓通常觉得这个国家没希望了,开始琢磨造反改朝换代。咱当老板总不能让公司员工揭竿而起或用脚表态一走了之吧,既然主管和部门经理享受着公司岗位津贴当然应该为老板分忧,该唱黑脸作恶人时就应当仁不让,而老板一般应保持一个超然的态度,置身于事件之外,旁观者清吗。不过部门经理需要支持时,只要不是原则性错误,我通常态度鲜明予以支持。
    7.公司里的亲戚
      这个问题,我只有教训,没有经验。还好,老婆工作单位一直不错,世界500强,对我的小公司没什么兴趣,因此公司刚成立时,我根据平时耳濡目染的各类情况,决定尽量不用亲戚朋友。后来公司到一定规模时,外地一个长辈打来电话,说她儿子(也就是我表弟)毕业一年,在当地我们这个行业的一个小公司当业务员,收入不是很高,希望来北京发展。我这个亲戚家庭比较困难,其中一个孩子因为特殊情况无法上班,而要来北京的这个表弟我原来见过,现在十八九岁,相当聪明,当时想公司正缺人,用谁不是用,因此我爽快地同意了。
      表弟刚来北京时,吃住都在我父母家,年轻人和老年人生活习惯不同,搞得我妈经常找我抱怨。过了一段时间,我将其安排到公司宿舍,算是解决了问题。表弟人很机灵,又会来事,几个月时间就完全适应公司环境,而且在部门里业务完成的很好,提成总在前几名。后来我发现,表弟经常在公司里表白自己的特殊身份,对同事吆五喝六,公司其他员工反响很大。为此我找他谈过几回,他都表示一定改正,不过收效不大。转眼一年过去,表弟在这个行业里已经如鱼得水,挥洒自如。这时,表弟找我说他在老家有几个同学,又聪明又可靠,希望带过来一起在公司发展。我想这是好事啊,来吧,照单全收。麻烦开始了。
      表弟和他的几个朋友吃住都在一起,相互之间只说家乡话,公司里除了我谁也听不懂。而且他们虽在不同部门,但被部门主管察觉他们相互勾结挣黑钱。表弟非常聪明,他散布说公司股东之间有矛盾,他是我这一派的,让他的直接主管不要站错队,否则后患无穷。公司不少员工真被他唬住了,过了一段时间,问题才反映到我这来。公司对待此类问题一向是第一次罚款警告,第二次开除。我和表弟谈了一回,他拍胸脯表示绝不再犯类似错误。没过一个月,又有部门主管向我反映表弟的小团伙在干黒活,而且不但不避讳其他员工,甚至鼓励其他人一起干。我真的很为难,再不管该养虎为患了,我还指望公司做强做大,让一起创业的股东老有所依呐。长痛不如短痛,一咬牙,我将表弟和他的小团伙陆续请出了公司。公司业务为此震荡半年。
      表弟靠着从公司带走的客户,现在还在这个行业做,每年也挣不少钱还买了车。
      亲戚朋友能不用还是不用吧,否则最后亲戚朋友也没得做了。
      曾经听过其他公司老总讲他在公司做大后如何对待亲戚。他的五六个亲戚在他创业时不计得失帮他干,做大后亲戚跟不上公司发展步调,且占据高位不好管理。这时,他采取牺牲钱财保全亲情的方法:岁数大的给一笔钱帮其另外创业,岁数小的公司出钱送到国外留学并负担所有开销,读成MBA后帮其再找工作从而顺利解决这一棘手问题,高!
    8.当老板和开车
      去年回老家,坐一个亲戚开的车。亲戚刚拿本没多久,属于实习司机。一道上马路又宽又直,司机的手却在不停地动,左一下右一下,车也在画龙,我坐在副座上,心里很紧张,系上安全带,嘴里话也少了,脚下直使劲,旁边车道上的车不停地在按喇叭,还好,最后终于安全到达。回想十年前自己刚拿本时,已是老司机的弟弟坐我的车也提过同样问题,当时自己信心很足,根本不理解坐车的人怎么会有这种感觉,现在方才明白。
      总结自己开公司,也经常犯类似的错。政策朝令夕改,看见别的公司有什么新章程常常一拍脑门拿来就用,过段时间发现效果不好又推倒重来,弄得公司员工无所适从。原有的提成奖励方法有的已经很好,经过实践检验较为合理,员工也认可,偏偏听完什么专家讲座或看完某本管理书后,不经过深思熟虑并结合公司实际情况进行改造照搬照抄,立刻重新制定政策,结果会计抱怨不好操作,员工抱怨政策不合理,一通折腾后又改回原样。
      现在常想,办公司和开车很像,老板就好比驾驶员,车在路上跑,只要在本车道的两条白线内就OK,不必时刻调整方向盘,否则司机累,乘客累,车还画龙易出危险,费力不讨好。同样办公司只要公司运营在可控范围内不犯大错,政策就应稳定执行,保持连贯性,让员工心里有底。小公司老板权力集于一身,缺乏监督,制定政策更应该小心谨慎,不然公司总在调整,员工缺乏稳定感,不跑光才怪呢。想想当初Dengxp为什么承诺香港回归后体制50年不变。
    9.按时发工资
      其实这一条是当老板最基本的素质。估计每一个老板都不会反对这一点(至少在口头上不会反对),但实际情况是很多公司做不到这一点。
      公司在日常运营时,会经常遇到资金紧张的情况,比如月底或年底压一批货从厂家拿个高额折扣,做工程甲方押着工程款未能及时支付,银行贷款到期需立即归还等等,所有这一切对于老板来说都是未能及时发工资的充分理由。老板一般想:又不是不发工资,只不过稍微晚几天,公司资金紧张,员工应该理解。真实情况是:无论任何理由,对于不按时足额发工资,员工都无法理解。员工的工资不是老板赏赐的,而是他辛苦所得,没准他正等着到日子拿工资交房租,还月供或支付孩子的学费。未能及时领到工资员工可能马上就会面临生存问题。正常情况下,老板兜里的钱总比员工活分些,所以老板经常想当然认为员工晚拿几天工资没关系。
      那么如果碰到资金紧张时该怎么办?一般情况下,做生意量力而行吧,有多少本挣多少利,不行就找银行贷款。如果银行贷不到款,也可公司内部或亲戚朋友之间集资,讲明用钱的地方,谈好借款期及利息,大部分员工对于公司有把握的业务还是愿意参与的。到月底实在发不出工资,如果公司还想继续做下去,老板还是先从自己做起把私房钱拿出来吧,还不够把房子车子先典当了,资金周转过来再赎回。
      拖欠工资这事有点像吸毒,有一回就会有第二回,只要资金一紧张老板就会用拖欠员工工资来缓解,结果员工对公司和老板的信任荡然无存。调查表明,员工对于公司最无法容忍的就是拖欠工资,这也经常是某些企业人员流动的最主要因素。

    10.学会说“不”
      中国人好面子,“不”字很难说出口,而老板又是公司的最后一道关口,有时不得不拉下脸说“不”。
      我们公司有规定,公司的钱一律不借个人,当然,特殊情况员工可以预支部分工资。前两年,公司一个骨干员工找我聊天,他问:“如果公司里一个员工,对公司贡献是其他人的好几倍,公司会不会借钱给他?”对这个问题我真的很犹豫,想了半天,我说:“公司有规定,公司的钱一律不借个人。”他还不甘心,又问:“对骨干员工也这样?”。我说:“对所有人公司一视同仁,骨干员工工资奖金可以多发,可以优惠条件入股,但对于这项规定谁也不能例外。”随后我问他是不是自己要借钱,他承认说要买房子想借三十万。我很奇怪,买房可找银行贷款呀,这个员工说找银行贷款要付利息和手续费,想着找公司借钱可以不付利息了。后来我了解到他已经有一套住房想着再买一套住房等升值挣钱呢。一年后,该员工因为其他原因离职了。想想当初要是借钱给他,此时还真不好要回来。回绝过一回,以后类似情况就好处理了。这些年,公司包括我在内的所有股东买房钱不够都是找银行贷款,没人借用公司流动资金。想想公司再有钱又怎能代替银行的功能。
      有时公司的不少规定都有特殊情况,但在原则问题上老板一定站稳立场,规定面前人人平等,所谓不患多寡患不公,没有不透风的墙,只要开了先例以后其他员工就不好管了。近些年媒体上不是一直嚷嚷要法制不要人治,一定有他的道理。当老板该说“不”时就说“不”,无论对谁,虽然当时被人骂难受一下总比公司歇菜难受一辈子强,有很多公司就因为老板抹不开面子盲目给别人担保或随意借款给人结果最后自己公司倒闭了。当老板不对自己的公司负责别人是不会为你着想的。
    11.不要在公司内部奢望交朋友
      刚当老板时不习惯管人,总觉得公司里应该人人平等,大家都是朋友,有什么事好商量。干了一段时间后,感觉公司里比较混乱,制度形同虚设,犯错误成本非常低,大家日常基本是想干啥就干啥,月底工资还谁也不能少发。
      一天,一个在大公司工作的朋友到我这待了半天,走时深有感触地对我说:你这管理要加强啊,在公司半天都看不出谁是老板,员工既不怕你也不听你呀。我听后觉得很有道理,但具体怎么做也搞不明白。后来问题终于集中爆发了,公司里贪污现象严重,效率低下,员工觉得没有奔头,几个骨干自己一合计单挑一滩,十几个人的公司跑了七八个并带走了一半客户。
      好在此时我还有另外一个较小的分公司,新招了几个业务员。毕竟本人是白手起家,心理承受能力足够强,一咬牙重新开始。这次吸取教训,制定严格的规章制度并认真执行,业务很快有了起色,一年后人员又恢复到十几个,利润也超过以前。
      想想还是自己当初还是心态不对,认为自己的公司应象国营企业一样,人人都是公司的主人翁,人人都平等,大家自觉把事干好,纯粹是扯淡。公司内部大家利益不同,岗位不同,哪来什么绝对平等。虽然大家人格上是平等的,但岗位职权工资奖金上怎么可能平等呢?为什么除了垄断行业外,大部分国营企业都倒闭了?因为国营企业的经营观念管理方法不符合目前的市场经济和社会环境,我觉得我们从小接受的教育从根本上不符合人的本性。当初红灯记里鸠山说“人不为己天诛地灭”一直被当作反面典型加以批判,其实我现在认为这话好像符合每个人自然的第一反应。世人熙熙皆为利来,使人攘攘皆为利往,连出家的和尚都明白这个道理。当老板就当老板吧,甘蔗没有两头甜,我不再奢望与公司员工做朋友,一切按规章制度来,只要管理好公司,让大家尽量拿到更多的工资奖金,人人都上保险,骨干员工入股共享公司发展成果,对得起自己的良心就完了。老板本来就是个孤独的职业,交朋友就在公司以外吧。
      要说规章制度,每个稍具规模的公司都有一大本,但不同公司的管理水平相差可大了去了,关键还在于规章制度是否被认真执行,老板能不能自己认可规章制度并亲自或安排专人监督落实。规章制度执行好了,人员管理就水到渠成,一切按规矩来,老板也无用一天到晚训斥员工。其实,从办公司到现在,我没有骂过任何一个员工,有几次公司员工离职后又回来,原因竟然都是无法忍受新公司老板发脾气骂人,呵呵,不过我感觉现在我在公司还挺有威信,至少朋友来公司不会说看不出谁是老板了。
    12.避免当场做决定
      影视作品,报纸广播里经常有这样的场景:领导干部现场办公或下基层走访,有人民群众扶老携幼涕泪滂沱地反映当地官员久拖不决的某些问题,领导同志大手一挥,无比激动地斥责那些不作为的贪官污吏,该免职的免职,该法办的法办,几年解决不了的问题五分钟之内现场解决,真是大快人心,爽!
      当老板没多久,公司人员渐渐多起来,我的领导欲望也逐渐膨胀,常常脑袋一热手一挥解决问题。有一回,业务员甲向我投诉,另一个业务员乙恶性竞争抢他的客户,同一单生意故意报低价致使用户未从甲业务员处购买,公司也在利润上受到损失。我一听,非常生气,这种极端自私的行为如何能够容忍,于是贴出通知:此担生意,乙业务员不仅没有提成,而且通报批评,所有提成奖励归甲业务员。后来乙业务员反应激烈地找到我说该用户他已经跟了半年多,价格型号都基本谈妥,前些天有次他外出拜访其他用户时该用户打电话到公司落实细节问题结果甲业务员接了电话,过后甲不仅未转告乙业务员,而且还让用户直接找甲业务员自己并许诺更多优惠,差点将生意搅黄。我听完后非常诧异,怎么与甲说的完全不一样啊。后又找其他几个业务员核实,乙业务员说的基本属实。唉,通告已经张贴了,这可如何是好?于是一通补救并制定相应规章制度避免以后类似情况发生。过后反思:当初为什么不调查一下再做决定呢?如果乙业务员性格内向些没准不找我申辩直接开路走人了,这对公司损失更大而且公司其他员工又会有何想法呀。再回想最近经常快速做出一些鲁莽的决定,非常后悔,看来官僚的口头禅:这个问题要考虑考虑研究研究确有其道理。过去的皇帝金口玉言,说的话不能随便改,今天的公司老板也不能不过脑子不全面调查随口做决定,否则天天朝令夕改威信尽失。
      现在员工找我解决问题我一般都说:行,我知道了,等我查一下,几天之内给你回复。这样类似错误就很少发生了。看来做事不能只图一时痛快,要全面考虑,职位越高越应避免当场做出决定。要不怎么很多人感觉大公司办事反应慢,估计如果大公司反应都向个体户一样快很快大公司也就变成个体户了。


  • LR11如何手动关联 Web 脚本

    2011-10-12 13:37:51

    LR11如何手动关联 Web 脚本

    如何手动关联 Web 脚本
    说明了如何通过修改代码手动关联 Web 脚本。
    包含以下步骤:
    ➤ “找到字符串及其详细信息”
    ➤ “添加 web_reg_save_param_* 函数”
    ➤ “使用参数替换数据”
    1 找到字符串及其详细信息
    识别包含动态数据的语句以及描绘数据位置特征的模式。这些模式可以是边界
    或 Xpath。
    a 使用边界识别模式
    根据以下规则确定并设置动态数据的边界:
    ➤ 分析 HTTP 响应中动态数据的位置。
    ➤ 识别紧跟在动态数据左侧的字符串。此字符串定义动态数据的左边界。
    ➤ 识别紧跟在动态数据右侧的字符串。此字符串定义动态数据的右边界。
    ➤ 左、右边界应尽可能唯一,以便更好地定位字符串。
    ➤ web_reg_save_param_ex 查找指定边界之间(但不包括边界)的字
    符,并保存从左边界后一个字节开始到右边界前一个字节结束的信息。
    web_reg_save_param_ex 不支持嵌入式边界字符。
    例如,如果输入缓冲区为 {a{b{c},且“{”指定为左边界,“}”指定为右
    边界,则第一个实例是 c,并且没有其他实例,因为它找到了右边界和左
    边界,且不允许使用嵌入式边界,因此“c”是唯一符合要求的有效实例。
    默认情况下,边界字符串的最大长度为 256 个字符。在脚本中包含
    web_set_max_html_param_len 函数可增加允许的最大长度。例如,以下
    函数将最大长度增加至 1024 个字符:
    这些长度限制不会应用于左边界或右边界为空的字符串。

    b 使用 Xpath 识别模式
    使用快照窗格手动搜索所需字符串的 Xpath。
    默认情况下,边界字符串的最大长度为 256 个字符,脚本中包含
    web_set_max_html_param_len 函数以增加允许的最大长度。例如,以下
    函数将最大长度增加至 1024 个字符:
    这些长度限制不会应用于左边界或右边界为空的字符串。
    2 添加 web_reg_save_param_* 函数
    将 web_reg_save_param_ex 或 web_reg_save_param_xpath 函数添加到
    脚本中包含动态数据的语句之前。
    a web_reg_save_param_ex
    此函数搜索 Web 步骤中左边界后为字符串和右边界的服务器响应,并将字
    符串保存到在函数实参中指定的形参。找到指定数目的对象后,
    web_reg_save_param_ex 不再搜索其他响应。有关详细信息,请参阅
    《HP LoadRunner Online Function Reference》。
    b web_reg_save_param_xpath
    此函数搜索 Web 步骤中服务器响应的指定 Xpath。位于指定 Xpath 中的字符串
    保存在函数实参中指定的形参内。有关详细信息,请参阅《HP LoadRunner
    Online Function Reference》。
    3 使用参数替换数据
    请从 VuGen 主窗口中选择编辑 > 替换,以显示“搜索和替换”对话框。在整
    个脚本中搜索动态数据,并将其替换为参数。为参数赋予任意名称,并用括号
    括起:{参数名}。每个脚本中最多可以包含 64 个参数。

     

  • 用QTP的描述性编程高亮显示任意对象

    2011-07-24 09:52:05

    这里运用描述性编程实现高亮显示计算器中的0到9的按钮对象
    把以下代码拷到QTP中,点“运行”,看看效果。
    注:本程序windows XP下的计算器演示,若使用windows 2000的计算器无效。


    SystemUtil.Run "C:\WINDOWS\system32\calc.exe","","C:\WINDOWS\system32","open"
    For i =0 to 9
    HighlightAll Window("regexpwndclass:=SciCalc").WinButton("text:=" & cstr(i) )
    Next


    Sub HighlightAll(TestObject)

           Dim Parent, Desc, Props, PropsCount, MaxIndex, i, Objs
           If IsEmpty(TestObject.GetTOProperty("parent")) Then
                  Set Parent = Desktop
           Else
                  Set Parent = TestObject.GetTOProperty("parent")
           End If
           Set Desc = Description.Create
           Set Props = TestObject.GetTOProperties
           PropsCount = Props.Count - 1
           For i = 0 to PropsCount
                  Desc(Props(i).Name).Value = Props(i).Value
           Next
           Set bjs = Parent.ChildObjects(Desc)
           MaxIndex= Objs.Count - 1
           For i = 0 to MaxIndex
                  Objs.Item(i).Highlight
           Next

    End Sub

  • QTP的Test参数以及顶级Action参数的使用

    2011-07-24 09:51:06

    网上有些关于如何使用Action参数的文章,不过关于QTP的Test参数和Top-Level Action参数的使用例子几乎没有。
    有些人甚至不知道这个参数做什么用的,尤其是Test的output不知道怎么取。
    其实它是外部对象传给它的(这个外部对象可以是Quality Center,也可以是vbs这样的驱动程序)。
    以下给大家讲解一个关于QuickTest的Flight的例子。
    首先,在QTP里录制一段脚本代码如下:
    1. SystemUtil.Run "C:\Program Files\Mercury\QuickTest Professional\samples\flight\app\flight4a.exe","","C:\Program Files\Mercury\QuickTest Professional\samples\flight\app\","open"
    2. Dialog("Login").WinEdit("Agent Name:").Set Parameter("InAction1")
    3. wait 5
    4. Dialog("Login").WinEdit("Agent Name:").Type  micTab
    5. Dialog("Login").WinEdit("Password:").SetSecure "4649c633ffc8803c10097292953c6334fde3e923"
    6. Dialog("Login").WinEdit("Password:").Type  micReturn
    7. Window("Flight Reservation").Close
    8. Parameter("OutAction1") = True
    复制代码

    然后,鼠标选中Keyword View中的Action1,点右键---Action Property,在Parameters的Tab标签下,分别加入:输入参数 InAction1 ,类型String;输出参数 OutAction1,类型 Boolean。如下图。
    再然后,在QTP的菜单File--->>Settings的Parameters的Tab标签下,分别加入:输入参数 InParam1 ,类型String;输出参数 OutParam1,类型 Boolean。如下图。
    接着,鼠标还是选中Keyword View中的Action1,点右键,这次点“Action Call Properties”,在Parameter Values里进行参数化传递设置,把InParam1的值传递给InAction1,把OutAction1的值传递给OutParam1。如下图。
    以上设置完毕后,点“保存”,保存到C:\下,存为Test1好了。

    最后,在你的硬盘上新建一个vbs文件,文件内容如下:
    1. Dim qtApp ,pDefColl,pDef ,rtParams,rtParam
    2. Set qtApp = CreateObject("QuickTest.Application")
    3. qtApp.Launch
    4. qtApp.Visible = True
    5. qtApp.Open "C:\Test1"
    6. Set pDefColl = qtApp.Test.ParameterDefinitions
    7. cnt = pDefColl.Count
    8. Indx = 1
    9. While Indx <= cnt
    10.     Set pDef = pDefColl.Item(Indx)
    11.     Indx = Indx + 1
    12. Wend
    13. Set rtParams = pDefColl.GetParameters()
    14. Set rtParam = rtParams.Item("InParam1")
    15. rtParam.Value = "songfun"
    16. qtApp.Test.Run , True, rtParams
    17. MsgBox rtParams.Item("OutParam1").Value  
    复制代码


    做完这步之后,保存这个vbs文件,双击执行这个vbs文件,你会发现它自动启动了QTP,而且进行了自动测试,最后还取到了运行成功与否的布尔值。
    这就是关于Test、Top-Level Action参数使用的例子,它的参数的整个传递过程是:
    外部vbs文件 传参数给QuickTest的Test的输入参数InParam1,然后InParam1传参数到InAction1去驱动了Action1的测试,然后通过这个Action1得出了OutAction1的值,然后通过OutAction1传给OutParam1,最后再传回到vbs文件中。示例用MsgBox来打出重新传回到vbs文件中的字符串。

    [ 本帖最后由 songfun 于 2007-5-17 09:33 编辑 ]

    quicktestparam.bmp (1.83 MB)

    quicktestparam.bmp

  • 用QTP调用外部vbs读写XML的例子(一)

    2011-07-24 09:49:01

    目前,企业中对XML的应用越来越广泛,作为自动化测试的测试工程师,也应该掌握XML的读写操作。
    以下我使用XML DOM技术演示一个例子,用以读取XML指定节点的节点内容值。
    读取函数原型 GetXml strXmlPath,nodeName
    这个函数的第一个参数表示xml文件所在路径,第二个参数表示希望获取到的xml节点名,请结合下列例子看
    首先,新建一个vbs文件(取个名字叫readXml.vbs),输入代码
    1. '==================================================================
    2. '   Author  : songfun
    3. '
    4. '  Description :  Read XML
    5. '==================================================================
    6. Dim strXML

    7. GetXml "c:\search.xml","TestResult"  '这个函数的第一个参数表示xml文件所在路径,第二个参数表示希望获取到的xml节点名,请结合下列例子看
    8. MsgBox strXML


    9. Function GetXml (ByVal strXmlFilePath,ByVal xmlNodeName)
    10.         Dim xmlDoc,xmlRoot
    11.        
    12.         Set xmlDoc = CreateObject("Microsoft.XMLDOM") '创建XML DOM对象
    13.         xmlDoc.async = False  '控制加载模式为同步模式(xml树加载完毕后再执行后续代码)
    14.         xmlDoc.load strXmlFilePath        '载入xml文件
    15.         If xmlDoc.parseError.errorCode <> 0 Then
    16.                 MsgBox "XML文件格式不对,原因是:" & Chr(13) &  xmlDoc.parseError.reason
    17.                 Exit Function               
    18.         End If
    19.         Set xmlRoot = xmlDoc.documentElement       
    20.         xmlRecursion xmlRoot,xmlNodeName        '调用xml递归函数传入指定的根和节点名       
    21.         GetXml = True 'xmlRecursion (xmlRoot)
    22.        
    23. End Function

    24. Function xmlRecursion(byval xmlNode,byval strNodeName)
    25.         If xmlNode.nodeName = strNodeName And xmlNode.hasChildNodes Then
    26.                 If  xmlNode.childNodes.item(0).nodeName = "#text" Then
    27.                         strXML = strXML & xmlNode.nodeName & ":" & xmlNode.childNodes.item(0).nodeValue & Chr(13)                                               
    28.                 End If               
    29.         End If                       
    30.         If xmlNode.hasChildNodes Then
    31.                 For Each childNodeItem In xmlNode.ChildNodes
    32.                         If childNodeItem.hasChildNodes Then
    33.                                 xmlRecursion childNodeItem,strNodeName                               
    34.                         End If                       
    35.                 Next
    36.         End If       
    37. End Function
    复制代码


    接着,自己构造一个xml文件(取个名字叫search.xml),如:

    1. <?xml version="1.0" encoding="GB2312"?>

    2. <ROOT>
    3.         <TestCase>
    4.                 <TestNumberOne>1</TestNumberOne>
    5.                 <TestNumberTwo>2</TestNumberTwo>
    6.                 <TestNumberThree>+</TestNumberThree>
    7.                 <TestResult>3</TestResult>
    8.         </TestCase>
    9.         <TestCase>
    10.                 <TestNumberOne>3</TestNumberOne>
    11.                 <TestNumberTwo>2</TestNumberTwo>
    12.                 <TestNumberThree>-</TestNumberThree>
    13.                 <TestResult>1</TestResult>
    14.         </TestCase>
    15.         <TestCase>
    16.                 <TestNumberOne>3</TestNumberOne>
    17.                 <TestNumberTwo>7</TestNumberTwo>
    18.                 <TestNumberThree>*</TestNumberThree>
    19.                 <TestResult>21</TestResult>
    20.         </TestCase>
    21.         <TestCase>
    22.                 <TestNumberOne>2</TestNumberOne>
    23.                 <TestNumberTwo>5</TestNumberTwo>
    24.                 <TestNumberThree>/</TestNumberThree>
    25.                 <TestResult>0.4</TestResult>
    26.         </TestCase>       
    27. </ROOT>
    复制代码


    然后,在QTP的expert view中调用刚才写的vbs文件:
    executefile "c:\readXml.vbs"

    点“Run”,就能看到这个效果了。
    当然,如果你不用调用外部文件的方式,也可以,如下图。

    [ 本帖最后由 songfun 于 2007-5-19 13:46 编辑 ]

    qtpxml.JPG (132.46 KB)

    qtpxml.JPG

  • 在QTP中如何使用Class(类)

    2011-07-24 09:47:34

    大家知道VB是面向对象的,其中Class(类)是一个“模板”,对象是由它而创建的。类中的代码描述了从该类创建的对象的特性 (attribute) 和行为。
    虽然Class(类)不是对象,但是它的确有定义其特性 (attribute) 的设计时属性 (property) 和定义其行为的事件。
    类里的数据,是相对于类实例(也就是,由类创建的每一对象)而独立存在的。
    也就是说,它存在于程序的存活期中;而类实例中的数据只存在于对象的存活期,它随对象的创建而创建,随对象的撤消而消失。
    在编程的时候使用Class正是符合了OO(面向对象封装)的编程原则,我们在使用QTP进行自动化测试编程的时候也要时刻牢记这一原则,进行脚本设计。
    然而,如何在QTP中使用Class呢,以下是本人写的一个在QTP中使用Class的例子,大家直接把它粘贴到QTP的Expert View中就能看到效果了:)


    '****************************************************************
    Call Test

    Class Tester

            Dim mvarTesterName,mvarAge,mvarGender       
           
            Sub Class_Initialize   '构造函数
                   MsgBox  "接下来,大家欢迎新同事的到来!"
            End Sub
           
            Sub Class_Terminate  '析构函数
                    If mvarGender Then
                        MsgBox "很遗憾," & mvarTesterName & "先生脱离了测试行业!"
                    Else
                        MsgBox "很遗憾," & mvarTesterName & "女士脱离了测试行业!"
                    End If
            End Sub

            Sub Test(ByVal ProjectName)
                    MsgBox mvarTesterName & "正在加班加点的测试" & ProjectName & "呢!"
            End Sub
           
            Sub Eat(ByVal food)
                    MsgBox mvarTesterName & "正在吃" & food & "呢,好爽啊!"
            End Sub
           
            Property Let Gender(ByVal vData)
                mvarGender = vData            
            End Property
           
            Property Get Gender()
                Gender = mvarGender
            End Property
           
            Property Let Age(ByVal vData)
                mvarAge = vData
            End Property
           
            Property Get Age()
                Age = mvarAge
            End Property
           
            Property Let TesterName(ByVal vData)
                mvarTesterName = vData
            End Property
           
            Property Get TesterName()
                TesterName = mvarTesterName
            End Property
       
    End Class



    Sub Test()
            Set sb = New Tester  '创建一个对象,对象名叫somebody,它是由Tester创建出来的
            sb.TesterName = "songfun"
            sb.Age = 29
            sb.Gender = True
            sb.Eat "HagenDaz"
            sb.Test "手机"
            If sb.Gender Then
                    MsgBox sb.TesterName & "先生年方" & sb.Age
       Else
                    MsgBox sb.TesterName & "女士芳龄" & sb.Age
            End If
            Set sb = Nothing
    End Sub
    '****************************************************************

  • QTP中连接MySQL的方法(数据库验证点和ADO连接)

    2011-07-24 09:45:41

    很多朋友对于QTP中连接MYSQL束手无策,其实根本原因是默认的我们的操作系统中ODBC驱动里默认不支持开源的MySQL驱动。
    解决这个问题的方法非常简单,安装一个相关的驱动就能解决问题了。
    这里给出这个驱动程序下载地址MyODBC-3.51.11-2-win.exe
    安装完毕后,到“控制面板--管理工具--数据源ODBC--系统DSN”把它添加进来,步骤见下面截图qtpmysqsl1.JPG到qtpmysqsl5.JPG(我在本机上安装了一个Discuz论坛)。
    添加完毕后,就可以开始使用了。
    以下给出具体的实现过程
    (一)数据库验证点:
    见下面截图 qtpmysqsl6.JPG 到 qtpmysqsl9.JPG
    (二)ADO连接MySQL数据库的代码
    例子(获取论坛中的帖子主题和内容):
    1. Dim Cnn, Rst, strCnn

    2. strCnn = "DRIVER={MySQL ODBC 3.51 Driver};SERVER=localhost;DATABASE=discuz;USER=root;Option=3"
    3. Set Cnn = CreateObject("ADODB.connection")
    4. Cnn.Open strCnn
    5. Set Rst = CreateObject("ADODB.Recordset")
    6. Rst.Open "select * from cdb_posts", Cnn
    7. Rst.MoveFirst
    8. While Rst.EOF <> True
    9.     MsgBox Rst.Fields("subject") & Chr(13) & Chr(10) & Rst.Fields("message") & Chr(13) & Chr(10)
    10.     Rst.MoveNext
    11. Wend
    12. Rst.Close
    13. Cnn.Close

    14. Set Rst = Nothing
    15. Set Cnn = Nothing
    复制代码

    qtpmysqsl1.JPG (34.27 KB)

    qtpmysqsl1.JPG

    qtpmysqsl2.JPG (44.58 KB)

    qtpmysqsl2.JPG

    qtpmysqsl3.JPG (34.17 KB)

    qtpmysqsl3.JPG

    qtpmysqsl4.JPG (34.97 KB)

    qtpmysqsl4.JPG

    qtpmysqsl5.JPG (36.01 KB)

    qtpmysqsl5.JPG

    qtpmysqsl6.JPG (27.92 KB)

    qtpmysqsl6.JPG

    qtpmysqsl7.JPG (35.67 KB)

    qtpmysqsl7.JPG

    qtpmysqsl8.JPG (25.09 KB)

    qtpmysqsl8.JPG

    qtpmysqsl9.JPG (35.41 KB)

    qtpmysqsl9.JPG

  • 如何用QTP解决图片验证码(解析QuickTest文本识别机制)?

    2011-07-24 09:43:55

    大家在使用QTP进行自动化测试的过程中经常会遇到图片验证码的问题——大家所关心的就是如何解决此类问题。
    这里我们首先要去了解为什么会有图片验证码。其实验证码的本质作用就是防止有人利用工具(灌水机、注册机,当然也不小心包括了我们的自动化测试工具)恶意猜解登陆或者不停的注册和灌水的。因此如果我们完全寄希望于通过GUI识别来获取内容是不切实际的——先打好预防针,免得读者希望太大,失望更大,呵呵!
    下面说说验证码的解决思路:
    其实解决图片验证码的思路有很多,我这里主要结合QTP9.5的新特性给大家介绍其中一种解决方案,就是利用它的OCR机制抓取文本内容。
    在QTP9.5中,对象识别能力有了进一步改善,其中针对文本识别方面进行了优化,引入了ABBYY公司的OCR解决方案——这个相关的功能体现在QTP菜单的“Tools-->Options-->General--Use text recognition mechanisms in this order”里,详细内容后面会有具体介绍。
    先来看看ABBYY是何许公司,登录他们的官方网站可以看到一段相关介绍:“ABBYY是世界OCR(光学字符识别)、ICR(手写体识别)和语言软件的领航者。ABBYY 致力于人工智能(AI)和语言软件开发。提供全套文档识别,转换和数据捕获技术的产品解决方案。”如果你使用过图像文档转换的软件,一定会听说过FineReader OCR Professional ,其实它就是ABBYY公司的产品,用官方的说法就是“将通过扫描仪、MFP 或数码相机生成的图像快速转换为可编辑和可搜索的电子格式,而且识别率很高”,说白了就是可以借助它先进的OCR机制“读”出图片里的文本内容,并转换为PDF之类的文档。
    有了ABBYY这么强大的背后支持,QTP自然底气十足,那么QTP到底如何以OCR机制识别文本呢?我们首先先了解一下什么是OCR。
    打开“百度百科_OCR”,它的说明:“OCR(Optical Character Recognition,光学字符识别),是属于图型识别(Pattern Recognition,PR)的一门学问。其目的就是要让计算机知道它到底看到了什么,尤其是文字资料。 由于OCR是一门与识别率拔河的技术,因此如何除错或利用辅助信息提高识别正确率,是OCR最重要的课题,ICR(Intelligent Character Recognition)的名词也因此而产生。而根据文字资料存在的媒体介质不同,及取得这些资料的方式不同,就衍生出各式各样、各种不同的应用。”这里有个关键词:“正确率”,也就是“识别率”——既然不能够总是100%,我们自然不可能完全寄希望于通过QTP能够每次100%正确的去识别图片里的文本。尤其是“道高一尺魔高一丈”的今天,验证码加入了大量的干扰素,如扭曲、变形、错位、随机背景花纹,给OCR识别增加了很多难度——本来就不希望被软件识别到嘛。

    了解了OCR之后,我们再来看看QTP对应的这个设置。如前面所说,通过QTP菜单的“Tools-->Options”选中到“General--Use text recognition mechanisms in this order”,这里的四个选项就是对应的不同设置。我们看看帮助的描述(我做了翻译):
    =================================
    使用文本识别机制

    指定QTP在采用 “文本”或者“文本区域” 的 检查点或输出值 的步骤时,捕获文本内容所使用的文本识别机制。
    以下有三种识别方式:
    1、先使用Windows API,再使用OCR(默认)。
        指示QTP首先尝试以基于Windows API的机制从对象上直接获取文本内容。如果未获取到文本(比如,文本属于图片的一部分),QTP就会使用OCR的机制尝试获取这段文本。
        强烈建议在使用中日韩(象形文字)、英的语言环境下采用这个设置。

    2、先使用OCR,再使用Windows API。
        指示QTP首先尝试使用OCR机制从对象上去获取文本。如果未获取到文本,QTP就会以Windows API的机制去获取文本内容。

    3、仅使用Windows API方式。
        指示QTP仅采用基于Windows API的机制从对象上获取文本内容。

    4、仅使用OCR的方式。
        指示QTP仅采用基于OCR的机制从对象上获取文本内容。
        在使用Windows Vista要使用这种方式。

    =================================
    上面的内容已经解释的很明确了,接下来我们通过TextArea Output Value看看效果。

    如下图所示,QTP针对几张图片的识别效果:
    (一)、内容是51Testing的,QTP获取正确;内容是51Testing的G风格彩字,QTP获取错误(显示为IC_CHECK_PATTERN)



    (二)、内容是songfun的普通文本,QTP获取正确;内容是songfun的G风格彩字,QTP获取错误(也显示为IC_CHECK_PATTERN)




    有兴趣大家可以自己做一些图片,甚至可以用QQ的验证码图片来试验一下,看看OCR效果。
  • QTP六脉神剑之调用Java程序

    2011-07-24 09:41:33

    不少网友对于QTP调用Java程序感到束手无策,实际上要调用Java程序是非常容易的。接下来songfun老师传授给大家武林绝技之六脉神剑。在演示这个例子前,请大家先造一个java程序(我以java计算器为例,源码见下),以方便观察调用结果

    第一式:少商剑。特点:剑路雄劲,石破天惊。

    打开QTP,在QTPExpert View中输入:InvokeApplication "cmd /k cd c:\ && java Counter && exit"
    运行QTP,看看,打开了吗?

    第二式:商阳剑 特点:巧妙灵活,难以捉摸。

    C盘上新建一个bat文件,取名为runjava.bat,在文件里面输入一段文本:cmd /k "cd c:\ && java Counter && exit",然后保存下来。
    打开QTP,在QTPExpert View中输入:SystemUtil.Run "C:\runjava.bat"
    运行QTP,看看,打开了吗?

    第三式:中冲剑 特点:大开大阖,气势雄迈。

    打开QTP,在QTPExpert View中输入:
    Dim oWsh
    Set Wsh = CreateObject("WScript.Shell")
    oWsh.Exec "cmd /k cd c:\ && java Counter && exit"
    Set Wsh = Nothing
    运行QTP,看看,打开了吗?

    第四式:关冲剑 特点:以拙滞古朴取胜。

    C盘上新建一个qfl文件,取名为runjava.qfl,在文件里面输入一段文本:
    CallJava "Counter"
    Sub CallJava(ByVal strJavaName)

    Dim oWsh


    Set Wsh = CreateObject("WScript.Shell")


    oWsh.Run "cmd /k cd c:\ && java " & strJavaName & " && exit"


    Set Wsh = Nothing

    End Sub
    打开QTP,在QTPExpert View中输入:ExecuteFile "C:\runjava.qfl"
    运行QTP,看看,打开了吗?

    第五式:少冲剑 特点:轻灵婀娜,迅雷不及掩耳。

    安装QTPJava Add-in,之后在Automation—Record and Run Settings中出现了Java标签页。根据下图的内容设置即可(runjava.bat文件内容参照六脉神剑第二式)。
    javarecord.PNG

    第六式:少泽剑 特点:忽来忽去,变化精微。

    采用直接调用jar包的形式。要生成jar包,首先要确保在C盘下已经放置了Counter.java 源文件,然后通过命令行工具去编译它:
    cd \
    javac Counter.java
    jar cvf Counter.jar *.class
    执行完命令看看在C盘是否已经生成了Counter.jar文件?
    接下来解压Counter.jar文件,在C:\Counter\META-INF目录下可以找到MANIFEST.MF这个文件,用Notepad打开,在第三行空行处加入入口类的代码(蓝色字体部分):
    Manifest-Version: 1.0
    Created-By: 1.6.0_07 (Sun Microsystems Inc.)
    Main-Class: Counter
    保存完以后,回到命令行窗口处,输入命令更新jar包:
    jar umf C:\Counter\META-INF\MANIFEST.MF Counter.jar
    写完测试一下:java -jar Counter.jar
    如果计算器可以打开说明前期铺垫工作已经完成,那接下来的就是在QTPExpert View中输入:SystemUtil.Run "C:\Counter.jar"
    运行QTP,看看,打开了吗?


    当然实际上要调用Java程序的方法还有很多,这里就不一一介绍了。在下次课,songfun老师将会传授QTP独门秘笈之降龙十八掌给大家。谢谢!再见!

    附:Counter.java源码。
    import java.awt.*;
    import java.awt.event.*;
    import java.lang.*;
    import javax.swing.*;
    public class Counter extends Frame.
    {
    //声明三个面板的布局
    GridLayout gl1,gl2,gl3;
    Panel p0,p1,p2,p3;
    JTextField tf1;
    TextField tf2;
    Button b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13,b14,b15,b16,b17,b18,b19,b20,b21,b22,b23,b24,b25,b26;
    StringBuffer str;//显示屏所显示的字符串
    double x,y;//x和y都是运算数
    int z;//Z表示单击了那一个运算符.0表示"+",1表示"-",2表示"*",3表示"/"
    static double m;//记忆的数字
    public Counter()
    {
    gl1=new GridLayout(1,4,10,0);//实例化三个面板的布局
    gl2=new GridLayout(4,1,0,15);
    gl3=new GridLayout(4,5,10,15);
    tf1=new JTextField(27);//显示屏
    tf1.setHorizontalAlignment(JTextField.RIGHT);
    tf1.setEnabled(false);
    tf1.setText("0");
    tf2=new TextField(10);//显示记忆的索引值
    tf2.setEditable(false);
    //实例化所有按钮、设置其前景色并注册**
    b0=new Button("Backspace");
    b0.setForeground(Color.red);
    b0.addActionListener(new Bt());
    b1=new Button("CE");
    b1.setForeground(Color.red);
    b1.addActionListener(new Bt());
    b2=new Button("C");
    b2.setForeground(Color.red);
    b2.addActionListener(new Bt());
    b3=new Button("MC");
    b3.setForeground(Color.red);
    b3.addActionListener(new Bt());
    b4=new Button("MR");
    b4.setForeground(Color.red);
    b4.addActionListener(new Bt());
    b5=new Button("MS");
    b5.setForeground(Color.red);
    b5.addActionListener(new Bt());
    b6=new Button("M+");
    b6.setForeground(Color.red);
    b6.addActionListener(new Bt());
    b7=new Button("7");
    b7.setForeground(Color.blue);
    b7.addActionListener(new Bt());
    b8=new Button("8");
    b8.setForeground(Color.blue);
    b8.addActionListener(new Bt());
    b9=new Button("9");
    b9.setForeground(Color.blue);
    b9.addActionListener(new Bt());
    b10=new Button("/");
    b10.setForeground(Color.red);
    b10.addActionListener(new Bt());
    b11=new Button("sqrt");
    b11.setForeground(Color.blue);
    b11.addActionListener(new Bt());
    b12=new Button("4");
    b12.setForeground(Color.blue);
    b12.addActionListener(new Bt());
    b13=new Button("5");
    b13.setForeground(Color.blue);
    b13.addActionListener(new Bt());
    b14=new Button("6");
    b14.setForeground(Color.blue);
    b14.addActionListener(new Bt());
    b15=new Button("*");
    b15.setForeground(Color.red);
    b15.addActionListener(new Bt());
    b16=new Button("%");
    b16.setForeground(Color.blue);
    b16.addActionListener(new Bt());
    b17=new Button("1");
    b17.setForeground(Color.blue);
    b17.addActionListener(new Bt());
    b18=new Button("2");
    b18.setForeground(Color.blue);
    b18.addActionListener(new Bt());
    b19=new Button("3");
    b19.setForeground(Color.blue);
    b19.addActionListener(new Bt());
    b20=new Button("-");
    b20.setForeground(Color.red);
    b20.addActionListener(new Bt());
    b21=new Button("1/X");
    b21.setForeground(Color.blue);
    b21.addActionListener(new Bt());
    b22=new Button("0");
    b22.setForeground(Color.blue);
    b22.addActionListener(new Bt());
    b23=new Button("+/-");
    b23.setForeground(Color.blue);
    b23.addActionListener(new Bt());
    b24=new Button(".");
    b24.setForeground(Color.blue);
    b24.addActionListener(new Bt());
    b25=new Button("+");
    b25.setForeground(Color.red);
    b25.addActionListener(new Bt());
    b26=new Button("=");
    b26.setForeground(Color.red);
    b26.addActionListener(new Bt());

    //实例化四个面板
    p0=new Panel();
    p1=new Panel();
    p2=new Panel();
    p3=new Panel();
    //创建一个空字符串缓冲区
    str=new StringBuffer();
    //添加面板p0中的组件和设置其在框架中的位置和大小
    p0.add(tf1);
    p0.setBounds(10,25,300,40);
    //添加面板p1中的组件和设置其在框架中的位置和大小
    p1.setLayout(gl1);
    p1.add(tf2);
    p1.add(b0);
    p1.add(b1);
    p1.add(b2);
    p1.setBounds(10,65,300,25);
    //添加面板p2中的组件并设置其的框架中的位置和大小
    p2.setLayout(gl2);
    p2.add(b3);
    p2.add(b4);
    p2.add(b5);
    p2.add(b6);
    p2.setBounds(10,110,40,150);
    //添加面板p3中的组件并设置其在框架中的位置和大小
    p3.setLayout(gl3);//设置p3的布局
    p3.add(b7);
    p3.add(b8);
    p3.add(b9);
    p3.add(b10);
    p3.add(b11);
    p3.add(b12);
    p3.add(b13);
    p3.add(b14);
    p3.add(b15);
    p3.add(b16);
    p3.add(b17);
    p3.add(b18);
    p3.add(b19);
    p3.add(b20);
    p3.add(b21);
    p3.add(b22);
    p3.add(b23);
    p3.add(b24);
    p3.add(b25);
    p3.add(b26);
    p3.setBounds(60,110,250,150);
    //设置框架中的布局为空布局并添加4个面板
    setLayout(null);
    add(p0);
    add(p1);
    add(p2);
    add(p3);
    setResizable(false);//禁止调整框架的大小
    //匿名类关闭窗口
    addWindowListener(new WindowAdapter(){
    public void windowClosing(WindowEvent e1)
    {
    System.exit(0);
    }
    });
    setBackground(Color.lightGray);
    setBounds(100,100,320,280);
    setVisible(true);
    }
    //构造**
    class Bt implements ActionListener
    {
    public void actionPerformed(ActionEvent e2)
    {
    try{
    if(e2.getSource()==b1)//选择"CE"清零
    {
    tf1.setText("0");//把显示屏清零
    str.setLength(0);//清空字符串缓冲区以准备接收新的输入运算数
    }
    else if(e2.getSource()==b2)//选择"C"清零
    {
    tf1.setText("0");//把显示屏清零
    str.setLength(0);
    }
    else if(e2.getSource()==b23)//单击"+/-"选择输入的运算数是正数还是负数
    {
    x=Double.parseDouble(tf1.getText().trim());
    tf1.setText(""+(-x));
    }
    else if(e2.getSource()==b25)//单击加号按钮获得x的值和z的值并清空y的值
    {
    x=Double.parseDouble(tf1.getText().trim());
    str.setLength(0);//清空缓冲区以便接收新的另一个运算数
    y=0d;
    z=0;
    }
    else if(e2.getSource()==b20)//单击减号按钮获得x的值和z的值并清空y的值
    {
    x=Double.parseDouble(tf1.getText().trim());
    str.setLength(0);
    y=0d;
    z=1;
    }
    else if(e2.getSource()==b15)//单击乘号按钮获得x的值和z的值并清空y的值
    {
    x=Double.parseDouble(tf1.getText().trim());
    str.setLength(0);
    y=0d;
    z=2;
    }
    else if(e2.getSource()==b10)//单击除号按钮获得x的值和z的值并空y的值
    {
    x=Double.parseDouble(tf1.getText().trim());
    str.setLength(0);
    y=0d;
    z=3;
    }
    else if(e2.getSource()==b26)//单击等号按钮输出计算结果
    {
    str.setLength(0);
    switch(z)
    {
    case 0 : tf1.setText(""+(x+y));break;
    case 1 : tf1.setText(""+(x-y));break;
    case 2 : tf1.setText(""+(x*y));break;
    case 3 : tf1.setText(""+(x/y));break;
    }
    }
    else if(e2.getSource()==b24)//单击"."按钮输入小数
    {
    if(tf1.getText().trim().indexOf('.')!=-1)//判断字符串中是否已经包含了小数点
    {
    }
    else//如果没数点有小
    {
    if(tf1.getText().trim().equals("0"))//如果初时显示为0
    {
    str.setLength(0);
    tf1.setText((str.append("0"+e2.getActionCommand())).toString());
    }
    else if(tf1.getText().trim().equals(""))//如果初时显示为空则不做任何操作
    {
    }
    else
    {
    tf1.setText(str.append(e2.getActionCommand()).toString());
    }
    }
    y=0d;
    }
    else if(e2.getSource()==b11)//求平方根
    {
    x=Double.parseDouble(tf1.getText().trim());
    tf1.setText("数字格式异常");
    if(x<0)
    tf1.setText("负数没有平方根");
    else
    tf1.setText(""+Math.sqrt(x));
    str.setLength(0);
    y=0d;
    }
    else if(e2.getSource()==b16)//单击了"%"按钮
    {
    x=Double.parseDouble(tf1.getText().trim());
    tf1.setText(""+(0.01*x));
    str.setLength(0);
    y=0d;
    }
    else if(e2.getSource()==b21)//单击了"1/X"按钮
    {
    x=Double.parseDouble(tf1.getText().trim());
    if(x==0)
    {
    tf1.setText("除数不能为零");
    }
    else
    {
    tf1.setText(""+(1/x));
    }
    str.setLength(0);
    y=0d;
    }
    else if(e2.getSource()==b3)//MC为清除内存
    {
    m=0d;
    tf2.setText("");
    str.setLength(0);
    }
    else if(e2.getSource()==b4)//MR为重新调用存储的数据
    {
    if(tf2.getText().trim()!="")//有记忆数字
    {
    tf1.setText(""+m);
    }
    }
    else if(e2.getSource()==b5)//MS为存储显示的数据
    {

    m=Double.parseDouble(tf1.getText().trim());
    tf2.setText("M");
    tf1.setText("0");
    str.setLength(0);
    }
    else if(e2.getSource()==b6)//M+为将显示的数字与已经存储的数据相加要查看新的数字单击MR
    {
    m=m+Double.parseDouble(tf1.getText().trim());
    }
    else//选择的是其他的按钮
    {
    if(e2.getSource()==b22)//如果选择的是"0"这个数字键
    {
    if(tf1.getText().trim().equals("0"))//如果显示屏显示的为零不做操作
    {
    }
    else
    {
    tf1.setText(str.append(e2.getActionCommand()).toString());
    y=Double.parseDouble(tf1.getText().trim());
    }
    }
    else if(e2.getSource()==b0)//选择的是“BackSpace”按钮
    {
    if(!tf1.getText().trim().equals("0"))//如果显示屏显示的不是零
    {
    if(str.length()!=1)
    {
    tf1.setText(str.delete(str.length()-1,str.length()).toString());//可能抛出字符串越界异常
    }
    else
    {
    tf1.setText("0");
    str.setLength(0);
    }
    }
    y=Double.parseDouble(tf1.getText().trim());
    }
    else//其他的数字键
    {
    tf1.setText(str.append(e2.getActionCommand()).toString());
    y=Double.parseDouble(tf1.getText().trim());
    }
    }
    }
    catch(NumberFormatException e){
    tf1.setText("数字格式异常");
    }
    catch(StringIndexOutOfBoundsException e){
    tf1.setText("字符串索引越界");
    }
    }
    }
    public static void main(String args[])
    {
        new Counter();
    }
    }

  • 如何使用LR做DNS压力测试

    2011-07-20 19:15:46

    使用LR输入以下代码,有什么业务需求,自己根据具体情况改代码就行了!(特别说明:选择DNS协议)
    Action()
    {
            char *results = NULL;
            int   rescnt  = 0;

            lr_save_string("DNS地址","DnsServer");        // “DNS地址”使用实际地址替换即可
            lr_save_string("域名", "Hostname");        // “域名”使用实际域名替换即可

            // Perform. DNS Query



            results = (char *) ms_dns_query("DnsQuery",
                            "URL=dns://{DnsServer}",
                            "QueryHost={Hostname}",
                    LAST);

            // List all the results... (if more than one)
            while (*results) {
                    rescnt++;
                    lr_log_message(
                            lr_eval_string("(%d) IP address for {Hostname} is %s"),
                            rescnt,
                            results);
                    results = (char *) ms_dns_nextresult(results);
            }



            return 0;

    }
  • loadrunner-ip欺骗经验总结

    2011-06-05 16:22:32

    网络上介绍如何增加IP欺骗的文章已经很多,这里就不再赘述,只说明下在使用过程中要注意的几个方面:

    1、本地的IP不能设置为“自动获取”,必须指定一个静态IP;
    原因:
    如果设置为“自动获取”,在运行IP Wizard时会弹出错误提示;
       提示信息为:IP向导不支持启用DHCP的网卡。您的卡启用了DHCP或者配置了无效设置。请与系统管理员联系。

    2、添加IP欺骗使用的IP后,会有提示框提示保存IP列表,确定,取消等按钮;建议保存IP列表后再确定完成;
    原因:保存IP列表后,下次使用时,可以直接导入IP列表;也可以直接修改保存的IP列表文件,再导入;

    3、添加IP欺骗,和释放IP,都要重启机器后才会生效;
    原因:重启后,网络配置才会生效;

    4、在controller中使用ip欺骗的注意事项;
    (1)勾选“场景”->“启用IP欺骗器”;
    (2)勾选“工具”->“专家模式”;
    (3)“场景”->“选项”->“常规”->“多个IP地址模式”;
    这个选项一定要与当前场景的模式相匹配,也就是说使用本地虚拟IP测试时需要选中线程方式,使用负载生成器使用虚拟IP测试时需要选中进程方式

    5、设置IP欺骗后,验证其是否生效;
    有两种方法查看:
    (1)可用如下代码段来查看:
    char *ip = lr_get_vuser_ip();
    if (ip)
         lr_output_message("The IP address is %s", ip);
    else
         lr_output_message("IP spoofing disabled");
    注意:如果把上面这一段加入代码中间,第一句要修改下:

    char *ip;(这句放在函数起始部位,对变量ip进行声明)
    ip=lr_get_vuser_ip();(这个和后面的if-else语句一起放在要输出的地方)

    另:这个在generator中是不生效的,所以在回放代码时看到的都是"IP spoofing disabled",在contorller中设置了启用IP欺骗,日志中就可以看到;

    (2)controller的运行页,运行完场景后,在通过、失败的虚拟用户处,右键可显示VUser日志;
    弹出的提示框头几行就有显示当前使用的IP;

    6、使用IP欺骗过程中,会有出现下述问题:
    启用IP欺骗后,运行1个虚拟用户的场景都失败;不启用IP欺骗后,运行场景通过;
    原因:查看失败的虚拟用户,使用的IP地址(查看方法可使用第5点中的方法),在服务器端通过ping等命令查看网络是否互通;
    如果服务器ping不通虚拟IP,说明网络设置有问题,检查网络设置;

  • QC字体大小问题解决方案

    2011-05-25 00:37:51

    在网上找了大概有两个方案:

    第一种:但是这种在实践过程中,有时会提示"Invalid server response",所以也无法修改和添加任何内容。些种方案被否决了。
    1,语言设置
    1.1,开始>控制面板>regional and language options,字体改成是english(united states)
    2,注册表设置
    2.1.输入命入regedit,打开注册表.
    2.2,键值:[HKEY_CURRENT_USER\Software\Mercury Interactive\TestDirector\General
          "TDFontSize"=15(可以自己设定大小)
    3.3.重新打开浏览器.

    第二种
    由于在安装QC10.0的补丁13以前字体都是正常的。打补丁后字体变得很小。通过一些网友的建议。把服务器端的QCClientUI.xco控件更新到安装补丁以前的版本。
    通过这种方法解决了字体很小的问题。
  • QTP自动化测试相关资源列表[摘自TIB自动化测试工作室]

    2011-05-25 00:35:36

    TIB自动化测试工作
    网站:www.AutomationQA.com QQ:1837632674 Email:quicktest#qq.com

    QTP自动化测试相关资源列表

    网站、博客

    1、QTP专业网站

    http://www.advancedqtp.com/

    http://knowledgeinbox.com/

    http://www.learnqtp.com/

    http://relevantcodes.com/

    http://www.intellipro.co.uk/

    http://www.softwareinquisition.com/

    http://www.qtp10.com/

    2、HP官方QTP主页

    https://h10078.www1.hp.com/cda/hpms/display/main/hpms_content.jsp?zn=bto&cp=1-11-127-24^1352_4000_100__

    3、QTP第三方工具Test Design Studio的主页

    http://www.patterson-consulting.net/products/test_design_studio/Default.aspx

    4、QTP WEB测试辅助工具IE Developer Toolbar下载页面

    http://www.microsoft.com/downloads/details.aspx?familyid=e59c3964-672d-4511-bb3e-2d5e1db91038&displaylang=en

    5、QTP论坛

    SQAForums论坛上的QTP版块:

    http://www.sqaforums.com/postlist.php?Cat=0&Board=UBB20

    AdvancedQTP论坛上启动的一个QTP虚拟项目(围绕QTP附带的样例程序Flight开展):

    http://www.advancedqtp.com/forums/index.php/board,5.0.html

    6、自动化测试方面的网站

    http://www.automatedtestinginstitute.com/

    http://safsdev.sourceforge.net/

    http://www.io.com/~wazmo/qa/#test_automation

    QTP项目实战课程测试脚本下载(以Discuz论坛测试为例讲解QTP脚本设计):

    http://files.cnblogs.com/testware/QTP_Training_Scripts.rar

    相关课程:

    http://blog.csdn.net/Testing_is_believing/category/639478.aspx

    《软件自动化测试成功之道》学习资源:

    http://blog.csdn.net/Testing_is_believing/archive/2010/05/27/5628697.aspx

    QTP基础视频(《软件自动化测试成功之道》光盘视频):

    http://www.verycd.com/topics/2823906

    《QTP自动化测试进阶》一书附带的源代码,包含脚本例子、小工具:

    http://download.csdn.net/source/2473429

    ADO教程:

    http://www.w3school.com.cn/ado/index.asp

    QTP读取PDF、测试PDF

    http://files.cnblogs.com/testware/AccessingPDF.rar

    QTP认证考试题目样例:

    选择题

    http://www.softwaretestinggenius.com/categoryDetail.php?catId=147

    描述问答题

    http://www.softwaretestinggenius.com/categoryDetail.php?catId=118

    自动化测试框架

    1、《测试对象级框架 - QTestWare》

    http://blog.csdn.net/Testing_is_believing/archive/2010/01/03/5125592.aspx

    2、《QTP面向对象框架》

    http://blog.csdn.net/Testing_is_believing/archive/2009/12/19/5040680.aspx

    3、《自动化测试框架剖析》

    http://blog.csdn.net/Testing_is_believing/archive/2009/12/20/5042211.aspx

    4、《QTRunner》

    http://blog.csdn.net/Testing_is_believing/archive/2009/12/19/5037830.aspx

    5、《自动化测试框架开发5步法》

    http://blog.csdn.net/Testing_is_believing/archive/2009/12/17/5026712.aspx

    6、《QTP下基于XML+DP的关键字驱动DEMO》

    http://blog.csdn.net/Testing_is_believing/archive/2009/11/29/4900529.aspx

    7、《如何选择自动化测试框架》

    http://blog.csdn.net/Testing_is_believing/archive/2008/06/29/2595477.aspx

    8、《自动化测试框架设计指南》

    http://blog.csdn.net/Testing_is_believing/archive/2008/06/22/2576208.aspx

    9、《QTP的报告管理扩展框架 - ReporterManager》

    http://blog.csdn.net/Testing_is_believing/archive/2008/01/27/2068905.aspx

    10、《透析QTP自动化测试框架SAFFRON》

    http://blog.csdn.net/Testing_is_believing/archive/2008/08/28/2845530.aspx

    11、《Test Automation Frameworks》

    http://safsdev.sourceforge.net/FRAMESDataDrivenTestAutomationFrameworks.htm

    12、《QTP关键字驱动框架 - RelevantCodes[1]One》

    http://blog.csdn.net/Testing_is_believing/archive/2010/03/14/5378979.aspx

    13、《介绍一个QTP基础框架 - SIFL》

    http://blog.csdn.net/Testing_is_believing/archive/2010/03/16/5384390.aspx

    文章

    1、《QTP10调试时查看变量显示空白 - 补丁QTP_00591》

    http://blog.csdn.net/Testing_is_believing/archive/2010/02/28/5333934.aspx

    2、《HP发布QTP的新补丁支持FireFox3.5》

    http://blog.csdn.net/Testing_is_believing/archive/2010/01/10/5170279.aspx

    3、《QTP10的Reporter对象》

    http://blog.csdn.net/Testing_is_believing/archive/2010/01/02/5121064.aspx

    4、《QTP10的Tips.txt文件》

    http://blog.csdn.net/Testing_is_believing/archive/2009/12/13/4996879.aspx

    5、《HP发布了针对QTP 10的Web2.0 Feature Pack》

    http://blog.csdn.net/Testing_is_believing/archive/2009/11/22/4851752.aspx

    6、《QTP的智能识别(Smart Identification)过程》

    http://blog.csdn.net/Testing_is_believing/archive/2010/02/01/5277890.aspx

    7、《如何让你的QTP脚本执行效率更高》

    http://blog.csdn.net/Testing_is_believing/archive/2009/12/19/5040174.aspx

    8、《用户体验测试的自动化实现》

    http://blog.csdn.net/Testing_is_believing/archive/2008/05/27/2488303.aspx

    9、《使用QTP进行非GUI的自动化测试》

    http://blog.csdn.net/Testing_is_believing/archive/2010/03/14/5379213.aspx

    10、《QTP调用外部应用程序的4种方法》

    http://blog.csdn.net/Testing_is_believing/archive/2010/03/18/5394213.aspx

    11、stickyminds网站上关于QTP和自动化测试的一些文章:

    <p style="margin-top: 5px; margin-right: auto; margin-bottom: 5px; margin-left: auto; line-height: 1

  • 六种测试工作量的估算方法

    2009-07-23 15:44:20

    测试项目管理中或编写测试计划时,经常需要对某个测试工作进行工作量的预算,很多时候都是凭个人的工作经验进行估算的,如能结合一些常规的估算方法,有助于估算的精确度。

      以下是网上找到的一些常规的估算测试工作量的方法:

      1、 Ad-hoc方法

      这种方法下的测试工作量不基于任何确定的期限。工作一直继续直到达到一些由管理或市场人员预先定下的时间表。或者,一直到用完了预算的经费。

      这种情况普遍存在于非常不成熟的组织,并且时常有100%的错误差数。

      2、开发时间的百分比法Percentage of development time。

      这个方法的基本前提是测试工作量依赖于开发时间/开发工作量。首先,开发工作量使用例如LOC或FP方法被估算出来,然后使用一些探索性的方法来限制测试的工作量。  这种方法变化比较大而且通常基于以前的经验。

      通常预留项目的总花费时间的35%给测试。? 5-7%给组件和集成测试? 18-20%给系统测试? 10%给接收测试(或回归测试等)

      3、类比法(经验值法或历史数据法)

      根据以前或相似项目(主要在项目性质,领域,规模上有相似)所积累的经验或历史数据来估算工作量。类比法估计结果的精确度取决于历史项目数据的完整性和准确度,因此,用好类比法的前提条件之一是组织建立起较好的项目后评价与分析机制,对历史项目的数据分析是可信赖的。需要收集以下相关的历史数据:? 在设计和实现阶段花费的时间? 测试工作的规模,例如用户需求的数量,页面数,功能点? 数据样式,例如实体,字段的数量? 屏幕或字段数量? 测试对象的规模,例如KLOC

      4、WBS(work breakdown structure)估算法

      将项目或产品分解为具体的工作,然后分别对各个工作进行时间估算,最终求和得出项目或产品的测试工作量/时间。

      5、Delphi法

      Delphi法是最流行的专家评估技术,在没有历史数据的情况下,这种方式可以减轻估算的偏差。Delphi法鼓励参加者就问题相互讨论。这个技术,要求有多种相关经验人的参与,互相说服对方……

      Delphi法的步骤是:1、协调人向各专家提供项目规格和估计表格;2、协调人召集小组会各专家讨论与规模相关的因素;3、各专家匿名填写迭代表格;4、协调人整理出一个估计总结,以迭代表的形式返回专家;5、协调人召集小组会,讨论较大的估计差异;6、专家复查估计总结并在迭代表上提交另一个匿名估计;7、重复4-6, 直到达到一个最低和最高估计的一致。

      6、PERT估计法

      PERT对各个项目活动的完成时间按三种不同情况估计:一个产品的期望规模,一个最低可能估计,一个最高可能估计。用这三个估计用来得到一个产品期望规模和标准偏差的Pert 统计估计。Pert 估计可得到代码行的期望值E, 和标准偏差SD。

  • Loadrunner函数中文解释

    2007-12-19 16:46:27

     

    web_url

    语法:

    Int Web_url(const char *name, const char * url, <Lists of Attributes>, [EXTRARES,<Lists of Resource Attributes>,LAST)

    返回值

    成功时返回LR_PASS (0),失败时返回 LR_FAIL (1)。

    参数:

    Name:VuGen中树形视图中显示的名称,在自动事务处理中也可以用做事务的名称。

    url:页面url地址。

    List of Attributes

    EXTRARES:分隔符,标记下一个参数是资源属性的列表了。

    List of Resource Attributes

    LAST:属性列表结束的标记符。

    说明

    Web_url根据函数中的URL属性加载对应的URL,不需要上下文。

    只有VuGen处于URL-based或者HTML-based(此时A scrīpt containing explicit URLs only选项被选中时)的录制模式时,web_url才会被录制到。

    可以使用web_url 模拟从FTP服务器上下载文件。web_url 函数会使FTP服务器执行文件被真实下载时的操作。除非手工指定了"FtpAscii=1",下载会以二进制模式完成。

    在录制选项中,Toos—Recording Option下,Recording选项中,有一个Advanced HTML选项,可以设置是否录制非HTML资源,只有选择了“Record within the current scrīpt step”时,List of Resource Attributes才会被录制到。非HTML资源的例子是gif和jpg图象文件。

    通过修改HTTP头可以传递给服务器一些附加的请求信息。使用HTTP头允许请求中包含其他的内容类型(Content_type),象压缩文件一样。还可以只请求特定状态下的web页面。

    所有的Web Vusers ,HTTP模式下的WAP Vusers或者回放模式下的Wireless Session Protocol(WSP),都支持web_url函数。

    web_image

    语法:

    Int web_image (const char *StepName, <List of Attributes>, [EXTRARES, <List of Resource Attributes>,] LAST );

    返回值

    成功时返回LR_PASS (0),失败时返回 LR_FAIL (1)。

    参数:

    StepName:VuGen中树形视图中显示的名称,在自动事务处理中也可以用做事务的名称。

    List of Attributes(服务器端和客户端映射的图片):SRC属性是一定会被录制到的,其他的ALT、Frame、TargetFrame、Ordinal则是有的话会被录制到。

    1、ALT:描述图象的元素。用鼠标指向图象时,所浮出来的文字提示。

    2、SRC:描述图象的元素,可以是图象的文件名. 如: button.gif。也可以使用SRC/SFX来指定图象路径的后缀。所有拥有相同此后缀的字符串都会被匹配到。

    3、Frame:录制操作时所在的Frame的名称。

    4、TargetFrame:见List of Attributes的同名参数。

    5、Ordinal:参见Web_link的同名参数。

    List of Attributes(客户端映射的图片):

    1、AreaAlt:鼠标单击区域的ALT属性。 

    2、AreaOrdinal:鼠标单击区域的顺序号。 

    3、MapName:图象的映射名。 

    List of Attributes(服务器端映射的图片):尽管点击坐标不属于属性,但还是以属性的格式来使用。 

    1、Xcoord:点击图象时的X坐标。

    2、Ycoord:点击图象时的Y坐标。

    EXTRARES:分隔符,标记下一个参数是资源属性的列表了。

    List of Resource Attributes:参见List of Resource Attributes一节。

    LAST:属性列表结束的标记符。

    说明

    web_image模拟鼠标在指定图片上的单击动作。此函数必须在有前置操作的上下文中使用。 

    在Toos—Recording Option,如果录制级别设为基于HMTL的录制方式时,web_image才会被录制到。 

    web_image支持客户端(client-side)和服务器端server-side的图片映射。 

    在录制选项中,Toos—Recording Option下,Recording选项中,有一个Advanced HTML选项,可以设置是否录制非HTML资源,只有选择了“Record within the current scrīpt step”时,List of Resource Attributes才会被录制到。非HTML资源的例子是gif和jpg图象文件。

    通过修改HTTP头可以传递给服务器一些请求附加信息。使用HTTP头允许请求中包含内容,如同压缩文件一样。还可以只请求特定状态的web页面。

    web_image支持Web虚拟用户,不支持WAP虚拟用户。

    例子

    下面的例子模拟用户单击Home图标以回到主页(黑体部分):

    web_url("my_home", "URL=http://my_home/", LAST)

    web_link("Employees", "Text=Employees", LAST)

    web_image("Home.gif", "SRC=../gifs/Buttons/Home.gif", LAST)

    web_link("Library", "Text=Library", LAST)

    web_image("Home.gif", "SRC=../../gifs/buttons/Home.gif", LAST)

    下面的例子模拟用户在客户端映射的图片上单击:

    web_image("dpt_house.gif", 

           "Src=../gifs/dpt_house.gif", 

           "MapName=dpt_house", 

           "AreaOrdinal=4", 

           LAST)

    下面的例子模拟用户在服务端映射的图片上单击:

    web_image("The Web Developer's Virtual Library", 

           "Alt=The Web Developer's Virtual Library", 

           "Ordinal=1", 

           "XCoord=91", 

           "YCoord=17", 

           LAST)

    下面是一个使用文件名后缀的例子:它指定了dpt_house.gif作为后缀,所以象../gifs/dpt_house.gif、/gifs/dpt_house.gif、gifs/dpt_house.gif、/dpt_house.gif等都会匹配到。

    web_image("dpt_house.gif",

            "Src/sfx=dpt_house.gif", LAST)

    web_link

    语法:

    Int web_link (const char *StepName, <List of Attributes>, [EXTRARES, <List of Resource Attributes>,] LAST )

    返回值

    成功时返回LR_PASS (0),失败时返回 LR_FAIL (1)。

    参数:

    StepName:VuGen中树形视图中显示的名称,在自动事务设置中也被用做事务名称。

    List of Attributes:支持下列的属性:

    1.      Text:超链接中的文字,必须精确匹配。

    2.      Frame:录制操作时所在的Frame的名称。

    3.      TargetFrame、ResourceByteLimit:见List of Attributes一节。

    4.      Ordinal:如果用给出的属性(Attributes)筛选出的元素不唯一,那么VuGen使用此属性来指定其中的一个。例如:“SRC=abc.gif”,“Ordinal=3”标记的是SRC的值是“abc.gif”的第3张图片。

    EXTRARES:表明下面的参数将会是list of resource attributes了。

    LAST:结尾标示符。

    说明

    模拟鼠标在由若干个属性集合描述的链接上进行单击。此函数必须在前置动作的上下文中才可以执行。

    web_link 仅仅在基于HTML的录制方式中才会被VuGen捕捉到。

    非HTML生成的资源的例子有.gif 和.jpg图像。对于List of Resource Attributes参数来说,仅仅当Recording Options--Recording --HTML-based scrīpt-- Record within the current scrīpt step选项被选中时,它们才会被插入到代码中。

    可以通过改变HTTP头信息给服务器传递一些附加信息。使用HTTP头信息可以,允许响应体中包含其他的内容类型(Content-Type),例如压缩文件,或者只有满足了特定的状态才去请求web页。

    此函数值支持Web虚拟用户,不支持WAP虚拟用户。

    web_submmit_form

    语法:

    Int web_submit_form (const char *StepName, <List of Attributes>, <List of Hidden Fields>, ITEMDATA, <List of Data Fields>, [ EXTRARES, <List of Resource Attributes>,] LAST ); 

    返回值

    成功时返回LR_PASS (0),失败时返回 LR_FAIL (1)。

    参数:

    StepName:Form的名字。VuGen中树形视图中显示的名称,在自动事务处理中也可以用做事务的名称。

    List of Attributes:支持以下属性:

    1.      Action:Form中的ACTION属性,指定了完成Form中的操作用到的URL。也可以使用“Action/sfx” 表示使用此后缀的所有Action。

    2.      Frame:录制操作时所在的Frame的名称。

    3.      TargetFrame、ResourceByteLimit:见List of Attributes的同名参数。

    4.      Ordinal:参见Web_link的同名参数。

    VuGen通过记录数据域唯一的标识每个Form。如果这样不足以识别Form,VuGen会记录Action 属性。如果还不足以识别,则会记录Ordinal 属性,这种情况下不会记录Action属性。

    List of Hidden Fields:补充属性(Serves)。 通过此属性可以使用一串隐含域来标识Form。使用下面的格式:

    STARTHIDDENS, 

    "name=n1", "value=v1", ENDITEM, 

    "name=n2", "value=v2", ENDITEM, 

    ENDHIDDENS,

    List of Data Fields

    Data项用来标识form。Form是通过属性和数据来共同识别的。

    使用下面的格式来表示数据域列表

    "name=n1", "value=v1", ENDITEM,

    "name=n2", "value=v2", ENDITEM,

    ITEMDATA:Form中数据和属性的分隔符。

    EXTRARES:一个分隔符,标记下一个参数是资源属性的列表了。

    List of Resource Attributes:参见List of Resource Attributes一节。

    LAST:属性列表结束的标记符。

    说明

    web_submit_form 函数用来提交表单。此函数可能必须在前一个操作的上下文中执行。在Toos—Recording Option,只有录制级别设为基于HMTL的录制方式,web_image才会被录制到。 

    在录制选项中,Toos—Recording Option下,Recording选项中,有一个Advanced HTML选项,可以设置是否录制非HTML资源,只有选择了“Record within the current scrīpt step”时,List of Resource Attributes才会被录制到。非HTML资源的例子是gif和jpg图象文件。

    通常情况下,如果录制了web_submit_form 函数,VuGen会把“name”和“value”一起录制到ITEMDATA属性中。如果不想在脚本中以明文显示“value”,可以对它进行加密。把“Value”改为“EncryptedValue”,然后把录制到的值改为加密后的值。

    例如:可以把 "Name=grpType", "Value=radRoundtrip", ENDITEM

    改为:"Name=grpType", EncryptedValue=409e41ebf102f3036b0549c799be3609", ENDITEM

    如果你完整的安装了LoadRunner,那么打开开始菜单--Mercury LoadRunner—Tools--Password Encoder,这个小工具是用来加密字符串的。把需要加密的值粘贴到Password一栏,再点Generate按钮。加密后的字符串会出现在Encoded string框中。接着点Copy按钮,然后把它粘贴到脚本中,覆盖原来显示的“Value”。

    加密的另一种方法时使用lr_decrypt函数。方法:选择整个字符串,例如“Value=radRoundtrip”(注意不要选择引号),右击鼠标,选择Encrypt string选现,脚本会变为:

    "Name=grpType", lr_decrypt("40d176c46f3cf2f5fbfaa806bd1bcee65f0371858163"), ENDITEM, 

    web_submit_form支持Web虚拟用户,不支持WAP虚拟用户。 

    例子:

    下面的例子中,web_submit_form 函数的名字是“employee.exe”。此函数提交了一个请求,此请求包含雇员信息John Green。此函数没有使用属性(Attributes)是因为通过数据项已经能唯一的标识这个Form了。

  • Acronis TrueImage Server 8.0 简体中文注册版

    2007-12-19 16:46:19

    RL8BM-ELU6N-BFPJL-D6YCM-USGP7
Open Toolbar