﻿<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>杭州日辉信息技术有限公司</title>
	<atom:link href="http://www.fastpoint.cn/index.php/feed" rel="self" type="application/rss+xml" />
	<link>http://www.fastpoint.cn</link>
	<description>BPO及解决方案专家</description>
	<lastBuildDate>Thu, 01 Sep 2011 04:47:36 +0000</lastBuildDate>
	<language>zh</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Test the truth</title>
		<link>http://www.fastpoint.cn/index.php/archives/569</link>
		<comments>http://www.fastpoint.cn/index.php/archives/569#comments</comments>
		<pubDate>Sat, 06 Aug 2011 16:43:51 +0000</pubDate>
		<dc:creator>fastpoint</dc:creator>
				<category><![CDATA[未分类]]></category>

		<guid isPermaLink="false">http://www.fastpoint.cn/?p=569</guid>
		<description><![CDATA[Test the truth]]></description>
			<content:encoded><![CDATA[<p>Test the truth</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fastpoint.cn/index.php/archives/569/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>60 New ideas</title>
		<link>http://www.fastpoint.cn/index.php/archives/567</link>
		<comments>http://www.fastpoint.cn/index.php/archives/567#comments</comments>
		<pubDate>Sat, 06 Aug 2011 16:40:35 +0000</pubDate>
		<dc:creator>fastpoint</dc:creator>
				<category><![CDATA[未分类]]></category>

		<guid isPermaLink="false">http://www.fastpoint.cn/?p=567</guid>
		<description><![CDATA[60 New ideas]]></description>
			<content:encoded><![CDATA[<p>60 New ideas</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fastpoint.cn/index.php/archives/567/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>黑客曝光iPad和iPhone软件漏洞 转</title>
		<link>http://www.fastpoint.cn/index.php/archives/406</link>
		<comments>http://www.fastpoint.cn/index.php/archives/406#comments</comments>
		<pubDate>Fri, 05 Aug 2011 16:39:40 +0000</pubDate>
		<dc:creator>fastpoint</dc:creator>
				<category><![CDATA[未分类]]></category>

		<guid isPermaLink="false">http://www.fastpoint.cn/?p=406</guid>
		<description><![CDATA[黑客曝光iPad和iPhone软件漏洞 转 发布时间：2011-07-13 10:56:25 大洋网-广州日报 　据路透社报道，安全专家表示，黑客曝光苹果软件存在的一个漏洞，这点或被犯罪分子利用，远程操控iPhone、iPad和iPod Touch等设备。苹果系统存在安全隐患上周三曝光，www.jailbreakme.com网站发布代码，苹果用户可“越狱”更改iOS操作系统。 一些苹果用户选择将设备“越狱”，以便下载和运行苹果未授权的软件。安全专家警告称，黑客犯罪分子可能也会下载这一代码，用其寻找iOS安全漏洞，并设计出一款恶意软件。 网络安全公司Websense高级研究员罗纳德（Patrik Runald）说：“如果你是恶意攻击者，这没什么不可能。”苹果尚未发布iOS更新软件，防止利用该漏洞的恶意软件攻击用户设备。 苹果发言人穆勒（Trudy Muller）表示，公司知道该问题，“我们正在研发补丁程序，用户将在即将发布的更新软件中获得补丁。”]]></description>
			<content:encoded><![CDATA[<h1 style="text-align: center;">黑客曝光iPad和iPhone软件漏洞 转</h1>
<p style="text-align: center;">发布时间：2011-07-13 10:56:25 大洋网-广州日报</p>
<p>　据路透社报道，安全专家表示，黑客曝光苹果软件存在的一个漏洞，这点或被犯罪分子利用，远程操控iPhone、iPad和iPod Touch等设备。苹果系统存在安全隐患上周三曝光，www.jailbreakme.com网站发布代码，苹果用户可“越狱”更改iOS操作系统。</p>
<p>一些苹果用户选择将设备“越狱”，以便下载和运行苹果未授权的软件。安全专家警告称，黑客犯罪分子可能也会下载这一代码，用其寻找iOS安全漏洞，并设计出一款恶意软件。</p>
<p>网络安全公司Websense高级研究员罗纳德（Patrik Runald）说：“如果你是恶意攻击者，这没什么不可能。”苹果尚未发布iOS更新软件，防止利用该漏洞的恶意软件攻击用户设备。</p>
<p>苹果发言人穆勒（Trudy Muller）表示，公司知道该问题，“我们正在研发补丁程序，用户将在即将发布的更新软件中获得补丁。”</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fastpoint.cn/index.php/archives/406/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>卡巴斯基列PC十大软件漏洞：Adobe位列榜首 转</title>
		<link>http://www.fastpoint.cn/index.php/archives/404</link>
		<comments>http://www.fastpoint.cn/index.php/archives/404#comments</comments>
		<pubDate>Fri, 05 Aug 2011 16:35:22 +0000</pubDate>
		<dc:creator>fastpoint</dc:creator>
				<category><![CDATA[未分类]]></category>

		<guid isPermaLink="false">http://www.fastpoint.cn/?p=404</guid>
		<description><![CDATA[2011年05月22日12:12腾讯科技 腾讯科技讯（观海）北京时间5月22日消息，据国外媒体 报道，卡巴斯基实验室(Kaspersky Lab)日前公布的个人电脑十大软件漏洞中，Adobe Reader/Acrobat SING “uniqueName” 缓冲区溢出漏洞(Buffer Overflow Vulnerability)位居榜单首位。Adobe Reader/Acrobat和Flash的漏洞位列榜单前三位。 以下为卡巴斯基实验室列举的个人电脑十大软件漏洞： 漏洞代码 漏洞名称 1 SA 38805 Adobe Reader/Acrobat SING “uniqueName”缓冲区溢出漏洞(Buffer Overflow Vulnerability) 2、SA 37255 Adobe Flash Player多个漏洞 3、SA 35377 Adobe Flash Player多个漏洞 4、SA 38547 Sun Java JDK/JRE/SDK多个漏洞 5、SA 31744 Sun Java JDK/JRE/SDK多个漏洞 6、SA 34572 Apple QuickTime多个漏洞 7、SA 39272 Winamp MIDI Timestamp解析缓冲区溢出漏洞(Parsing Buffer Overflow Vulnerability) <a href="http://www.fastpoint.cn/index.php/archives/404">more</a>]]></description>
			<content:encoded><![CDATA[<h1 style="text-align: center;">2011年05月22日12:12<a href="http://tech.qq.com/" target="_blank">腾讯科技</a></h1>
<p><strong>腾讯科技讯</strong>（观海）北京时间5月22日消息，据国外媒体 报道，卡巴斯基实验室(Kaspersky Lab)日前公布的个人电脑十大软件漏洞中，Adobe Reader/Acrobat SING “uniqueName” 缓冲区溢出漏洞(Buffer Overflow Vulnerability)位居榜单首位。Adobe Reader/Acrobat和Flash的漏洞位列榜单前三位。</p>
<p><strong>以下为卡巴斯基实验室列举的个人电脑十大软件漏洞：</strong></p>
<p>漏洞代码 漏洞名称</p>
<p>1 SA 38805 Adobe Reader/Acrobat SING “uniqueName”缓冲区溢出漏洞(Buffer Overflow Vulnerability)</p>
<p>2、SA 37255 Adobe Flash Player多个漏洞</p>
<p>3、SA 35377 Adobe Flash Player多个漏洞</p>
<p>4、SA 38547 Sun Java JDK/JRE/SDK多个漏洞</p>
<p>5、SA 31744 Sun Java JDK/JRE/SDK多个漏洞</p>
<p>6、SA 34572 Apple QuickTime多个漏洞</p>
<p>7、SA 39272 Winamp MIDI Timestamp解析缓冲区溢出漏洞(Parsing Buffer Overflow Vulnerability)</p>
<p>8、SA 29320 Microsoft Office OneNote URI处理漏洞(Handling Vulnerability)</p>
<p>9、SA 39375 Adobe Shockwave Player多个漏洞</p>
<p>10、SA 37690 Adobe Reader/Acrobat多个漏洞</p>
<p>或许有人会问，为什么索尼以及PSN网络并未列入榜单？该榜单只显示了在个人电脑中容易被攻击的软件，尽管PSN网络并不只是通过PlayStation 3游戏机进行访问，还可以通过电脑进行访问，但PSN网络是基于网络的服务。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fastpoint.cn/index.php/archives/404/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>杭州日辉信息技术有限公司信息技术 &#8211; 杂说映射&amp;影射（对象捕捉中的处理技术） [Fastpoint]</title>
		<link>http://www.fastpoint.cn/index.php/archives/401</link>
		<comments>http://www.fastpoint.cn/index.php/archives/401#comments</comments>
		<pubDate>Fri, 05 Aug 2011 16:07:54 +0000</pubDate>
		<dc:creator>fastpoint</dc:creator>
				<category><![CDATA[未分类]]></category>

		<guid isPermaLink="false">http://www.fastpoint.cn/?p=401</guid>
		<description><![CDATA[杭州日辉信息技术有限公司信息技术 - 杂说映射&#38;影射（对象捕捉中的处理技术） [Fastpoint] 2004年在太原做项目的时候，经常听我们的系分说一个名词“傻用户”，然后他说起一些“傻用户”做的傻事的时候，大家都在狂笑。因为工作关系我跟 系分需要经常沟通和交流，系分说过这么一段话“让傻用户活跃的团队是失败的，最好的处理方式就是让他们保持有限的沉默，并且一直努力维护着它的平衡”，我 觉得当时听了挺震撼的，所以记忆特别深刻。为什么说这件事情，是因为曾经有段时间，某个公司的产品一直把我当成了“傻用户”，后来经历了同系列产品研发我 才知道，这一切的一切都是有特别的设计深意的。 我们经常听说功能级自动化测试工具有个非常好用的技术，即对象的映射，例如在Winrunner或者QuickTestPro中对识别出的 Object对象，根据外表、交互性形式重新映射为Windows的标准对象，以期更好的操作处理它。可能有很多朋友并不明白这个处理动作，我用 QuickTestPro来做一个示范： 1.首先打开QuickTestPro的tools菜单下的红色框选项目   2.在“Environment”中选择Standard Windows环境及环境插件模式，因为QuickTestPro不能对其他环境模式做重定义动作，即所谓的“映射”，当“User-Defined”被Enable的时候，充分说明了这个问题   3.点击“User-Defined”进入新的窗口，其实这块的处理完全继承与Winrunner，算不上什么功能创新   4.蓝框中显示的是QuickTestPro已经确定的一些比较常见的“自定义”控件组，这些都不属于Windows的标准控件，仅仅是经常使用而已，这里我们需要使用Windows自带的“写字板”来做个示范   5.这次我们对空色框选位置进行一次map，操作著名的“手”按钮，将手光标放在红色框选内任意位置，最后出现   6.当classname被填充的时候，你自己感觉需要被map的控件类似于哪种windows标准控件，就大胆的操作吧，这里完全靠 QuickTestPro自己的对象内核验证机制做校验，你不用担心会出现系统崩溃的事情，最后别忘了操作“Add”按钮加入这次map动作。顺利的话， 当你再次进行被测试对象识别的时候，会有个标准windows控件图标暂时欺骗你一下，这也直接给出一个让初学者挠头的“三色块”强的多了。   这里需要说明的是，“Mapping”的翻译成“映射”是正确的，如同Drive可以被翻译成马车或者计算机中的驱动器一样。令我反感的是，国内催 生的大批的“机械式翻译家”只是从字面做了翻译而未及其里，几乎可以肯定这些人根本就没有严谨的针对这些关键词做过一丁点的体验，相反台湾的技术翻译就人 性化得多(例如Object翻译成“物件”比“对象”更能说明一些问题）。那么什么是Map映射，这里我展示一下TestMice的映射表： Html Element TestMice Maping TestMice Class Script Operational Browser WebTestBrowser Browser(“Google”,5) Get\Set\Check Page WebTestPage Page(“Google”,5) Get\Set\Check &#60;from&#62; Form WebTestForm Form(“…”) Get\Set\Check &#60;frame&#62; Frame WebTestButton Frame(“…”) Get\Set\Check <a href="http://www.fastpoint.cn/index.php/archives/401">more</a>]]></description>
			<content:encoded><![CDATA[<h1 style="text-align: center;" align="left"><strong>杭州日辉信息技术有限公司信息技术 -<br />
杂说映射&amp;影射（对象捕捉中的处理技术） [Fastpoint]</strong><strong></strong></h1>
<p align="left">2004年在太原做项目的时候，经常听我们的系分说一个名词“傻用户”，然后他说起一些“傻用户”做的傻事的时候，大家都在狂笑。因为工作关系我跟 系分需要经常沟通和交流，系分说过这么一段话“让傻用户活跃的团队是失败的，最好的处理方式就是让他们保持有限的沉默，并且一直努力维护着它的平衡”，我 觉得当时听了挺震撼的，所以记忆特别深刻。为什么说这件事情，是因为曾经有段时间，某个公司的产品一直把我当成了“傻用户”，后来经历了同系列产品研发我 才知道，这一切的一切都是有特别的设计深意的。</p>
<p align="left">我们经常听说功能级自动化测试工具有个非常好用的技术，即对象的映射，例如在Winrunner或者QuickTestPro中对识别出的 Object对象，根据外表、交互性形式重新映射为Windows的标准对象，以期更好的操作处理它。可能有很多朋友并不明白这个处理动作，我用 QuickTestPro来做一个示范：</p>
<p align="left">1.首先打开QuickTestPro的tools菜单下的红色框选项目</p>
<p align="left"> <img class="alignnone" src="http://www.fastpoint.cn/wp-content/uploads/2011/08/7002.jpg" alt="" /></p>
<p align="left">2.在“Environment”中选择Standard Windows环境及环境插件模式，因为QuickTestPro不能对其他环境模式做重定义动作，即所谓的“映射”，当“User-Defined”被Enable的时候，充分说明了这个问题</p>
<p align="left"> <img class="alignnone" src="http://www.fastpoint.cn/wp-content/uploads/2011/08/7003.jpg" alt="" width="256" height="375" /></p>
<p align="left">3.点击“User-Defined”进入新的窗口，其实这块的处理完全继承与Winrunner，算不上什么功能创新</p>
<p align="left"> <img class="alignnone" src="http://www.fastpoint.cn/wp-content/uploads/2011/08/7004.jpg" alt="" /></p>
<p align="left">4.蓝框中显示的是QuickTestPro已经确定的一些比较常见的“自定义”控件组，这些都不属于Windows的标准控件，仅仅是经常使用而已，这里我们需要使用Windows自带的“写字板”来做个示范</p>
<p align="left"> <img class="alignnone" src="http://www.fastpoint.cn/wp-content/uploads/2011/08/7005.jpg" alt="" width="321" height="340" /></p>
<p align="left">5.这次我们对空色框选位置进行一次map，操作著名的“手”按钮，将手光标放在红色框选内任意位置，最后出现</p>
<p align="left"> <img class="alignnone" src="http://www.fastpoint.cn/wp-content/uploads/2011/08/7006.jpg" alt="" /></p>
<p align="left">6.当classname被填充的时候，你自己感觉需要被map的控件类似于哪种windows标准控件，就大胆的操作吧，这里完全靠 QuickTestPro自己的对象内核验证机制做校验，你不用担心会出现系统崩溃的事情，最后别忘了操作“Add”按钮加入这次map动作。顺利的话， 当你再次进行被测试对象识别的时候，会有个标准windows控件图标暂时欺骗你一下，这也直接给出一个让初学者挠头的“三色块”强的多了。</p>
<p align="left"> <img class="alignnone" src="http://www.fastpoint.cn/wp-content/uploads/2011/08/7007.jpg" alt="" /></p>
<p align="left">这里需要说明的是，“Mapping”的翻译成“映射”是正确的，如同Drive可以被翻译成马车或者计算机中的驱动器一样。令我反感的是，国内催 生的大批的“机械式翻译家”只是从字面做了翻译而未及其里，几乎可以肯定这些人根本就没有严谨的针对这些关键词做过一丁点的体验，相反台湾的技术翻译就人 性化得多(例如Object翻译成“物件”比“对象”更能说明一些问题）。那么什么是Map映射，这里我展示一下TestMice的映射表：</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="155">
<p align="center"><strong>Html Element</strong></p>
</td>
<td valign="top" width="85">
<p align="center"><strong>TestMice </strong></p>
<p align="center"><strong>Maping</strong></p>
</td>
<td valign="top" width="119">
<p align="center"><strong>TestMice Class</strong></p>
</td>
<td valign="top" width="140">
<p align="center"><strong>Script</strong></p>
</td>
<td valign="top" width="92">
<p align="center"><strong>Operational</strong></p>
</td>
</tr>
<tr>
<td valign="top" width="155"></td>
<td valign="top" width="85">
<p align="left">Browser</p>
</td>
<td valign="top" width="119">
<p align="left">WebTestBrowser</p>
</td>
<td valign="top" width="140">
<p align="left">Browser(“Google”,5)</p>
</td>
<td valign="top" width="92">
<p align="left">Get\Set\Check</p>
</td>
</tr>
<tr>
<td valign="top" width="155"></td>
<td valign="top" width="85">
<p align="left">Page</p>
</td>
<td valign="top" width="119">
<p align="left">WebTestPage</p>
</td>
<td valign="top" width="140">
<p align="left">Page(“Google”,5)</p>
</td>
<td valign="top" width="92">
<p align="left">Get\Set\Check</p>
</td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;from&gt;</p>
</td>
<td valign="top" width="85">
<p align="left">Form</p>
</td>
<td valign="top" width="119">
<p align="left">WebTestForm</p>
</td>
<td valign="top" width="140">
<p align="left">Form(“…”)</p>
</td>
<td valign="top" width="92">
<p align="left">Get\Set\Check</p>
</td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;frame&gt;</p>
</td>
<td valign="top" width="85">
<p align="left">Frame</p>
</td>
<td valign="top" width="119">
<p align="left">WebTestButton</p>
</td>
<td valign="top" width="140">
<p align="left">Frame(“…”)</p>
</td>
<td valign="top" width="92">
<p align="left">Get\Set\Check</p>
</td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;iframe&gt;</p>
</td>
<td valign="top" width="85"></td>
<td valign="top" width="119"></td>
<td valign="top" width="140"></td>
<td valign="top" width="92"></td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;frameset&gt;</p>
</td>
<td valign="top" width="85"></td>
<td valign="top" width="119"></td>
<td valign="top" width="140"></td>
<td valign="top" width="92"></td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;img&gt;</p>
</td>
<td valign="top" width="85">
<p align="left">Image</p>
</td>
<td valign="top" width="119">
<p align="left">WebTestImage</p>
</td>
<td valign="top" width="140">
<p align="left">Image(“…”)</p>
</td>
<td valign="top" width="92">
<p align="left">Get\Set\Check</p>
</td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;a&gt;</p>
</td>
<td valign="top" width="85">
<p align="left">Link</p>
</td>
<td valign="top" width="119">
<p align="left">WebTestLink</p>
</td>
<td valign="top" width="140">
<p align="left">Link(“…”,5)</p>
</td>
<td valign="top" width="92">
<p align="left">Get\Set\Check</p>
</td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;input type=button&gt;</p>
</td>
<td valign="top" width="85">
<p align="left">Button</p>
</td>
<td valign="top" width="119">
<p align="left">WebTestButton</p>
</td>
<td valign="top" width="140">
<p align="left">Button(“…”,5)</p>
</td>
<td valign="top" width="92">
<p align="left">Get\Set\Check</p>
</td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;input type=reset&gt;</p>
</td>
<td valign="top" width="85"></td>
<td valign="top" width="119"></td>
<td valign="top" width="140"></td>
<td valign="top" width="92"></td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;input type=submit&gt;</p>
</td>
<td valign="top" width="85"></td>
<td valign="top" width="119"></td>
<td valign="top" width="140"></td>
<td valign="top" width="92"></td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;input type=checkbox&gt;</p>
</td>
<td valign="top" width="85">
<p align="left">CheckBox</p>
</td>
<td valign="top" width="119">
<p align="left">WebTestCheckBox</p>
</td>
<td valign="top" width="140">
<p align="left">CheckBox(“…”)</p>
</td>
<td valign="top" width="92">
<p align="left">Get\Set\Check</p>
</td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;input type=text&gt;</p>
</td>
<td valign="top" width="85">
<p align="left">TextBox</p>
</td>
<td valign="top" width="119">
<p align="left">WebTestTextBox</p>
</td>
<td valign="top" width="140">
<p align="left">TextBox(“…”)</p>
</td>
<td valign="top" width="92">
<p align="left">Get\Set\Check</p>
</td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;input type=image&gt;</p>
</td>
<td valign="top" width="85"></td>
<td valign="top" width="119"></td>
<td valign="top" width="140"></td>
<td valign="top" width="92"></td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;input type=password&gt;</p>
</td>
<td valign="top" width="85"></td>
<td valign="top" width="119"></td>
<td valign="top" width="140"></td>
<td valign="top" width="92"></td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;input type=radio&gt;</p>
</td>
<td valign="top" width="85">
<p align="left">RadioBox</p>
</td>
<td valign="top" width="119">
<p align="left">WebTestRadioBox</p>
</td>
<td valign="top" width="140">
<p align="left">RadioBox(“…”)</p>
</td>
<td valign="top" width="92">
<p align="left">Get\Set\Check</p>
</td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;textarea&gt;</p>
</td>
<td valign="top" width="85"></td>
<td valign="top" width="119"></td>
<td valign="top" width="140"></td>
<td valign="top" width="92"></td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;td&gt;</p>
</td>
<td valign="top" width="85">
<p align="left">TableCell</p>
</td>
<td valign="top" width="119">
<p align="left">WebTestTableCell</p>
</td>
<td valign="top" width="140">
<p align="left">TableCell(“…”)</p>
</td>
<td valign="top" width="92">
<p align="left">Get\Set\Check</p>
</td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;tr&gt;</p>
</td>
<td valign="top" width="85"></td>
<td valign="top" width="119"></td>
<td valign="top" width="140"></td>
<td valign="top" width="92"></td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;select&gt;</p>
</td>
<td valign="top" width="85">
<p align="left">DropList</p>
</td>
<td valign="top" width="119">
<p align="left">WebTestDropList</p>
</td>
<td valign="top" width="140">
<p align="left">DropList(“…”)</p>
</td>
<td valign="top" width="92">
<p align="left">Get\Set\Check</p>
</td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;option&gt;</p>
</td>
<td valign="top" width="85"></td>
<td valign="top" width="119"></td>
<td valign="top" width="140"></td>
<td valign="top" width="92"></td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;table&gt;</p>
</td>
<td valign="top" width="85">
<p align="left">Table</p>
</td>
<td valign="top" width="119">
<p align="left">WebTestTable</p>
</td>
<td valign="top" width="140">
<p align="left">Table(“…”)</p>
</td>
<td valign="top" width="92">
<p align="left">Get\Set\Check</p>
</td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;tbody&gt;</p>
</td>
<td valign="top" width="85"></td>
<td valign="top" width="119"></td>
<td valign="top" width="140"></td>
<td valign="top" width="92"></td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;label&gt;</p>
</td>
<td valign="top" width="85">
<p align="left">Label</p>
</td>
<td valign="top" width="119">
<p align="left">WebTestLabel</p>
</td>
<td valign="top" width="140">
<p align="left">Label.check(“”)</p>
</td>
<td valign="top" width="92">
<p align="left">Get\Set\Check</p>
</td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;div&gt;</p>
</td>
<td valign="top" width="85">
<p align="left">Div</p>
</td>
<td valign="top" width="119">
<p align="left">WebTestDiv</p>
</td>
<td valign="top" width="140">
<p align="left">Div(“”)</p>
</td>
<td valign="top" width="92">
<p align="left">Get\Set\Check</p>
</td>
</tr>
<tr>
<td valign="top" width="155"></td>
<td valign="top" width="85">
<p align="left">Dialog</p>
</td>
<td valign="top" width="119">
<p align="left">TestDialog</p>
</td>
<td valign="top" width="140">
<p align="left">Dialog(“…”,5)</p>
</td>
<td valign="top" width="92">
<p align="left">Get\Set\Check</p>
</td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;object&gt;</p>
</td>
<td valign="top" width="85">
<p align="left">ActiveX</p>
</td>
<td valign="top" width="119">
<p align="left">TestActiveXObject</p>
</td>
<td valign="top" width="140">
<p align="left">ActiveX(“…”)</p>
</td>
<td valign="top" width="92">
<p align="left">Get\Set\Check</p>
</td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;object&gt;</p>
</td>
<td valign="top" width="85">
<p align="left">Flash</p>
</td>
<td valign="top" width="119">
<p align="left">TestFlashObject</p>
</td>
<td valign="top" width="140">
<p align="left">Flash(“…”)</p>
</td>
<td valign="top" width="92">
<p align="left">Get\Set\Check</p>
</td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">… …</p>
</td>
<td valign="top" width="85">
<p align="left">WebElement</p>
</td>
<td valign="top" width="119">
<p align="left">TestElement</p>
</td>
<td valign="top" width="140">
<p align="left">WebElement</p>
</td>
<td valign="top" width="92">
<p align="left">Customer</p>
</td>
</tr>
</tbody>
</table>
<p align="left">如果是QUickTestPro的话，那么这张表是这样的：</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="155">
<p align="center"><strong>Html Element</strong></p>
</td>
<td valign="top" width="92">
<p align="center"><strong>QuiclTestPro</strong></p>
<p align="center"><strong>Maping</strong></p>
</td>
<td valign="top" width="119">
<p align="center"><strong>QuiclTestPro</strong></p>
<p align="center"><strong>Class</strong></p>
</td>
<td valign="top" width="140">
<p align="center"><strong>Script</strong></p>
</td>
<td valign="top" width="92">
<p align="center"><strong>Operational</strong></p>
</td>
</tr>
<tr>
<td valign="top" width="155"></td>
<td valign="top" width="92">
<p align="left">Browser</p>
</td>
<td valign="top" width="119">
<p align="left">Browser</p>
</td>
<td valign="top" width="140"></td>
<td valign="top" width="92">
<p align="left">Get\Set\Check</p>
</td>
</tr>
<tr>
<td valign="top" width="155"></td>
<td valign="top" width="92">
<p align="left">Page</p>
</td>
<td valign="top" width="119">
<p align="left">Page</p>
</td>
<td valign="top" width="140"></td>
<td valign="top" width="92">
<p align="left">Get\Set\Check</p>
</td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;frame&gt;</p>
</td>
<td valign="top" width="92">
<p align="left">Frame</p>
</td>
<td valign="top" width="119">
<p align="left">Frame</p>
</td>
<td valign="top" width="140"></td>
<td valign="top" width="92">
<p align="left">Get\Set\Check</p>
</td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;img&gt;</p>
</td>
<td valign="top" width="92">
<p align="left">Image</p>
</td>
<td valign="top" width="119">
<p align="left">Image</p>
</td>
<td valign="top" width="140"></td>
<td valign="top" width="92">
<p align="left">Get\Set\Check</p>
</td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;a&gt;</p>
</td>
<td valign="top" width="92">
<p align="left">Link</p>
</td>
<td valign="top" width="119">
<p align="left">Link</p>
</td>
<td valign="top" width="140"></td>
<td valign="top" width="92">
<p align="left">Get\Set\Check</p>
</td>
</tr>
<tr>
<td valign="top" width="155"></td>
<td valign="top" width="92">
<p align="left">ViewLink</p>
</td>
<td valign="top" width="119">
<p align="left">ViewLink</p>
</td>
<td valign="top" width="140"></td>
<td valign="top" width="92"></td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;inputtype=button&gt;</p>
</td>
<td valign="top" width="92">
<p align="left">WebButton</p>
</td>
<td valign="top" width="119">
<p align="left">WebButton</p>
</td>
<td valign="top" width="140"></td>
<td valign="top" width="92">
<p align="left">Get\Set\Check</p>
</td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;inputtype=reset&gt;</p>
</td>
<td valign="top" width="92">
<p align="left">WebButton</p>
</td>
<td valign="top" width="119">
<p align="left">WebButton</p>
</td>
<td valign="top" width="140"></td>
<td valign="top" width="92"></td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;inputtype=submit&gt;</p>
</td>
<td valign="top" width="92">
<p align="left">WebButton</p>
</td>
<td valign="top" width="119">
<p align="left">WebButton</p>
</td>
<td valign="top" width="140"></td>
<td valign="top" width="92"></td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;inputtype=file&gt;</p>
</td>
<td valign="top" width="92">
<p align="left">WebFile</p>
</td>
<td valign="top" width="119">
<p align="left">WebFile</p>
</td>
<td valign="top" width="140"></td>
<td valign="top" width="92"></td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;inputtype=checkbox&gt;</p>
</td>
<td valign="top" width="92">
<p align="left">WebCheckBox</p>
</td>
<td valign="top" width="119">
<p align="left">WebCheckBox</p>
</td>
<td valign="top" width="140"></td>
<td valign="top" width="92">
<p align="left">Get\Set\Check</p>
</td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;inputtype=text&gt;</p>
</td>
<td valign="top" width="92">
<p align="left">WebEdit</p>
</td>
<td valign="top" width="119">
<p align="left">WebEdit</p>
</td>
<td valign="top" width="140"></td>
<td valign="top" width="92">
<p align="left">Get\Set\Check</p>
</td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;inputtype=password&gt;</p>
</td>
<td valign="top" width="92">
<p align="left">WebEdit</p>
</td>
<td valign="top" width="119">
<p align="left">WebEdit</p>
</td>
<td valign="top" width="140"></td>
<td valign="top" width="92"></td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;textarea&gt;</p>
</td>
<td valign="top" width="92">
<p align="left">WebEdit</p>
</td>
<td valign="top" width="119">
<p align="left">WebEdit</p>
</td>
<td valign="top" width="140"></td>
<td valign="top" width="92"></td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;inputtype=image&gt;</p>
</td>
<td valign="top" width="92">
<p align="left">WebArea</p>
</td>
<td valign="top" width="119">
<p align="left">WebArea</p>
</td>
<td valign="top" width="140"></td>
<td valign="top" width="92"></td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;inputtype=radio&gt;</p>
</td>
<td valign="top" width="92">
<p align="left">WebRadioGroup</p>
</td>
<td valign="top" width="119">
<p align="left">WebRadioGroup</p>
</td>
<td valign="top" width="140"></td>
<td valign="top" width="92">
<p align="left">Get\Set\Check</p>
</td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;select&gt;</p>
</td>
<td valign="top" width="92">
<p align="left">WebList</p>
</td>
<td valign="top" width="119">
<p align="left">WebList</p>
</td>
<td valign="top" width="140"></td>
<td valign="top" width="92">
<p align="left">Get\Set\Check</p>
</td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">&lt;table&gt;</p>
</td>
<td valign="top" width="92">
<p align="left">WebTable</p>
</td>
<td valign="top" width="119">
<p align="left">WebTable</p>
</td>
<td valign="top" width="140"></td>
<td valign="top" width="92">
<p align="left">Get\Set\Check</p>
</td>
</tr>
<tr>
<td valign="top" width="155">
<p align="left">… …</p>
</td>
<td valign="top" width="92">
<p align="left">WebElement</p>
</td>
<td valign="top" width="119">
<p align="left">WebElement</p>
</td>
<td valign="top" width="140"></td>
<td valign="top" width="92">
<p align="left">Customer</p>
</td>
</tr>
</tbody>
</table>
<p align="left">其实映射的含义更多的是被用在对象识别内核概念上，而不是指用户某项具体的操作或动作。对不可识别对象做标准化处理，完全可以使用一个新的名词“影 射”，区别的是，它仅代表了某些黑盒动作，成为内核映射机制的前置，至于是不是能真的成功，那就完全取决于对象识别内核了，用户没办法干预只能如此。那么 影射是如何实现的？有个非常有趣的现象，即在QuickTestPro中只能对Win32对象做影射，其他的应用类型它是无能为力的。为什么Web类型的 不可以？这里需要感谢W3C为WEB世界做出的巨大贡献，避免HTML标准不被滥用。在Html定义中所有的元素都是独一无二的，即使有的元素名称相同也 会根据不同的type类型表现出完全不一样的UI反馈（Html诞生之初，群雄逐鹿标准混乱，其实到了现在我们还是不能保证IE能正常解析 的，FirFox是否能一样正常的解析。更令人吃惊的是，ForFox是100%的执行W3C标准的，那么IE……），用户影射动作在这里根本就没有意 义。也会有人说ActiveX难道就不能做影射吗？我只能说，因为CLSID的存在而使用影射那就显得太为“愚蠢”了，并且ActiveX对于Html本 身来说就属于一个黑盒子，你看到哪个Html元素会携带一个句柄的？</p>
<p align="left">Win32的内核映射机制表面看起来好像是根据classname做“表命名”的处理，其实后来跟了一下，发现其核心算法是比较复杂的，至少里面重 用了Atom的一些复合计算。好在TestMice在这块的技术储备也不算差，我们处理自定义控件的概念是，不需要用户做太多的影射操作，1-2步交互就 可以了。并且最重要的是在控件验证中，我们需要更负责任的告诉用户，哪些方法和属性是可用的，哪些是无效，哪些是令人“崩溃”的。</p>
<p align="left">当富客户端时代来临的时候，内核映射机制又重新被带到了前台，Flex、AIR、flash、Silverlight这些技术兴起，让TestMice看的了新的机会，老技术终于重新发芽了。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fastpoint.cn/index.php/archives/401/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>杭州日辉信息技术有限公司信息技术 &#8211; 功能自动化测试工具技术剖析 [Fastpoint]</title>
		<link>http://www.fastpoint.cn/index.php/archives/395</link>
		<comments>http://www.fastpoint.cn/index.php/archives/395#comments</comments>
		<pubDate>Fri, 05 Aug 2011 16:01:36 +0000</pubDate>
		<dc:creator>fastpoint</dc:creator>
				<category><![CDATA[未分类]]></category>

		<guid isPermaLink="false">http://www.fastpoint.cn/?p=395</guid>
		<description><![CDATA[杭州日辉信息技术有限公司信息技术 &#8211; 功能自动化测试工具技术剖析 [Fastpoint] 《程序员》2009.10期 所有的自动化测试工具都由一套非常稳定的、成熟的、预设概念的测试思想作为支撑，无论QuickTestPro、SilkTest或者 TestComplete皆是如此。为何本文标题使用了“结构”一词，而非大家经常朗朗上口的“框架”？我认为，“框架”包容的概念过多，而本文又不打算 针对某套自动化测试工具进行整体层面的分析和解构，所以使用了相对描述范围比较小的“结构”一词，用它足矣。 自动化测试的一个经典特征就是应用对象识别容器，用对象识别容器内捕获的对象实现一系列的模拟人工测试动作，其优点是巨大的，缺陷同样明显存在。对 象识别容器内置的识别算法、映射算法、排序和出栈算法都让自动化测试工具在执行复杂的、多变的测试案例时，表现出非常耗时和力不从心。另外，对象识别容器 并不知晓它所捕获的对象是临时的还是持久的，所以这直接导致了自动化测试过程难以被跟踪和可重复利用。为此，几乎所有实施了自动化测试的企业，都相应为此 付出了极其昂贵的后续维护成本。 回顾国内测试10年，自动化测试应用的大范围推广是必然的，没有一个行业会停滞不前，总有更好更快的技术来提升整个行业的技术水准。在本文中，我会 从一个自开发项目(TestMice)展开，描述一些迅捷的、轻量的自动化测试工具结构，例如对象描述，脚本构建， 描述性编程，测试数据驱动，场景恢复，插件和编译运行。我不会评价的任何测试工具的好与坏，我只会说明他们为什么要这么做，为什么有的时候鱼和熊掌不能兼 得。 1.    对象描述 在自动化测试中，对象泛指一切可能被捕获和虚拟的东西，可以说一个按钮就是一个对象，一组文字也是一个对象，一个程序进程也是一个对象，包含在 Html里面的某个Activex控件也是等等。自动化测试工具的核心件就是对象识别容器，其他看到的脚本、组合时序、数据和程序外调都是围绕这个核心来 开发的。总体而言，针对Win32的对象识别难度要高于对Html对象的识别，主要原因就是早期Win32的体系设计和微软大量未放开的结构和API声 明，所以本文使用Win32对象展开一个综述。 这里使用Windows最常使用两个附件“计算器”和“扫雷”来展开对象说明。   “计算器”程序使用了大量的标准Win32控件，所以针对其的对象识别还是比较简单的。那么对象识别容器如何捕获“计算器”程序的所有对象，这里面 涉及到一个很著名的Windows名词“句柄”，句柄是个很泛意的单词，它是怎么产生的，这又要涉及到Windows系统的一系列机制和相关API函数的 调用。我这里简单描述一下，因为我发现国内大部分的测试人员并不知晓Windows创建一个窗体是多么的“复杂”，补充一下相关知识还是非常有必要的。一 个窗体(window)诞生首先要向Windows系统进行注册（针对Windows的程序设计是一种标准对象导向的程序设计，业内简称OOP），注册函 数为RegisterClass(API)，注册完成后由CreateWindow(API)进行窗体(window)构建，如果这个函数执行成功那么就 会返回一个32位的整数，简称窗体句柄hwnd。其实在自动化测试工具中经常看到的就是这个hwnd，窗体句柄值的大小多少倒是无关紧要，不过它关联着窗 体对象，所有需要进行窗体(window)的操作都必须通过它。这个时候屏幕上还不能马上显示窗体(window)，接着使用 ShowWindow(API)和UpdateWindow(API)这两个函数后，这个窗体(window)才会最终显示在我们的计算机屏幕上。剩下的 就是构建窗体消息循环，在消息回调函数中声明消息处理方式等等，所以Windows也会被称为消息驱动的操作系统。句柄概念在Windows系统中应用频 繁，除了HINSTANCE(实例句柄)、HWND(窗口句柄)、HDC(设备句柄)，还有HICON(图标句柄)、HCURSOR(光标句柄)、 HBRUSH(刷子句柄)等等，正是因为句柄的存在，所以对象识别容器才能如此“轻松”的捕获这些对象，在Windows系统里所有的东西都是窗 体，Button也是，List也是，TextBox等皆是，窗体具容器最后导至整个Win32变得如此“多姿多彩”了。这里我使用自己编写的一个程序列 出整个“计算器”程序的对象列表，大家也可以使用Windows Spy++来获取：   整个“计算器”程序上所有的对象都被捕获其中，这里产生了父对象和子对象的树形结构，描述方式为：窗体句柄+ Window Text + Class Name，基本上这三个“属性”任意组合都可快速定位到一个对象。为何自动化测试工具中提供如此之多的属性选项，原理就是：属性提供的越多，对象识别容器 筛选对象的精度就越高，负面的是额外消耗的资源也会增加，这都取决于对象搜索机制的具体实现(SilkTest在这方面速度相对比较快)。在 QuickTestPro中，另外采用了“映射”机制，即用户所看到的界面识别属性并非是对象识别容器内真正的对象属性，其实用户也无需知道那些难以理解 的Window常量、句柄和对应结构描述。用户所能看到的实际上是由测试工具在真实对象上构建的虚拟属性地图，这样的好处是可以附加额外的搜索方式交给用 户选择，例如QuickTestPro提供的“对象属性正则表达式”、“对象Index或者Location”定位等，我本人对这种设计方式非常赞 同，TestMice项目中同样也实现了这种设计，工具应该提供最大的技术支持，让用户的灵活度充分得到体现。另外所谓的“对象重定义”技术也是采用了上 述原理，将非标准对象在UI层面显示为标准Windows对象，本质都是换汤不换药，既然用户看了舒心，那么我认为此项技术还是颇有商业应用前景的。 扫雷程序的对象识别相对比较难，因为其本身只有一个Window窗体句柄，扫雷窗口的构建和针对扫雷的动作的都是开发者操纵DC和挂钩消息来实现 的，这里就需要自动化测试工具提供一种更为灵活的测试方式，即虚拟化对象。虚拟化对象的实现机制并不是很困难，一般来说就是用户操作光标在需要进行虚拟化 的区域画出一个不可视矩阵，随即测试工具在指定区域内实现钩子机制，模拟发送Windows鼠标和键盘的各种消息操作，这可以让原来无法进行对象捕获的区 域也实现正常的用户模拟操作。这些技术非常普遍的存在于一些黑客工具中，现在甚至有人重写鼠标和键盘的虚拟设备驱动程序，以达到更高层面的操作需求。在 <a href="http://www.fastpoint.cn/index.php/archives/395">more</a>]]></description>
			<content:encoded><![CDATA[<h1 style="text-align: center;" align="left"><strong>杭州日辉信息技术有限公司信息技术 &#8211; 功能自动化测试工具技术剖析 [Fastpoint]</strong></h1>
<h4 style="text-align: center;" align="left"><strong> 《程序员》2009.10期</strong><strong></strong></h4>
<p align="left">所有的自动化测试工具都由一套非常稳定的、成熟的、预设概念的测试思想作为支撑，无论QuickTestPro、SilkTest或者 TestComplete皆是如此。为何本文标题使用了“结构”一词，而非大家经常朗朗上口的“框架”？我认为，“框架”包容的概念过多，而本文又不打算 针对某套自动化测试工具进行整体层面的分析和解构，所以使用了相对描述范围比较小的“结构”一词，用它足矣。</p>
<p align="left">自动化测试的一个经典特征就是应用对象识别容器，用对象识别容器内捕获的对象实现一系列的模拟人工测试动作，其优点是巨大的，缺陷同样明显存在。对 象识别容器内置的识别算法、映射算法、排序和出栈算法都让自动化测试工具在执行复杂的、多变的测试案例时，表现出非常耗时和力不从心。另外，对象识别容器 并不知晓它所捕获的对象是临时的还是持久的，所以这直接导致了自动化测试过程难以被跟踪和可重复利用。为此，几乎所有实施了自动化测试的企业，都相应为此 付出了极其昂贵的后续维护成本。</p>
<p align="left">回顾国内测试10年，自动化测试应用的大范围推广是必然的，没有一个行业会停滞不前，总有更好更快的技术来提升整个行业的技术水准。在本文中，我会 从一个自开发项目(TestMice)展开，描述一些迅捷的、轻量的自动化测试工具结构，例如对象描述，脚本构建， 描述性编程，测试数据驱动，场景恢复，插件和编译运行。我不会评价的任何测试工具的好与坏，我只会说明他们为什么要这么做，为什么有的时候鱼和熊掌不能兼 得。</p>
<p align="left"><strong>1.    </strong><strong>对象描述</strong></p>
<p align="left">在自动化测试中，对象泛指一切可能被捕获和虚拟的东西，可以说一个按钮就是一个对象，一组文字也是一个对象，一个程序进程也是一个对象，包含在 Html里面的某个Activex控件也是等等。自动化测试工具的核心件就是对象识别容器，其他看到的脚本、组合时序、数据和程序外调都是围绕这个核心来 开发的。总体而言，针对Win32的对象识别难度要高于对Html对象的识别，主要原因就是早期Win32的体系设计和微软大量未放开的结构和API声 明，所以本文使用Win32对象展开一个综述。</p>
<p align="left">这里使用Windows最常使用两个附件“计算器”和“扫雷”来展开对象说明。</p>
<p align="left"> <img class="alignnone" src="http://www.fastpoint.cn/wp-content/uploads/2011/08/6002.jpg" alt="" /></p>
<p align="left">“计算器”程序使用了大量的标准Win32控件，所以针对其的对象识别还是比较简单的。那么对象识别容器如何捕获“计算器”程序的所有对象，这里面 涉及到一个很著名的Windows名词“句柄”，句柄是个很泛意的单词，它是怎么产生的，这又要涉及到Windows系统的一系列机制和相关API函数的 调用。我这里简单描述一下，因为我发现国内大部分的测试人员并不知晓Windows创建一个窗体是多么的“复杂”，补充一下相关知识还是非常有必要的。一 个窗体(window)诞生首先要向Windows系统进行注册（针对Windows的程序设计是一种标准对象导向的程序设计，业内简称OOP），注册函 数为RegisterClass(API)，注册完成后由CreateWindow(API)进行窗体(window)构建，如果这个函数执行成功那么就 会返回一个32位的整数，简称窗体句柄hwnd。其实在自动化测试工具中经常看到的就是这个hwnd，窗体句柄值的大小多少倒是无关紧要，不过它关联着窗 体对象，所有需要进行窗体(window)的操作都必须通过它。这个时候屏幕上还不能马上显示窗体(window)，接着使用 ShowWindow(API)和UpdateWindow(API)这两个函数后，这个窗体(window)才会最终显示在我们的计算机屏幕上。剩下的 就是构建窗体消息循环，在消息回调函数中声明消息处理方式等等，所以Windows也会被称为消息驱动的操作系统。句柄概念在Windows系统中应用频 繁，除了HINSTANCE(实例句柄)、HWND(窗口句柄)、HDC(设备句柄)，还有HICON(图标句柄)、HCURSOR(光标句柄)、 HBRUSH(刷子句柄)等等，正是因为句柄的存在，所以对象识别容器才能如此“轻松”的捕获这些对象，在Windows系统里所有的东西都是窗 体，Button也是，List也是，TextBox等皆是，窗体具容器最后导至整个Win32变得如此“多姿多彩”了。这里我使用自己编写的一个程序列 出整个“计算器”程序的对象列表，大家也可以使用Windows Spy++来获取：</p>
<p align="left"> <img class="alignnone" src="http://www.fastpoint.cn/wp-content/uploads/2011/08/6003.jpg" alt="" /></p>
<p align="left">整个“计算器”程序上所有的对象都被捕获其中，这里产生了父对象和子对象的树形结构，描述方式为：窗体句柄+ Window Text + Class Name，基本上这三个“属性”任意组合都可快速定位到一个对象。为何自动化测试工具中提供如此之多的属性选项，原理就是：属性提供的越多，对象识别容器 筛选对象的精度就越高，负面的是额外消耗的资源也会增加，这都取决于对象搜索机制的具体实现(SilkTest在这方面速度相对比较快)。在 QuickTestPro中，另外采用了“映射”机制，即用户所看到的界面识别属性并非是对象识别容器内真正的对象属性，其实用户也无需知道那些难以理解 的Window常量、句柄和对应结构描述。用户所能看到的实际上是由测试工具在真实对象上构建的虚拟属性地图，这样的好处是可以附加额外的搜索方式交给用 户选择，例如QuickTestPro提供的“对象属性正则表达式”、“对象Index或者Location”定位等，我本人对这种设计方式非常赞 同，TestMice项目中同样也实现了这种设计，工具应该提供最大的技术支持，让用户的灵活度充分得到体现。另外所谓的“对象重定义”技术也是采用了上 述原理，将非标准对象在UI层面显示为标准Windows对象，本质都是换汤不换药，既然用户看了舒心，那么我认为此项技术还是颇有商业应用前景的。</p>
<p align="left">扫雷程序的对象识别相对比较难，因为其本身只有一个Window窗体句柄，扫雷窗口的构建和针对扫雷的动作的都是开发者操纵DC和挂钩消息来实现 的，这里就需要自动化测试工具提供一种更为灵活的测试方式，即虚拟化对象。虚拟化对象的实现机制并不是很困难，一般来说就是用户操作光标在需要进行虚拟化 的区域画出一个不可视矩阵，随即测试工具在指定区域内实现钩子机制，模拟发送Windows鼠标和键盘的各种消息操作，这可以让原来无法进行对象捕获的区 域也实现正常的用户模拟操作。这些技术非常普遍的存在于一些黑客工具中，现在甚至有人重写鼠标和键盘的虚拟设备驱动程序，以达到更高层面的操作需求。在 QuickTestPro中提供了一个独立的功能来实现虚拟化操作，在SilkTest中提供了一组函数来实现虚拟化的操作，相比较SilkTest在这 块的实力更强也更加灵活。另，虚拟对象在用户构建后是挂载在所属窗体对象下的，同理，Html的虚拟化对象是挂载在对应的Page对象中，理论上虚拟化对 象无构建限制个数，但是过多的虚拟化对象会影响测试工具的实际执行效率。</p>
<p align="left">在对象的世界里，额外并存在着固定测试对象和实时测试对象(也称运行时态对象)的概念，有的固定测试对象在实际软件运行时会发生变更，或者有些对象 在静态捕获的时候根本不存在，它只存在于程序运行时态，那么这些现象都会对对象识别容器产生了巨大的挑战。所有的测试工具中都隐含了一些拆分对象属性，以 最大的灵活度来匹配、捕获和重构对象，而不管它是否属于上述概念的哪一种，这些都被称为识别的核心执行机制而被保护起来，相关的技术文献并不多。在 TestMice中，我们也是用了一种特殊的机制来增强运行时态对象的鉴别，并且会提供额外的函数或者UI调整模式让用户自由选择，尽量做到所见即所得， 达到自动变形的目的，防止对正常测试过程的干扰。可以说在Win32领域，各类测试工具都差不多，没有什么特别突出的，好在这个Win32时代离普通用户 是越来越远了。</p>
<p align="left">另外需要声明的是，在Win32或者Html的值获取中，经常有人问我自动化工具是如何实现的，其实只有二种模式而已，第一种即调用对象本身支持的 属性通过相应函数获取，例如获取TextBox的getText(API)等，第二种就是自构建OCR识别程序进行矢量字转换，后者需要投入大量的时间和 金钱，最终效果也不见得有多好。当然也可以购买现成的OCR产品，以支持库的方式写入到测试工具中，这些不管是什么测试工具都是支持的。</p>
<p align="left"><strong>2.    </strong><strong>脚本构建</strong></p>
<p align="left">个人认为，在所有的自动化测试工具中，脚本的表现形式是决定用户是否选用该工具的关键之一，很多测试工具都输在用户对其脚本的第一视觉映象中，其表现形式如下：</p>
<ul>
<li>Start Main()<br />
SetWindow ( “Caption=Scical”, “”)<br />
PushButton.Click(”ObjectIndex=3″) //4<br />
PushButton.Click(”ObjectIndex=32″) //+<br />
PushButton.Click(”ObjectIndex=8″) //5<br />
PushButton.Click(”ObjectIndex=27″) //=<br />
Result = Compare (CompareProperties, “Object.Text”, “9. “) //比对结果<br />
End Main</li>
</ul>
<p align="left">可以看出这是个自动化测试脚本，但是至少让我在短时间内看不出脚本与对象之间的关联，这种脚本设计相对比较失败。有的时候，软件行业充斥着“自己好用，用户就好用”的研发思维，过于突出于技术而忽略了用户体验。如果这些你都可以快速适应，那么就让我再增加一些脚本量：</p>
<ul>
<li>Start Main()<br />
SetWindow ( “Caption=Scical”, “”)<br />
PushButton.Click(”ObjectIndex=3″) //46<br />
PushButton.Click(”ObjectIndex=21″)<br />
PushButton.Click(”ObjectIndex=3″) //+<br />
PushButton.Click(”ObjectIndex=8″) //5212<br />
PushButton.Click(”ObjectIndex=32″)<br />
PushButton.Click(”ObjectIndex=37″)<br />
PushButton.Click(”ObjectIndex=32″)<br />
PushButton.Click(”ObjectIndex=27″) //=<br />
Result = Compare (CompareProperties, “Object.Text”, “5258. “) //比对结果<br />
End Main</li>
</ul>
<p align="left">看了上面的脚本组成方式，我相信很多实际从事测试行业的人员都是强烈排斥的，这些脚本越多就会让整个自动化测试项目在脚本重构，业务分拆和项目管理 上陷入巨大的困境，进而加速整个自动化测试项目的死亡。在TestMice中采用一种比较贴切使用者，能快速理解，用极低的培训成本即可达到快速书写测试 脚本的方式。并且，这种脚本组成方式便于其维护、分解和重构，例如在对“计算器”程序进行加减乘除运算测试中，TestMice的脚本组成方式为：</p>
<ul>
<li>Window(”计算器”).Button(”4″).click();<br />
<strong>/</strong>/或者Window(”windowtext=’计算器’”,”HWND=’234985′”).Button(”4″).click();附加属性匹配<br />
//或者Window(”windowtext=’^计算*’”).Button(”4″).click();附加属性正则表达式匹配<br />
//或者Window(”算”).Button(”4″).click();模糊匹配<br />
Window(”计算器”).Button(”+”).click();<br />
Window(”计算器”).Button(”5″).click();<br />
Window(”计算器”).Button(”=”).click();<br />
Assert(Window(”计算器”).Edit(””).getText().trim(””,”.”),”9″);</li>
</ul>
<p align="left">看起来类似某商业自动化测试工具的脚本，其实好的设计概念大家都可以学习并加以沿用，如果是对多数字进行操作，我们可以写成这样：</p>
<ul>
<li>public static function mockNumberDClick(String number)<br />
{<br />
for(int i=1;i&lt;=len(number);i++)<br />
{<br />
Window(”计算器”).Button(right(number,i,1)).click();<br />
}<br />
}<br />
mockNumberDClick(”20″)<br />
Window(”计算器”).Button(”+”).click();<br />
mockNumberDClick(”20″)<br />
Window(”计算器”).Button(”=”).click();<br />
Assert(Window(”计算器”).Edit(””).getText().trim(””,”.”),”40″);</li>
</ul>
<p align="left">或者可以更进一步的增强加减乘除运算，例如：</p>
<ul>
<li>public static function mockComputing(String num1,String operator,String num2)<br />
{<br />
… …<br />
}<br />
mockNumberDClick(”20″,”+”,”20″)<br />
Assert(Window(”计算器”).Edit(””).getText().trim(””,”.”),”40″);<br />
mockNumberDClick(”2.543″,”+”,”11″)<br />
Assert(Window(”计算器”).Edit(””).getText().trim(””,”.”),”13.543″);<br />
mockNumberDClick(”-2.”,”+”,”10″)<br />
Assert(Window(”计算器”).Edit(””).getText().trim(””,”.”),”8″);</li>
</ul>
<p align="left">测试人员既要实现测试动作逻辑，又要特别关注测试数据的选取，如果可以让测试人员从脚本中就快速的获知对象关联，降低他在这块的开发时间，那么这个设计就是成功的。简单的设计即可达到最佳用户体验，这也是TestMice一直追求的。</p>
<p align="left"><strong>3.    </strong><strong>描述性编程</strong></p>
<p align="left">如果对自己的对象识别容器有足够的信心，那么支持“描述性编程”是必然的，这也引发了“描述性编程”的应用热潮。描述性编程一般都是经过长时间的测 试和使用最终被确定下来的，为什么Win32中这种技术未被广大用户所知(例如HP Winrunner中即存在描述性编程技术)，是因为Win32对象的非标准性(几乎各大厂商都有着自己的专属开发工具，产生了大量的控件集合)和不确定 性造成的，对象根本无法被捕获(在对象识别机制无法被扩展的情况下)，大肆推广描述性编程是不明智的商业之举。进入WEB时代后，因为W3C的强力介入 Html内容格式至少有了个统一的标准，所以描述性编程终于在自动化测试中成长起来了。描述性编程的概念就是要使用者直接脱离传统的识别对象-存储对象- 再操作对象的模式，升级为你无需进行这些繁琐的操作，直接使用轻量级的附带Spy工具查到被测试对象的几个基本属性，即可快速的书写测试脚本，以节省宝贵 的开发时间。一般描述性编程脚本结构为：</p>
<p align="left"><strong>对象(”属性:=‘值’”,”属性:=‘值’”,”属性:=‘值’”,… …).动作 “值” //QuickTestPro中使用的描述性编程格式</strong></p>
<p align="left"><strong>对象(”属性值1|属性值2|属性值3|… …“).动作(“值“) //SilkTest中使用的描述性编程格式</strong></p>
<p align="left">在TestMice中，这种描述性编程脚本结构微调为：</p>
<p align="left"><strong>对象(属性=“值“,属性=“值”,属性=“值”,… …).动作(“值“);</strong></p>
<p align="left">不管采用何种描述性编程格式，本质上是没有任何区别的，可以这样说<strong>，</strong>描述性编程是自动化测试工具一个必然发展的结果，所有的工具厂商都希望使用者更加关注测试数据和测试业务逻辑，脚本本身的表现形式则是越简单、越直白就越好。</p>
<p align="left"><strong>4.    </strong><strong>测试数据驱动</strong></p>
<p align="left">数据驱动在自动化测试中至少包含了两种概念，一为对象关键字驱动，二为业务关键字驱动，采用什么样的驱动模式完全取决于使用者本身。那么对象关键字驱动是如何实现的，我们可以用下面的一张图来做个简单的解释，这是对Windows附带计算器进行对象关键字驱动：</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="110">
<p align="center"><strong>Window</strong></p>
</td>
<td width="110">
<p align="center"><strong>Obejct</strong></p>
</td>
<td width="110">
<p align="center"><strong>Description</strong></p>
</td>
<td width="110">
<p align="center"><strong>Action</strong></p>
</td>
</tr>
<tr>
<td rowspan="14" width="110">
<p align="center">计算器</p>
</td>
<td valign="top" width="110">
<p align="left">Menu</p>
</td>
<td valign="top" width="110">
<p align="left">查看，标准型</p>
</td>
<td valign="top" width="110">
<p align="left">NULL</p>
</td>
</tr>
<tr>
<td valign="top" width="110">
<p align="left">Button</p>
</td>
<td valign="top" width="110">
<p align="left">1</p>
</td>
<td valign="top" width="110">
<p align="left">Click</p>
</td>
</tr>
<tr>
<td valign="top" width="110">
<p align="left">Button</p>
</td>
<td valign="top" width="110">
<p align="left">+</p>
</td>
<td valign="top" width="110">
<p align="left">Click</p>
</td>
</tr>
<tr>
<td valign="top" width="110">
<p align="left">Button</p>
</td>
<td valign="top" width="110">
<p align="left">1</p>
</td>
<td valign="top" width="110">
<p align="left">Click</p>
</td>
</tr>
<tr>
<td valign="top" width="110">
<p align="left">Button</p>
</td>
<td valign="top" width="110">
<p align="left">=</p>
</td>
<td valign="top" width="110">
<p align="left">Click</p>
</td>
</tr>
<tr>
<td valign="top" width="110">
<p align="left">Edit</p>
</td>
<td valign="top" width="110">
<p align="left">NULL<strong> </strong></p>
</td>
<td valign="top" width="110">
<p align="left">GetText</p>
</td>
</tr>
<tr>
<td valign="top" width="110">
<p align="left">NULL</p>
</td>
<td valign="top" width="110">
<p align="left"><strong>Assert</strong></p>
</td>
<td valign="top" width="110">
<p align="left">2</p>
</td>
</tr>
<tr>
<td valign="top" width="110">
<p align="left">Button</p>
</td>
<td valign="top" width="110">
<p align="left">CE</p>
</td>
<td valign="top" width="110">
<p align="left">Click</p>
</td>
</tr>
<tr>
<td valign="top" width="110">
<p align="left">Button</p>
</td>
<td valign="top" width="110">
<p align="left">5</p>
</td>
<td valign="top" width="110">
<p align="left">Click</p>
</td>
</tr>
<tr>
<td valign="top" width="110">
<p align="left">Button</p>
</td>
<td valign="top" width="110">
<p align="left">*</p>
</td>
<td valign="top" width="110">
<p align="left">Click</p>
</td>
</tr>
<tr>
<td valign="top" width="110">
<p align="left">Button</p>
</td>
<td valign="top" width="110">
<p align="left">5</p>
</td>
<td valign="top" width="110">
<p align="left">Click</p>
</td>
</tr>
<tr>
<td valign="top" width="110">
<p align="left">Button</p>
</td>
<td valign="top" width="110">
<p align="left">=</p>
</td>
<td valign="top" width="110">
<p align="left">Click</p>
</td>
</tr>
<tr>
<td valign="top" width="110">
<p align="left">Edit</p>
</td>
<td valign="top" width="110">
<p align="left">NULL<strong> </strong></p>
</td>
<td valign="top" width="110">
<p align="left">GetText</p>
</td>
</tr>
<tr>
<td valign="top" width="110">
<p align="left">NULL</p>
</td>
<td valign="top" width="110">
<p align="left"><strong>Assert</strong></p>
</td>
<td valign="top" width="110">
<p align="left">25</p>
</td>
</tr>
</tbody>
</table>
<p align="left">对象关键字驱动本质上就是对可操作对象做一个显式属性标注，然后使用任意数据存储方式(文件，数据库，Excel等)将这些属性、动作存储下来，最 后递交给脚本和对象识别容器统一实现。好处是简单明了，坏处是对象变更了数据就作废了，维护成本偏高，这也是众多商业自动化测试工具的通病。那么业务关键 字驱动表现得目的性稍微强了一些，基本上表格中的关键字都跟业务描述测试数据挂钩，例如这样的一个业务界面，那么它的业务关键字驱动表现为：</p>
<p align="left"> <img class="alignnone" src="http://www.fastpoint.cn/wp-content/uploads/2011/08/6004.jpg" alt="" /></p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="109">
<p align="center"><strong>书   号</strong></p>
</td>
<td valign="top" width="110">
<p align="center"><strong>会 员 价</strong></p>
</td>
<td valign="top" width="109">
<p align="center"><strong>数    量</strong></p>
</td>
<td valign="top" width="110">
<p align="center"><strong>验   证</strong></p>
</td>
</tr>
<tr>
<td valign="top" width="109">
<p align="left">7111099257</p>
</td>
<td valign="top" width="110">
<p align="left">25.50</p>
</td>
<td valign="top" width="109">
<p align="left">10</p>
</td>
<td valign="top" width="110">
<p align="left">正确</p>
</td>
</tr>
<tr>
<td valign="top" width="109">
<p align="left">7111255164</p>
</td>
<td valign="top" width="110">
<p align="left">78.00</p>
</td>
<td valign="top" width="109">
<p align="left">1</p>
</td>
<td valign="top" width="110">
<p align="left">正确</p>
</td>
</tr>
<tr>
<td valign="top" width="109">
<p align="left">8993099211</p>
</td>
<td valign="top" width="110">
<p align="left">45.00</p>
</td>
<td valign="top" width="109">
<p align="left">34</p>
</td>
<td valign="top" width="110">
<p align="left">正确</p>
</td>
</tr>
<tr>
<td valign="top" width="109">
<p align="left">1345266574</p>
</td>
<td valign="top" width="110">
<p align="left">49.00</p>
</td>
<td valign="top" width="109">
<p align="left">9999</p>
</td>
<td valign="top" width="110">
<p align="left">库存报错</p>
</td>
</tr>
<tr>
<td valign="top" width="109">
<p align="left">7532243222</p>
</td>
<td valign="top" width="110">
<p align="left">105.00</p>
</td>
<td valign="top" width="109">
<p align="left">1278</p>
</td>
<td valign="top" width="110">
<p align="left">正确</p>
</td>
</tr>
<tr>
<td valign="top" width="109">
<p align="left">3456576574</p>
</td>
<td valign="top" width="110">
<p align="left">35.00</p>
</td>
<td valign="top" width="109">
<p align="left">0</p>
</td>
<td valign="top" width="110">
<p align="left">输入错误</p>
</td>
</tr>
<tr>
<td valign="top" width="109">
<p align="left">3456576574</p>
</td>
<td valign="top" width="110">
<p align="left">35.00</p>
</td>
<td valign="top" width="109">
<p align="left">-1</p>
</td>
<td valign="top" width="110">
<p align="left">输入错误</p>
</td>
</tr>
<tr>
<td valign="top" width="109">
<p align="left">3456576574</p>
</td>
<td valign="top" width="110">
<p align="left">35.00</p>
</td>
<td valign="top" width="109">
<p align="left">0.1</p>
</td>
<td valign="top" width="110">
<p align="left">输入错误</p>
</td>
</tr>
</tbody>
</table>
<p align="left">对于业务关键字驱动来说，业务本身的数据和对应验证是最为重要的，只有通过更多的测试数据来达到一个满意的、足够安全的测试覆盖。而这些重复的、千 篇一律的数据输入却是手工测试人员最不愿意面对的，那么就交给工具来实现吧。至于这些数据以何种方式存放，任何测试工具都会提供稳定的数据接 口，TestMice同样也全部提供。</p>
<p align="left"><strong>5.    </strong><strong>场景恢复</strong></p>
<p align="left">自动化测试执行过程中遇到中断事件是非常普遍和令人沮丧的，我们经常告诫测试人员在脚本的执行机器上不要安装过多的额外软件，就是因为某些软件可能 产生一些莫名其妙的对话框或者发送一些古怪的消息来阻断正常自动化测试进程。那么作为一款强大的自动化测试工具，保存这种错误场景和继续恢复测试正常执行 是非常必要的，这些统称为场景恢复。在场景中，我们需要分析哪些现象会阻断脚本的正常运行？或许是一个软件升级的对话框，或许是来自于网络的一个弹出式窗 体，或许是防火墙拦截到的一段信息提示等等，这些一切皆有可能。那么如何处理这些令人讨厌的事情呢？TestMice项目中提供3种场景恢复，即：</p>
<ul>
<li>Windows弹出式对话框场景恢复</li>
<li>被测试软件错误场景恢复</li>
<li>对象属性变化场景恢复</li>
</ul>
<p align="left">第一种场景还是需要被动的预先获知弹出式对话的句柄，或者通过预设对话框Title属性，一旦该机制被触发，测试软件会自动寻找符合Title属性的窗体，然后启动由用户选择的4类后续对应处理：</p>
<ul>
<li>模拟鼠标和键盘消息，进行关闭窗体或者其他可定义操作</li>
<li>关闭阻碍自动化测试过程的软件进程，可由用户设定此项较危险</li>
<li>调用预约脚本，例如发送紧急短信或者邮件通知等</li>
<li>重启Windows系统，这里建议自动化测试做在虚拟机里，可用虚拟机SDK作辅助插件开发，保存当前软件执行Cookie</li>
</ul>
<p align="left">第二种场景在测试过程中是最为常见的，例如已识别菜单项没找到(Winrunner中常见)，List下拉项目中数据和脚本预设数据不匹配，出现多 个重复的对象(例如打开两个以上相同的IE窗口)，或者被测试对象状态为Visable等等，所以针对此场景，最好设置一个All Error处理，即不管出现了什么被测试软件错误，一概调用4类后续对应处理。更好的办法是，错误可以由使用者自定义，那么这就需要测试工具在实现机制上 有更多的考虑了。</p>
<p align="left">第三种场景，对象的属性变化处理最为复杂，不过这种处理机制也是对象识别容器的重要功能，可以由软件内部提供对象重新模糊匹配方式，略过该测试案例 执行，直接跳转到其他待测试案例执行等。同样该场景的触发也可以调用4类后续对应处理。既然测试执行过程中产生阻碍事件是无法预料的，那么有备无患的后续 处理机制就显得格外重要了。</p>
<p align="left">这三种场景恢复TestMice全部支持，并且我们将场景后续处理机制做在了插件里，这样的话就把对其他场景的定义交给了实际使用者，因为我们永远相信，预设的都是不够的，是最容易招惹抱怨的。</p>
<p align="left"><strong>6.   </strong><strong>插件和编译运行</strong></p>
<p align="left">目前很多测试工具有限的放开了二次开发接口，可以让使用者进行受一定限制的功能开发，但是至今还是没有一款商业测试工具放开到可以操作其对象识别容 器的地步。我认为一款再优秀的软件，没有提供额外的、灵活的、可扩展的SDK包在商业上都是不够“Open”的，甚至有扼杀行业技术进步、垄断市场之嫌。 TestMice完全提供对象识别容器内核所有的接口SDK开发包，以供任何个人或者企业制作具有自己特色的自动化测试应用。另外，我在大量的自动化测试 项目实施中发现了一些很有趣的事情，即目前市面上的测试工具脚本大多是以明码方式运行的，企业比较抵触这种方式，认为这种明码执行方式有泄漏企业秘密的重 大风险。那么在TestMice项目中有个有趣的插件专门负责把脚本编译成二进制模式，顺便对脚本进行解释运行。插件是所有工具扩展的灵魂，既然开发商不 能提供足够的想象力，那么就把这项任务交给广大插件开发者来完成吧。</p>
<p align="left"><strong>7.    </strong><strong>总结</strong></p>
<p align="left">国内至今尚未有正式机构对自动化测试工具进行整体式的深入研究和商业研发，自2007年国内某人开始制作成体系的研究性自动化测试工具，直至今日发 展颇为艰难。在经历了一个又一个的技术攻关后，终于让我们开始成熟起来。项目组同样希望TestMice可以成为国内每个测试人员，不，甚至是开发人员手 中的测试利器，国产的商业自动化测试工具应用年代终于离我们越来越近了！</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fastpoint.cn/index.php/archives/395/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>杭州日辉信息技术有限公司信息技术 &#8211; 谈测试体系规范的推行 [Fastpoint]</title>
		<link>http://www.fastpoint.cn/index.php/archives/393</link>
		<comments>http://www.fastpoint.cn/index.php/archives/393#comments</comments>
		<pubDate>Fri, 05 Aug 2011 15:55:34 +0000</pubDate>
		<dc:creator>fastpoint</dc:creator>
				<category><![CDATA[未分类]]></category>

		<guid isPermaLink="false">http://www.fastpoint.cn/?p=393</guid>
		<description><![CDATA[杭州日辉信息技术有限公司信息技术 - 谈测试体系规范的推行 [Fastpoint] 这几天在考虑这么一个问题：测试被慢慢认可了之后，为什么测试的价值还得不到体现？为什么测试体系还是得不到广泛的推广？以下是我个人的一些分析。 1.    测试体系的整体概念 一直以来，我都觉得这个问题挺概念化的，就是说出来后让人抓不住重点的感觉。要说某个具体的技术细节，很明确。比如说Weblogic的调优，可能会有人很快联想到：连接池、JVM、线程数等等。但是测试体系是什么？有点虚。 在多次听测试人员的报怨之后，我觉得现有规范可能是影响测试体系建设的第一要素。当然，领导还要强力支持。先说测试规范，后面再说其他因素的影响。 首先，要把软件测试和质量保证分开来。尽管现在大部分公司把测试人员叫做QA工程师，尽管这一叫法是错的（个人认为是错的），还是被一些人屁颠屁颠接受并 推广去了。好吧，这些概念性的问题，我们先不认真的追究了。测试体系在我的意识里是：为了尽可能找到系统的缺陷的和评估系统，对应测试需求，使用相应的管 理方式，按照流程和方法进行系列的测试动作，并最终产生符合规范的测试产品的过程描述。在这一过程中，有几个词是要体现在测试体系里的，就是：管理、流 程、规范、方法。 要推广测试体系，首先要求的个人素质，就是要有整体的体系概念。这样说起来好像有点太正式了，有点累。换个角度说：现在有没有太多的人有测试体系的整体概念？如果有，知道不知道自己在这个体系中处在什么位置？职责是什么？ 曾经看到一些公司和人生套CMMI、RUP、ISO之类的规范标准（这几套东西的角度是不一样的），但是由于推广的方式太生硬而导致人的意识转换不过来。 最后不了了之。尽管过了什么认证，也是推倒重来，恢复旧制。理由很简单：这些体系不适合我们，还是我们自己对体系比较清楚。测试体系也同样如此。精髓没有 领会到，就生套，是不可能推广开的。记得有人说，进一家公司是一个“固化—僵化—优化”的过程。而我觉得大部分人连固化还没走出第一步，就觉得回头才是岸 了。 前一阵子为一个客户推行测试体系，其实从技术角度来说，基本上都可以实现了。但是通过反复沟通，才知道客户想要的体系只是要一个可控制的PDCA过程，于 是我把体系整个给缩小了，客户才觉得这是他要的。实际上很多内容已经删减了。如果做一个项目的话，我觉得客户要的这种是可以直接和做事相关的。而如果要为 一个公司建立一套完整的体系，显然这样只能留下记录，而留不下体系中其他的关键部分。 要让相关人员有测试体系的整体概念。向与推行体系必然相关的人培训体系概念，阐述体系的优点。当然也会有缺点，所以才需要变更流程。 2.    利润驱动的影响 无可厚非，追求利润永远是公司的第一要务。在很多时候，我们不得不为利润让路。有时候就是因为一直是这样，才导致了我们的测试体系不可能完全建立起来。我们只能绕着客户转。 最近大领导组织开了一个会，就是建立一套完整的测试体系。在这个体系的各个部分，都有相应的文档来支持。当时我画了一个大概的思维框架图，包括的内容很广 泛；其中有每个职位上的人在什么样的阶段、按照什么流程和规范、做什么样的事情、做成什么样子，等等。都有相关的模块来维护其完整性。领导一看，觉得不 错。接下来就要提到如何落地。在参考了很多意见之后，决定落实成为一种可以按时间推移而实行的方法。但后来实际情况是：做事是需要时间的，在某些时候，一 个人要兼顾好几个事情，就不得不为与客户有关的事情让路。自从年后，我画了一个小范围内的ＰＤＣＡ流程图之后，就开始为客户的一个方案而不停打字。这件事 情，也就此放下。 这是暂时现象，还是大部分时候都是这样？我想在其位的人一定深有体会。我们经常可以看到听到或者亲身经历需求经常变更的事情，不仅是业务需求，测试需求也 是这样。做事情的人不知道上层的人怎么想的，但是只有做事情的人知道怎么才能做得更完善。有时，有些客户只是要一个自己认为重要的结果。其实对整个系统来 说，这个结果意义并不大。我曾经做过一些以客户为核心的业务。比如，客户只需要知道系统在当前配置下的性能状态。也许客户只需要响应时间，认为用户数是很 关键的数据。于是他们迫切地想得到这个数据，但是没有考虑到整个系统的性能表现应该是从不同角度来关注的。在这个过程中，其实我们可以关注一下如何做得更 完善，从而逐步丰富体系。 如果仅从当前项目出发，个人认为：从长远的发展来看，这种做法是会降低利润的。当然，没有完整的体系。很多时候，我们做一件事情，可能重复了好多次，前后 都没有历史资源可以借鉴。其实是有的，只是没有人去整理。没有形成知识管理库。大部分公司以目录式的结构来管理文档，这也没有什么。但是文档散乱得不成样 子，就让人接受不了了。如果下定决心去做一个体系的建立，可能会导致当前的事情会有些滞后，但是会让后面的工作顺利进行。可能有人提出异议，认为即使这样 也不见得能提高多少工作效率，于是举出N个例子来说明。我只能说：创建的体系有问题，要变更。利润驱动的一个最大误区就是：太关注眼前的利益而放弃了长远 的利益。这和人生的规划如出一辙。有些人花了四年的时候，好好学习大学课程，毕业后找工作，可以很快上手；而有些人玩了四年，出来后，找工作处处碰壁。 所以个人认为，在利润驱动时，不要忘记长远的利益规划。在近期利润可以平衡的前提下，应该尽量以长远的眼光来看事情，一点一点积累。按流程说明来控制近期要做的事情，往往也不会增加太多工作量。只是需要在平时工作中灌输体系控制的思想。 3.    领导支持不力 和 朋友聊天时，说到公司里的测试人员不足，测试不被重视的现象，这是老生常谈的话题。有很多人报怨：领导是如何如何不理解测试，如何如何不理解测试的重要 性，等等。有个问题他们没有描述到的是：测试带来的直接和间接的利润究竟是多少？这是个比较难确定的问题。但是如果这个问题回答不好，让领导们感觉不到利 润的提升，想让他们重视测试还是比较难的。还有一个大环境的问题：我们都知道测试行业的发展没有几年，或者说普遍认识到测试的重要性还没有几年，以前只有 少数人在做，而现在大部分人都意识到了应该做测试。但仅是意识到而已，并没有形成测试必做的传统。那就意味着：可能是意识到了，但不知如何发展下去。 80年左右的人现在也差不多30岁左右了，这些人接受的教育和工作时做的测试可能稍微多一些，但是他们大部分是中层领导（普遍情况），或者说更多的是干活 的人。中层领导要想推广测试体系几乎是不可能的事情。他们能做的只是局部更新。这是不是意味着，只有这一代中有测试体系的概念、并且身体力行的人做了上层 领导后，才有可能推动全面的测试体系？果真如是，恐怕还要等几年了。商鞅变法成功是因为有秦孝公的支持，秦孝公是个天才领袖。而测试的天才领袖在哪儿？同 样有了天才领袖和可堪大用的人，还是要面对老世族的攻击。而这场战争至少要打两代人的时间。软件测试体系如果要推行，纵然有人可以做，在大部分的企业里， 估计也要等到媳妇熬成婆。 在其职，有其能，才能谋其事。所以这个要求的是个人的机会和能力。 4.   <a href="http://www.fastpoint.cn/index.php/archives/393">more</a>]]></description>
			<content:encoded><![CDATA[<h1 style="text-align: center;" align="left"><strong></strong><strong>杭州日辉信息技术有限公司信息技术 -<br />
谈测试体系规范的推行 [Fastpoint]</strong><strong></strong></h1>
<p align="left">这几天在考虑这么一个问题：测试被慢慢认可了之后，为什么测试的价值还得不到体现？为什么测试体系还是得不到广泛的推广？以下是我个人的一些分析。</p>
<p align="left"><strong>1.    </strong><strong>测试体系的整体概念</strong></p>
<p align="left">一直以来，我都觉得这个问题挺概念化的，就是说出来后让人抓不住重点的感觉。要说某个具体的技术细节，很明确。比如说Weblogic的调优，可能会有人很快联想到：连接池、JVM、线程数等等。但是测试体系是什么？有点虚。<br />
在多次听测试人员的报怨之后，我觉得现有规范可能是影响测试体系建设的第一要素。当然，领导还要强力支持。先说测试规范，后面再说其他因素的影响。<br />
首先，要把软件测试和质量保证分开来。尽管现在大部分公司把测试人员叫做QA工程师，尽管这一叫法是错的（个人认为是错的），还是被一些人屁颠屁颠接受并 推广去了。好吧，这些概念性的问题，我们先不认真的追究了。测试体系在我的意识里是：为了尽可能找到系统的缺陷的和评估系统，对应测试需求，使用相应的管 理方式，按照流程和方法进行系列的测试动作，并最终产生符合规范的测试产品的过程描述。在这一过程中，有几个词是要体现在测试体系里的，就是：管理、流 程、规范、方法。<br />
要推广测试体系，首先要求的个人素质，就是要有整体的体系概念。这样说起来好像有点太正式了，有点累。换个角度说：现在有没有太多的人有测试体系的整体概念？如果有，知道不知道自己在这个体系中处在什么位置？职责是什么？<br />
曾经看到一些公司和人生套CMMI、RUP、ISO之类的规范标准（这几套东西的角度是不一样的），但是由于推广的方式太生硬而导致人的意识转换不过来。 最后不了了之。尽管过了什么认证，也是推倒重来，恢复旧制。理由很简单：这些体系不适合我们，还是我们自己对体系比较清楚。测试体系也同样如此。精髓没有 领会到，就生套，是不可能推广开的。记得有人说，进一家公司是一个“固化—僵化—优化”的过程。而我觉得大部分人连固化还没走出第一步，就觉得回头才是岸 了。<br />
前一阵子为一个客户推行测试体系，其实从技术角度来说，基本上都可以实现了。但是通过反复沟通，才知道客户想要的体系只是要一个可控制的PDCA过程，于 是我把体系整个给缩小了，客户才觉得这是他要的。实际上很多内容已经删减了。如果做一个项目的话，我觉得客户要的这种是可以直接和做事相关的。而如果要为 一个公司建立一套完整的体系，显然这样只能留下记录，而留不下体系中其他的关键部分。<br />
要让相关人员有测试体系的整体概念。向与推行体系必然相关的人培训体系概念，阐述体系的优点。当然也会有缺点，所以才需要变更流程。</p>
<p align="left"><strong>2.    </strong><strong>利润驱动的影响</strong></p>
<p align="left">无可厚非，追求利润永远是公司的第一要务。在很多时候，我们不得不为利润让路。有时候就是因为一直是这样，才导致了我们的测试体系不可能完全建立起来。我们只能绕着客户转。<br />
最近大领导组织开了一个会，就是建立一套完整的测试体系。在这个体系的各个部分，都有相应的文档来支持。当时我画了一个大概的思维框架图，包括的内容很广 泛；其中有每个职位上的人在什么样的阶段、按照什么流程和规范、做什么样的事情、做成什么样子，等等。都有相关的模块来维护其完整性。领导一看，觉得不 错。接下来就要提到如何落地。在参考了很多意见之后，决定落实成为一种可以按时间推移而实行的方法。但后来实际情况是：做事是需要时间的，在某些时候，一 个人要兼顾好几个事情，就不得不为与客户有关的事情让路。自从年后，我画了一个小范围内的ＰＤＣＡ流程图之后，就开始为客户的一个方案而不停打字。这件事 情，也就此放下。<br />
这是暂时现象，还是大部分时候都是这样？我想在其位的人一定深有体会。我们经常可以看到听到或者亲身经历需求经常变更的事情，不仅是业务需求，测试需求也 是这样。做事情的人不知道上层的人怎么想的，但是只有做事情的人知道怎么才能做得更完善。有时，有些客户只是要一个自己认为重要的结果。其实对整个系统来 说，这个结果意义并不大。我曾经做过一些以客户为核心的业务。比如，客户只需要知道系统在当前配置下的性能状态。也许客户只需要响应时间，认为用户数是很 关键的数据。于是他们迫切地想得到这个数据，但是没有考虑到整个系统的性能表现应该是从不同角度来关注的。在这个过程中，其实我们可以关注一下如何做得更 完善，从而逐步丰富体系。<br />
如果仅从当前项目出发，个人认为：从长远的发展来看，这种做法是会降低利润的。当然，没有完整的体系。很多时候，我们做一件事情，可能重复了好多次，前后 都没有历史资源可以借鉴。其实是有的，只是没有人去整理。没有形成知识管理库。大部分公司以目录式的结构来管理文档，这也没有什么。但是文档散乱得不成样 子，就让人接受不了了。如果下定决心去做一个体系的建立，可能会导致当前的事情会有些滞后，但是会让后面的工作顺利进行。可能有人提出异议，认为即使这样 也不见得能提高多少工作效率，于是举出N个例子来说明。我只能说：创建的体系有问题，要变更。利润驱动的一个最大误区就是：太关注眼前的利益而放弃了长远 的利益。这和人生的规划如出一辙。有些人花了四年的时候，好好学习大学课程，毕业后找工作，可以很快上手；而有些人玩了四年，出来后，找工作处处碰壁。<br />
所以个人认为，在利润驱动时，不要忘记长远的利益规划。在近期利润可以平衡的前提下，应该尽量以长远的眼光来看事情，一点一点积累。按流程说明来控制近期要做的事情，往往也不会增加太多工作量。只是需要在平时工作中灌输体系控制的思想。</p>
<p align="left"><strong>3.    </strong><strong>领导支持不力</strong></p>
<p align="left">和 朋友聊天时，说到公司里的测试人员不足，测试不被重视的现象，这是老生常谈的话题。有很多人报怨：领导是如何如何不理解测试，如何如何不理解测试的重要 性，等等。有个问题他们没有描述到的是：测试带来的直接和间接的利润究竟是多少？这是个比较难确定的问题。但是如果这个问题回答不好，让领导们感觉不到利 润的提升，想让他们重视测试还是比较难的。还有一个大环境的问题：我们都知道测试行业的发展没有几年，或者说普遍认识到测试的重要性还没有几年，以前只有 少数人在做，而现在大部分人都意识到了应该做测试。但仅是意识到而已，并没有形成测试必做的传统。那就意味着：可能是意识到了，但不知如何发展下去。<br />
80年左右的人现在也差不多30岁左右了，这些人接受的教育和工作时做的测试可能稍微多一些，但是他们大部分是中层领导（普遍情况），或者说更多的是干活 的人。中层领导要想推广测试体系几乎是不可能的事情。他们能做的只是局部更新。这是不是意味着，只有这一代中有测试体系的概念、并且身体力行的人做了上层 领导后，才有可能推动全面的测试体系？果真如是，恐怕还要等几年了。商鞅变法成功是因为有秦孝公的支持，秦孝公是个天才领袖。而测试的天才领袖在哪儿？同 样有了天才领袖和可堪大用的人，还是要面对老世族的攻击。而这场战争至少要打两代人的时间。软件测试体系如果要推行，纵然有人可以做，在大部分的企业里， 估计也要等到媳妇熬成婆。<br />
在其职，有其能，才能谋其事。所以这个要求的是个人的机会和能力。</p>
<p align="left"><strong>4.    </strong><strong>执行不力</strong></p>
<p align="left">这个问题出现的前提是第3点中的描述已经不是问题。执行碰到的最大问题是与旧制度的冲突。要知道，让人改变一种习惯是很难的事情。要让一个企业改变 习惯，就更难。还记得在以前公司里推行ISO这个体系时，开始时，每个人学按照ISO来做些事情还可以。但突然改变以前的习惯很难受。终于到了不能承担的 时候，还是恢复了旧制度。ISO相关的内容成了公司在市场上的一个说辞。但是为了满足这个体系，公司每到要再次评审的时候，要耗费大量人力来再次修正。<br />
执行不力的另一个大问题是意识不到体系的重要性。从而得不到广泛的支持。很多人在报怨的同时，没有考虑到一个本质的问题：就是自己处在什么样的位置上，应 该负什么样的责任，这件事情是这个职位上做得了的事情吗？这一点我反复强调，就是因为现在很多职位的责任不清晰。直接导致了很多人都觉得做了自己不应该做 的事。这一点在体系中会通过角色职责做清楚的描述。所以要让每个人理解到整个体系存在的必要性，再来理解个人的角色职责就不会出现这个问题。这样使体系的 执行也就更有中坚基础。<br />
这个问题要依赖第3点中的问题解决。就是要有相应权力的人推行。这是最直接的。要不然还是比较麻烦。</p>
<p align="left"><strong>5.    </strong><strong>人治还是体系方法治？</strong></p>
<p align="left">此部分只讲述软件测试方面的内容，不妄言公司的全面管理。<br />
我们知道具体的技术细节是有方法可以参考的，比如测试用例的覆盖率，是可以从技术角度来计算出来的（计算需要时间和相应知识支撑）。但是，在大部分情况 下，我们碰到的现象还是：领导分配哪个模块让谁来负责测试，这个测试人员只从业务角度来写瀑布似的用例描述，最后执行这个测试用例。这样的覆盖率是没办法 计算的。而有些人还妄图从这样的执行结果中去计算覆盖率。最后只能不了了之。这里导致了一个后果就是测试的充分性得不到保障，发布后的系统又出现新问题并 且没有人为此承担责任。这就是拍脑袋形成的现象。<br />
我们知道，人治是一种主观的判断。我觉得你不行，我是领导，你就是不行。这样的描述让人清晰地感觉到：一个人的职位和他的主观判断严重影响到后续的质量。 我记得看过一句话：一个公司的老板的个人素质决定了这个公司的企业文化和前途。暂不说这句话的合理性，应该有很多人同意这句话说的是对的。所谓仁政、周 礼、井田制，已经在很多人的潜意识里扎下了根。<br />
那体系方法治呢，明确了一些扯不清的职责，也让人在项目的各个阶段中，知道了自己应该做什么，做成什么样子。做不到，要么是能力不行，要么是规范有问题， 需要变更。在经过裁决之后，如果是前者，可以通过换人、培训等手段解决；如果是后者变更体系方法就好了。不会出现头脑一晕、停滞不动的现象。也不会出现像 有些人说的，我现在脑子都大了，不知道领导到底要我做什么，也不知道做成什么样子，才算是领导满意了。这里说的是公司内部，如果涉及到客户，其判断的规范 标准就是客户的满意度。从大结构上理解各个层面，然后去做，这是我认为有效的控制质量的办法。<br />
那是不是说体系治就万无一失了呢？当然不是，因为事是人做的，而涉及到人，变数就很大的。还是需要人治的辅助。灵活综合运用，才能见实效。建议固化体系制度为根本。当形成强大的体系传统时才考虑人治参与其中，但一定要有所侧重，并在见到实效后立即回归体系制度。</p>
<p align="left"><strong>6.    </strong><strong>什么是适合的体系？</strong></p>
<p align="left">在交流中我发现很多人把体系看得很死，好像说到CMMI就应该按初始级、管理级、已定义级、量化管理级、最佳化级一层层发展上去，或者说到RUP就 得按照先启、精化、构造、移交这样的步骤来做。我想说的是，如果你要过CMMI的认证，完全有按照要求做的必要。而要是我们觉得都不适合，完全可以自己去 制定一个体系，借鉴是没有问题的，只要符合就行。并且，这些建议采纳不采纳，也是我们自己决定的。要做，就落到实地来做。别空摆一个架子。而有些人有潜意 识 里的排斥心理：我们要有自己的流程，我们不按照任何成熟的流程来做。好像自己拍拍脑袋，体系就出来了。搞到最后，依旧是不了了之。从规划到实现，不管是对 的错的，如果只有规划没有实现，是如何也无法落地的。<br />
所以有画饼的能力，也要有把饼做成的能力。</p>
<p align="left"><strong>7.    </strong><strong>总结</strong></p>
<p align="left">当有了整体的测试体系概述之后，即使有利润驱动，也应该与此同时关注一下体系的建立。因为客户对公司的测试需求也是在测试体系之内的。再加上有领导 的支持和一批有执行力的人推广整个体系，测试体系才会有可能发展起来。而在这一过程中，尽可能避免人治的手段。只有这样才能使体系有生存的空间，否则将使 苦心建立的体系很快就荡然无存。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fastpoint.cn/index.php/archives/393/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>杭州日辉信息技术有限公司信息技术 &#8211; 成功的自动化测试项目实施[Fastpoint]</title>
		<link>http://www.fastpoint.cn/index.php/archives/215</link>
		<comments>http://www.fastpoint.cn/index.php/archives/215#comments</comments>
		<pubDate>Fri, 05 Aug 2011 06:41:32 +0000</pubDate>
		<dc:creator>fastpoint</dc:creator>
				<category><![CDATA[未分类]]></category>

		<guid isPermaLink="false">http://www.fastpoint.cn/?p=215</guid>
		<description><![CDATA[杭州日辉信息技术有限公司信息技术 &#8211; 成功的自动化测试项目实施[Fastpoint] 导语：本文基于商业工具结合实际项目，分析自动化测试实施期间出现的各种问题，以提高大家对自动化测试项目的真正认识与理解。 现 在自动化测试工具很多，商业的或者开源的、以对象识别为基础的或者以语言特性为基础的等等。在挑选的时候，首先我们要明确被操作软件的范畴和特性、可预知 风险、培训潜在成本及是否具备被虚拟化等一系列问题，这些问题可制成标准检查列表，以便确定一个解决一个。在本次自动化测试实施中，首先可知的是被测试软 件属于行业金融软件，使用Borland C++Builder语言开发，测试范畴锁定在软件前台需配对后台数据验证，前台由RedHat Linux服务端、自研发中间件和Oracle数据库支撑。一般来说，这种软件应用架构比较清晰，但是GUI层使用了大量的非标准第三方控件（相对于标准 Win32控件），有可能会导致部分GUI对象无法捕获造成实施困难，所以在进入真正的实施前作充分、快速的实验性评估是非常重要的。 实验性评估阶段 职业化的自动化测试团队，应当非常熟悉当前主流的商业或者开源测试工具，这种团队的定义是：技术让位与成本控制，快速实施且能快速递交，精确控制每 12周为一周期，项目延时误差小于7天。考虑到脚本会被移交给其他团队执行，所以我们选择了目前在国内应用范围比较广、相关技术资料比较丰富的HP Winrunner和HP QuickTestPro。第一个被评估的是QuickTestPro 9.5版本，不带任何插件，结果大量的GUI对象无法被捕捉，不能捕捉意味着不能被操作，所以团队快速转换到不带任何插件的Winrunner 9.2版本，不带任何插件，实验结果是基本可以正确识别和捕获我们所要操作的GUI对象，满足了对自动化测试的需求。其实QuickTestPro 9.5版本带Delphi插件也可大大增加捕获率，但是使用插件违反了团队定义的工具应用管理规范，也不符合“有对象即可操作”的强硬编程作风。 在工具定义后，需要立刻选择2组典型业务进行试验性测试，这时需要业务专家和脚本专家一起工作。带GUI界面软件测试用例的设计核心问题是：需要精 确区分正常测试用例和异常测试用例。按照先异常后正常的实际执行方式，组织最终的测试数据存放关系，一般合适的比例控制在异常75%及正常25%范围内。 脚本专家需要快速处理对象识别库，如果涉及到GUI对象重定义则需要在指定文件中加以注明，因为这部分工作可被复用到后续的项目实施中，避免造成人力成本 重复投入。通常实验性阶段主要产生的问题是： 该阶段是否会产生脚本框架？答案是否定的，首先自动化测试不一定要有框架，框架产生的唯一目的就是牺牲一部分脚本性能，而对测试数据进行高效、有序 的管理。不过在试验性阶段可以考虑这个问题，如果框架是个平台，那么我们可以在这个平台上放置一些我们需要的单位脚本、性能监视器或者其他一些东西。由于 Winrunner的描述性编程机能不够，那么在后续正常项目实施中，框架更多被定位于为可测量、可伸缩、可动态、可智能解析测试数据的执行管理。在后续 项目中我们的框架结构描述如下图： 图：项目自动化测试框架结构 该阶段是否需要考虑测试数据存放问题？答案是否定的，没有必要浪费太多的时间在这种地方，一个文本文件或者干脆不要文件的数据存放形式都可以，关键是成本。 该阶段对于人员的要求是什么？答案是人员需要精干。一个业务专家，一个脚本专家，一个统计专家足够，自动化测试实施非常注重绩效比，绩效比不够根本没必要执行后续的项目，你必须通过实验性测试得出一个准确的结论，就是重复执行多少次脚本，执行成本才可以由负转正。 该阶段是否需要考虑环境的问题？答案是肯定的，在这之前就应该安装好虚拟系统了，如果脚本专家的一边开着即时通讯工具一边录制脚本，我们认为这是 非常不专业的。系统环境的清洁程度如同医院的手术室，需要提前对各种必须的软件（例如杀毒软件，网管软件等）做好适应性选择，有干扰的、或者影响系统机能 的坚决卸载掉。 该阶段的硬件是怎么规划的？前端的测试主机需要有同时承受开2—3个虚拟系统的准备，不能产生明显的切换和操作停顿甚至系统假死。虽然32位的 Windows XP系统不支持4G物理内存，但是经验告诉我们内存容量多多益善，至于CPU和显卡处于正常水平即可。后端使用的硬件需要稳定，因为不是性能测试所以不作 太多要求。 该阶段的管理模式和输出是什么？答案是没有太复杂的管理模式，实验性评估一般都会在1周内被关闭，唯一重要的就是实施评估报告。报告内容大致包 含：周期定义、工具定型描述、应用软件描述、系统框架描述、可能采用的框架描述、可能递交工件描述、可加入业务列表、预测脚本规模、可实施技术分析、评估 人/时分析、预测实际人/时分析、评估脚本价值、预测实际脚本价值、可能遇到的问题警告等，这些条目都必须一一做出详实而且准确的描述。 实验性评估结束后，需要确定自动化测试实施项目的时间及周期里程碑，我们采用12周为一个周期里程碑，快速发布快速递交的方式以确保整个测试项目的 实施成功。在开始的1周内，管理专家需要快速定义对象控制表、项目跟踪表、需求跟踪表、周/发布项目进度、日/问题跟踪表、配置管理须知，脚本专家需要快 速定义代码规范、脚本设计维护手册、数据作用说明及填写规范，环境专家需要快速定义虚拟环境配置手册、维护与复制手册，培训专家需要制定实施阶段课程培训 体系等，专家都是角色可复用，工作都是实打实的，需要认真对待，缺一不可。 “混乱点”及其经典问题 我 们通常将项目在快要接近380个可操作对象或者脚本代码接近25000行的时候称之为一个“混乱点”。之所以称为“混乱点”，因为这是项目执行过程中的必 然现象，如同飞机速度超过音速时产生的音障一样，正确的对待和处理有助于后续项目实施的健康成长，否则后果不堪设想。下面是“混乱点”会出现的经典问题： 经典问题一：文档混乱。这里的文档混乱并非指文档丢失、残缺或者缺少维护这些低级错误，事实上这里的文档混乱是多个文档内产生了部分内容相同的冗 余数据，且这些冗余数据在可控制范围内。“冗余即懒惰”，所以对应的解决方案就是将所有文档转交EPG团队，由专人看管做日终处理，只要不增加本团队的成 本我们是非常乐于这么做的。 经典问题二：培训热度过高。为了确保脚本的周递交转移速度，我们在每周末需要对接应团队做一定培训，很多人（非合作团队）都想增加自己在这方面的 知识，所以原来的2小时培训时间被延长到4小时，原来一场25人小团队培训被扩展为二场各180人的培训，很累。直接造成的后果就是很多人要内部转岗来我 们团队，这也违背了“简单既是美”。 经典问题三：框架的测试数据处理规划？在本项目中，我们采用了TestPackage—TestSuite—TestCase的测试数据组合模式,描述如下图： <a href="http://www.fastpoint.cn/index.php/archives/215">more</a>]]></description>
			<content:encoded><![CDATA[<h1 style="text-align: center;" align="left">杭州日辉信息技术有限公司信息技术 &#8211; 成功的自动化测试项目实施[Fastpoint]</h1>
<p align="left"><em>导语：本文基于商业工具结合实际项目，分析自动化测试实施期间出现的各种问题，以提高大家对自动化测试项目的真正认识与理解。</em></p>
<p align="left">现 在自动化测试工具很多，商业的或者开源的、以对象识别为基础的或者以语言特性为基础的等等。在挑选的时候，首先我们要明确被操作软件的范畴和特性、可预知 风险、培训潜在成本及是否具备被虚拟化等一系列问题，这些问题可制成标准检查列表，以便确定一个解决一个。在本次自动化测试实施中，首先可知的是被测试软 件属于行业金融软件，使用Borland C++Builder语言开发，测试范畴锁定在软件前台需配对后台数据验证，前台由RedHat Linux服务端、自研发中间件和Oracle数据库支撑。一般来说，这种软件应用架构比较清晰，但是GUI层使用了大量的非标准第三方控件（相对于标准 Win32控件），有可能会导致部分GUI对象无法捕获造成实施困难，所以在进入真正的实施前作充分、快速的实验性评估是非常重要的。</p>
<p align="left"><strong>实验性评估阶段</strong></p>
<p align="left">职业化的自动化测试团队，应当非常熟悉当前主流的商业或者开源测试工具，这种团队的定义是：技术让位与成本控制，快速实施且能快速递交，精确控制每 12周为一周期，项目延时误差小于7天。考虑到脚本会被移交给其他团队执行，所以我们选择了目前在国内应用范围比较广、相关技术资料比较丰富的HP Winrunner和HP QuickTestPro。第一个被评估的是QuickTestPro 9.5版本，不带任何插件，结果大量的GUI对象无法被捕捉，不能捕捉意味着不能被操作，所以团队快速转换到不带任何插件的Winrunner 9.2版本，不带任何插件，实验结果是基本可以正确识别和捕获我们所要操作的GUI对象，满足了对自动化测试的需求。其实QuickTestPro 9.5版本带Delphi插件也可大大增加捕获率，但是使用插件违反了团队定义的工具应用管理规范，也不符合“有对象即可操作”的强硬编程作风。</p>
<p align="left">在工具定义后，需要立刻选择2组典型业务进行试验性测试，这时需要业务专家和脚本专家一起工作。带GUI界面软件测试用例的设计核心问题是：需要精 确区分正常测试用例和异常测试用例。按照先异常后正常的实际执行方式，组织最终的测试数据存放关系，一般合适的比例控制在异常75%及正常25%范围内。 脚本专家需要快速处理对象识别库，如果涉及到GUI对象重定义则需要在指定文件中加以注明，因为这部分工作可被复用到后续的项目实施中，避免造成人力成本 重复投入。通常实验性阶段主要产生的问题是：</p>
<p align="left">该阶段是否会产生脚本框架？答案是否定的，首先自动化测试不一定要有框架，框架产生的唯一目的就是牺牲一部分脚本性能，而对测试数据进行高效、有序 的管理。不过在试验性阶段可以考虑这个问题，如果框架是个平台，那么我们可以在这个平台上放置一些我们需要的单位脚本、性能监视器或者其他一些东西。由于 Winrunner的描述性编程机能不够，那么在后续正常项目实施中，框架更多被定位于为可测量、可伸缩、可动态、可智能解析测试数据的执行管理。在后续 项目中我们的框架结构描述如下图：</p>
<p align="center">图：项目自动化测试框架结构</p>
<ol start="1">
<li>该阶段是否需要考虑测试数据存放问题？答案是否定的，没有必要浪费太多的时间在这种地方，一个文本文件或者干脆不要文件的数据存放形式都可以，关键是成本。</li>
<li>该阶段对于人员的要求是什么？答案是人员需要精干。一个业务专家，一个脚本专家，一个统计专家足够，自动化测试实施非常注重绩效比，绩效比不够根本没必要执行后续的项目，你必须通过实验性测试得出一个准确的结论，就是重复执行多少次脚本，执行成本才可以由负转正。</li>
<li>该阶段是否需要考虑环境的问题？答案是肯定的，在这之前就应该安装好虚拟系统了，如果脚本专家的一边开着即时通讯工具一边录制脚本，我们认为这是 非常不专业的。系统环境的清洁程度如同医院的手术室，需要提前对各种必须的软件（例如杀毒软件，网管软件等）做好适应性选择，有干扰的、或者影响系统机能 的坚决卸载掉。</li>
<li>该阶段的硬件是怎么规划的？前端的测试主机需要有同时承受开2—3个虚拟系统的准备，不能产生明显的切换和操作停顿甚至系统假死。虽然32位的 Windows XP系统不支持4G物理内存，但是经验告诉我们内存容量多多益善，至于CPU和显卡处于正常水平即可。后端使用的硬件需要稳定，因为不是性能测试所以不作 太多要求。</li>
<li>该阶段的管理模式和输出是什么？答案是没有太复杂的管理模式，实验性评估一般都会在1周内被关闭，唯一重要的就是实施评估报告。报告内容大致包 含：周期定义、工具定型描述、应用软件描述、系统框架描述、可能采用的框架描述、可能递交工件描述、可加入业务列表、预测脚本规模、可实施技术分析、评估 人/时分析、预测实际人/时分析、评估脚本价值、预测实际脚本价值、可能遇到的问题警告等，这些条目都必须一一做出详实而且准确的描述。</li>
</ol>
<p align="left">实验性评估结束后，需要确定自动化测试实施项目的时间及周期里程碑，我们采用12周为一个周期里程碑，快速发布快速递交的方式以确保整个测试项目的 实施成功。在开始的1周内，管理专家需要快速定义对象控制表、项目跟踪表、需求跟踪表、周/发布项目进度、日/问题跟踪表、配置管理须知，脚本专家需要快 速定义代码规范、脚本设计维护手册、数据作用说明及填写规范，环境专家需要快速定义虚拟环境配置手册、维护与复制手册，培训专家需要制定实施阶段课程培训 体系等，专家都是角色可复用，工作都是实打实的，需要认真对待，缺一不可。</p>
<p align="left"><strong>“</strong><strong>混乱点”及其经典问题</strong></p>
<p align="left">我 们通常将项目在快要接近380个可操作对象或者脚本代码接近25000行的时候称之为一个“混乱点”。之所以称为“混乱点”，因为这是项目执行过程中的必 然现象，如同飞机速度超过音速时产生的音障一样，正确的对待和处理有助于后续项目实施的健康成长，否则后果不堪设想。下面是“混乱点”会出现的经典问题：</p>
<ul>
<li>经典问题一：文档混乱。这里的文档混乱并非指文档丢失、残缺或者缺少维护这些低级错误，事实上这里的文档混乱是多个文档内产生了部分内容相同的冗 余数据，且这些冗余数据在可控制范围内。“冗余即懒惰”，所以对应的解决方案就是将所有文档转交EPG团队，由专人看管做日终处理，只要不增加本团队的成 本我们是非常乐于这么做的。</li>
<li>经典问题二：培训热度过高。为了确保脚本的周递交转移速度，我们在每周末需要对接应团队做一定培训，很多人（非合作团队）都想增加自己在这方面的 知识，所以原来的2小时培训时间被延长到4小时，原来一场25人小团队培训被扩展为二场各180人的培训，很累。直接造成的后果就是很多人要内部转岗来我 们团队，这也违背了“简单既是美”。</li>
<li>经典问题三：框架的测试数据处理规划？在本项目中，我们采用了TestPackage—TestSuite—TestCase的测试数据组合模式,描述如下图：</li>
</ul>
<p align="center"><img class="alignnone" src="http://www.fastpoint.cn/wp-content/uploads/2011/08/1108.jpg" alt="" /></p>
<p align="center">图：TestPackage—TestSuite—TestCase组合模式</p>
<ul>
<li>TestPackage作为测试数据顶集归属于总项目，作用于整个项目团队，其描述在整棵树形中唯一。TestSuite，TestCase和 TC-Child是测试数据的最终管理形式，多对多模式居多。另外每一个TestSuite，TestCase和TC-Child都必须附带额外的三种执 行属性，即强制、独立与从属，本来在团队内还有更多的执行属性争议，但是在实际运作中，我们发现三种属性足够使用了。另外，在TC-Child中还必须考 虑嵌入正则表达式的支持，或者你也可以遵循Fit的规则，做数据、行为和表格的统一验证处理。</li>
<li>经典问题四：脚本的增加突出了性能的缺失。一旦对象突破380个（不包含描述性对象），脚本突破25000行（不包含注释及空行），不优化，那么 在一台机器上的综合运行时间超过了4个小时，所以对代码优化的工作在后续几周的实施中急待解决。对于脚本性能调优，需要综合考虑语言特性、数据结构、外调 和对象识别处理，这里需要对TestPackage—TestSuite—TestCase的组合模式进行事务级的时间分析，精确到毫秒。调优的处理有多 种，每个团队的方法各不一样，经过综合处理，现在我们能做到35532行脚本、451个对象、37个虚拟对象，合计78个综合处理包全部在一台机器上运 行，时间可控制在2小时之内。继续压缩时间的资源投入大于产出，这不符合成本控制团队的初衷，所以最终放弃。</li>
<li>经典问题五：原来测试工具的函数有BUG。实际上大规模的代码运用对测试工具本身也是一种考验，一切软件皆有问题，随着时间的推移会逐渐暴露出 来。我们发现了测试工具部分函数会在某些特定环境下出现问题，所以替换这些函数是非常必要的。替换的方法是，使用第三方开发工具（例如VC）开发出可被脚 本直接调用的函数（例如各种动态库技术），以替换原自带问题函数，这样既增加了整体代码的稳定性，又提升了团队的研发能力。例如Winrunner偶尔出 现的菜单丢失的问题，都可用自研发函数给予解决。另外测试工具本身提供的语言也可能存在某些局限性，所以测试团队具备自我开发能力也关系着项目是否能被顺 利实施。</li>
<li>经典问题六：脚本不动了。实际上这是最让人讨厌的问题，可能涉及的方面非常多，例如系统交互、网络环境、本机环境、软件冲突等等，我们总结了一条 处理该类型事件的方法：先排除系统本身，排除干扰软件，再分析比和对卡死位置数据，最后分析脚本本身，例如我们发现部分问题跟字符处理函数有关，这对提高 脚本本身的健壮性，提出了很高的要求。</li>
</ul>
<p align="left">项 目进行到距离里程碑最后一周，大部分的问题列表需要被提前被关闭，相关递交工件需要被整理评审，脚本经过验证被最终集成转交，这里都需要配置管理来提供良 好的控制环境。必须指明的是，日脚本构建和测试是贯穿整个项目周期的，这种做法能使脚本的开发状态得到频繁的更新，以及尽早发现设计和集成的缺陷。为了充 分利用时间与设备资源，夜晚21点后，脚本的自动执行测试（这里多数指的是系统测试或回归测试）是一个非常行之有效的方法。一切都顺利的话，等到第二天上 班时，测试结果就已经在相关人员的邮箱里面了。通过这份报告，你可以知道那些脚本是必须修改的，如果不太清楚还有一份更详细的截图列表辅助定位，准确告诉 你当时软件究竟出现了什么现象导致了问题的产生。</p>
<p align="left"><strong>首阶段</strong></p>
<p align="left">最终该项目第一阶段在12周且延长6个小时后被准确关闭，并且通过了严格的部门验收，6人参与到这个项目中，合计2916个有效工作时。经过计算每 行代码价值为1.77元，总的来说还算是成功的。接下来，我们会进入该项目的第二个实施阶段，能否将每行代码价值控制在1元以下，请各位拭目以待。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fastpoint.cn/index.php/archives/215/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>日辉信息迁入新的软件科技园区</title>
		<link>http://www.fastpoint.cn/index.php/archives/209</link>
		<comments>http://www.fastpoint.cn/index.php/archives/209#comments</comments>
		<pubDate>Fri, 05 Aug 2011 06:40:33 +0000</pubDate>
		<dc:creator>fastpoint</dc:creator>
				<category><![CDATA[未分类]]></category>

		<guid isPermaLink="false">http://www.fastpoint.cn/?p=209</guid>
		<description><![CDATA[日辉信息迁入新的软件科技园区]]></description>
			<content:encoded><![CDATA[<p>日辉信息迁入新的软件科技园区</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fastpoint.cn/index.php/archives/209/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>手机论坛成病毒传播“重灾区”</title>
		<link>http://www.fastpoint.cn/index.php/archives/206</link>
		<comments>http://www.fastpoint.cn/index.php/archives/206#comments</comments>
		<pubDate>Fri, 05 Aug 2011 06:39:33 +0000</pubDate>
		<dc:creator>fastpoint</dc:creator>
				<category><![CDATA[未分类]]></category>

		<guid isPermaLink="false">http://www.fastpoint.cn/?p=206</guid>
		<description><![CDATA[手机论坛成病毒传播“重灾区” 2011年08月05日 10:16　来源：科技日报 　　近日，网秦公司发布了《2011年第二季度全球Android手机安全报告》，报告数据显示，在手机病毒、恶意软件的传播渠道上，手机论坛的危险指数正在持续上升，以39%的比例成为二季度Android手机病毒以恶意软件的传播重灾区，Android应用商店则以26%的比例位居其后。 相比一季度，应用商店感染比例最高的情况，二季度在Google官方商店对新发现的恶意软件均采用了发现一个，快速下架一个的措施，和国内多家Android应用商店与安全厂商达成了技术合作之后，商店的安全性得到了初步控制。但由于手机论坛的安全监管力度依然较低，安全威胁仍然很大。 “任何人都可以将任何软件传到论坛之中，包括黑客，过于开放让大家可以更好的交流和共享，但过于开放又会让其充满安全风险。”专家表示，黑客会利用大家喜欢去论坛中“淘宝”的心理，通过论坛贴的形式传播病毒；或伪装为知名软件，以破解版为名骗取下载；或直接以间谍软件为名，诱惑存在猎奇心理的网民下载试用。由于缺乏对论坛附件安全性的检测，使得手机论坛已超越应用商店，在二季度成为手机病毒、恶意软件的传播温床。 手机安全专家建议，用户应提高对智能手机的安全意识，养成较好的手机使用习惯，如加强手机密码设置的安全性，不随意下载陌生软件，谨防其存在安全隐患，在安装软件前还建议详细查看其索取的权限列表，避免其中存在隐私安全陷阱。 (记者左常睿)]]></description>
			<content:encoded><![CDATA[<div>
<h1 style="text-align: center;">手机论坛成病毒传播“重灾区”</h1>
</div>
<p style="text-align: center;">2011年08月05日 10:16　来源：科技日报</p>
<p>　　近日，网秦公司发布了《2011年第二季度全球Android手机安全报告》，报告数据显示，在手机病毒、恶意软件的传播渠道上，手机论坛的危险指数正在持续上升，以39%的比例成为二季度Android手机病毒以恶意软件的传播重灾区，Android应用商店则以26%的比例位居其后。</p>
<p>相比一季度，应用商店感染比例最高的情况，二季度在Google官方商店对新发现的恶意软件均采用了发现一个，快速下架一个的措施，和国内多家Android应用商店与安全厂商达成了技术合作之后，商店的安全性得到了初步控制。但由于手机论坛的安全监管力度依然较低，安全威胁仍然很大。</p>
<p>“任何人都可以将任何软件传到论坛之中，包括黑客，过于开放让大家可以更好的交流和共享，但过于开放又会让其充满安全风险。”专家表示，黑客会利用大家喜欢去论坛中“淘宝”的心理，通过论坛贴的形式传播病毒；或伪装为知名软件，以破解版为名骗取下载；或直接以间谍软件为名，诱惑存在猎奇心理的网民下载试用。由于缺乏对论坛附件安全性的检测，使得手机论坛已超越应用商店，在二季度成为手机病毒、恶意软件的传播温床。</p>
<p>手机安全专家建议，用户应提高对智能手机的安全意识，养成较好的手机使用习惯，如加强手机密码设置的安全性，不随意下载陌生软件，谨防其存在安全隐患，在安装软件前还建议详细查看其索取的权限列表，避免其中存在隐私安全陷阱。</p>
<p>(记者左常睿)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fastpoint.cn/index.php/archives/206/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

