﻿<?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>学习日记 &#187; 软件测试</title>
	<atom:link href="https://www.softwareace.cn/?cat=10&#038;feed=rss2" rel="self" type="application/rss+xml" />
	<link>https://www.softwareace.cn</link>
	<description>时刻想着为自己的产品多做一些对他好的事情</description>
	<lastBuildDate>Fri, 20 Mar 2026 06:58:28 +0000</lastBuildDate>
	<language>zh-CN</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	
	<item>
		<title>Code Review是软件工程中很有意义的一个活动</title>
		<link>https://www.softwareace.cn/?p=1083</link>
		<comments>https://www.softwareace.cn/?p=1083#comments</comments>
		<pubDate>Sat, 13 Dec 2014 08:08:45 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[软件测试]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=1083</guid>
		<description><![CDATA[Code reviews 确实有很多用处，而在实际工作中它被用来找到程序bug、保证代码风格、编码标准。过于负 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Code reviews 确实有很多用处，而在实际工作中它被用来找到程序bug、保证代码风格、编码标准。过于负担了。它不应该承担发现代码错误的职责，而是审核代码的质量，如可读性，可维护性，健壮性以及程序逻辑对需求的实现正确完整性。程序中的bug应该由单元测试、集成测试、性能测试、系统测试、回归测试来保证的，其中主要是单元测试是最重要的环节，因为那是最接近Bug，也是Bug没有扩散的地方。 它不应该成为保证代码风格和编码标准的手段。编码风格和代码规范都属于死的东西，每个程序员在把自己的代码提交团队Review的时候，代码就应该是符合规范的，这是默认值，属于每个人自己的事情，不应该交由团队来完成，否则只会浪费大家本来就不够的时间。 今天，在中国的很多公司里，上面这两件事依然被认为是Code Reivew最重要的事，但在实际工作中够看到很多开发Team抱怨Code Review就是一个形式，费时费力不说，发现的问题还不如测试。对于代码规范，这应该是程序作者自己需要保证的，而且有一些工具是可以帮你来检查代码规范的。 上述言论并不是说，在Code Review中报告一个程序的bug或是一个代码规范的问题。我只是说，那并不是Code Review的意图。 如何使Code Review更有意义。 经常进行Code Review。就好像人家都把整个房子盖好了，大家Review时这挑一点、那挑一点，有时候触动地基或是承重墙体，需要大动手术，让人返工，这当然会让盖房的人一下就跳起来极力地维护自己的代码，最后还伤了团队成员的感情。所以，千万不要等大厦都盖好了再去Reivew，而且当有了地基，有了框架，有了房顶，有了门窗，有了装修的各个时候循序渐进地进行Review，这样反而会更有效率，也更有帮助。当然，在敏捷开发中，他们不需要Code Reivew，其实，敏捷开发中使用更为极端的“结对编程”（Pair-Programming）的方法 —— 一种时时刻刻都在进行Code Review的方法，个人感觉在实际过程中，这种方法有点过了。 保持积极的正面的态度。程序最大的问题就是“自负”，程序员在Code Review的时候，开始抨击别人的代码，质疑别人的能力。他们指责对方的目的是想告诉大家自己有多么的牛。无论是代码作者，还是评审者，都需要一种积极向上的正面的态度，作者需要能够虚心接受别人的建议，因为别人的建议是为了让你做得更好；评审者也需要以一种积极的正面的态度向作者提意见，因为那是和你在一个战壕里的战友。 Code Review不要太正式，而且要短。忘了那个代码评审的Checklist吧，走到你的同事座位跟前，像请师父一样请 他坐到你的电脑面前，然后，花5分钟给他讲讲你的代码，给他另外一个5分钟让他给你的代码提提意见，这比什么都好。 尽可能的让不同的人Reivew你的代码。不同的人有不同的思考方式，有不同的见解，所以，不同的人可以全面的从各个方面评论你的代码，有的从实现的角度，有的从需求的角度，有的从用户使用的角度，有的从算法的角度，有的从性能效率的角度，有的从易读的角度，有的从扩展性的角度……。当然，不要太多了，人多嘴杂反而适得其反。 学会享受Code Reivew。如果你到了一个人人都喜欢Code Reivew的团阿，那么，你会进入到一个生机勃勃的地方，在那里，每个人都能写出质量非常好的代码，在那里，他们相互学习，相互帮助，不仅仅是写出好的代码，而且团队和其中的每个人都会自动进化，这个是一个团队。</p>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=1083</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Windows API 调用监视工具 API Monitor</title>
		<link>https://www.softwareace.cn/?p=1064</link>
		<comments>https://www.softwareace.cn/?p=1064#comments</comments>
		<pubDate>Sat, 13 Dec 2014 04:56:35 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[开发工具]]></category>
		<category><![CDATA[软件测试]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=1064</guid>
		<description><![CDATA[API Monitor 是一款用来监视和显示用户应用程序和服务程序中的Windows API调用的免费软件。它 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p style="color: #000000;">API Monitor 是一款用来监视和显示用户应用程序和服务程序中的Windows API调用的免费软件。它是一个强大的工具，在跟踪调试你开发的应用程序时，可以帮助发现产生问题可能的原因。API Monitor支持windows 7及windows 64位系统。</p>
<p style="color: #000000;"><img src="http://www.oschina.net/uploads/img/201011/08081448_9ols.png" alt="" data-bd-imgshare-binded="1" /></p>
<p style="color: #000000;">http://www.rohitab.com/apimonitor#Download</p>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=1064</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>差网络环境模拟工具 Clumsy</title>
		<link>https://www.softwareace.cn/?p=1036</link>
		<comments>https://www.softwareace.cn/?p=1036#comments</comments>
		<pubDate>Fri, 14 Nov 2014 01:54:15 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[软件测试]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=1036</guid>
		<description><![CDATA[clumsy 能在 Windows 平台下人工造成不稳定的网络状况，方便你调试应用程序在极端网络状况下的表现。 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p style="color: #000000;"><strong>clumsy 能在 Windows 平台下人工造成不稳定的网络状况，方便你调试应用程序在极端网络状况下的表现。</strong></p>
<h4 style="color: #000000;">简介</h4>
<p style="color: #000000;">利用封装 Winodws Filtering Platform 的<a style="color: #3e62a6;" href="http://reqrypt.org/windivert.html">WinDivert 库</a>, clumsy 能实时的将系统接收和发出的网络数据包拦截下来，人工的造成延迟，掉包和篡改操作后再进行发送。无论你是要重现网络异常造成的程序错误，还是评估你的应用 程序在不良网络状况下的表现，clumsy 都能让你在不需要额外添加代码的情况下，在系统层次帮你达到想要的效果：</p>
<p style="color: #000000;">特色：</p>
<ul class="textlist list-paddingleft-2" style="color: #000000;">
<li>下载即用，不需要安装任何东西。</li>
<li>不需要额外设置，不需要修改你的程序的代码。</li>
<li>系统级别的网络控制，可以适用于命令行，图形界面等任何 Windows 应用程序。</li>
<li>不仅仅只支持 HTTP，任何 TCP, UDP 的网络连接都可以被处理。</li>
<li>支持本地调试(服务器和客户端都在 localhost)</li>
<li>&#8220;热插拔&#8221;，你的程序可以一直运行，而 clumsy 可以随时开启和关闭。</li>
<li>实时调节各种参数，详细控制网络情况。</li>
</ul>
<h4 style="color: #000000;">实例</h4>
<p style="color: #000000;">下面的动画展示了 clumsy 作用于一个本地的基于 netcat 的 UDP 服务器/客户端的情况。仔细观察你可以看到数据根据在 clumsy 的影响下产生了相应的变化。</p>
<p style="color: #000000;">如果你基本知道了 clumsy 是干什么用的，不妨到<a style="color: #3e62a6;" href="http://jagt.github.io/clumsy/cn/download">下载页面</a>选择适用于你系统的版本进行下载。</p>
<p style="color: #000000;"><img class="demo" src="http://static.oschina.net/uploads/img/201411/14065843_PsSP.gif" alt="" /></p>
<h4 style="color: #000000;">详细信息</h4>
<p style="color: #000000;">clumsy 首先根据用户选择的 <em>filter</em> 来拦截指定的网络数据。在 filter 中可以设定你感兴趣的协议(tcp/udp)，端口号，是接收还是发出的端口。你也可以通过简单的逻辑语句来进一步缩小范围。当 clumsy 被激活时，只有符合这些标准的网络数据会被进行处理，而你不感兴趣的数据仍然会由系统正常传输。</p>
<p style="color: #000000;">当被 filter 的网络数据包被拦截后，你可以选择 clumsy 提供的功能来有目的性的调整网络情况：</p>
<ol class="textlist list-paddingleft-2" style="color: #000000;">
<li>延迟(Lag)，把数据包缓存一段时间后再发出，这样能够模拟网络延迟的状况。</li>
<li>掉包(Drop)，随机丢弃一些数据。</li>
<li>节流(Throttle)，把一小段时间内的数据拦截下来后再在之后的同一时间一同发出去。</li>
<li>重发(Duplicate)，随机复制一些数据并与其本身一同发送。</li>
<li>乱序(Out of order)，打乱数据包发送的顺序。</li>
<li>篡改(Tamper)，随机修改小部分的包裹内容。</li>
</ol>
<p style="color: #000000;">尽管当前宽带网络连接十分普及，但网络传输其本身在本质上总不是稳定的。如果你的应用程序中没有应对各种情况的处理，那么有可能一个丢失的 UDP 包裹都会让你的程序崩溃。正确的调试这类行为            显然需要再代码结构上进行仔细的设计和处理，还会很花功夫。而且在某些封装紧密的开发环境(Unity3D 自带的网络库可能是一个例子)下会更麻烦。clumsy 以尽可能减轻程序员负担为目标，希望提供一个简单方便（但并不完美）的解决方案。</p>
<p style="color: #000000;">http://www.oschina.net/p/clumsy</p>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=1036</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>基于 Jenkins 快速搭建持续集成环境</title>
		<link>https://www.softwareace.cn/?p=979</link>
		<comments>https://www.softwareace.cn/?p=979#comments</comments>
		<pubDate>Mon, 13 Oct 2014 11:55:48 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[软件测试]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=979</guid>
		<description><![CDATA[持续集成概述 什么是持续集成 随着软件开发复杂度的不断提高，团队开发成员间如何更好地协同工作以确保软件开发的质 [&#8230;]]]></description>
				<content:encoded><![CDATA[<h2 id="major1" style="color: #000000;">持续集成概述</h2>
<h3 id="minor1.1" style="color: #000000;">什么是持续集成</h3>
<p style="color: #222222;">随着软件开发复杂度的不断提高，团队开发成员间如何更好地协同工作以确保软件开发的质量已经慢慢成为开发过程中不可回避的问题。尤其是近些年来，敏捷（Agile） 在软件工程领域越来越红火，如何能再不断变化的需求中快速适应和保证软件的质量也显得尤其的重要。</p>
<p style="color: #222222;">持续集成正是针对这一类问题的一种软件开发实践。它倡导团队开发成员必须经常集成他们的工作，甚至每天都可能发生多次集成。而每次的集成都是通过自动化的构建来验证，包括自动编译、发布和测试，从而尽快地发现集成错误，让团队能够更快的开发内聚的软件。</p>
<p style="color: #222222;">持续集成的核心价值在于：</p>
<ol type="1">
<li>持续集成中的任何一个环节都是自动完成的，无需太多的人工干预，有利于减少重复过程以节省时间、费用和工作量；</li>
<li>持续集成保障了每个时间点上团队成员提交的代码是能成功集成的。换言之，任何时间点都能第一时间发现软件的集成问题，使任意时间发布可部署的软件成为了可能；</li>
<li>持续集成还能利于软件本身的发展趋势，这点在需求不明确或是频繁性变更的情景中尤其重要，持续集成的质量能帮助团队进行有效决策，同时建立团队对开发产品的信心。</li>
</ol>
<h3 id="minor1.2" style="color: #000000;">持续集成的原则</h3>
<p style="color: #222222;">业界普遍认同的持续集成的原则包括：</p>
<p style="color: #222222;">1）需要版本控制软件保障团队成员提交的代码不会导致集成失败。常用的版本控制软件有 IBM Rational ClearCase、CVS、Subversion 等；</p>
<p style="color: #222222;">2）开发人员必须及时向版本控制库中提交代码，也必须经常性地从版本控制库中更新代码到本地；</p>
<p style="color: #222222;">3）需要有专门的集成服务器来执行集成构建。根据项目的具体实际，集成构建可以被软件的修改来直接触发，也可以定时启动，如每半个小时构建一次；</p>
<p style="color: #222222;">4）必须保证构建的成功。如果构建失败，修复构建过程中的错误是优先级最高的工作。一旦修复，需要手动启动一次构建。</p>
<h3 id="minor1.3" style="color: #000000;">持续集成系统的组成</h3>
<p style="color: #222222;">由此可见，一个完整的构建系统必须包括：</p>
<ol type="1">
<li>一个自动构建过程，包括自动编译、分发、部署和测试等。</li>
<li>一个代码存储库，即需要版本控制软件来保障代码的可维护性，同时作为构建过程的素材库。</li>
<li>一个持续集成服务器。本文中介绍的 Jenkins 就是一个配置简单和使用方便的持续集成服务器。</li>
</ol>
<div class="ibm-alternate-rule" style="color: #000000;"></div>
<p class="ibm-ind-link ibm-back-to-top" style="color: #222222;"><a class="ibm-anchor-up-link" style="font-weight: bold; color: #745285;" href="http://www.ibm.com/developerworks/cn/java/j-lo-jenkins/#ibm-pcon">回页首</a></p>
<h2 id="major2" style="color: #000000;">Jenkins 简介</h2>
<p style="color: #222222;">Jenkins 是一个开源项目，提供了一种易于使用的持续集成系统，使开发者从繁杂的集成中解脱出来，专注于更为重要的业务逻辑实现上。同时 Jenkins 能实施监控集成中存在的错误，提供详细的日志文件和提醒功能，还能用图表的形式形象地展示项目构建的趋势和稳定性。下面将介绍 Jenkins 的基本功能。</p>
<p style="color: #222222;">Jenkins 的安装非常简单，只需要从 Jenkins 的主页上下载最新的 jenkins.war 文件然后运行 java -jar jenkins.war。同时，还可以点击 Jenkins 页面上的 launch 按钮完成下载和运行 Jenkins。</p>
<h5 id="fig1" style="color: #000000;">图 1. Jenkins Launch 按钮</h5>
<p><img style="color: #000000;" src="http://www.ibm.com/developerworks/cn/java/j-lo-jenkins/image003.jpg" alt="图 1. Jenkins Launch 按钮" width="515" /></p>
<p style="color: #222222;">启动 Jenkins 后，会有一个后台进程在命令行模式下运行。此时在浏览器地址栏中打开 http://localhost:8080 就可以看到 Jenkins 的页面了。Jenkins 的可贵之处在于具有非常高的可用性，从它的界面中能很轻松地完成各种配置，更多的配置和使用信息，可以在 Jenkins 的官方网站上查询。</p>
<h5 id="fig2" style="color: #000000;">图 2. 命令行模式下运行 Jenkins</h5>
<p><img style="color: #000000;" src="http://www.ibm.com/developerworks/cn/java/j-lo-jenkins/image005.jpg" alt="图 2. 命令行模式下运行 Jenkins" width="559" /></p>
<h5 id="fig3" style="color: #000000;">图 3. Jenkins 主界面</h5>
<p><img style="color: #000000;" src="http://www.ibm.com/developerworks/cn/java/j-lo-jenkins/image007.jpg" alt="图 3. Jenkins 主界面" width="539" /></p>
<p style="color: #222222;">非常有趣的是，Jenkins 还提供了非常丰富的插件支持，这使得 Jenkins 变得越来越强大。我们可以方便的安装各种第三方插件，从而方便快捷的集成第三方的应用。比如 Jenkins 提供了对于 IBM Rational ClearCase 的插件支持。</p>
<h5 id="fig4" style="color: #000000;">图 4. Jenkins 可以集成 ClearCase 插件</h5>
<p><img style="color: #000000;" src="http://www.ibm.com/developerworks/cn/java/j-lo-jenkins/image009.jpg" alt="图 4. Jenkins 可以集成 ClearCase 插件" width="525" /></p>
<p style="color: #222222;">此外，Jenkins 提供了丰富的管理和配置的功能，包括系统配置、管理插件、查看系统信息、系统日志、节点管理、Jenkins 命令行窗口、信息统计等功能。试试看，您就会发现 Jenkins 非常好上手使用。</p>
<h5 id="fig5" style="color: #000000;">图 5. Jenkins 提供了丰富的管理功能</h5>
<p><img style="color: #000000;" src="http://www.ibm.com/developerworks/cn/java/j-lo-jenkins/image011.jpg" alt="图 5. Jenkins 提供了丰富的管理功能" width="542" /></p>
<div class="ibm-alternate-rule" style="color: #000000;"></div>
<p class="ibm-ind-link ibm-back-to-top" style="color: #222222;"><a class="ibm-anchor-up-link" style="font-weight: bold; color: #745285;" href="http://www.ibm.com/developerworks/cn/java/j-lo-jenkins/#ibm-pcon">回页首</a></p>
<h2 id="major3" style="color: #000000;">基于 Jenkins 快速搭建持续集成环境</h2>
<p style="color: #222222;">正如前文中所描述的那样，一个持续集成环境需要包括三个方面要素：代码存储库、构建过程和持续集成服务器。对 Jenkins 有了初步了解后，我们通过一个实例来集中展示如何快速搭建一个简单的基于 Jenkins 的持续集成环境。</p>
<p style="color: #222222;">假设我们使用的代码存储库是 IBM Rational ClearCase。Jenkins 提供了对 ClearCase 的插件支持，它能方便地让我们连接到 Base ClearCase 或者 UCM ClearCase，使其成为 Jenkins Project 的代码控制器。另外，这个插件是基于 cleartool 命令的，所以必须在 Jenkins 的持续集成服务器上安装 ClearCase 的客户端程序。</p>
<p style="color: #222222;">在 Jenkins 的插件管理界面中选择 ClearCase Plugin，点击页面下方的 Install 按钮。</p>
<h5 id="fig6" style="color: #000000;">图 6. 选择 ClearCase 插件</h5>
<p><img style="color: #000000;" src="http://www.ibm.com/developerworks/cn/java/j-lo-jenkins/image013.jpg" alt="图 6. 选择 ClearCase 插件" width="558" /></p>
<p style="color: #222222;">在打开的页面中提示安装完成后，Jenkins 需要重新启动来激活这个插件。重新执行 java -jar Jenkins.war 后，在 Jenkins 的页面中，我们就能看到 ClearCase plugin 已经被安装到 Jenkins 了。</p>
<h5 id="fig7" style="color: #000000;">图 7. ClearCase 插件安装成功</h5>
<p><img style="color: #000000;" src="http://www.ibm.com/developerworks/cn/java/j-lo-jenkins/image015.jpg" alt="图 7. ClearCase 插件安装成功" width="563" /></p>
<p style="color: #222222;">类似 IBM Rational ClearCase，SVN（subversion）是目前比较流行的版本管理工具。很多开源软件都是用 SVN 作为代码版本管理软件。为了让实例更具有代表性，本文中我们使用 SVN 作为代码存储器。</p>
<p style="color: #222222;">接下来，我们开始新建一个 Jenkins 项目， 由于我们需要连接 SVN 的代码存储器， 我们选择 Build a free-style software project。</p>
<h5 id="fig8" style="color: #000000;">图 8. 新建 JenkinsTest Job</h5>
<p><img style="color: #000000;" src="http://www.ibm.com/developerworks/cn/java/j-lo-jenkins/image017.jpg" alt="图 8. 新建 JenkinsTest Job" width="575" /></p>
<p style="color: #222222;">然后我们就可以很方便的配置这个 JenkinsTest 项目了。Jenkins 很人性化的一点是在每个配置项的右侧都有一个帮助的图标，点击这个图标，Jenkins 会告诉您如何配置这个配置项。</p>
<h5 id="fig9" style="color: #000000;">图 9. 配置 JenkinsTest</h5>
<p><img style="color: #000000;" src="http://www.ibm.com/developerworks/cn/java/j-lo-jenkins/image019.jpg" alt="图 9. 配置 JenkinsTest" width="559" /></p>
<p style="color: #222222;">根据实际的 SVN 服务器服务器信息配置 Source Code Management，这能让 Jenkins 知道如何从哪里获取最新的代码。本例中假设 Repository 就在本地。</p>
<h5 id="fig10" style="color: #000000;">图 10. 配置连接到 SVN 服务器</h5>
<p><img style="color: #000000;" src="http://www.ibm.com/developerworks/cn/java/j-lo-jenkins/image021.jpg" alt="图 10. 配置连接到 SVN 服务器" width="551" /></p>
<p style="color: #222222;">根据开发需要，假设每一个小时我们需要重新构建一次。选择 Build periodically，在 Schedule 中填写 0 * * * *。</p>
<p style="color: #222222;">第一个参数代表的是分钟 minute，取值 0~59；</p>
<p style="color: #222222;">第二个参数代表的是小时 hour，取值 0~23；</p>
<p style="color: #222222;">第三个参数代表的是天 day，取值 1~31；</p>
<p style="color: #222222;">第四个参数代表的是月 month，取值 1~12；</p>
<p style="color: #222222;">最后一个参数代表的是星期 week，取值 0~7，0 和 7 都是表示星期天。</p>
<p style="color: #222222;">所以 0 * * * * 表示的就是每个小时的第 0 分钟执行一次构建。</p>
<h5 id="fig11" style="color: #000000;">图 11. 选择如何触发构建</h5>
<p><img style="color: #000000;" src="http://www.ibm.com/developerworks/cn/java/j-lo-jenkins/image023.jpg" alt="图 11. 选择如何触发构建" width="512" /></p>
<p style="color: #222222;">接下来就是要添加 build 的步骤了。Jenkins 提供了四个选项供我们选择，可以根据需要执行或调用外部命令和脚本。</p>
<h5 id="fig12" style="color: #000000;">图 12. 四种 build step 供选择</h5>
<p><img style="color: #000000;" src="http://www.ibm.com/developerworks/cn/java/j-lo-jenkins/image025.jpg" alt="图 12. 四种 build step 供选择" width="513" /></p>
<p style="color: #222222;">在本例中，我们通过调用和执行 Windows batch command，将 SVN repository 中 Java 代码编译并生成 Jar 文件。也可以根据项目的实际编写自己的 shell 脚本配置在这里。</p>
<h5 id="fig13" style="color: #000000;">图 13. 配置 Execute Windows batch command</h5>
<p><img style="color: #000000;" src="http://www.ibm.com/developerworks/cn/java/j-lo-jenkins/image027.jpg" alt="图 13. 配置 Execute Windows batch command" width="564" /></p>
<p style="color: #222222;">选择和配置其他的选项，比如邮件提醒，然后点击 save 保存。</p>
<h5 id="fig14" style="color: #000000;">图 14. 配置邮件提醒</h5>
<p><img style="color: #000000;" src="http://www.ibm.com/developerworks/cn/java/j-lo-jenkins/image029.jpg" alt="图 14. 配置邮件提醒" width="567" /></p>
<p style="color: #222222;">接下来的每小时的第 0 分钟，JenkinsTest Job 就会被构建。我们可以在 Jenkins 中观察构建的进度和最终的状态——成功或者失败。太阳代表之前的构建没有任何失败，蓝色的小球代表构建成功。</p>
<h5 id="fig15" style="color: #000000;">图 15. JenkinsTest 开始构建</h5>
<p><img style="color: #000000;" src="http://www.ibm.com/developerworks/cn/java/j-lo-jenkins/image031.jpg" alt="图 15. JenkinsTest 开始构建" width="572" /></p>
<p style="color: #222222;">同时我们可以点击 JenkinsTest 查看单次构建的 Console 的输出结果。从中我们能看到构建的第一步是从 SVN 服务器上 check out 代码，然后调用我们先前配置的 Windows batch command。</p>
<h5 id="fig16" style="color: #000000;">图 16. JenkinsTest 构建的 console 输出</h5>
<p><img style="color: #000000;" src="http://www.ibm.com/developerworks/cn/java/j-lo-jenkins/image033.jpg" alt="图 16. JenkinsTest 构建的 console 输出" width="568" /></p>
<p style="color: #222222;">最后，我们可以看到 build 的最后结果 Success，表明本次构建成功。</p>
<h5 id="fig17" style="color: #000000;">图 17. 构建成功的 Console 输出</h5>
<p><img style="color: #000000;" src="http://www.ibm.com/developerworks/cn/java/j-lo-jenkins/image035.jpg" alt="图 17. 构建成功的 Console 输出" width="565" /></p>
<p style="color: #222222;">接下来我们再次新建一个 Jenkins 的 Job，用于将生成的 build 分发到不同的节点上。这次 build triggers 我们选择 Build after other projects are built，让这个 Job 在 JenkinsTest 成功 build 后触发。这样一来就能达到我们自动 build 和自动分发的功能。</p>
<h5 id="fig18" style="color: #000000;">图 18. 新建 Distribute job</h5>
<p><img style="color: #000000;" src="http://www.ibm.com/developerworks/cn/java/j-lo-jenkins/image037.jpg" alt="图 18. 新建 Distribute job" width="534" /></p>
<p style="color: #222222;">不同的是，这次我们选择调用 Ant 脚本来完成分发的工作。只需要将 Ant 脚本的 XML 的文件配置在 Targets 中供 Jenkins 调用。</p>
<h5 id="fig19" style="color: #000000;">图 19. Distribute 调用外部 Ant 脚本</h5>
<p><img style="color: #000000;" src="http://www.ibm.com/developerworks/cn/java/j-lo-jenkins/image039.jpg" alt="图 19. Distribute 调用外部 Ant 脚本" width="516" /></p>
<p style="color: #222222;">然后我们就可以在 Jenkins 中观察构建的状态了。一旦构建失败我们能看到相应的警示图标，同时，如果配置了邮件提醒，相关人员也会受到邮件。记住我们先前所提醒的那样，分析和处理构建的失败是优先级最高的工作。接下来，我们还可以加入更多的 Jenkins 项目来实现自动化测试等功能，让持续集成更方便有效地服务于项目开发。</p>
<h5 id="fig20" style="color: #000000;">图 20. 查看持续集成状态</h5>
<p><img style="color: #000000;" src="http://www.ibm.com/developerworks/cn/java/j-lo-jenkins/image041.jpg" alt="图 20. 查看持续集成状态" width="559" /></p>
<div class="ibm-alternate-rule" style="color: #000000;"></div>
<p class="ibm-ind-link ibm-back-to-top" style="color: #222222;"><a class="ibm-anchor-up-link" style="font-weight: bold; color: #745285;" href="http://www.ibm.com/developerworks/cn/java/j-lo-jenkins/#ibm-pcon">回页首</a></p>
<h2 id="major4" style="color: #000000;">结束语</h2>
<p style="color: #222222;">本文简单介绍了持续集成的概念并着重介绍了如何基于 Jenkins 快速构建持续集成环境。通过具体实例的描述，相信读者对 Jenkins 的基本功能和实现方法有个更清楚地认识和理解。其实，Jenkins 的功能远不至文中所述的这些，Jenkins 还有详尽的日志处理和持续集成构建状态的分析等功能。希望在进一步的学习和应用中与大家分享。</p>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=979</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Jenkins知识地图</title>
		<link>https://www.softwareace.cn/?p=977</link>
		<comments>https://www.softwareace.cn/?p=977#comments</comments>
		<pubDate>Mon, 13 Oct 2014 11:54:42 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[软件测试]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=977</guid>
		<description><![CDATA[这篇文章大概写于三个月前，当时写了个大纲列表，但是在CSDN上传资源实在不方便，有时上传了莫名审核不通过，如果 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>这篇文章大概写于三个月前，当时写了个大纲列表，但是在CSDN上传资源实在不方便，有时上传了莫名审核不通过，如果以前有人上传过，也会导致上传失败。现在把之前工作中找到的好东西和各位分享。现在不搞这些了，也算是个归档吧。内容主要涉及Hudson/Jenkins的使用，维护，以及插件开发，开发的东西更多些吧。</p>
<p>首先说下Jenkins能干什么？说下两个典型的应用场景。</p>
<p>1. Git/Repo + Gerrit + Jenkins 打造强大的Android持续集成环境。用户上传代码到Gerrit进行code review和入库，用户上传代码操作和入库都可以触发Jenkins获取代码进行自动构建。Jenkins也可以定时构建，构建结果可以通过邮件自动发送给相关人员。当然用户提交代码到Gerrit时，Gerrit也会自动发邮件给具有代码检视权限的人员。</p>
<p>2. SVN/Git + Jenkins 以apk代码为例，Jenkins可以监测SVN/Git等代码配置库，一旦有人提交代码，就会自动获取代码进行构建，构建结果可以通过邮件在内的多种方式通知人员。</p>
<p>以下是之前文章的内容，稍作补充。</p>
<p>===================================</p>
<p>&nbsp;</p>
<p><strong>Jenkins知识地图</strong></p>
<div>Jenkins是一款优秀的持续集成工具，源于Hudson，后来由不同的团队维护，两者的使用方法，插件大部分通用，开发方法也大同小异。</div>
<div>在此罗列一些自己积累的一些资料，供有需要的人参考。</div>
<h2><a style="color: #336699;" name="t0"></a>1 Jenkins官方网站</h2>
<div>首先推荐Jenkins的官方网站。里面不但有Jenkins详细的使用说明，而且有针对于开发者的教程，墙裂推荐！</div>
<div><a style="color: #336699;" href="http://jenkins-ci.org/" target="_blank">http://jenkins-ci.org/</a></div>
<div><strong>Meet Jenkins</strong> 介绍Jenkins是什么</div>
<div><strong>Use Jenkins</strong> 介绍Jenkins的安装和使用</div>
<div><strong>Extend Jenkins</strong> 介绍Jenkins插件和Jenkins本身的开发</div>
<div><strong>Plugins</strong> 介绍Jenkins社区上已有的插件列表和使用Wiki，Wiki中介绍了插件的功能，使用方法，源码链接，应用情况。注意这里并没有插件hpi文件下载</div>
<div><strong>Plugin下载 </strong>hpi文件下载可以访问这里：<a style="color: #336699;" href="http://mirrors.jenkins-ci.org/plugins/" target="_blank">http://mirrors.jenkins-ci.org/plugins/</a> 。当然也可以自己将插件源码下载到本地编译即可。</div>
<div></div>
<h2><a style="color: #336699;" name="t1"></a>2. Jenkins书籍</h2>
<div>两本Jenkins书籍，网上都可以下载到。至于内容我看的也比较少。就不评论了。</div>
<div>下载链接不保证长期有效，需要的就尽快下载或转存到自己的网盘吧。</div>
<div>Jenkins: The Definitive Guide</div>
<div><a style="color: #336699;" href="http://pan.baidu.com/share/link?shareid=1021560144&amp;uk=1979754919" target="_blank">http://pan.baidu.com/share/link?shareid=1021560144&amp;uk=1979754919</a></div>
<div>Jenkins Continuous Integration Cookbook</div>
<div><a style="color: #336699;" href="http://pan.baidu.com/share/link?shareid=1025587179&amp;uk=1979754919" target="_blank">http://pan.baidu.com/share/link?shareid=1025587179&amp;uk=1979754919</a></div>
<div>JAVA开发超级工具集_第八章用Hudson持续集成</div>
<div>第一部分 <a style="color: #336699;" href="http://download.csdn.net/detail/marking122/4890033" target="_blank">http://download.csdn.net/detail/marking122/4890033</a></div>
<div>第二部分 <a style="color: #336699;" href="http://download.csdn.net/detail/marking122/4890047" target="_blank">http://download.csdn.net/detail/marking122/4890047</a></div>
<div></div>
<h2><a style="color: #336699;" name="t2"></a>3. Jenkins学习资料</h2>
<div>Continuous Deployment with Gerrit and Jenkins</div>
<div><a style="color: #336699;" href="http://pan.baidu.com/share/link?shareid=1029989664&amp;uk=1979754919" target="_blank">http://pan.baidu.com/share/link?shareid=1029989664&amp;uk=1979754919</a></div>
<div>这是Jenkins官方的一个PPT，建议先看看这个。复习一下基本知识。</div>
<div></div>
<div></div>
<h2><a style="color: #336699;" name="t3"></a>4. 一篇经典的Jenkins插件开发入门文档</h2>
<div>虽然出自Hudson，但是同样适用于Jenkins</div>
<div><a style="color: #336699;" href="http://www.eclipse.org/hudson/documents/Writing-first-hudson-plugin.pdf" target="_blank">http://www.eclipse.org/hudson/documents/Writing-first-hudson-plugin.pdf</a></div>
<div>附上一个百度网盘下载链接</div>
<div><a style="color: #336699;" href="http://pan.baidu.com/share/link?shareid=1032509575&amp;uk=1979754919" target="_blank">http://pan.baidu.com/share/link?shareid=1032509575&amp;uk=1979754919</a></div>
<div></div>
<div></div>
<h2><a style="color: #336699;" name="t4"></a>5. Hudson Architecture Documents</h2>
<div>Hudson官方网站上介绍Jenkins/Hudson架构很好的一个系列PPT</div>
<div>Hudson Architecture Documents</div>
<div><a style="color: #336699;" href="http://pan.baidu.com/share/link?shareid=1034319818&amp;uk=1979754919" target="_blank">http://pan.baidu.com/share/link?shareid=1034319818&amp;uk=1979754919</a></div>
<ul>
<li>Hudson Web/REST Architecture</li>
<li>Hudson View Architecture</li>
<li>Hudson Execution Architecture</li>
<li>Hudson Remote Execution Architecture</li>
<li>Hudson Security Architecture</li>
<li>Hudson Plugin Architecture</li>
</ul>
<h2><a style="color: #336699;" name="t5"></a>6. 国内某博主写的系列文章</h2>
<div>很实用，值得推荐。</div>
<div><a style="color: #336699;" href="http://www.cnblogs.com/itech/archive/2011/11/23/2260009.html" target="_blank">http://www.cnblogs.com/itech/archive/2011/11/23/2260009.html</a></div>
<div></div>
<h2><a style="color: #336699;" name="t6"></a>7. 淘宝Jenkins开发的系列文档</h2>
<div>网上找到的</div>
<div><a style="color: #336699;" href="http://pan.baidu.com/share/link?shareid=1036559705&amp;uk=1979754919" target="_blank">http://pan.baidu.com/share/link?shareid=1036559705&amp;uk=1979754919</a></div>
<div>
<div>1.使用软件包管理大规模应用.pdf</div>
<div>2.ABS总体介绍.pdf</div>
<div>3.ABS配置案例.pdf</div>
<div>4.DailyBuild简介.pdf</div>
<div>5.ABS与TOAST自动化测试对接介绍.pdf</div>
<div>6.Hudson插件开发-技术文档.pdf</div>
<div>8.Hudson后台管理.pdf</div>
<div>9.ABS常用插件介绍.pdf</div>
<div>abs使用手册.pdf</div>
<div></div>
</div>
<div>
<h2><a style="color: #336699;" name="t7"></a>8. 其他一些不错的中文博客</h2>
<div>涉及Jenkins/Hudson使用和开发的很多东西</div>
<div>jenkins 使用文档</div>
<div><a style="color: #336699;" href="http://blog.csdn.net/zhaoxu0312/article/details/7567361#" target="_blank">http://blog.csdn.net/zhaoxu0312/article/details/7567361#</a></div>
<div>Hudson插件之按主题分类。这个人的博客里还有很多的关于Hudson的资料。</div>
<div><a style="color: #336699;" href="http://jdonee.iteye.com/blog/515424" target="_blank">http://jdonee.iteye.com/blog/515424</a></div>
<div>Hudson插件开发简介</div>
<div><a style="color: #336699;" href="http://blog.csdn.net/littleatp2008/article/details/7001793" target="_blank">http://blog.csdn.net/littleatp2008/article/details/7001793</a></div>
<div>还有这个人的博客</div>
<div><a style="color: #336699;" href="http://scmbob.org/category/cat_jenkins" target="_blank">http://scmbob.org/category/cat_jenkins</a></div>
<div>还有这里</div>
<div><a style="color: #336699;" href="http://blog.csdn.net/OnlyQi/article/category/921911" target="_blank">http://blog.csdn.net/OnlyQi/article/category/921911</a></div>
<div></div>
<div>
<h2><a style="color: #336699;" name="t8"></a>9. 关于Jelly的教程</h2>
<div>Jenkins和插件的UI基本都是用jelly写的，对于jenkins开发非常重要。</div>
<div>jelly 借鉴jsp和jstl，tag library 有34个</div>
<div><a style="color: #336699;" href="http://commons.apache.org/proper/commons-jelly/" target="_blank">http://commons.apache.org/proper/commons-jelly/</a></div>
<div>常用的tag</div>
<div><a style="color: #336699;" href="https://jenkins-ci.org/maven-site/jenkins-core/jelly-taglib-ref.html" target="_blank">https://jenkins-ci.org/maven-site/jenkins-core/jelly-taglib-ref.html</a></div>
<div>Basic guide to Jelly usage in Jenkins</div>
<div><a style="color: #336699;" href="https://wiki.jenkins-ci.org/display/JENKINS/Basic+guide+to+Jelly+usage+in+Jenkins" target="_blank">https://wiki.jenkins-ci.org/display/JENKINS/Basic+guide+to+Jelly+usage+in+Jenkins</a></div>
<div>
<div>jelly:stapler</div>
<div><a style="color: #336699;" href="http://stapler.kohsuke.org/jelly-taglib-ref.html" target="_blank">http://stapler.kohsuke.org/jelly-taglib-ref.html</a></div>
</div>
</div>
<div></div>
<h2><a style="color: #336699;" name="t9"></a>10. 总结</h2>
<div></div>
<div></div>
<div>如果你能把上面的这样都大致看一遍，Jenkins的部署，维护和插件开发都没多大问题了。</div>
<div>总之，从开发的角度看，Jenkins涉及的东西非常多。</div>
<div>代码配置管理可能会涉及到 Git/Reop, SVN</div>
<div>简单的构建步骤是用shell或者batch脚本，有些也会是ant</div>
<div>Jenkins及插件开发会涉及maven</div>
<div>UI开发主要是Jelly，也会涉及到HTML/CSS, JavaScript，YahooUI，AJAX</div>
<div>逻辑开发主要是Java，分布式，JavaBean，JsonObject</div>
<div>Jenkins系统开发接触的比较少，最起码要了解REST API吧。</div>
</div>
<div></div>
<div>如果你是某司某持续集成项目组的成员，正好看到这篇文章，先去翻翻你们内部的博客或者服务器，也许能找到更多干货，那些总结的英文或中文的文档还是非常好的，哈哈。</div>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=977</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>xampp mysql 自动备份</title>
		<link>https://www.softwareace.cn/?p=928</link>
		<comments>https://www.softwareace.cn/?p=928#comments</comments>
		<pubDate>Mon, 01 Sep 2014 04:44:12 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[软件测试]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=928</guid>
		<description><![CDATA[set datevar=%date:~0,4%%date:~5,2%%date:~8,2% d: cd D:/ [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>set datevar=%date:~0,4%%date:~5,2%%date:~8,2%<br />
d:<br />
cd D:/xampp/mysql/bin<br />
mysqldump -uwps_email_zt -p123456789 zentao &gt; D:/xampp/mysql/mysqlBak/zentao_back%datevar%.sql<br />
exit</p>
<p>&nbsp;</p>
<p>http://jingyan.baidu.com/article/4f34706e8a2c29e387b56d9e.html</p>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=928</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>XAMPP 启用 LDAP 支持</title>
		<link>https://www.softwareace.cn/?p=926</link>
		<comments>https://www.softwareace.cn/?p=926#comments</comments>
		<pubDate>Wed, 27 Aug 2014 11:12:43 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[软件测试]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=926</guid>
		<description><![CDATA[解决方法：1. 复制 phplibsasl.dll 到 apachebin 路径下；2. 修改 phpphp. [&#8230;]]]></description>
				<content:encoded><![CDATA[<p><span style="color: #323e32;">解决方法：</span><br style="color: #323e32;" /><span style="color: #323e32;">1. 复制 phplibsasl.dll 到 apachebin 路径下；</span><br style="color: #323e32;" /><span style="color: #323e32;">2. 修改 phpphp.ini 文件，取消 extension=php_ldap.dll 的注释；</span><br style="color: #323e32;" /><span style="color: #323e32;">3. 启动 apache。</span></p>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=926</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>给禅道用户登陆函数成员，加入ldap验证</title>
		<link>https://www.softwareace.cn/?p=921</link>
		<comments>https://www.softwareace.cn/?p=921#comments</comments>
		<pubDate>Fri, 22 Aug 2014 09:26:36 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[软件测试]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=921</guid>
		<description><![CDATA[http://jkers.blog.51cto.com/3016670/579787/ &#160;]]></description>
				<content:encoded><![CDATA[<p>http://jkers.blog.51cto.com/3016670/579787/</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=921</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>黑盒测试用例设计方法</title>
		<link>https://www.softwareace.cn/?p=897</link>
		<comments>https://www.softwareace.cn/?p=897#comments</comments>
		<pubDate>Fri, 08 Aug 2014 09:32:57 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[软件测试]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=897</guid>
		<description><![CDATA[1. 概述   黑盒测试用例设计方法包括等价类划分法、边界值分析法、错误推测法、因果图法、判定表驱动法、正交试 [&#8230;]]]></description>
				<content:encoded><![CDATA[<div>
<h1><strong><span style="font-size: x-large;">1.</span> </strong><strong><span style="font-size: x-large;">概述</span></strong><strong></strong></h1>
<p><span style="font-family: 'Times New Roman';"> </span></p>
<p>黑盒测试用例设计方法包括等价类划分法、边界值分析法、错误推测法、因果图法、判定表驱动法、正交试验设计法、功能图法等。</p>
<p><br clear="all" /></p>
<h1><strong><span style="font-size: x-large;">2.</span> </strong><strong><span style="font-size: x-large;">等价类划分法</span></strong><strong></strong></h1>
<p><span style="font-family: 'Times New Roman';"> </span></p>
<div>
<h2><span style="font-size: medium;">2.1.</span>              <span style="font-size: medium;">概念</span></h2>
</div>
<p>等价类划分法是把程序的输入域划分成若干部分（子集），然后从每个部分中选取少数代表性数据作为测试用例。每一类的代表性数据在测试中的作用等价于这一类中的其他值。</p>
<p><span style="font-family: 'Times New Roman';"> </span></p>
<div>
<h2><span style="font-size: medium;">2.2.</span>              <span style="font-size: medium;">等价类划分法的应用</span></h2>
</div>
<ol>
<li>等价类是指某个输入域的子集合。在该子集合中，各个输入数据对于揭露程序中的错误都是等效的，并合理地假定：测试某等价类的代表值就等于对这一类其它值的测试.因此,可以把全部输入数据合理划分为若干等价类,在每一个等价类中取一个数据作为测试的输入条件,就可以用少量代表性的测试数据.取得较好的测试结果.等价类划分可有两种不同的情况:有效等价类和无效等价类。</li>
</ol>
<ul>
<li>有效等价类:是指对于程序的规格说明来说是合理的,有意义的输入数据构成的集合.利用有效等价类可检验程序是否实现了规格说明中所规定的功能和性能。</li>
<li>无效等价类:与有效等价类的定义恰巧相反。</li>
</ul>
<p>设计测试用例时,要同时考虑这两种等价类.因为,软件不仅要能接收合理的数据,也要能经受意外的考验.这样的测试才能确保软件具有更高的可靠性。</p>
<ol>
<li>划分等价类的六大原则：</li>
</ol>
<ul>
<li>在输入条件规定了取值范围或值的个数的情况下,则可以确立一个有效等价类和两个无效等价类.</li>
</ul>
<p>例：输入值是学生成绩，范围是0～100：</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<ul>
<li>在输入条件规定了输入值的集合或者规定了“必须如何”的条件的情况下,可确立一个有效等价类和一个无效等价类.</li>
<li>在输入条件是一个布尔量的情况下,可确定一个有效等价类和一个无效等价类. <span style="color: #cc0033;">布尔量</span>是一个二值枚举类型, 一个<span style="color: #cc0033;">布尔量</span>具有两种状态: true 和 false 。</li>
<li>在规定了输入数据的一组值（假定n个）,并且程序要对每一个输入值分别处理的情况下,可确立n个有效等价类和一个无效等价类.</li>
</ul>
<p>例：输入条件说明输入字符为:中文、英文、阿拉伯文三种之一，则分别取这三种这三个值作为三个有效等价类，另外把三种字符之外的任何字符作为无效等价类。</p>
<ul>
<li>在规定了输入数据必须遵守的规则的情况下,可确立一个有效等价类（符合规则）和若干个无效等价类（从不同角度违反规则）</li>
<li>在确知已划分的等价类中各元素在程序处理中的方式不同的情况下,则应再将该等价类进一步的划分为更小的等价类</li>
</ul>
<ol>
<li>将等价类转化成测试用例：</li>
</ol>
<ul>
<li>按照[输入条件][有效等价类][无效等价类] 建立等价类表,列出所有划分出的等价类</li>
<li>为每一个等价类规定一个唯一的编号.</li>
<li>设计一个新的测试用例,使其尽可能多地覆盖尚未被覆盖地有效等价类,重复这一步.直到所有的有效等价类都被覆盖为止.</li>
<li>设计一个新的测试用例,使其仅覆盖一个尚未被覆盖的无效等价类,重复这一步.直到所有的无效等价类都被覆盖为止.</li>
</ul>
<p><span style="font-family: 'Times New Roman';"> </span></p>
<div>
<h2><span style="font-size: medium;">2.3.</span>              <span style="font-size: medium;">等价类划分实例</span></h2>
</div>
<p>&nbsp;</p>
<ol>
<li>某程序规定：&#8221;输入三个整数 a 、 b 、 c 分别作为三边的边长构成三角形。通过程序判定所构成的三角形的类型，当此三角形为一般三角形、等腰三角形及等边三角形时，分别作计算 … &#8220;。用等价类划分方法为该程序进行测试用例设计。（三角形问题的复杂之处在于输入与输出之间的关系比较复杂。）</li>
</ol>
<p>分析题目中给出和隐含的对输入条件的要求：</p>
<p>（1）整数    （2）三个数    （3）非零数   （4）正数<br />
（5）两边之和大于第三边     （6）等腰     （7）等边<br />
如果 a 、 b 、 c 满足条件（ 1 ） ~ （ 4 ），则输出下列四种情况之一：<br />
1)如果不满足条件（5），则程序输出为 &#8221; 非三角形 &#8221; 。<br />
2)如果三条边相等即满足条件（7），则程序输出为 &#8221; 等边三角形 &#8221; 。<br />
3)如果只有两条边相等、即满足条件（6），则程序输出为 &#8221; 等腰三角形 &#8221; 。<br />
4)如果三条边都不相等，则程序输出为 &#8221; 一般三角形 &#8221; 。<br />
列出等价类表并编号</p>
<p align="center">
<p>&nbsp;</p>
<p>覆盖有效等价类的测试用例：</p>
<p>a      b      c              覆盖等价类号码</p>
<p>3      4      5             （1）&#8211;（7）</p>
<p>4      4      5             （1）&#8211;（7），（8）</p>
<p>4      5      5             （1）&#8211;（7），（9）</p>
<p>5      4      5             （1）&#8211;（7），（10）</p>
<p>4      4      4             （1）&#8211;（7），（11）</p>
<p>覆盖无效等价类的测试用例：</p>
<p align="center">
<ol>
<li>设有一个档案管理系统，要求用户输入以年月表示的日期。假设日期限定在1990年1月~2049年12月，并规定日期由6位数字字符组成，前4位表示年，后2位表示月。现用等价类划分法设计测试用例，来测试程序的&#8221;日期检查功能&#8221;。（不考虑2月的问题）</li>
</ol>
<p>1)划分等价类并编号,下表等价类划分的结果</p>
<div align="center">
<table width="494" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<p align="center"><strong>输入等价类</strong></p>
</td>
<td>
<p align="center"><strong>有效等价类</strong></p>
</td>
<td>
<p align="center"><strong>无效等价类</strong></p>
</td>
</tr>
<tr>
<td>日期的类型及长度</td>
<td>①6位数字字符</td>
<td>②有非数字字符</p>
<p>③少于6位数字字符</p>
<p>④多于6位数字字符</td>
</tr>
<tr>
<td>年份范围</td>
<td>⑤在1990~2049之间</td>
<td>⑥小于1990</p>
<p>⑦大于2049</td>
</tr>
<tr>
<td>月份范围</td>
<td>⑧在01~12之间</td>
<td>⑨等于00</p>
<p>⑩大于12</td>
</tr>
</tbody>
</table>
</div>
<p>2)设计测试用例，以便覆盖所有的有效等价类在表中列出了3个有效等价类，编号分别为①、⑤、⑧，设计的测试用例如下：</p>
<p>测试数据    期望结果      覆盖的有效等价类<br />
200211      输入有效      ①、⑤、⑧<br />
3)为每一个无效等价类设计一个测试用例，设计结果如下：<br />
测试数据   期望结果     覆盖的无效等价类<br />
95June     无效输入          ②<br />
20036      无效输入          ③<br />
2001006   无效输入          ④<br />
198912     无效输入          ⑥<br />
200401     无效输入          ⑦<br />
200100     无效输入          ⑨<br />
200113     无效输入          ⑩</p>
<ol>
<li>NextDate 函数包含三个变量：month 、 day 和 year ，函数的输出为输入日期后一天的日期。 例如，输入为 2006年3月 7日，则函数的输出为 2006年3月8日 。要求输入变量 month 、 day 和 year 均为整数值，并且满足下列条件：<br />
①1≤month≤12<br />
②1≤day≤31<br />
③1920≤year≤2050<br />
1)有效等价类为：<br />
M1＝{月份：1≤月份≤12}<br />
D1＝{日期：1≤日期≤31}<br />
Y1＝{年：1812≤年≤2012}<br />
2)若条件 ① ~ ③中任何一个条件失效，则 NextDate 函数都会产生一个输出，指明相应的变量超出取值范围，比如 &#8220;month 的值不在 1-12 范围当中 &#8221; 。显然还存在着大量的 year 、 month 、 day 的无效组合， NextDate 函数将这些组合作统一的输出： &#8221; 无效输入日期 &#8221; 。其无效等价类为：<br />
M2＝{月份：月份&lt;1}<br />
M3＝{月份：月份&gt;12}<br />
D2＝{日期：日期&lt;1}<br />
D3＝{日期：日期&gt;31}<br />
Y2＝{年：年&lt;1812}<br />
Y3＝{年：年&gt;2012}<br />
弱一般等价类测试用例<br />
月份    日期       年               预期输出<br />
6       15        1912           1912年6月16日<br />
强一般等价类测试用例同弱一般等价类测试用例<br />
注：弱&#8211;有单缺陷假设；健壮&#8211;考虑了无效值</p>
<p>(一)弱健壮等价类测试<br />
用例ID   月份  日期    年          预期输出<br />
WR1      6      15    1912      1912年6月16日<br />
WR2     -1     15    1912      月份不在1～12中<br />
WR3     13     15    1912      月份不在1～12中<br />
WR4      6      -1    1912      日期不在1～31中<br />
WR5      6      32    1912      日期不在1～31中<br />
WR6      6      15    1811      年份不在1812～2012中<br />
WR7      6      15    2013      年份不在1812～2012中</li>
</ol>
<p>(二)强健壮等价类测试<br />
用例ID   月份    日期      年          预期输出<br />
SR1       -1      15       1912      月份不在1～12中<br />
SR2        6      -1        1912      日期不在1～31中<br />
SR3        6      15       1811      年份不在1812～2012中<br />
SR4       -1      -1       1912      两个无效一个有效<br />
SR5        6      -1        1811      两个无效一个有效<br />
SR6       -1      15       1811      两个无效一个有效<br />
SR7       -1      -1       1811      三个无效</p>
<ol>
<li>佣金问题等价类测试用例，它是根据佣金函数的输出值域定义等价类，来改进测试用例集合。<br />
输出销售额≤1000元     佣金10％<br />
1000&lt;销售额≤1800     佣金=100+(销售额-1000)*15%<br />
销售额&gt;1800              佣金=220+(销售额-1800)*20%<br />
测试用例         枪机(45)    枪托(30)      枪管(25)          销售额     佣金<br />
1               5             5                5                  500        50<br />
2              15           15              15                 1500       175<br />
3              25           25              25                 2500       360<br />
根据输出域选择输入值，使落在输出域等价类内，可以结合弱健壮测试用例结合。</li>
</ol>
<h1></h1>
<p><span style="font-family: 'Times New Roman';"> </span></p>
<p><br clear="all" />&nbsp;</p>
<h1><strong><span style="font-size: x-large;">3.</span> </strong><strong><span style="font-size: x-large;">边界值分析法</span></strong><strong></strong></h1>
<p><span style="font-family: 'Times New Roman';"> </span></p>
<div>
<h2><span style="font-size: medium;">3.1.</span>              <span style="font-size: medium;">概念</span></h2>
</div>
<p>&nbsp;</p>
<p>边界值分析法就是对输入或输出的边界值进行测试的一种黑盒测试方法。通常边界值分析法是作为对等价类划分法的补充，这种情况下，其测试用例来自等价类的边界。</p>
<div>
<h2><span style="font-size: medium;">3.2.</span>              <span style="font-size: medium;">边界值分析法的应用</span></h2>
</div>
<p>&nbsp;</p>
<p>根据大量的测试统计数据，很多错误是发生在输入或输出范围的边界上，而不是发生在输入/输出范围的中间区域。因此针对各种边界情况设计测试用例，可以查出更多的错误。</p>
<p>使用边界值分析方法设计测试用例，首先应确定边界情况。通常输入和输出等价类的边界，就是应着重测试的边界情况。应当选取正好等于，刚刚大于或刚刚小于边界的值作为测试数据，而不是选取等价类中的典型值或任意值作为测试数据。</p>
<p>1.     边界值分析法与等价类分析法的区别：</p>
<p>1)    边界值分析不是从某等价类中随便挑一个作为代表，而是使这个等价类的每个边界都要作为测试条件。</p>
<p>2)    边界值分析不仅考虑输入条件，还要考虑输出空间产生的测试情况。</p>
<p>例：测试计算平方根的函数</p>
<p>&#8211;输入：实数</p>
<p>&#8211;输出：实数</p>
<p>&#8211;需求说明：当输入一个0或比0大的数的时候，返回其正平方根；当输入一个小于0的数时，显示错误信息&#8221;平方根非法-输入值小于0&#8243;并返回0；库函数Print-Line可以用来输出错误信息。</p>
<p>A.    等价类划分：<br />
I.可以考虑作出如下划分：<br />
a、输入 (i)&lt;0 和 (ii)&gt;=0<br />
b、输出 (a)&gt;=0 和 (b) Error<br />
II.测试用例有两个：<br />
a、输入4，输出2。对应于 (ii) 和 (a) 。<br />
b、输入-10，输出0和错误提示。对应于 (i) 和 (b)。</p>
<p>B.     边界值分析：</p>
<p>划分(ii)的边界为0和最大正实数；划分(i)的边界为最小负实数和0。由此得到以下测试用例：<br />
a、输入 {最小负实数}<br />
b、输入 {绝对值很小的负数}<br />
c、输入 0<br />
d、输入 {绝对值很小的正数}<br />
e、输入 {最大正实数}</p>
<p>2.     通常情况下，软件测试所包含的边界检验有几种类型：数字、字符、位置、重量、大小、速度、方位、尺寸、空间等。</p>
<p>3.     相应地，以上类型的边界值应该在：最大/最小、首位/末位、上/下、最快/最慢、最高/最低、  最短/最长、 空/满等情况下。利用边界值作为测试数据</p>
<p align="center">
<div align="center">
<table width="506" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="47">
<p align="center"><strong>项</strong></p>
</td>
<td width="93">
<p align="center"><strong>边界值</strong></p>
</td>
<td width="366">
<p align="center"><strong>测试用例的设计思路</strong></p>
</td>
</tr>
<tr>
<td width="47">字符</td>
<td width="93">起始-1个字符/结束+1个字符</td>
<td width="366">假设一个文本输入区域允许输入1个到255个 字符，输入1个和255个字符作为有效等价类；输入0个和256个字符作为无效等价类，这几个数值都属于边界条件值。</td>
</tr>
<tr>
<td width="47">数值</td>
<td width="93">最小值-1/最大值+1</td>
<td width="366">假设某软件的数据输入域要求输入5位的数据值，可以使用10000作为最小值、99999作为最大值；然后使用刚好小于5位和大于5位的 数值来作为边界条件。</td>
</tr>
<tr>
<td width="47">空间</td>
<td width="93">小于空余空间一点/大于满空间一点</td>
<td width="366">例如在用U盘存储数据时，使用比剩余磁盘空间大一点（几KB）的文件作为边界条件。</td>
</tr>
</tbody>
</table>
</div>
<p>&nbsp;</p>
<p>4.     内部边界值分析：<br />
在多数情况下，边界值条件是基于应用程序的功能设计而需要考虑的因素，可以从软件的规格说明或常识中得到，也是最终用户可以很容易发现问题的。然而，在测试用例设计过程中，某些边界值条件是不需要呈现给用户的，或者说用户是很难注意到的，但同时确实属于检验范畴内的边界条件，称为内部边界值条件或子边界值条件。<br />
内部边界值条件主要有下面几种：</p>
<p>1)    数值的边界值检验：计算机是基于二进制进行工作的，因此，软件的任何数值运算都有一定的范围限制。</p>
<div align="center">
<table width="454" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="106">
<p align="center"><strong>项</strong></p>
</td>
<td valign="top" width="347">
<p align="center"><strong>范围或值</strong></p>
</td>
</tr>
<tr>
<td valign="top" width="106">
<p align="center">位（bit）</p>
</td>
<td valign="top" width="347">
<p align="center">0 或 1</p>
</td>
</tr>
<tr>
<td valign="top" width="106">
<p align="center">字节（byte）</p>
</td>
<td valign="top" width="347">
<p align="center">0 ~ 255</p>
</td>
</tr>
<tr>
<td valign="top" width="106">
<p align="center">字（word）</p>
</td>
<td valign="top" width="347">
<p align="center">0~65535（单字）或 0~4294967295（双字）</p>
</td>
</tr>
<tr>
<td valign="top" width="106">
<p align="center">千（K）</p>
</td>
<td valign="top" width="347">
<p align="center">1024</p>
</td>
</tr>
<tr>
<td valign="top" width="106">
<p align="center">兆（M）</p>
</td>
<td valign="top" width="347">
<p align="center">1048576</p>
</td>
</tr>
<tr>
<td valign="top" width="106">
<p align="center">吉（G）</p>
</td>
<td valign="top" width="347">
<p align="center">1073741824</p>
</td>
</tr>
</tbody>
</table>
</div>
<p>&nbsp;</p>
<p>2)    字符的边界值检验：在计算机软件中，字符也是很重要的表示元素，其中ASCII和Unicode是常见的编码方式。如下列出了一些常用字符对应的ASCII码值。</p>
<p>&nbsp;</p>
<div align="center">
<table width="215" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="103">
<p align="center"><strong>字符</strong></p>
</td>
<td valign="top" width="113">
<p align="center"><strong>ASCII</strong><strong>码值</strong></p>
</td>
</tr>
<tr>
<td valign="top" width="103">
<p align="center">空 (null)</p>
</td>
<td valign="top" width="113">
<p align="center">0</p>
</td>
</tr>
<tr>
<td valign="top" width="103">
<p align="center">空格(space)</p>
</td>
<td valign="top" width="113">
<p align="center">32</p>
</td>
</tr>
<tr>
<td valign="top" width="103">
<p align="center">可输入的字符</p>
</td>
<td valign="top" width="113">
<p align="center">33~126</p>
</td>
</tr>
<tr>
<td valign="top" width="103">
<p align="center">0~9</p>
</td>
<td valign="top" width="113">
<p align="center">48~57</p>
</td>
</tr>
<tr>
<td valign="top" width="103">
<p align="center">A~Z</p>
</td>
<td valign="top" width="113">
<p align="center">65~90</p>
</td>
</tr>
<tr>
<td valign="top" width="103">
<p align="center">a~z</p>
</td>
<td valign="top" width="113">
<p align="center">97~122</p>
</td>
</tr>
</tbody>
</table>
</div>
<p>&nbsp;</p>
<p>3)     其它边界值检验：在不同的行业应用领域，依据硬件和软件的标准不同而具有各自特定的边界值。如下列出部分手机相关的边界值：</p>
<div align="center">
<table width="475" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="137">
<p align="center"><strong>硬件设备</strong></p>
</td>
<td valign="top" width="338">
<p align="center"><strong>范围或值</strong></p>
</td>
</tr>
<tr>
<td valign="top" width="137">
<p align="center">手机锂电池电压</p>
</td>
<td valign="top" width="338">工作电压：3.6~4.2V；</p>
<p>保护电压：2.5~3V不等</td>
</tr>
<tr>
<td valign="top" width="137">
<p align="center">手机正常使用温度</p>
</td>
<td valign="top" width="338">
<p align="center">-25°C~+60°C</p>
</td>
</tr>
</tbody>
</table>
</div>
<p>&nbsp;</p>
<p>5.     基于边界值分析方法选择测试用例的原则</p>
<p>1)    如果输入条件规定了值的范围,则应取刚达到这个范围的边界的值,以及刚刚超越这个范围边界的值作为测试输入数据。</p>
<p>Ø  例如，如果程序的规格说明中规定：&#8221;重量在10公斤至50公斤范围内的邮件，其邮费计算公式为……&#8221;。作为测试用例，我们应取10及50，还应取10.01,49.99,9.99及50.01等。</p>
<p>2)    如果输入条件规定了值的个数,则用最大个数,最小个数,比最小个数少一,比最大个数多一的数作为测试数据。</p>
<p>Ø  例如，一个输入文件应包括1~255个记录，则测试用例可取1和255，还应取0及256等。</p>
<p>3)    将规则1）和2）应用于输出条件，即设计测试用例使输出值达到边界值及其左右的值。</p>
<p>Ø  例如，某程序的规格说明要求计算出&#8221;每月保险金扣除额为0至1165.25元&#8221;，其测试用例可取0.00及1165.24、还可取一0.01及1165．26等。</p>
<p>Ø  再如一程序属于情报检索系统，要求每次&#8221;最少显示1条、最多显示4条情报摘要&#8221;，这时我们应考虑的测试用例包括1和4，还应包括0和5等。</p>
<p>4)    如果程序的规格说明给出的输入域或输出域是有序集合,则应选取集合的第一个元素和最后一个元素作为测试用例。</p>
<p>5)    如果程序中使用了一个内部数据结构,则应当选择这个内部数据结构的边界上的值作为测试用例。</p>
<p>6)    分析规格说明,找出其它可能的边界条件。</p>
<p>&nbsp;</p>
<div>
<h2><span style="font-size: medium;">3.3.</span>              <span style="font-size: medium;">实例</span></h2>
</div>
<p>&nbsp;</p>
<p>1.     现有一个学生标准化考试批阅试卷,产生成绩报告的程序。其规格说明如下:程序的输入文件由一些有80个字符的记录组成,如右图所示，所有记录分为3组：</p>
<p align="center">
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>1)    标题：这一组只有一个记录，其内容为输出成绩报告的名字。</p>
<p>2)    试卷各题标准答案记录：每个记录均在第80个字符处标以数字&#8221;2&#8243;。该组的第一个记录的第1至第3个字符为题目编号（取值为1一999）。第10至第59个字符给出第1至第50题的答案（每个合法字符表示一个答案）。该组的第2，第3……个记录相应为第51至第100，第101至第150，…题的答案。</p>
<p>3)    每个学生的答卷描述：该组中每个记录的第80个字符均为数字&#8221;3&#8243;。每个学生的答卷在若干个记录中给出。如甲的首记录第1至第9字符给出学生姓名及学号，第10至第59字符列出的是甲所做的第1至第50题的答案。若试题数超过50，则第2，第3……纪录分别给出他的第51至第100，第101至第150……题的解答。然后是学生乙的答卷记录。</p>
<p>4)    学生人数不超过200，试题数不超过999。</p>
<p>5)    程序的输出有4个报告：<br />
a)按学号排列的成绩单，列出每个学生的成绩、名次。<br />
b)按学生成绩排序的成绩单。<br />
c)平均分数及标准偏差的报告。<br />
d)试题分析报告。按试题号排序，列出各题学生答对的百分比。</p>
<p>解答：分别考虑输入条件和输出条件，以及边界条件。给出下表所示的输入条件及相应的测试用例。</p>
<p align="center">
<p>输出条件及相应的测试用例表。</p>
<p align="center">
<p>2.     三角形问题的边界值分析测试用例<br />
在三角形问题描述中，除了要求边长是整数外，没有给出其它的限制条件。在此，我们将三角形每边边长的取范围值设值为[1, 100] 。</p>
<div align="center">
<table width="489" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="82">
<p align="center"><strong>测试用例</strong></p>
</td>
<td valign="top" width="93">
<p align="center"><strong>a</strong></p>
</td>
<td valign="top" width="100">
<p align="center"><strong>b</strong></p>
</td>
<td valign="top" width="100">
<p align="center"><strong>c</strong></p>
</td>
<td valign="top" width="113">
<p align="center"><strong>预期输出</strong></p>
</td>
</tr>
<tr>
<td valign="top" width="82">
<p align="center">Test1</p>
<p align="center">Test2</p>
<p align="center">Test3</p>
<p align="center">Test4</p>
<p align="center">Test5</p>
</td>
<td valign="top" width="93">
<p align="center">60</p>
<p align="center">60</p>
<p align="center">60</p>
<p align="center">50</p>
<p align="center">50</p>
</td>
<td valign="top" width="100">
<p align="center">60</p>
<p align="center">60</p>
<p align="center">60</p>
<p align="center">50</p>
<p align="center">50</p>
</td>
<td valign="top" width="100">
<p align="center">1</p>
<p align="center">2</p>
<p align="center">60</p>
<p align="center">99</p>
<p align="center">100</p>
</td>
<td valign="top" width="113">
<p align="center">等腰三角形</p>
<p align="center">等腰三角形</p>
<p align="center">等边三角形</p>
<p align="center">等腰三角形</p>
<p align="center">非三角形</p>
</td>
</tr>
<tr>
<td valign="top" width="82">
<p align="center">Test6</p>
<p align="center">Test7</p>
<p align="center">Test8</p>
<p align="center">Test9</p>
</td>
<td valign="top" width="93">
<p align="center">60</p>
<p align="center">60</p>
<p align="center">50</p>
<p align="center">50</p>
</td>
<td valign="top" width="100">
<p align="center">1</p>
<p align="center">2</p>
<p align="center">99</p>
<p align="center">100</p>
</td>
<td valign="top" width="100">
<p align="center">60</p>
<p align="center">60</p>
<p align="center">50</p>
<p align="center">50</p>
</td>
<td valign="top" width="113">
<p align="center">等腰三角形</p>
<p align="center">等腰三角形</p>
<p align="center">等腰三角形</p>
<p align="center">非三角形</p>
</td>
</tr>
<tr>
<td valign="top" width="82">
<p align="center">Test10</p>
<p align="center">Test11</p>
<p align="center">Test12</p>
<p align="center">Test13</p>
</td>
<td valign="top" width="93">
<p align="center">1</p>
<p align="center">2</p>
<p align="center">99</p>
<p align="center">100</p>
</td>
<td valign="top" width="100">
<p align="center">60</p>
<p align="center">60</p>
<p align="center">50</p>
<p align="center">50</p>
</td>
<td valign="top" width="100">
<p align="center">60</p>
<p align="center">60</p>
<p align="center">50</p>
<p align="center">50</p>
</td>
<td valign="top" width="113">
<p align="center">等腰三角形</p>
<p align="center">等腰三角形</p>
<p align="center">等腰三角形</p>
<p align="center">非三角形</p>
</td>
</tr>
</tbody>
</table>
</div>
<p>3.     NextDate函数的边界值分析测试用例<br />
在NextDate函数中，隐含规定了变量mouth和变量day的取值范围为1≤mouth≤12和1≤day≤31，并设定变量year的取值范围为1912≤year≤2050 。</p>
<div align="center">
<table width="503" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="90">
<p align="center"><strong>测试用例</strong></p>
</td>
<td valign="top" width="82">
<p align="center"><strong>mouth</strong></p>
</td>
<td valign="top" width="87">
<p align="center"><strong>day</strong></p>
</td>
<td valign="top" width="91">
<p align="center"><strong>year</strong></p>
</td>
<td valign="top" width="153">
<p align="center"><strong>预期输出</strong></p>
</td>
</tr>
<tr>
<td valign="top" width="90">
<p align="center">Test1</p>
<p align="center">Test2</p>
<p align="center">Test3</p>
<p align="center">Test4</p>
<p align="center">Test5</p>
<p align="center">Test6</p>
<p align="center">Test7</p>
</td>
<td valign="top" width="82">
<p align="center">6</p>
<p align="center">6</p>
<p align="center">6</p>
<p align="center">6</p>
<p align="center">6</p>
<p align="center">6</p>
<p align="center">6</p>
</td>
<td valign="top" width="87">
<p align="center">15</p>
<p align="center">15</p>
<p align="center">15</p>
<p align="center">15</p>
<p align="center">15</p>
<p align="center">15</p>
<p align="center">15</p>
</td>
<td valign="top" width="91">
<p align="center">1911</p>
<p align="center">1912</p>
<p align="center">1913</p>
<p align="center">1975</p>
<p align="center">2049</p>
<p align="center">2050</p>
<p align="center">2051</p>
</td>
<td valign="top" width="153">
<p align="center">1911.6.16</p>
<p align="center">1912.6.16</p>
<p align="center">1913.6.16</p>
<p align="center">1975.6.16</p>
<p align="center">2049.6.16</p>
<p align="center">2050.6.16</p>
<p align="center">2051.6.16</p>
</td>
</tr>
<tr>
<td valign="top" width="90">
<p align="center">Test8</p>
<p align="center">Test9</p>
<p align="center">Test10</p>
<p align="center">Test11</p>
<p align="center">Test12</p>
<p align="center">Test13</p>
</td>
<td valign="top" width="82">
<p align="center">6</p>
<p align="center">6</p>
<p align="center">6</p>
<p align="center">6</p>
<p align="center">6</p>
<p align="center">6</p>
</td>
<td valign="top" width="87">
<p align="center">-1</p>
<p align="center">1</p>
<p align="center">2</p>
<p align="center">30</p>
<p align="center">31</p>
<p align="center">32</p>
</td>
<td valign="top" width="91">
<p align="center">2001</p>
<p align="center">2001</p>
<p align="center">2001</p>
<p align="center">2001</p>
<p align="center">2001</p>
<p align="center">2001</p>
</td>
<td valign="top" width="153">
<p align="center">day超出[1…31]</p>
<p align="center">2001.6.2</p>
<p align="center">2001.6.3</p>
<p align="center">2001.7.1</p>
<p align="center">输入日期超界</p>
<p align="center">day超出[1…31]</p>
</td>
</tr>
<tr>
<td valign="top" width="90">
<p align="center">Test14</p>
<p align="center">Test15</p>
<p align="center">Test16</p>
<p align="center">Test17</p>
<p align="center">Test18</p>
<p align="center">Test19</p>
</td>
<td valign="top" width="82">
<p align="center">-1</p>
<p align="center">1</p>
<p align="center">2</p>
<p align="center">11</p>
<p align="center">12</p>
<p align="center">13</p>
</td>
<td valign="top" width="87">
<p align="center">15</p>
<p align="center">15</p>
<p align="center">15</p>
<p align="center">15</p>
<p align="center">15</p>
<p align="center">15</p>
</td>
<td valign="top" width="91">
<p align="center">2001</p>
<p align="center">2001</p>
<p align="center">2001</p>
<p align="center">2001</p>
<p align="center">2001</p>
<p align="center">2001</p>
</td>
<td valign="top" width="153">
<p align="center">Mouth超出[1…12]</p>
<p align="center">2001.1.16</p>
<p align="center">2001.2.16</p>
<p align="center">2001.11.16</p>
<p align="center">2001.12.16</p>
<p align="center">Mouth超出[1…12]</p>
</td>
</tr>
</tbody>
</table>
</div>
<p>&nbsp;</p>
<p><br clear="all" /></p>
<h1><strong><span style="font-size: x-large;">4.</span> </strong><strong><span style="font-size: x-large;">错误推断法</span></strong><strong></strong></h1>
<p><span style="font-family: 'Times New Roman';"> </span></p>
<div>
<h2><span style="font-size: medium;">4.1.</span>              <span style="font-size: medium;">概念</span></h2>
</div>
<p>&nbsp;</p>
<p>基于经验和直觉推测程序中所有可能存在的各种错误, 从而有针对性的设计测试用例的方法。</p>
<div>
<h2><span style="font-size: medium;">4.2.</span>              <span style="font-size: medium;">错误推断法的应用</span></h2>
</div>
<p>&nbsp;</p>
<p>基本思想：列举出程序中所有可能有的错误和容易发生错误的特殊情况,根据他们选择测试用例。</p>
<p>1.     例如, 输入数据和输出数据为0的情况；输入表格为空格或输入表格只有一行。 这些都是容易发生错误的情况。可选择这些情况下的例子作为测试用例。</p>
<p>2.     例如，前面例子中成绩报告的程序，采用错误推测法还可补充设计一些测试用例：</p>
<p>1)     程序是否把空格作为回答</p>
<p>2)     在回答记录中混有标准答案记录</p>
<p>3)     除了标题记录外，还有一些的记录最后一个字符即不是2也不是3</p>
<p>4)     有两个学生的学号相同</p>
<p>5)     试题数是负数</p>
<p>3.     例如，测试一个对线性表（比如数组）进行排序的程序，可推测列出以下几项需要特别测试的情况：</p>
<p>1)    输入的线性表为空表；</p>
<p>2)    表中只含有一个元素；</p>
<p>3)    输入表中所有元素已排好序；</p>
<p>4)    输入表已按逆序排好；</p>
<p>5)    输入表中部分或全部元素相同。</p>
<p>4.     例如，测试手机终端的通话功能，可以设计各种通话失败的情况来补充测试用例：</p>
<p>1)    无SIM 卡插入时进行呼出（非紧急呼叫）</p>
<p>2)    插入已欠费SIM卡进行呼出</p>
<p>3)    射频器件损坏或无信号区域插入有效SIM卡呼出</p>
<p>4)    网络正常，插入有效SIM卡，呼出无效号码（如1、888、333333、不输入任何号码等）</p>
<p>5)    网络正常，插入有效SIM卡，使用“快速拨号”功能呼出设置无效号码的数字</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span style="font-family: 'Times New Roman';"> </span></p>
<p><br clear="all" /></p>
<h1><strong><span style="font-size: x-large;">5.</span> </strong><strong><span style="font-size: x-large;">因果图法</span></strong><strong></strong></h1>
<p><span style="font-family: 'Times New Roman';"> </span></p>
<div>
<h2><span style="font-size: medium;">5.1.</span>              <span style="font-size: medium;">概念</span></h2>
</div>
<p>&nbsp;</p>
<p>因果图法是一种利用图解法分析输入的各种组合情况，从而设计测试用例的方法，它适合于检查程序输入条件的各种组合情况。</p>
<div>
<h2><span style="font-size: medium;">5.2.</span>              <span style="font-size: medium;">因果图法的应用</span></h2>
</div>
<p>&nbsp;</p>
<p>等价类划分法和边界值分析方法都是着重考虑输入条件，但没有考虑输入条件的各种组合、输入条件之间的相互制约关系。这样虽然各种输入条件可能出错的情况已经测试到了，但多个输入条件组合起来可能出错的情况却被忽视了。</p>
<p>如果在测试时必须考虑输入条件的各种组合，则可能的组合数目将是天文数字，因此必须考虑采用一种适合于描述多种条件的组合、相应产生多个动作的形式来进行测试用例的设计，这就需要利用因果图（逻辑模型）。</p>
<p>1.     因果图介绍</p>
<p>1)    4种符号分别表示了规格说明中向4种因果关系。</p>
<p align="center">
<p>2)    因果图中使用了简单的逻辑符号，以直线联接左右结点。左结点表示输入状态（或称原因），右结点表示输出状态（或称结果）。</p>
<p>3)    C1表示原因，通常置于图的左部；e1表示结果，通常在图的右部。C1和e1均可取值0或1，0表示某状态不出现，1表示某状态出现。</p>
<p>2.     因果图涉及的概念</p>
<p>1)    关系</p>
<ul>
<li>恒等：若c1是1，则e1也是1；否则e1为0。</li>
<li>非：若c1是1，则e1是0；否则e1是1。</li>
<li>或：若c1或c2或c3是1，则e1是1；否则e1为0。“或”可有任意个输入。</li>
<li>与：若c1和c2都是1，则e1为1；否则e1为0。“与”也可有任意个输入。</li>
</ul>
<p>2)    约束</p>
<p>输入状态相互之间还可能存在某些依赖关系，称为约束。例如, 某些输入条件本身不可能同时出现。输出状态之间也往往存在约束。在因果图中,用特定的符号标明这些约束。</p>
<p align="center">
<ul>
<li>输入条件的约束有以下4类：
<ul>
<li>E约束（异）：a和b中至多有一个可能为1，即a和b不能同时为1。</li>
<li>I约束（或）：a、b和c中至少有一个必须是1，即 a、b 和c不能同时为0。</li>
<li>O约束（唯一）；a和b必须有一个，且仅有1个为1。</li>
<li>R约束（要求）：a是1时，b必须是1，即不可能a是1时b是0。</li>
<li>输出条件约束类型</li>
</ul>
</li>
</ul>
<p>输出条件的约束只有M约束（强制）：若结果a是1，则结果b强制为0。</p>
<p>3.     采用因果图法设计测试用例的步骤：</p>
<p>1)    分析软件规格说明描述中, 那些是原因(即输入条件或输入条件的等价类),那些是结果(即输出条件), 并给每个原因和结果赋予一个标识符。</p>
<p>2)    分析软件规格说明描述中的语义，找出原因与结果之间, 原因与原因之间对应的关系，根据这些关系,画出因果图。</p>
<p>3)    由于语法或环境限制, 有些原因与原因之间,原因与结果之间的组合情况不可能出现，为表明这些特殊情况, 在因果图上用一些记号表明约束或限制条件。</p>
<p>4)    把因果图转换为判定表。</p>
<p>5)    把判定表的每一列拿出来作为依据,设计测试用例。</p>
<p>&nbsp;</p>
<div>
<h2><span style="font-size: medium;">5.3.</span>              <span style="font-size: medium;">实例</span></h2>
</div>
<p>&nbsp;</p>
<p>1.     某软件规格说明书包含这样的要求：第一列字符必须是A或B，第二列字符必须是一个数字，在此情况下进行文件的修改，但如果第一列字符不正确，则给出信息L；如果第二列字符不是数字，则给出信息M。</p>
<p>解答：</p>
<p>1)    根据题意，原因和结果如下：</p>
<p>原因：</p>
<p>1——第一列字符是A；</p>
<p>2——第一列字符是B；</p>
<p>3——第二列字符是一数字。</p>
<p>结果：</p>
<p>21——修改文件；</p>
<p>22 ——给出信息L；</p>
<p>23——给出信息M。</p>
<p>2)    其对应的因果图如下：</p>
<p>11为中间节点；考虑到原因1和原因2不可能同时为1，因此在因果图上施加E约束。</p>
<p align="center">
<p>3)    根据因果图建立判定表。</p>
<p align="center">
<p>                           表中8种情况的左面两列情况中，原因①和原因②同时为1，这是不可能出现的，故应排除这两种情况。表的最下一栏给出了6种情况的测试用例，这是我们所需要的数据。</p>
<p>2.     有一个处理单价为5角钱的饮料的自动售货机软件测试用例的设计。其规格说明如下：若投入5角钱或1元钱的硬币，押下〖橙汁〗或〖啤酒〗的按钮，则相应的饮料就送出来。若售货机没有零钱找，则一个显示〖零钱找完〗的红灯亮，这时在投入1元硬币并押下按钮后，饮料不送出来而且1元硬币也退出来；若有零钱找，则显示〖零钱找完〗的红灯灭，在送出饮料的同时退还5角硬币。</p>
<p>1)    分析这一段说明，列出原因和结果</p>
<p>原因：</p>
<p>1——售货机有零钱找</p>
<p>2——投入1元硬币</p>
<p>3——投入5角硬币</p>
<p>4——押下橙汁按钮</p>
<p>5——.押下啤酒按钮</p>
<p>结果：</p>
<p>21——售货机〖零钱找完〗灯亮</p>
<p>22——退还1元硬币</p>
<p>23——退还5角硬币</p>
<p>24——送出橙汁饮料</p>
<p>25——送出啤酒饮料</p>
<p>2)    画出因果图，如图所示。所有原因结点列在左边，所有结果结点列在右边。建立中间结点，表示处理的中间状态。中间结点：</p>
<p>11—— 投入1元硬币且押下饮料按钮</p>
<p>12——押下〖橙汁〗或〖啤酒〗的按钮</p>
<p>13——应当找5角零钱并且售货机有零钱找</p>
<p>14——钱已付清</p>
<p align="center">
<p>3)    转换成判定表：</p>
<p align="center">
<p>4)    在判定表中，阴影部分表示因违反约束条件的不可能出现的情况，删去。第16列与第32列因什么动作也没做，也删去。最后可根据剩下的16列作为确定测试用例的依据。</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><br clear="all" /></p>
<h1><strong><span style="font-size: x-large;">6.</span> </strong><strong><span style="font-size: x-large;">判定表驱动法</span></strong><strong></strong></h1>
<p><span style="font-family: 'Times New Roman';"> </span></p>
<div>
<h2><span style="font-size: medium;">6.1.</span>              <span style="font-size: medium;">概念</span></h2>
</div>
<p>&nbsp;</p>
<p>判定表是分析和表达多逻辑条件下执行不同操作的情况的工具。</p>
<div>
<h2><span style="font-size: medium;">6.2.</span>              <span style="font-size: medium;">判定表驱动法</span></h2>
</div>
<p>&nbsp;</p>
<p>1.     判定表的优点</p>
<p>能够将复杂的问题按照各种可能的情况全部列举出来，简明并避免遗漏。因此，利用判定表能够设计出完整的测试用例集合。</p>
<p>在一些数据处理问题当中，某些操作的实施依赖于多个逻辑条件的组合，即：针对不同逻辑条件的组合值，分别执行不同的操作。判定表很适合于处理这类问题。</p>
<p>2.     “阅读指南”判定表</p>
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td colspan="2" valign="top" width="116"></td>
<td valign="top" width="57">
<p align="center"><strong>1</strong></p>
</td>
<td valign="top" width="56">
<p align="center"><strong>2</strong></p>
</td>
<td valign="top" width="56">
<p align="center"><strong>3</strong></p>
</td>
<td valign="top" width="56">
<p align="center"><strong>4</strong></p>
</td>
<td valign="top" width="56">
<p align="center"><strong>5</strong></p>
</td>
<td valign="top" width="56">
<p align="center"><strong>6</strong></p>
</td>
<td valign="top" width="56">
<p align="center"><strong>7</strong></p>
</td>
<td valign="top" width="56">
<p align="center"><strong>8</strong></p>
</td>
</tr>
<tr>
<td rowspan="3" width="28"><strong>问题</strong></td>
<td valign="top" width="87">
<p align="center"><strong>觉得疲倦？</strong></p>
</td>
<td valign="top" width="57">
<p align="center"><strong>Y</strong></p>
</td>
<td valign="top" width="56">
<p align="center"><strong>Y</strong></p>
</td>
<td valign="top" width="56">
<p align="center"><strong>Y</strong></p>
</td>
<td valign="top" width="56">
<p align="center"><strong>Y</strong></p>
</td>
<td valign="top" width="56">
<p align="center"><strong>N</strong></p>
</td>
<td valign="top" width="56">
<p align="center"><strong>N</strong></p>
</td>
<td valign="top" width="56">
<p align="center"><strong>N</strong></p>
</td>
<td valign="top" width="56">
<p align="center"><strong>N</strong></p>
</td>
</tr>
<tr>
<td valign="top" width="87">
<p align="center"><strong>感兴趣吗？</strong></p>
</td>
<td valign="top" width="57">
<p align="center"><strong>Y</strong></p>
</td>
<td valign="top" width="56">
<p align="center"><strong>Y</strong></p>
</td>
<td valign="top" width="56">
<p align="center"><strong>N</strong></p>
</td>
<td valign="top" width="56">
<p align="center"><strong>N</strong></p>
</td>
<td valign="top" width="56">
<p align="center"><strong>Y</strong></p>
</td>
<td valign="top" width="56">
<p align="center"><strong>Y</strong></p>
</td>
<td valign="top" width="56">
<p align="center"><strong>N</strong></p>
</td>
<td valign="top" width="56">
<p align="center"><strong>N</strong></p>
</td>
</tr>
<tr>
<td valign="top" width="87">
<p align="center"><strong>糊涂吗？</strong></p>
</td>
<td valign="top" width="57">
<p align="center"><strong>Y</strong></p>
</td>
<td valign="top" width="56">
<p align="center"><strong>N</strong></p>
</td>
<td valign="top" width="56">
<p align="center"><strong>Y</strong></p>
</td>
<td valign="top" width="56">
<p align="center"><strong>N</strong></p>
</td>
<td valign="top" width="56">
<p align="center"><strong>Y</strong></p>
</td>
<td valign="top" width="56">
<p align="center"><strong>N</strong></p>
</td>
<td valign="top" width="56">
<p align="center"><strong>Y</strong></p>
</td>
<td valign="top" width="56">
<p align="center"><strong>N</strong></p>
</td>
</tr>
<tr>
<td rowspan="4" width="28"><strong>建议</strong></td>
<td valign="top" width="87">
<p align="center"><strong>重读</strong></p>
</td>
<td valign="top" width="57"></td>
<td valign="top" width="56"></td>
<td valign="top" width="56"></td>
<td valign="top" width="56"></td>
<td valign="top" width="56">
<p align="center"><strong>√</strong></p>
</td>
<td valign="top" width="56"></td>
<td valign="top" width="56"></td>
<td valign="top" width="56"></td>
</tr>
<tr>
<td valign="top" width="87">
<p align="center"><strong>继续</strong></p>
</td>
<td valign="top" width="57"></td>
<td valign="top" width="56"></td>
<td valign="top" width="56"></td>
<td valign="top" width="56"></td>
<td valign="top" width="56"></td>
<td valign="top" width="56">
<p align="center"><strong>√</strong></p>
</td>
<td valign="top" width="56"></td>
<td valign="top" width="56"></td>
</tr>
<tr>
<td valign="top" width="87">
<p align="center"><strong>跳下一章</strong></p>
</td>
<td valign="top" width="57"></td>
<td valign="top" width="56"></td>
<td valign="top" width="56"></td>
<td valign="top" width="56"></td>
<td valign="top" width="56"></td>
<td valign="top" width="56"></td>
<td valign="top" width="56">
<p align="center"><strong>√</strong></p>
</td>
<td valign="top" width="56">
<p align="center"><strong>√</strong></p>
</td>
</tr>
<tr>
<td valign="top" width="87">
<p align="center"><strong>休息</strong></p>
</td>
<td valign="top" width="57">
<p align="center"><strong>√</strong></p>
</td>
<td valign="top" width="56">
<p align="center"><strong>√</strong></p>
</td>
<td valign="top" width="56">
<p align="center"><strong>√</strong></p>
</td>
<td valign="top" width="56">
<p align="center"><strong>√</strong></p>
</td>
<td valign="top" width="56"></td>
<td valign="top" width="56"></td>
<td valign="top" width="56"></td>
<td valign="top" width="56"></td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>3.     判定表通常由四个部分组成如下图所示。</p>
<p align="center">
<p>1)    条件桩（Condition Stub）：列出了问题得所有条件。通常认为列出的条件的次序无关紧要。</p>
<p>2)    动作桩（Action Stub）：列出了问题规定可能采取的操作。这些操作的排列顺序没有约束。</p>
<p>3)    条件项（Condition Entry）：列出针对它左列条件的取值。在所有可能情况下的真假值。</p>
<p>4)    动作项（Action Entry）：列出在条件项的各种取值情况下应该采取的动作。</p>
<p>4.     规则及规则合并</p>
<p>1)    规则：任何一个条件组合的特定取值及其相应要执行的操作称为规则。在判定表中贯穿条件项和动作项的一列就是一条规则。显然,判定表中列出多少组条件取值,也就有多少条规则,既条件项和动作项有多少列。</p>
<p>2)    化简：就是规则合并有两条或多条规则具有相同的动作，并且其条件项之间存在着极为相似的关系。</p>
<p>5.     规则及规则合并举例</p>
<p>1)    如下图左端，两规则动作项一样，条件项类似，在1、2条件项分别取Y、N时，无论条件3取何值，都执行同一操作。即要执行的动作与条件3无关。于是可合并。“－”表示与取值无关。</p>
<p align="center">
<p align="center">
<p>2)    与上类似，下图中，无关条件项“－”可包含其他条件项取值，具有相同动作的规则可合并。</p>
<p align="center">
<p align="center">
<p align="center">
<p align="center">
<p>3)    化简后的读书指南判定表</p>
<div align="center">
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td colspan="2" valign="top" width="204"></td>
<td valign="top" width="48">
<p align="center">1</p>
</td>
<td valign="top" width="48">
<p align="center">2</p>
</td>
<td valign="top" width="48">
<p align="center">3</p>
</td>
<td valign="top" width="36">
<p align="center">4</p>
</td>
</tr>
<tr>
<td rowspan="3" width="48">
<p align="center"><strong>问题</strong></p>
</td>
<td valign="top" width="156">
<p align="center"><strong>你觉得疲倦吗？</strong></p>
</td>
<td valign="top" width="48">
<p align="center">-</p>
</td>
<td valign="top" width="48">
<p align="center">-</p>
</td>
<td valign="top" width="48">
<p align="center">Y</p>
</td>
<td valign="top" width="36">
<p align="center">N</p>
</td>
</tr>
<tr>
<td valign="top" width="156">
<p align="center"><strong>你对内容感兴趣吗？</strong></p>
</td>
<td valign="top" width="48">
<p align="center">Y</p>
</td>
<td valign="top" width="48">
<p align="center">Y</p>
</td>
<td valign="top" width="48">
<p align="center">N</p>
</td>
<td valign="top" width="36">
<p align="center">N</p>
</td>
</tr>
<tr>
<td valign="top" width="156">
<p align="center"><strong>书中内容使你胡涂吗？</strong></p>
</td>
<td valign="top" width="48">
<p align="center">Y</p>
</td>
<td valign="top" width="48">
<p align="center">N</p>
</td>
<td valign="top" width="48">
<p align="center">-</p>
</td>
<td valign="top" width="36">
<p align="center">-</p>
</td>
</tr>
<tr>
<td rowspan="4" width="48">
<p align="center">
<p align="center"><strong>建议</strong></p>
</td>
<td valign="top" width="156">
<p align="center"><strong>请回到本章开头重读</strong></p>
</td>
<td valign="top" width="48">
<p align="center">x</p>
</td>
<td valign="top" width="48"></td>
<td valign="top" width="48"></td>
<td valign="top" width="36"></td>
</tr>
<tr>
<td valign="top" width="156">
<p align="center"><strong>继续读下去</strong></p>
</td>
<td valign="top" width="48"></td>
<td valign="top" width="48">
<p align="center">X</p>
</td>
<td valign="top" width="48"></td>
<td valign="top" width="36"></td>
</tr>
<tr>
<td valign="top" width="156">
<p align="center"><strong>跳到下一章去读</strong></p>
</td>
<td valign="top" width="48"></td>
<td valign="top" width="48"></td>
<td valign="top" width="48"></td>
<td valign="top" width="36">
<p align="center">x</p>
</td>
</tr>
<tr>
<td valign="top" width="156">
<p align="center"><strong>停止阅读，请休息</strong></p>
</td>
<td valign="top" width="48"></td>
<td valign="top" width="48"></td>
<td valign="top" width="48">
<p align="center">x</p>
</td>
<td valign="top" width="36"></td>
</tr>
</tbody>
</table>
</div>
<p>6.     判定表的建立步骤：（根据软件规格说明）</p>
<p>1)    确定规则的个数.假如有n个条件。每个条件有两个取值（0,1）,故有2n种规则。</p>
<p>2)    列出所有的条件桩和动作桩。</p>
<p>3)    填入条件项。</p>
<p>4)    填入动作项。等到初始判定表。</p>
<p>5)    简化.合并相似规则（相同动作）。</p>
<p><span style="font-family: 'Times New Roman';"> </span></p>
<div>
<h2><span style="font-size: medium;">6.3.</span>              <span style="font-size: medium;">实例</span></h2>
</div>
<p>&nbsp;</p>
<p>1.     问题要求：”……对功率大于50马力的机器、维修记录不全或已运行10年以上的机器，应给予优先的维修处理……” 。这里假定，“维修记录不全”和“优先维修处理”均已在别处有更严格的定义 。请建立判定表。</p>
<p>解答：</p>
<p>1)    确定规则的个数：这里有3个条件，每个条件有两个取值，故应有2*2*2=8种规则。</p>
<p>2)    列出所有的条件茬和动作桩：</p>
<p align="center">
<p>3)    填入条件项。可从最后1行条件项开始，逐行向上填满。如第三行是： Y N Y N Y N Y N，第二行是： Y Y N N Y Y N N等等。</p>
<p>4)    填入动作桩和动作顶。这样便得到形如图的初始判定表。</p>
<div align="center">
<table width="480" border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td colspan="2" valign="top" width="192"></td>
<td valign="top" width="36">
<p align="center">1</p>
</td>
<td valign="top" width="36">
<p align="center">2</p>
</td>
<td valign="top" width="36">
<p align="center">3</p>
</td>
<td valign="top" width="36">
<p align="center">4</p>
</td>
<td valign="top" width="36">
<p align="center">5</p>
</td>
<td valign="top" width="36">
<p align="center">6</p>
</td>
<td valign="top" width="36">
<p align="center">7</p>
</td>
<td valign="top" width="36">
<p align="center">8</p>
</td>
</tr>
<tr>
<td rowspan="3" width="36">
<p align="center"><strong>条件</strong></p>
</td>
<td valign="top" width="156">
<p align="center"><strong>功率大于</strong><strong>50马力吗？</strong></p>
</td>
<td valign="top" width="36">
<p align="center">N</p>
</td>
<td valign="top" width="36">
<p align="center">Y</p>
</td>
<td valign="top" width="36">
<p align="center">Y</p>
</td>
<td valign="top" width="36">
<p align="center">Y</p>
</td>
<td valign="top" width="36">
<p align="center">N</p>
</td>
<td valign="top" width="36">
<p align="center">N</p>
</td>
<td valign="top" width="36">
<p align="center">N</p>
</td>
<td valign="top" width="36">
<p align="center">N</p>
</td>
</tr>
<tr>
<td valign="top" width="156">
<p align="center"><strong>维修记录不全吗？</strong></p>
</td>
<td valign="top" width="36">
<p align="center">Y</p>
</td>
<td valign="top" width="36">
<p align="center">Y</p>
</td>
<td valign="top" width="36">
<p align="center">N</p>
</td>
<td valign="top" width="36">
<p align="center">N</p>
</td>
<td valign="top" width="36">
<p align="center">Y</p>
</td>
<td valign="top" width="36">
<p align="center">Y</p>
</td>
<td valign="top" width="36">
<p align="center">N</p>
</td>
<td valign="top" width="36">
<p align="center">N</p>
</td>
</tr>
<tr>
<td valign="top" width="156">
<p align="center"><strong>运行超过</strong><strong>10年吗？</strong></p>
</td>
<td valign="top" width="36">
<p align="center">Y</p>
</td>
<td valign="top" width="36">
<p align="center">N</p>
</td>
<td valign="top" width="36">
<p align="center">Y</p>
</td>
<td valign="top" width="36">
<p align="center">N</p>
</td>
<td valign="top" width="36">
<p align="center">Y</p>
</td>
<td valign="top" width="36">
<p align="center">N</p>
</td>
<td valign="top" width="36">
<p align="center">Y</p>
</td>
<td valign="top" width="36">
<p align="center">N</p>
</td>
</tr>
<tr>
<td rowspan="2" width="36">
<p align="center"><strong>动作</strong></p>
</td>
<td valign="top" width="156">
<p align="center"><strong>进行优先处理</strong></p>
</td>
<td valign="top" width="36">
<p align="center">x</p>
</td>
<td valign="top" width="36">
<p align="center">x</p>
</td>
<td valign="top" width="36">
<p align="center">X</p>
</td>
<td valign="top" width="36"></td>
<td valign="top" width="36">
<p align="center">X</p>
</td>
<td valign="top" width="36"></td>
<td valign="top" width="36">
<p align="center">X</p>
</td>
<td valign="top" width="36"></td>
</tr>
<tr>
<td valign="top" width="156">
<p align="center"><strong>作其他处理</strong></p>
</td>
<td valign="top" width="36"></td>
<td valign="top" width="36"></td>
<td valign="top" width="36"></td>
<td valign="top" width="36">
<p align="center">X</p>
</td>
<td valign="top" width="36"></td>
<td valign="top" width="36">
<p align="center">x</p>
</td>
<td valign="top" width="36"></td>
<td valign="top" width="36">
<p align="center">x</p>
</td>
</tr>
</tbody>
</table>
</div>
<p align="center">初始判定表</p>
<p>5)    化简，合并相似规则后得到图。</p>
<div align="center">
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td colspan="2" valign="top" width="204"></td>
<td valign="top" width="48">
<p align="center">1</p>
</td>
<td valign="top" width="48">
<p align="center">2</p>
</td>
<td valign="top" width="48">
<p align="center">3</p>
</td>
<td valign="top" width="48">
<p align="center">4</p>
</td>
<td valign="top" width="36">
<p align="center">5</p>
</td>
</tr>
<tr>
<td rowspan="3" width="48">
<p align="center"><strong>条件</strong></p>
</td>
<td valign="top" width="156">
<p align="center"><strong>功率大于</strong><strong>50马力吗？</strong></p>
</td>
<td valign="top" width="48">
<p align="center">Y</p>
</td>
<td valign="top" width="48">
<p align="center">Y</p>
</td>
<td valign="top" width="48">
<p align="center">Y</p>
</td>
<td valign="top" width="48">
<p align="center">N</p>
</td>
<td valign="top" width="36">
<p align="center">N</p>
</td>
</tr>
<tr>
<td valign="top" width="156">
<p align="center"><strong>维修记录不全吗？</strong></p>
</td>
<td valign="top" width="48">
<p align="center">Y</p>
</td>
<td valign="top" width="48">
<p align="center">N</p>
</td>
<td valign="top" width="48">
<p align="center">N</p>
</td>
<td valign="top" width="48">
<p align="center">-</p>
</td>
<td valign="top" width="36">
<p align="center">-</p>
</td>
</tr>
<tr>
<td valign="top" width="156">
<p align="center"><strong>运行超过</strong><strong>10年吗？</strong></p>
</td>
<td valign="top" width="48">
<p align="center">-</p>
</td>
<td valign="top" width="48">
<p align="center">Y</p>
</td>
<td valign="top" width="48">
<p align="center">N</p>
</td>
<td valign="top" width="48">
<p align="center">Y</p>
</td>
<td valign="top" width="36">
<p align="center">N</p>
</td>
</tr>
<tr>
<td rowspan="2" width="48">
<p align="center"><strong>动作</strong></p>
</td>
<td valign="top" width="156">
<p align="center"><strong>进行优先处理</strong></p>
</td>
<td valign="top" width="48">
<p align="center">x</p>
</td>
<td valign="top" width="48">
<p align="center">x</p>
</td>
<td valign="top" width="48"></td>
<td valign="top" width="48">
<p align="center">X</p>
</td>
<td valign="top" width="36"></td>
</tr>
<tr>
<td valign="top" width="156">
<p align="center"><strong>作其他处理</strong></p>
</td>
<td valign="top" width="48"></td>
<td valign="top" width="48"></td>
<td valign="top" width="48">
<p align="center">x</p>
</td>
<td valign="top" width="48"></td>
<td valign="top" width="36">
<p align="center">x</p>
</td>
</tr>
</tbody>
</table>
</div>
<p>2.     NextData函数的精简决策表</p>
<p>M1＝{月份， 每月有30天}</p>
<p>M2＝{月份， 每月有31天}</p>
<p>M3＝{月份， 2月}                 有29＝512条规则</p>
<p>D1＝{日期，1～28}                 12月末31日和其它31</p>
<p>D2＝{日期，29}                    日月份的31日处理不同</p>
<p>D3＝{日期，30}                    平年2月28日处理不同</p>
<p>D4＝{日期，31}                    于2月27日</p>
<p>Y1 ＝{年：年是闰年}</p>
<p>Y2 ＝{年：年不是闰年}</p>
<p><strong>改进为：</strong><strong></strong></p>
<p>M1＝{月份： 每月有30天}</p>
<p>M2＝{月份： 每月有31天， 12月除外}</p>
<p>M4＝{月份：12月}</p>
<p>M3＝{月份： 2月}</p>
<p>D1＝{日期：1&lt;=日期&lt;=27}</p>
<p>D2＝{日期：28}</p>
<p>D3＝{日期：29}</p>
<p>D4＝{日期：30}</p>
<p>D5＝{日期：31}</p>
<p>Y1 ＝{年：年是闰年}</p>
<p>Y2 ＝{年：年不是闰年}</p>
<p>输入变量间存在大量逻辑关系的NextData决策表</p>
<p align="center">
<p align="center">
<p>&nbsp;</p>
<p>3.     用决策表测试法测试以下程序：该程序有三个输入变量month、day、year（month、day和year均为整数值，并且满足：1≤month≤12和1≤day≤31），分别作为输入日期的月份、日、年份，通过程序可以输出该输入日期在日历上隔一天的日期。</p>
<p>例如，输入为2004年11月29日，则该程序的输出为2000年12月1日。</p>
<p>1)    分析各种输入情况，列出为输入变量month、day、year划分的有效等价类。</p>
<p>2)    分析程序规格说明，结合以上等价类划分的情况给出问题规定的可能采取的操作（即列出所有的动作桩）。</p>
<p>3)    根据（1）和（2），画出简化后的决策表。</p>
<p>案例分析如下：</p>
<ul>
<li>month变量的有效等价类：</li>
</ul>
<p>M1: {month=4,6,9,11}              M2: {month=1,3,5,7,8,10}</p>
<p>M3: {month=12                       }M4: {month=2}</p>
<ul>
<li>day变量的有效等价类：</li>
</ul>
<p>D1:{1≤day≤26}                        D2: {day=27}                D3: {day=28}               D4: {day=29}                             D5: {day=30}                D6: {day=31}</p>
<ul>
<li>year变量的有效等价类：</li>
</ul>
<p>Y1: {year是闰年}                       Y2:  {year不是闰年}</p>
<p>4)    考虑各种有效的输入情况，程序中可能采取的操作有以下六种：</p>
<p>a1: day+2                                 a2: day=2                     a3: day=1</p>
<p>a4: month+1                            a5: month=1                a6: year+1</p>
<p>4.     判定表在功能测试中的应用</p>
<p>1)    一些软件的功能需求可用判定表表达得非常清楚，在检验程序的功能时判定表也就成为一个不错的工具。如果一个软件的规格说明指出：</p>
<ul>
<li>当条件1和条件2满足，并且条件3和条件4不满足，或者当条件1、3和条件4满足时，要执行操作1。</li>
<li>在任一个条件都不满足时，要执行操作2。</li>
<li>在条件1不满足，而条件4被满足时，要执行操作3。 根据规格说明得到如下判定表：</li>
</ul>
<p align="center">
<p>这里，判定表只给出了16种规则中的8种。事实上，除这8条以外的一些规则是指当不能满足指定的条件，执行3种操作时，要执行1个默许的操作。在没必要时，判定表通常可略去这些规则。但如果用判定表来设计测试用例，就必须列出这些默许规则（如下表）。</p>
<div align="center">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="72"></td>
<td valign="top" width="63">
<p align="center">规则5</p>
</td>
<td valign="top" width="77">
<p align="center">规则6</p>
</td>
<td valign="top" width="77">
<p align="center">规则7</p>
</td>
<td valign="top" width="58">
<p align="center">规则8</p>
</td>
</tr>
<tr>
<td valign="top" width="72">
<p align="center">条件1</p>
</td>
<td valign="top" width="63">
<p align="center">-</p>
</td>
<td valign="top" width="77">
<p align="center">N</p>
</td>
<td valign="top" width="77">
<p align="center">Y</p>
</td>
<td valign="top" width="58">
<p align="center">Y</p>
</td>
</tr>
<tr>
<td valign="top" width="72">
<p align="center">条件2</p>
</td>
<td valign="top" width="63">
<p align="center">-</p>
</td>
<td valign="top" width="77">
<p align="center">Y</p>
</td>
<td valign="top" width="77">
<p align="center">Y</p>
</td>
<td valign="top" width="58">
<p align="center">N</p>
</td>
</tr>
<tr>
<td valign="top" width="72">
<p align="center">条件3</p>
</td>
<td valign="top" width="63">
<p align="center">Y</p>
</td>
<td valign="top" width="77">
<p align="center">N</p>
</td>
<td valign="top" width="77">
<p align="center">N</p>
</td>
<td valign="top" width="58">
<p align="center">N</p>
</td>
</tr>
<tr>
<td valign="top" width="72">
<p align="center">条件4</p>
</td>
<td valign="top" width="63">
<p align="center">N</p>
</td>
<td valign="top" width="77">
<p align="center">N</p>
</td>
<td valign="top" width="77">
<p align="center">Y</p>
</td>
<td valign="top" width="58">
<p align="center">-</p>
</td>
</tr>
<tr>
<td valign="top" width="72">
<p align="center">默许操作</p>
</td>
<td valign="top" width="63">
<p align="center">x</p>
</td>
<td valign="top" width="77">
<p align="center">x</p>
</td>
<td valign="top" width="77">
<p align="center">x</p>
</td>
<td valign="top" width="58">
<p align="center">x</p>
</td>
</tr>
</tbody>
</table>
</div>
<p align="center">默许的规则</p>
<p>2)    判定表的优点和缺点</p>
<ul>
<li>优点：它能把复杂的问题按各种可能的情况一一列举出来，简明而易于理解，也可避免遗漏。</li>
<li>缺点：不能表达重复执行的动作，例如循环结构。</li>
</ul>
<p>3)    B. Beizer 指出了适合使用判定表设计测试用例的条件：</p>
<ul>
<li>规格说明以判定表形式给出,或很容易转换成判定表。</li>
<li>条件的排列顺序不会也不影响执行哪些操作。</li>
<li>规则的排列顺序不会也不影响执行哪些操作。</li>
<li>每当某一规则的条件已经满足,并确定要执行的操作后,不必检验别的规则。</li>
<li>如果某一规则得到满足要执行多个操作,这些操作的执行顺序无关紧要。</li>
</ul>
<p>B. Beizer提出这5个必要条件的目的是为了使操作的执行完全依赖于条件的组合。其实对于某些不满足这几条的判定表，同样可以借以设计测试用例，只不过尚需增加其它的测试用例罢了。</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span style="font-family: 'Times New Roman';"> </span></p>
<p><br clear="all" /></p>
<h1><strong><span style="font-size: x-large;">7.</span> </strong><strong><span style="font-size: x-large;">正交试验法</span></strong><strong></strong></h1>
<p><span style="font-family: 'Times New Roman';"> </span></p>
<div>
<h2><span style="font-size: medium;">7.1.</span>              <span style="font-size: medium;">概念</span></h2>
</div>
<p>&nbsp;</p>
<p>依据Galois理论,从大量的（实验）数据（测试例）中挑选适量的,有代表性的点（例）,从而合理地安排实验（测试）的一种科学实验设计方法.类似的方法有:聚类分析方法,因子方法方法等.</p>
<div>
<h2><span style="font-size: medium;">7.2.</span>              <span style="font-size: medium;">正交试验法</span></h2>
</div>
<p>&nbsp;</p>
<p>利用因果图来设计测试用例时, 作为输入条件的原因与输出结果之间的因果关系,有时很难从软件需求规格说明中得到。往往因果关系非常庞大,以至于据此因果图而得到的测试用例数目多的惊人，给软件测试带来沉重的负担，为了有效地,合理地减少测试的工时与费用,可利用正交实验设计方法进行测试用例的设计。</p>
<p>利用正交实验设计测试用例的步骤：</p>
<p>1.     提取功能说明,构造因子&#8211;状态表</p>
<p>把影响实验指标的条件称为因子.而影响实验因子的条件叫因子的状态.利用正交实验设计方法来设计测试用例时,首先要根据被测试软件的规格说明书找出影响其功能实现的操作对象和外部因素,把他们当作因子,而把各个因子的取值当作状态.对软件需求规格说明中的功能要求进行划分,把整体的概要性的功能要求进行层层分解与展开,分解成具体的有相对独立性的基本的功能要求.这样就可以把被测试软件中所有的因子都确定下来,并为确定个因子的权值提供参考的依据.确定因子与状态是设计测试用例的关键.因此要求尽可能全面的正确的确定取值,以确保测试用例的设计作到完整与有效。</p>
<p>2.     加权筛选,生成因素分析表</p>
<p>对因子与状态的选择可按其重要程度分别加权.可根据各个因子及状态的作用大小,出现频率的大小以及测试的需要,确定权值的大小。</p>
<p>3.     利用正交表构造测试数据集</p>
<p>正交表的推导依据Galois理论（这里省略,需要时可查数理统计方面的教材）。</p>
<p>利用正交实验设计方法设计测试用例,比使用等价类划分,边界值分析,因果图等方法有以下优点:节省测试工作工时；可控制生成的测试用例数量；测试用例具有一定的覆盖率。</p>
<p>&nbsp;</p>
<p><br clear="all" /></p>
<h1><strong><span style="font-size: x-large;">8.</span> </strong><strong><span style="font-size: x-large;">功能图法</span></strong><strong></strong></h1>
<p><span style="font-family: 'Times New Roman';"> </span></p>
<div>
<h2><span style="font-size: medium;">8.1.</span>              <span style="font-size: medium;">概念</span></h2>
</div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>功能图由状态迁移图和布尔函数组成.状态迁移图用状态和迁移来描述.一个状态指出数据输入的位置（或时间）,而迁移则指明状态的改变.同时要依靠判定表或因果图表示的逻辑功能.例,一个简化的自动出纳机ATM的功能图。</p>
<div>
<h2><span style="font-size: medium;">8.2.</span>              <span style="font-size: medium;">功能图法的应用</span></h2>
</div>
<p>&nbsp;</p>
<ol>
<li>功能图介绍</li>
</ol>
<p>一个程序的功能说明通常由动态说明和静态说明组成.动态说明描述了输入数据的次序或转移的次序.</p>
<p>静态说明描述了输入条件与输出条件之间的对应关系.对于较复杂的程序,由于存在大量的组合情况,因此,仅用静态说明组成的规格说明对于测试来说往往是不够的.必须用动态说明来补充功能说明.功能图方法是用功能图FD形式化地表示程序的功能说明,并机械地生成功能图的测试用例.</p>
<p>功能图模型由状态迁移图和逻辑功能模型构成.状态迁移图用于表示输入数据序列以及相应的输出数据.在状态迁移图中,由输入数据和当前状态决定输出数据和后续状态.逻辑功能模型用于表示在状态中输入条件和输出条件之间的对应关系.逻辑功能模型只适合于描述静态说明,输出数据仅由输入数据决定.测试用例则是由测试中经过的一系列状态和在每个状态中必须依靠输入/输出数据满足的一对条件组成.功能图方法其实是是一种黑盒白盒混合用例设计方法。</p>
<p>（功能图方法中,要用到逻辑覆盖和路径测试的概念和方法,其属白盒测试方法中 的内容.逻辑覆盖是以程序内部的逻辑结构为基础的测试用例设计方法.该方法要求测试人员对程序的逻辑结构有清楚的了解.由于覆盖测试的目标不同,逻辑覆盖可分为:语句覆盖,判定覆盖,判定-条件覆盖,条件组合覆盖及路径覆盖.下面我们指的逻辑覆盖和路径是功能或系统水平上的,以区别与白盒测试中的程序内部的.）</p>
<ol>
<li>测试用例生成方法</li>
</ol>
<p>从功能图生成测试用例,得到的测试用例数是可接受的. 问题的关键的是如何从状态迁移图中选取测试用例. 若用节点代替状态,用弧线代替迁移,则状态迁移图就可转化成一个程序的控制流程图形式.问题就转化为程序的路径测试问题（如白盒测试）问题了.</p>
<ol>
<li>测试用例生成规则</li>
</ol>
<p>为了把状态迁移（测试路径）的测试用例与逻辑模型（局部测试用例）的测试用例组合起来,从功能图生成实用的测试用例,须定义下面的规则.在一个结构化的状态迁移（SST）中,定义三种形式的循环:顺序,选择和重复.但分辨一个状态迁移中的所有循环是有困难的.（其表示图形省略）。</p>
<ol>
<li>从功能图生成测试用例的过程</li>
</ol>
<p>1)    生成局部测试用例:在每个状态中,从因果图生成局部测试用例.局部测试用例由原因值（输入数据）组合与对应的结果值（输出数据或状态）构成。</p>
<p>2)    测试路径生成:利用上面的规则（三种）生成从初始状态到最后状态的测试路径。</p>
<p>3)    测试用例合成:合成测试路径与功能图中每个状态中的局部测试用例.结果是初始状态到最后状态的一个状态序列,以及每个状态中输入数据与对应输出数据的组合。</p>
<ol>
<li>测试用例的合成算法:采用条件构造树.</li>
</ol>
<p>&nbsp;</p>
<p><br clear="all" /></p>
<h1><strong><span style="font-size: x-large;">9.</span> </strong><strong><span style="font-size: x-large;">场景法</span></strong><strong></strong></h1>
<p><span style="font-family: 'Times New Roman';"> </span></p>
<div>
<h2><span style="font-size: medium;">9.1.</span>              <span style="font-size: medium;">概念</span></h2>
</div>
<p>&nbsp;</p>
<p>现在的软件几乎都是用事件触发来控制流程的，事件触发时的情景便形成了场景，而同一事件不同的触发顺序和处理结果就形成事件流。这种在软件设计方面的思想也可以引入到软件测试中，可以比较生动地描绘出事件触发时的情景，有利于测试设计者设计测试用例，同时使测试用例更容易理解和执行。</p>
<div>
<h2><span style="font-size: medium;">9.2.</span>              <span style="font-size: medium;">场景法的应用</span></h2>
</div>
<p>&nbsp;</p>
<p>基本流和备选流：如下图所示，图中经过用例的每条路径都用基本流和备选流来表示，直黑线表示基本流，是经过用例的最简单的路径。备选流用不同的色彩表示，一个备选流可能从基本流开始，在某个特定条件下执行，然后重新加入基本流中（如备选流1和3）；也可能起源于另一个备选流（如备选流2），或者终止用例而不再重新加入到某个流（如备选流2和4）。</p>
<p align="center">
<h1><span style="font-size: x-large;"> </span></h1>
<div>
<h2><span style="font-size: medium;">9.3.</span>              <span style="font-size: medium;">实例</span></h2>
</div>
<p>&nbsp;</p>
<ol>
<li>例子描述</li>
</ol>
<p>下图所示是ATM例子的流程示意图。</p>
<p align="center">
<p align="center">
<p align="center">
<p align="center">
<ol>
<li>场景设计：下表所示是生成的场景。</li>
</ol>
<p align="center">表3-8 场景设计</p>
<div align="center">
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="277">
<p align="center">场景1——成功提款</p>
</td>
<td width="72">
<p align="center">基本流</p>
</td>
<td valign="top" width="84"></td>
</tr>
<tr>
<td width="277">
<p align="center">场景2——ATM内没有现金</p>
</td>
<td width="72">
<p align="center">基本流</p>
</td>
<td width="84">
<p align="center">备选流2</p>
</td>
</tr>
<tr>
<td width="277">
<p align="center">场景3——ATM内现金不足</p>
</td>
<td width="72">
<p align="center">基本流</p>
</td>
<td width="84">
<p align="center">备选流3</p>
</td>
</tr>
<tr>
<td width="277">
<p align="center">场景4——PIN有误（还有输入机会）</p>
</td>
<td width="72">
<p align="center">基本流</p>
</td>
<td width="84">
<p align="center">备选流4</p>
</td>
</tr>
<tr>
<td width="277">
<p align="center">场景5——PIN有误（不再有输入机会）</p>
</td>
<td width="72">
<p align="center">基本流</p>
</td>
<td width="84">
<p align="center">备选流4</p>
</td>
</tr>
<tr>
<td width="277">
<p align="center">场景6——账户不存在/账户类型有误</p>
</td>
<td width="72">
<p align="center">基本流</p>
</td>
<td width="84">
<p align="center">备选流5</p>
</td>
</tr>
<tr>
<td width="277">
<p align="center">场景7——账户余额不足</p>
</td>
<td width="72">
<p align="center">基本流</p>
</td>
<td width="84">
<p align="center">备选流6</p>
</td>
</tr>
</tbody>
</table>
</div>
<p>注：为方便起见，备选流3和6（场景3和7）内的循环以及循环组合未纳入上表。</p>
<ol>
<li>用例设计</li>
</ol>
<p>对于这7个场景中的每一个场景都需要确定测试用例。可以采用矩阵或决策表来确定和管理测试用例。下面显示了一种通用格式，其中各行代表各个测试用例，而各列则代表测试用例的信息。本示例中，对于每个测试用例，存在一个测试用例ID、条件（或说明）、测试用例中涉及的所有数据元素（作为输入或已经存在于数据库中）以及预期结果。</p>
<p align="center">表3-9 测试用例表</p>
<p align="center">
<table width="560" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="70">
<p align="center">TCID</p>
</td>
<td width="123">
<p align="center">场景/条件</p>
</td>
<td width="44">
<p align="center">PIN</p>
</td>
<td width="46">
<p align="center">账号</p>
</td>
<td width="67">
<p align="center">输入（或选择）的金额</p>
</td>
<td width="46">
<p align="center">账面</p>
<p align="center">金额</p>
</td>
<td width="57">
<p align="center">ATM内的金额</p>
</td>
<td width="105">
<p align="center">预期结果</p>
</td>
</tr>
<tr>
<td width="70">
<p align="center">CW1</p>
</td>
<td width="123">
<p align="center">场景1：成功提款</p>
</td>
<td width="44">
<p align="center">V</p>
</td>
<td width="46">
<p align="center">V</p>
</td>
<td width="67">
<p align="center">V</p>
</td>
<td width="46">
<p align="center">V</p>
</td>
<td width="57">
<p align="center">V</p>
</td>
<td width="105">
<p align="center">成功提款</p>
</td>
</tr>
<tr>
<td width="70">
<p align="center">CW2</p>
</td>
<td width="123">
<p align="center">场景2：ATM内没有现金</p>
</td>
<td width="44">
<p align="center">V</p>
</td>
<td width="46">
<p align="center">V</p>
</td>
<td width="67">
<p align="center">V</p>
</td>
<td width="46">
<p align="center">V</p>
</td>
<td width="57">
<p align="center">I</p>
</td>
<td width="105">
<p align="center">提款选项不可用，用例结束</p>
</td>
</tr>
<tr>
<td width="70">
<p align="center">CW3</p>
</td>
<td width="123">
<p align="center">场景3：ATM内现金不足</p>
</td>
<td width="44">
<p align="center">V</p>
</td>
<td width="46">
<p align="center">V</p>
</td>
<td width="67">
<p align="center">V</p>
</td>
<td width="46">
<p align="center">V</p>
</td>
<td width="57">
<p align="center">I</p>
</td>
<td width="105">
<p align="center">警告消息，返回基本流步骤6，输入金额</p>
</td>
</tr>
<tr>
<td width="70">
<p align="center">CW4</p>
</td>
<td width="123">
<p align="center">场景4：PIN有误（还有不止一次输入机会）</p>
</td>
<td width="44">
<p align="center">I</p>
</td>
<td width="46">
<p align="center">V</p>
</td>
<td width="67">
<p align="center">n/a</p>
</td>
<td width="46">
<p align="center">V</p>
</td>
<td width="57">
<p align="center">V</p>
</td>
<td width="105">
<p align="center">警告消息，返回基本流步骤 4，输入PIN</p>
</td>
</tr>
<tr>
<td width="70">
<p align="center">CW5</p>
</td>
<td width="123">
<p align="center">场景4：PIN有误（还有一次输入机会）</p>
</td>
<td width="44">
<p align="center">I</p>
</td>
<td width="46">
<p align="center">V</p>
</td>
<td width="67">
<p align="center">n/a</p>
</td>
<td width="46">
<p align="center">V</p>
</td>
<td width="57">
<p align="center">V</p>
</td>
<td width="105">
<p align="center">警告消息，返回基本流步骤 4，输入PIN</p>
</td>
</tr>
<tr>
<td width="70">
<p align="center">CW6</p>
</td>
<td width="123">
<p align="center">场景4：PIN有误（不再有输入机会）</p>
</td>
<td width="44">
<p align="center">I</p>
</td>
<td width="46">
<p align="center">V</p>
</td>
<td width="67">
<p align="center">n/a</p>
</td>
<td width="46">
<p align="center">V</p>
</td>
<td width="57">
<p align="center">V</p>
</td>
<td width="105">
<p align="center">警告消息，卡予保留，用例结束</p>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<ol>
<li>数据设计</li>
</ol>
<p>一旦确定了所有的测试用例，则应对这些用例进行复审和验证以确保其准确且适度，并取消多余或等效的测试用例。</p>
<p>测试用例一经认可，就可以确定实际数据值（在测试用例实施矩阵中）并且设定测试数据，如表3-10所示。</p>
<p align="center">表3-10    测试用例表</p>
<div align="center">
<table width="560" border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="70">
<p align="center">TCID</p>
</td>
<td width="123">
<p align="center">场景/条件</p>
</td>
<td width="43">
<p align="center">PIN</p>
</td>
<td width="48">
<p align="center">账号</p>
</td>
<td width="67">
<p align="center">输入（或选择）的金额（元）</p>
</td>
<td width="47">
<p align="center">账面<br />
金额（元）</p>
</td>
<td width="57">
<p align="center">ATM内的金额（元）</p>
</td>
<td width="105">
<p align="center">预期结果</p>
</td>
</tr>
<tr>
<td width="70">
<p align="center">CW1</p>
</td>
<td width="123">
<p align="center">场景1：成功提款</p>
</td>
<td width="43">
<p align="center">4987</p>
</td>
<td width="48">
<p align="center">809-498</p>
</td>
<td width="67">
<p align="center">50.00</p>
</td>
<td width="47">
<p align="center">500.00</p>
</td>
<td width="57">
<p align="center">2 000</p>
</td>
<td width="105">
<p align="center">成功提款。账户余额被更新为450.00</p>
</td>
</tr>
<tr>
<td width="70">
<p align="center">CW2</p>
</td>
<td width="123">
<p align="center">场景2：ATM内没有现金</p>
</td>
<td width="43">
<p align="center">4987</p>
</td>
<td width="48">
<p align="center">809-498</p>
</td>
<td width="67">
<p align="center">100.00</p>
</td>
<td width="47">
<p align="center">500.00</p>
</td>
<td width="57">
<p align="center">0.00</p>
</td>
<td width="105">
<p align="center">提款选项不可用，用例结束</p>
</td>
</tr>
<tr>
<td width="70">
<p align="center">CW3</p>
</td>
<td width="123">
<p align="center">场景3：ATM内现金不足</p>
</td>
<td width="43">
<p align="center">4987</p>
</td>
<td width="48">
<p align="center">809-498</p>
</td>
<td width="67">
<p align="center">100.00</p>
</td>
<td width="47">
<p align="center">500.00</p>
</td>
<td width="57">
<p align="center">70.00</p>
</td>
<td width="105">
<p align="center">警告消息，返回基本流步骤6，输入金额</p>
</td>
</tr>
<tr>
<td width="70">
<p align="center">CW4</p>
</td>
<td width="123">
<p align="center">场景4：PIN有误（还有不止一次输入机会）</p>
</td>
<td width="43">
<p align="center">4978</p>
</td>
<td width="48">
<p align="center">809-498</p>
</td>
<td width="67">
<p align="center">n/a</p>
</td>
<td width="47">
<p align="center">500.00</p>
</td>
<td width="57">
<p align="center">2 000</p>
</td>
<td width="105">
<p align="center">警告消息，返回基本流步骤4，输入PIN</p>
</td>
</tr>
<tr>
<td width="70">
<p align="center">CW5</p>
</td>
<td width="123">
<p align="center">场景4：PIN有误（还有一次输入机会）</p>
</td>
<td width="43">
<p align="center">4978</p>
</td>
<td width="48">
<p align="center">809-498</p>
</td>
<td width="67">
<p align="center">n/a</p>
</td>
<td width="47">
<p align="center">500.00</p>
</td>
<td width="57">
<p align="center">2 000</p>
</td>
<td width="105">
<p align="center">警告消息，返回基本流步骤4，输入PIN</p>
</td>
</tr>
<tr>
<td width="70">
<p align="center">CW6</p>
</td>
<td width="123">
<p align="center">场景4：PIN有误（不再有输入机会）</p>
</td>
<td width="43">
<p align="center">4978</p>
</td>
<td width="48">
<p align="center">809-498</p>
</td>
<td width="67">
<p align="center">n/a</p>
</td>
<td width="47">
<p align="center">500.00</p>
</td>
<td width="57">
<p align="center">2 000</p>
</td>
<td width="105">
<p align="center">警告消息，卡予保留，用例结束</p>
</td>
</tr>
</tbody>
</table>
</div>
<p>&nbsp;</p>
<p><br clear="all" /></p>
<h1><strong><span style="font-size: x-large;">10.</span>     </strong><strong><span style="font-size: x-large;">测试用例设计综合策略</span></strong><strong></strong></h1>
<p><span style="font-family: 'Times New Roman';"> </span></p>
<ol>
<li>Myers提出了使用各种测试方法的综合策略：</li>
</ol>
<p>1)    在任何情况下都必须使用边界值分析方法，经验表明用这种方法设计出测试用例发现程序错误的能力最强。】</p>
<p>2)    必要时用等价类划分方法补充一些测试用例。</p>
<p>3)    用错误推测法再追加一些测试用例。</p>
<p>4)    对照程序逻辑，检查已设计出的测试用例的逻辑覆盖程度，如果没有达到要求的覆盖标准，应当再补充足够的测试用例。</p>
<p>5)    如果程序的功能说明中含有输入条件的组合情况，则一开始就可选用因果图法。</p>
<ol>
<li>测试用例的设计步骤】</li>
</ol>
<p>1)    构造根据设计规格得出的基本功能测试用例；</p>
<p>2)    边界值测试用例；</p>
<p>3)    状态转换测试用例；</p>
<p>4)    错误猜测测试用例；</p>
<p>5)    异常测试用例；】</p>
<p>6)    性能测试用例；</p>
<p>7)    压力测试用例。</p>
<ol>
<li>优化测试用例的方法</li>
</ol>
<p>1)    利用设计测试用例的8种方法不断的对测试用例进行分解与合并；</p>
<p>2)    采用遗传算法理论进化测试用例；</p>
<p>3)    在测试时利用发散思维构造测试用例；</p>
</div>
<div></div>
<div>
<div>分类: <a href="http://www.cnblogs.com/Jackc/category/175461.html">项目总结</a>, <a href="http://www.cnblogs.com/Jackc/category/175454.html">软件功能测试</a></div>
</div>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=897</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bug书写规范与对应等级</title>
		<link>https://www.softwareace.cn/?p=896</link>
		<comments>https://www.softwareace.cn/?p=896#comments</comments>
		<pubDate>Fri, 08 Aug 2014 09:27:03 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[软件测试]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=896</guid>
		<description><![CDATA[BUG书写规范 书写BUG的基本要求是准确、简洁、完整、规范，注意如下方面： 1、每个BUG中只书写一个缺陷或 [&#8230;]]]></description>
				<content:encoded><![CDATA[<div>
<div>
<div>
<p>BUG书写规范</p>
<p>书写BUG的基本要求是准确、简洁、完整、规范，注意如下方面：</p>
<p>1、每个BUG中只书写一个缺陷或错误，如果是相同类型的bug归纳到一个bug中。</p>
<p>2、对错误的描述要做到简洁、准确、完整，揭示错误实质，为了便于在数据库中寻找，记录包含错误发生时的用户界面是个良好的习惯。例如记录对话框的标题、菜单、按钮等控件的名称。</p>
<p>3、明确指明错误类型和严重程度，根据错误的现象，总结判断错误的类型和严重程度，例如，是功能错误？还是界面布局错误？该错误是属于特别严重的错误还是一般错误？是否影响软件的后续开发和发布？</p>
<p>4、每一个步骤尽量只记录一个操作，简洁、条理井然，容易重复操作步骤，以便确认、修复、验证该错误。</p>
<p>5、复现的操作步骤要完整，准确，简短。保证快速准确的重复错误，“完整”即没有缺漏，“准确”即步骤正确，“简短”即没有多余的步骤。</p>
<p>6、附加必要的错误截图。为了直观的观察缺陷或错误现象，需要附加错误出现的界面，为了节省空间，图像存为png格式。</p>
<p>7、附加必要的测试用例，如果打开某个特殊的测试用例而产生的错误，则必须附加该测试用例，从而可以迅速再现缺陷或错误。为了使错误修正者进一步明确缺陷或错误的表现，可以附加修改建议或注解。</p>
<p>8、尽量使用短语和短句，避免复杂句型句式，书写软件测试错误报告的目的是便于定位错误，因此，要求客观的描述操作步骤，不需要修饰性的词汇和复杂的句型，增强可读性。</p>
<p>&nbsp;</p>
<p lang="en-US">BUG的等级划分与优先级</p>
<p lang="en-US">
<div>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>Bug等级</td>
<td>对应数字</td>
<td>Bug优先级</td>
</tr>
<tr>
<td>非常严重（致命）</td>
<td>1</td>
<td>最高，立即修改</td>
</tr>
<tr>
<td>严重</td>
<td>2</td>
<td>高，尽快修改。</td>
</tr>
<tr>
<td>一般（普通）</td>
<td>3</td>
<td>中，需要修改</td>
</tr>
<tr>
<td>轻微及建议</td>
<td>4</td>
<td>低，需要修改或商议</td>
</tr>
</tbody>
</table>
</div>
<p>&nbsp;</p>
<p>1 、非常严重（致命）：死机，数据丢失，主要功能完全丧失，系统悬挂等错误。修改优先级为最高，该级别需要程序员立即修改。</p>
<p>致命性问题主要为：系统无法执行、崩溃或严重资源不足、应用模块无法启动或异常退出、无法测试、造成系统不稳定。</p>
<p>具体基本上可分为：</p>
<p>系统崩溃/死机</p>
<p>模块无法启动或异常退出</p>
<p>其它导致无法测试的错误</p>
<p>严重花屏</p>
<p>内存泄漏</p>
<p>用户数据丢失或破坏</p>
<p>2、严重：主要功能丧失，导致严重的问题，或致命的错误声明。修改优先级为高，该级别需要程序员尽快修改。</p>
<p>严重性问题主要为：影响系统功能或操作，主要功能存在严重缺陷，但不会影响到系统稳定性。</p>
<p>具体基本上可分为：</p>
<p>功能完全未实现</p>
<p>功能虽然实现，但与需求严重不符</p>
<p>重要的数值出现计算错误</p>
<p>能够影响用户利益的功能，如抽奖，充值，积分等发生错误</p>
<p>系统所提供的功能或服务受明显的影响</p>
<p>3、一般（普通）：次要功能丧失，不太严重，如提示信息不太准确。修改优先级为中，该级别需要程序员修改。</p>
<p>一般性问题主要为：界面、性能缺陷</p>
<p>具体基本上可分为：</p>
<p>操作界面错误（包括数据窗口内列名定义、含义是否一致）</p>
<p>边界条件下错误</p>
<p>提示信息错误（包括未给出信息、信息提示错误等）</p>
<p>长时间操作无进度提示</p>
<p>系统未优化（性能问题）</p>
<p>光标跳转设置不好，鼠标（光标）定位错误</p>
<p>系统刷新错误</p>
<p>非重要的数据发生计算错误；</p>
<p>4 、轻微及建议：微小的问题，对功能几乎没有影响，产品及属性仍可使用，如有个错别字。修改优先级为低，该级别需要程序员修改或不修改。</p>
<p>提示性问题主要为：易用性及建议性问题</p>
<p>具体基本上可分为：</p>
<p>界面格式等不规范，如错行，浏览器兼容问题，css问题</p>
<p>辅助说明描述不清楚</p>
<p>操作时未给用户提示</p>
<p>可输入区域和只读区域没有明显的区分标志</p>
<p>个别不影响产品理解的错别字</p>
<p>文字排列不整齐等一些小问题</p>
<p>建议性的问题</p>
</div>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=896</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
