posts - 9,  comments - 4,  trackbacks - 2
  2006年5月30日

Ping

Ping是个使用频率极高的实用程序,用于确定本地主机是否能与另一台主机交换(发送与接收)数据报。根据返回的信息,你就可以推断TCP/IP参数是否设置得正确以及运行是否正常。需要注意的是:成功地与另一台主机进行一次或两次数据报交换并不表示TCP/IP配置就是正确的,你必须执行大量的本地主机与远程主机的数据报交换,才能确信TCP/IP的正确性。

简单的说,Ping就是一个测试程序,如果Ping运行正确,你大体上就可以排除网络访问层、网卡、MODEM的输入输出线路、电缆和路由器等存在的故障,从而减小了问题的范围。但由于可以自定义所发数据报的大小及无休止的高速发送,Ping也被某些别有用心的人作为DDOS(拒绝服务攻击)的工具,前段时间Yahoo就是被黑客利用数百台可以高速接入互联网的电脑连续发送大量Ping数据报而瘫痪的。

按照缺省设置,Windows上运行的Ping命令发送4个ICMP(网间控制报文协议)回送请求,每个32字节数据,如果一切正常,你应能得到4个回送应答。

Ping能够以毫秒为单位显示发送回送请求到返回回送应答之间的时间量。如果应答时间短,表示数据报不必通过太多的路由器或网络连接速度比较快。Ping还能显示TTL(Time To Live存在时间)值,你可以通过TTL值推算一下数据包已经通过了多少个路由器:源地点TTL起始值(就是比返回TTL略大的一个2的乘方数)-返回时TTL值。例如,返回TTL值为119,那么可以推算数据报离开源地址的TTL起始值为128,而源地点到目标地点要通过9个路由器网段(128-119);如果返回TTL值为246,TTL起始值就是256,源地点到目标地点要通过9个路由器网段。

通过Ping检测网络故障的典型次序

正常情况下,当你使用Ping命令来查找问题所在或检验网络运行情况时,你需要使用许多Ping命令,如果所有都运行正确,你就可以相信基本的连通性和配置参数没有问题;如果某些Ping命令出现运行故障,它也可以指明到何处去查找问题。下面就给出一个典型的检测次序及对应的可能故障:

ping 127.0.0.1——这个Ping命令被送到本地计算机的IP软件,该命令永不退出该计算机。如果没有做到这一点,就表示TCP/IP的安装或运行存在某些最基本的问题。

ping 本机IP——这个命令被送到你计算机所配置的IP地址,你的计算机始终都应该对该Ping命令作出应答,如果没有,则表示本地配置或安装存在问题。出现此问题时,局域网用户请断开网络电缆,然后重新发送该命令。如果网线断开后本命令正确,则表示另一台计算机可能配置了相同的IP地址。

ping 局域网内其他IP——这个命令应该离开你的计算机,经过网卡及网络电缆到达其他计算机,再返回。收到回送应答表明本地网络中的网卡和载体运行正确。但如果收到0个回送应答,那么表示子网掩码(进行子网分割时,将IP地址的网络部分与主机部分分开的代码)不正确或网卡配置错误或电缆系统有问题。

ping 网关IP——这个命令如果应答正确,表示局域网中的网关路由器正在运行并能够作出应答。

ping 远程IP——如果收到4个应答,表示成功的使用了缺省网关。对于拨号上网用户则表示能够成功的访问Internet(但不排除ISP的DNS会有问题)。

ping localhost——localhost是个操作系统的网络保留名,它是127.0.0.1的别名,每太计算机都应该能够将该名字转换成该地址。如果没有做到这一带内,则表示主机文件(/Windows/host)中存在问题。

ping http://www.yahoo.com/——对这个域名执行Ping命令,你的计算机必须先将域名转换成IP地址,通常是通过DNS服务器(关于DNS本刊2000年3期有详述)。如果这里出现故障,则表示DNS服务器的IP地址配置不正确或DNS服务器有故障(对于拨号上网用户,某些ISP已经不需要设置DNS服务器了)。顺便说一句:你也可以利用该命令实现域名对IP地址的转换功能。

如果上面所列出的所有Ping命令都能正常运行,那么你对你的计算机进行本地和远程通信的功能基本上就可以放心了。但是,这些命令的成功并不表示你所有的网络配置都没有问题,例如,某些子网掩码错误就可能无法用这些方法检测到。

Ping命令的常用参数选项

ping IP -t——连续对IP地址执行Ping命令,直到被用户以Ctrl+C中断。

ping IP -l 2000——指定Ping命令中的数据长度为2000字节,而不是缺省的32字节。

ping IP -n——执行特定次数的Ping命令。


Netstat

Netstat用于显示与IP、TCP、UDP和ICMP协议相关的统计数据,一般用于检验本机各端口的网络连接情况。

如果你的计算机有时候接受到的数据报会导致出错数据删除或故障,你不必感到奇怪,TCP/IP可以容许这些类型的错误,并能够自动重发数据报。但如果累计的出错情况数目占到所接收的IP数据报相当大的百分比,或者它的数目正迅速增加,那么你就应该使用Netstat查一查为什么会出现这些情况了。

Netstat的一些常用选项:

netstat -s——本选项能够按照各个协议分别显示其统计数据。如果你的应用程序(如Web浏览器)运行速度比较慢,或者不能显示Web页之类的数据,那么你就可以用本选项来查看一下所显示的信息。你需要仔细查看统计数据的各行,找到出错的关键字,进而确定问题所在。

netstat -e——本选项用于显示关于以太网的统计数据。它列出的项目包括传送的数据报的总字节数、错误数、删除数、数据报的数量和广播的数量。这些统计数据既有发送的数据报数量,也有接收的数据报数量。这个选项可以用来统计一些基本的网络流量。

netstat -r——本选项可以显示关于路由表的信息,类似于后面所讲使用route print命令时看到的 信息。除了显示有效路由外,还显示当前有效的连接。

netstat -a——本选项显示一个所有的有效连接信息列表,包括已建立的连接(ESTABLISHED),也包括监听连接请求(LISTENING)的那些连接。

netstat -n——显示所有已建立的有效连接。

Netstat的妙用

经常上网的人一般都使用ICQ的,不知道你有没有被一些讨厌的人骚扰得不敢上线,想投诉却又不知从和下手?其实,你只要知道对方的IP,就可以向他所属的ISP投诉了。但怎样才能通过ICQ知道对方的IP呢?如果对方在设置ICQ时选择了不显示IP地址,那你是无法在信息栏中看到的。其实,你只需要通过Netstat就可以很方便的做到这一点:当他通过ICQ或其他的工具与你相连时(例如你给他发一条ICQ信息或他给你发一条信息),你立刻在DOS Prompt下输入netstat -n或netstat -a就可以看到对方上网时所用的IP或ISP域名了。甚至连所用Port都完全暴露了,如果你想给他一些教训,这些信息已经足够……


IPConfig

IPConfig实用程序和它的等价图形用户界面——Windows 95/98中的WinIPCfg可用于显示当前的TCP/IP配置的设置值。这些信息一般用来检验人工配置的TCP/IP设置是否正确。但是,如果你的计算机和所在的局域网使用了动态主机配置协议(Dynamic Host Configuration Protocol,DHCP——Windows NT下的一种把较少的IP地址分配给较多主机使用的协议,类似于拨号上网的动态IP分配),这个程序所显示的信息也许更加实用。这时,IPConfig可以让你了解你的计算机是否成功的租用到一个IP地址,如果租用到则可以了解它目前分配到的是什么地址。了解计算机当前的IP地址、子网掩码和缺省网关实际上是进行测试和故障分析的必要项目。

最常用的选项:

ipconfig——当使用IPConfig时不带任何参数选项,那么它为每个已经配置了的接口显示IP地址、子网掩码和缺省网关值。

ipconfig /all——当使用all选项时,IPConfig能为DNS和WINS服务器显示它已配置且所要使用的附加信息(如IP地址等),并且显示内置于本地网卡中的物理地址(MAC)。如果IP地址是从DHCP服务器租用的,IPConfig将显示DHCP服务器的IP地址和租用地址预计失效的日期(有关DHCP服务器的相关内容请详见其他有关NT服务器的书籍或询问你的网管),其输出信息见图6的下半部分。

ipconfig /release和ipconfig /renew——这是两个附加选项,只能在向DHCP服务器租用其IP地址的计算机上起作用。如果你输入ipconfig /release,那么所有接口的租用IP地址便重新交付给DHCP服务器(归还IP地址)。如果你输入ipconfig /renew,那么本地计算机便设法与DHCP服务器取得联系,并租用一个IP地址。请注意,大多数情况下网卡将被重新赋予和以前所赋予的相同的IP地址。

如果你使用的是Windows 95/98,那么你应该更习惯使用winipcfg而不是ipconfig,因为它是一个图形用户界面,而且所显示的信息与ipconfig相同,并且也提供发布和更新动态IP地址的选项。如果你购买了Windows NT Resource Kit(NT资源包),那么Windows NT也包含了一个图形替代界面,该实用程序的名字是wntipcfg,和Windows 95/98的winipcfg类似。

 

ARP(地址转换协议)

ARP是一个重要的TCP/IP协议,并且用于确定对应IP地址的网卡物理地址。实用arp命令,你能够查看本地计算机或另一台计算机的ARP高速缓存中的当前内容。此外,使用arp命令,也可以用人工方式输入静态的网卡物理/IP地址对,你可能会使用这种方式为缺省网关和本地服务器等常用主机进行这项操作,有助于减少网络上的信息量。

按照缺省设置,ARP高速缓存中的项目是动态的,每当发送一个指定地点的数据报且高速缓存中不存在当前项目时,ARP便会自动添加该项目。一旦高速缓存的项目被输入,它们就已经开始走向失效状态。例如,在Windows NT网络中,如果输入项目后不进一步使用,物理/IP地址对就会在2至10分钟内失效。因此,如果ARP高速缓存中项目很少或根本没有时,请不要奇怪,通过另一台计算机或路由器的ping命令即可添加。所以,需要通过arp命令查看高速缓存中的内容时,请最好先ping 此台计算机(不能是本机发送ping命令)。

常用命令选项:

arp -a或arp -g——用于查看高速缓存中的所有项目。-a和-g参数的结果是一样的,多年来-g一直是UNIX平台上用来显示ARP高速缓存中所有项目的选项,而Windows用的是arp -a(-a可被视为all,即全部的意思),但它也可以接受比较传统的-g选项。

arp -a IP——如果你有多个网卡,那么使用arp -a加上接口的IP地址,就可以只显示与该接口相关的ARP缓存项目。

arp -s IP 物理地址——你可以向ARP高速缓存中人工输入一个静态项目。该项目在计算机引导过程中将保持有效状态,或者在出现错误时,人工配置的物理地址将自动更新该项目。

arp -d IP——使用本命令能够人工删除一个静态项目。


看到这里,你也许已经有些累了……其实对于一般用户来说也已经足够——你可以用ipconfig和ping命令来查看自己的网络配置并判断是否正确、可以用netstat查看别人与你所建立的连接并找出ICQ使用者所隐藏的IP信息、可以用arp查看网卡的MAC地址——这些已足已让你丢掉菜鸟的头衔。如果你并不满足,那就“硬着头皮”(下面的内容可能有些枯燥)继续Follow me……


Tracert

当数据报从你的计算机经过多个网关传送到目的地时,Tracert命令可以用来跟踪数据报使用的路由(路径)。该实用程序跟踪的路径是源计算机到目的地的一条路径,不能保证或认为数据报总遵循这个路径。如果你的配置使用DNS,那么你常常会从所产生的应答中得到城市、地址和常见通信公司的名字。Tracert是一个运行得比较慢的命令(如果你指定的目标地址比较远),每个路由器你大约需要给它15秒钟。

Tracert的使用很简单,只需要在tracert后面跟一个IP地址或URL,Tracert会进行相应的域名转换的。Tracert一般用来检测故障的位置,你可以用tracert IP在哪个环节上出了问题,虽然还是没有确定是什么问题,但它已经告诉了我们问题所在的地方,你也就可以很有把握的告诉别人——某某出了问题。


Route

大多数主机一般都是驻留在只连接一台路由器的网段上。由于只有一台路由器,因此不存在使用哪一台路由器将数据报发表到远程计算机上去的问题,该路由器的IP地址可作为该网段上所有计算机的缺省网关来输入。

但是,当网络上拥有两个或多个路由器时,你就不一定想只依赖缺省网关了。实际上你可能想让你的某些远程IP地址通过某个特定的路由器来传递,而其他的远程IP则通过另一个路由器来传递。

在这种情况下,你需要相应的路由信息,这些信息储存在路由表中,每个主机和每个路由器都配有自己独一无二的路由表。大多数路由器使用专门的路由协议来交换和动态更新路由器之间的路由表。但在有些情况下,必须人工将项目添加到路由器和主机上的路由表中。Route就是用来显示、人工添加和修改路由表项目的。

一般使用选项:

route print——本命令用于显示路由表中的当前项目,由于用IP地址配置了网卡,因此所有的这些项目都是自动添加的。

route add——使用本命令,可以将信路由项目添加给路由表。例如,如果要设定一个到目的网络209.98.32.33的路由,其间要经过5个路由器网段,首先要经过本地网络上的一个路由器,器IP为202.96.123.5,子网掩码为255.255.255.224,那么你应该输入以下命令:

route add 209.98.32.33 mask 255.255.255.224 202.96.123.5 metric 5

route change——你可以使用本命令来修改数据的传输路由,不过,你不能使用本命令来改变数据的目的地。下面这个例子可以将数据的路由改到另一个路由器,它采用一条包含3个网段的更直的路径:

route add 209.98.32.33 mask 255.255.255.224 202.96.123.250 metric 3

route delete——使用本命令可以从路由表中删除路由。例如:route delete 209.98.32.33


NBTStat

NBTStat(TCP/IP上的NetBIOS统计数据)实用程序用于提供关于关于NetBIOS的统计数据。运用NetBIOS,你可以查看本地计算机或远程计算机上的NetBIOS名字表格。

常用选项:

nbtstat -n——显示寄存在本地的名字和服务程序。

nbtstat -c——本命令用于显示NetBIOS名字高速缓存的内容。NetBIOS名字高速缓存用于寸放与本计算机最近进行通信的其他计算机的NetBIOS名字和IP地址对。

nbtstat -r——本命令用于清除和重新加载NetBIOS名字高速缓存。

nbtstat -a IP——通过IP显示另一台计算机的物理地址和名字列表,你所显示的内容就像对方计算机自己运行nbtstat -n一样。

nbtstat -s IP——显示实用其IP地址的另一台计算机的NetBIOS连接表。


Net

Net命令有很多函数用于实用和核查计算机之间的NetBIOS连接。这里我只介绍最常用的两个:net view和net use。

net view UNC——运用此命令,你可以查看目标服务器上的共享点名字。任何局域网里的人都可以发出此命令,而且不需要提供用户ID或口令。UNC名字总是以\\开头,后面跟随目标计算机的名字。例如,net view file://lx/就是查看主机名为lx的计算机的共享点。

net use 本地盘符 目标计算机共享点——本命令用于建立或取消到达特定共享点的映像驱动器的连接(如果需要,你必须提供用户ID或口令)。例如,你输入net use f: file://lx/mp3就是将映像驱动器F:连接到file://lx/mp3共享点上,今后你直接访问F:就可以访问file://lx/mp3共享点,这和你右击“我的电脑”选择映射网络驱动器类似。

posted @ 2006-05-30 14:42 X-Axis 阅读(227) | 评论 (0)编辑
由于当前维护的项目的结构是:Winform + Webservice,所以在数据传输过程中消耗了很多的性能,因此在寻找一种简便实用的优化方法..

  先是用BinaryFormatter序列化数据集,经过WebService传输后,客户端接收到byte[]格式的数据,再反序列化,得到数据集,这种方式,在网络传输时间延迟比较长的情况下效果比较明显,否则,序列化和反序列化再传输二进制的时间甚至超过了直接传送DataSet.所以是否采取这种二进制压缩数据集就没有多大意义了.

  后来找到上面第一篇台湾同胞的文章,才发现在Vs2005的DataSet已经添加了一个RemotingFormat,是采用另外一种方式压缩的,(传说中.net1.1时期开源的DataSetSurrogate类)不过没有找到这个在什么地方下载,试了一下Vs2005里面的,查询12000条记录,设置RemotingFormat = SerializationFormat.Binary;

  再序列化,通过WebService传输,客户端接收,再反序列化,确实效果大大的优于直接传送DataSet,不仅网络传输中如此,即使本机,性能改善也非常明显.

  下面分别是WebService里面的方法和客户端反序列化取DataSet的方法.

  1. 服务器上面取数据,填充数据集,转换为二进制格式.

/**//// <summary>
/// Method for users data query with binaryFormatter
/// </summary>
/// <param name="err"></param>
/// <returns></returns>
public byte[] BinaryUserSelect(ref string err)
{
 ClearCommand();
 m_commandStringBuilder.Append("SELECT * FROM t_Users ;");
 DataSet dsResult = new DataSet();
 byte[] bArrayResult = null;
 try
 {
  dsResult = SqlHelper.ExecuteDataset(m_currentConnectionString, CommandType.Text, m_commandStringBuilder.ToString());
  // 上面都是取数据的,无需关心.二进制压缩数据集是下面一小段
  dsResult.RemotingFormat = SerializationFormat.Binary;
  MemoryStream ms = new MemoryStream();
  IFormatter bf = new BinaryFormatter();
  bf.Serialize(ms, dsResult);
  bArrayResult = ms.ToArray();
  ms.Close();
  //
 }
 catch (Exception ee)
 {
  err = ee.ToString();
 }
 return bArrayResult;
}

  2. 通过WebService把byte[]格式的数据发送到客户端,这里就是WebService自己的事情了,我们无需关心

  3.客户端接收到byte[]格式的数据,对其进行反序列化,得到数据集,进行客户端操作.

/**//// <summary>
/// Get user data with Binary format
/// </summary>
/// <returns></returns>
public DataSet GetBinaryUserData()
{
 string err = "";
 byte[] bUserData = svc.ByteArrayUserSelect(ref err);
 if (err != "")
 {
  MessageBox.Show(err);
  err = "";
  return null;
 }
 // 反序列化的过程
 MemoryStream ms = new MemoryStream(bUserData);
 IFormatter bf = new BinaryFormatter();
 object obj = bf.Deserialize(ms);
 DataSet dsResult = (DataSet)obj;
 //
 ms.Close();
 return dsResult;
}

  同样一台机器,手工生成12000条数据,在本地使用WebService分别读取、传输并在客户端显示数据集和byte[]格式的数据,前者平均时间2.3秒,后者平均时间为1.7秒,之间的差别仅在传输过程的格式,还有后者需要的序列化和反序列化的时间.本地WebService传输的差别尚且如此,通过网络传输的时间优化自然会更明显..

  .net1.1下面微软提供的DataSetSurrogate开发包下载地址:http://support.microsoft.com/default.aspx?scid=kb;en-us;829740

  对数据集序列化和反序列化的方法进行了一下简单的封装,使其可以得到重用的效果.见下面的类DatFormatter.

  通过GetBinaryFormatData方法可以转换数据集为二进制,在服务器端使用,转换数据集格式。发送,客户端接收,得到二进制格式数据,使用RetrieveDataSet方法,反序列化,得到数据集,进行客户端操作。通过这些简单的操作(序列化和反序列化,将数据压缩),可以使数据集等体积庞大的对象在远程传递中的时间大大减少,并且可以减少网络中断等问题对程序的影响。

1using System;
2using System.IO;
3using System.Data;
4using System.Runtime.Serialization;
5using System.Runtime.Serialization.Formatters.Binary;
6
7namespace Common
8{
9 public class DataFormatter
10 {
11 private DataFormatter() { }
12 /**//// <summary>
13 /// Serialize the Data of dataSet to binary format
14 /// </summary>
15 /// <param name="dsOriginal"></param>
16 /// <returns></returns>
17 static public byte[] GetBinaryFormatData(DataSet dsOriginal)
18 {
19 byte[] binaryDataResult = null;
20 MemoryStream memStream = new MemoryStream();
21 IFormatter brFormatter = new BinaryFormatter();
22 dsOriginal.RemotingFormat = SerializationFormat.Binary;
23
24 brFormatter.Serialize(memStream, dsOriginal);
25 binaryDataResult = memStream.ToArray();
26 memStream.Close();
27 memStream.Dispose();
28 return binaryDataResult;
29 }
30 /**//// <summary>
31 /// Retrieve dataSet from data of binary format
32 /// </summary>
33 /// <param name="binaryData"></param>
34 /// <returns></returns>
35 static public DataSet RetrieveDataSet(byte[] binaryData)
36 {
37 DataSet dataSetResult = null;
38 MemoryStream memStream = new MemoryStream(binaryData);
39 IFormatter brFormatter = new BinaryFormatter();
40
41 object obj = brFormatter.Deserialize(memStream);
42 dataSetResult = (DataSet)obj;
43 return dataSetResult;
44 }
45 }
46}
47
posted @ 2006-05-30 14:40 X-Axis 阅读(84) | 评论 (2)编辑
FROM:JARON_DOT_CN 
使用 .NET 建立分布式应用程序
Steve Kirk 和 Priya Dhawan
Microsoft Developer Network

 

摘要:本文介绍了如何使用 Microsoft SQL Server 2000 的 XML 功能将现有的存储过程代码作为 Web 服务提供。

目录
简介
SQL Server 2000 中的现有代码
总结

简介
Microsoft® SQL Server™ 2000 的 XML 功能可以简化将现有代码作为 Web 服务提供的任务。本文集中讨论了传入和传出 Transact SQL 代码的数据与 XML 消息(在 Web 服务客户机和服务器之间使用)之间的转换。

评估现有代码是否适合于作为 Web 服务提供时,本文讨论的数据转换问题并不是唯一需要考虑的问题。应考虑的其它因素包括状态模型、返回的数据大小、如何表示已经成功、如何返回错误信息、安全模型(包括访问控制、身份验证和加密)、执行模型(同步或异步)、如何分发代码,以及事务模型(COM+ 事务或声明事务),等等。这些问题将在即将发表的体系结构主题(英文)文章中进行讨论。

SQL Server 2000 中的现有代码
SQL Server 2000 的 XML 功能简化了将现有 Transact SQL 代码作为 Web 服务提供的过程。这依赖于 SQL Server 2000 中的两项 XML 功能:

对 Transact SQL 的扩展可将关系型数据转换为 XML,并且可以对传入的 XML 进行语法分析。
利用 ISAPI 模板功能,可将传入的 HTTP 请求应用于 Transact SQL 代码,并且可以使用 XSL 样式表对传出的 XML 进行转换。只要可以使用 FORXML 子句“选定”数据,SQL Server 就可以将 XML 返回到 XML 模板。
SQL Server 2000 XML 模板
SQL Server 2000 XML 模板以透明方式执行以下任务:

对传入的 HTTP 请求进行解码
将参数应用于 Transact SQL 查询
执行查询
使用 XSL 转换传出的 XML
读数据
以下示例执行 ISAPI 模板中指定的 Transact SQL。如果必要,可将 HTTP 请求传递到 Transact SQL 代码,并由该代码进行语法分析。根据模板中指定的 .xsl 文件,返回的 XML 将被转换为 SOAP 并返回给 Web 服务的客户:

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql" sql:xsl="BDAdotNetWebService3Example1.xsl">
<Orders>
<sql:query>
Exec GetOrdersXML
</sql:query>
</Orders>
</ROOT>
以下是模板中引用的 XSL 样式表,它将存储过程中的 XML 转换为 SOAP:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:m="Some-URI">
<xsl:template match="/">
<SOAP-ENV:Envelope>
<SOAP-ENV:Body>
<m:BDAdotNetWebService3Example1Response >
<xsl:copy-of select="//Orders"/>
</m:BDAdotNetWebService3Example1Response>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
</xsl:template>
</xsl:stylesheet>
最后,以下存储过程代码在 Transact SQL SELECT 语句中使用 FOR XML EXPLICIT 子句来返回 XML。“订单”和“订单详细信息”从单独的表中选择,然后合并到 XML 层次中:

/* 订单是父 XML 元素 */
Select 1 as Tag, NULL as Parent,
Orders.OrderId AS [Order!1!OrderId],
Orders.OrderStatus AS [Order!1!OrderStatus],
Orders.OrderDate AS [Order!1!OrderDate],
Orders.SubTotal AS [Order!1!SubTotal],
Orders.Tax AS [Order!1!Tax],
Orders.ShippingHandling AS [Order!1!ShippingHandling],
Orders.ShipToName AS [Order!1!ShipToName],
Orders.ShipToAddressId AS [Order!1!ShipToAddressId],
NULL AS [OrderDetail!2!OrderDetailId],
NULL AS [OrderDetail!2!OrderId],
NULL AS [OrderDetail!2!ItemId],
NULL AS [OrderDetail!2!UnitPrice],
NULL AS [OrderDetail!2!Quantity]
from Orders
UNION ALL
/* 订单详细信息是子 XML 元素 */
select 2 as tag, 1 as parent,
Orders.OrderId AS [Order!1!OrderId],
NULL AS [Order!1!OrderStatus],
NULL AS [Order!1!OrderDate],
NULL AS [Order!1!SubTotal],
NULL AS [Order!1!Tax],
NULL AS [Order!1!ShippingHandling],
NULL AS [Order!1!ShipToName],
NULL AS [Order!1!ShipToAddressId],
OrderDetails.OrderDetailId AS [OrderDetail!2!OrderDetailId],
OrderDetails.OrderId AS [OrderDetail!2!OrderId],
OrderDetails.ItemId AS [OrderDetail!2!ItemId],
OrderDetails.UnitPrice AS [OrderDetail!2!UnitPrice],
OrderDetails.Quantity AS [OrderDetail!2!Quantity]
from Orders, OrderDetails
where Orders.OrderId = OrderDetails.OrderId
ORDER BY [Order!1!OrderId],[OrderDetail!2!OrderDetailId]
For XML EXPLICIT
写数据
以下示例中,通过 HTTP 请求提供表示层次行数据的 XML,然后将其传递到 ISAPI 模板中指定的 Transact SQL 代码。在存储过程中对 XML 进行语法分析,并进行相应的写入操作:

Create Procedure InsertOrder
@Order NVARCHAR(4000) = NULL,
@OrderId int Output
-
DECLARE @hDoc INT
DECLARE @PKId INT
BEGIN TRANSACTION
/* 将 XML 载入文档以进行分析 */
EXEC sp_xml_preparedocument @hDoc OUTPUT, @Order
/* 插入订单标头 */
INSERT Orders(CustomerId,
OrderDate,
ShipToName,
ShipToAddressId,
OrderStatus)
SELECT *
FROM OPENXML(@hDoc, '/NewDataSet/Orders')
WITH ( CustomerId int 'CustomerId',
OrderDate Datetime 'OrderDate',
ShipToName nvarchar(40) 'ShipToName',
ShipToAddressId int 'ShipToAddressId',
OrderStatus int 'OrderStatus')
SELECT @PKId = @@IDENTITY
/* 插入订单详细信息 */
INSERT OrderDetails (OrderId,
ItemId,
UnitPrice,
Quantity)
SELECT @PKId as OrderId, ItemId, UnitPrice, Quantity
FROM OPENXML(@hDoc, '/NewDataSet/Details')
WITH ( ItemId int 'ItemId',
UnitPrice money 'UnitPrice',
Quantity int 'Quantity')
/* 指定输出参数的值 */
Select @OrderId = @PKId
COMMIT TRANSACTION
/* 清除 XML 文档 */
EXEC sp_xml_removedocument @hDoc
总结
本文以及附带的示例介绍了有关数据转换的信息。通过数据转换,可以使用 SQL Server 2000 的 XML 功能将现有 Transact SQL 代码作为 Web 服务提供。本文集中讨论了传入和传出 Transact SQL 代码的数据与 SOAP 消息(在 Web 服务客户机和服务器之间使用)之间的转换。

这些解决方案的性能各异,并且受所传递的数据大小影响。在本系列后面的文章中,我们将对这些实现方法进行比较。

评估现有代码是否适合作为 Web 服务时,接口只不过是应当考虑的诸多因素之一。应考虑的其它因素包括安全性(包括授权、身份验证和加密)、事务模型、状态模型、返回错误和结果的方式,以及代码是同步还是异步执行,等等。

posted @ 2006-05-30 14:37 X-Axis 阅读(56) | 评论 (0)编辑
  2005年9月7日
     摘要: Devenv 命令行开关提示要使 Visual Studio 启动并在编辑器中自动打开单个文件,请在键入无附加开关或参数的 Devenv 后输入完整路径和文件名。例如 devenv "c:\test.cpp"。Devenv 开关语法Devenv 开关遵守的语法规则与其他 DOS 命令行实用工具非常类似。Devenv 命令行开关用于 devenv.com 和 devenv.exe。默认情况下,如果输... 阅读全文
posted @ 2005-09-07 13:07 X-Axis 阅读(594) | 评论 (2)编辑
  2005年8月29日

修改了关于多国语言的一些小bug

下载地址:http://www.cnblogs.com/Files/cegcegceg/TestDataBuilder402.rar

posted @ 2005-08-29 20:19 X-Axis 阅读(357) | 评论 (2)编辑


微软的软件测试方法
微软的软件测试方法
 Jeff W
 
 
Joined: 19 Dec 2002
Total Posts: 91
 
 微软的软件测试方法
Posted: 19 Nov 2004 02:36 PM
Posted: 19 Nov 2004 02:36 PM
 
国内近年来关于软件测试的问题和讨论越来越活跃。但从总体上说交流软件测试技术的多,而探讨软件测试方法的少。这里的“技术”指的是具体的战术问题,比如说如何使用某种工具来解决某一特定测试问题,或者某一类型软件有哪些测试手段等等。而这里的“方法”指的是宏观的战略问题,或者叫方法论,这包括从软件测试的概念或理念,到企业软件质量控制体系;从软件测试的过程,到测试团队的设置及其职责的界定等等。
作为测试人员,热衷于“技术”讨论和交流是一件可喜可贺的事。从中可以感觉到软件测试在中国迅速发展的开端和潜力。但是作为企业的管理决策者,是否也应该以同样的热情来思考“方法”问题呢?特别是当一个软件企业的软件测试从无到有,或者当企业已有一定的软件测试的投入,但发现其实效并不显著,甚至由于测试的引入而带来了新的管理上的混乱。这个时候方法论的思考,更有利于发现问题的根源。即便是一个基层的测试人员,当积累了一定的技术经验后,也应该不时从日常的具体工作中走出来,在一个较高层次上进行回顾总结和借鉴,并试着提出一些优化和改进的措施,这无论对专业上还是对事业上的成长都是非常有意义的。
微软在软件测试方面有很多值得一提的经验,在此我想以我个人的体会和思考,同大家一同进行一些探讨。这里有一点须要特别说明,尽管微软的方法已被微软的实践多次证明是成功的,非常有效的,但这并不意味着这些方法在中国的软件企业中有广泛的可行性。一种方法是否可行还受到很多其他因素的影响,比如企业类型(微软是生产平台软件和通用软件产品的企业),企业管理体制,企业文化等等。所以我的目的只是给大家一些思路和借鉴。

两类经典的软件测试方法

在具体介绍微软的软件测试方法之前,我想首先从概念,或理念的层面上来理解究竟甚么是软件测试,目的是从中导出微软测试方法的理论根源。
传统上认为软件测试的方法从总体上分为两类。第一类测试方法是试图验证软件是“工作的”,所谓“工作的”就是指软件的功能是按照预先的设计执行的;而第二类测试方法则是设法证明软件是“不工作的”。
提出第一类方法的代表人物是软件测试领域的先驱Dr. Bill Hetzel(代表论著《The Complete Guide to Software Testing》),他曾于1972年6月在美国的北卡罗来纳大学组织了历史上第一次正式的关于软件测试的论坛。他首先在1973年给软件测试一个这样的定义:“就是建立一种信心,认为程序能够按预期的设想运行。Establish confidence that a program does what it is supposed to do. ”后来在1983年他又将定义修订为:“评价一个程序和系统的特性或能力,并确定它是否达到预期的结果。软件测试就是以此为目的的任何行为。 Any activities aimed at evaluating an attribute or capability of a program or system. ”在他的定义中的“设想”和“预期的结果”其实就是我们现在所说的用户需求或功能设计。他还把软件的质量定义为“符合要求”。
第一类测试可以简单抽象地描述为这样的过程:在设计规定的环境下运行软件的功能,将其结果与用户需求或设计结果相比较,如果相符则测试通过,如果不相符则视为Bug。这一过程的终极目标是将软件的所有功能在所有设计规定的环境全部运行,并通过。
在软件行业中一般把第一类方法奉为主流和行业标准。1990年的IEEE/ANSI标准将软件测试进行了这样的定义:“就是在既定的状况条件下,运行一个系统或组建,观察记录结果,并对其某些方面进行评价的过程。The process of operating a system or component under specified conditions, observing or recording the results, and making an evaluation of some aspect of the system or component (IEEE/ANSI, 1990 [Std 610.12-1990]”这里所谓“既定的状况”也可理解为需求或设计。
尽管如此,这一方法还是受到很多业界权威的质疑和挑战。代表人物是Glenford J. Myers(代表论著《The Art of Software Testing》)。他认为测试不应该着眼于验证软件是工作的,相反应该首先认定软件是有错误的,然后去发现尽可能多的错误。他还从人的心理学的角度论证,将 “验证软件是工作的”作为测试的目的,非常不利于测试人员发现软件的错误。于是他于1979年提出了他对软件测试的定义:“就是以发现错误为目的而运行程序的过程。The process of executing a program or system with the intent of finding errors.” 这就是软件测试的第二类方法,简单地说就是验证软件是“不工作的”,或者说是有错误的。他甚至极端地认为,一个成功的测试必须是发现Bug的测试,不然就没有价值。这就如同一个病人(假定此人确有病),到医院做一项医疗检查,结果各项指标都正常,那说明该项医疗检查对于诊断该病人的病情是没有价值的,是失败的。我并不完全同意这一看法。
第二类软件测试方法在业界也很流行,受到很多学术界专家的支持。大家熟悉的Ron Patton在《软件测试》( 中文版由机械工业出版社出版,具说此书是目前国内测试新手入门的经典教材)一书的第10页,有一个明确而简洁的定义:“软件测试员的目标是找到软件缺陷,尽可能早一些,并确保其得以修复。”有些软件企业以Bug数量来作为考核测试人员业绩的一项指标,其实就是接受了这样的方法。

两类方法的优劣对比

虽然软件测试总的目的是为了软件产品的质量,但很明显这两类测试方法在具体目标、或指导思想上截然相反。由此也决定了它们在思路、过程和测重点上有很大的差别,并各有利弊的。
第一类测试方法以需求和设计为本,因此有利于界定测试工作的范畴,更便于部署测试的侧重点,加强针对性。这一点对于大型软件的测试,尤其是在有限的时间和人力资源情况下显得格外重要。而第二类测试方法与需求和设计没有必然的关联,如果计划管理不当,测试活动很容易丢失重点,走入歧途。
第一类测试方法可以与软件的架构和软件开发的计划相配合,使软件测试活动逐层次的展开,从而使软件的功能和质量有计划地逐步完善和提高(关于测试的层次问题,我会在今后的讨论中专门介绍)。第二类测试方法不具备这种过程的渐进性。
第一类测试方法的缺点是缺乏灵活性,不利于测试人员主观能动性的发挥,正像Myers先生所说,不容易找到软件的错误(Bug)。而这方面正是第二类测试方法的长处。

微软的策略

正是因为认识到两类测试方法各有利弊,微软在软件测试活动中将两类方法结合起来,以第一类测试方法为基础和主要线索,阶段性地运用第二类测试方法。

微软的第一类测试

微软的第一类测试总体上说分为三个步骤进行:审核需求和设计—〉设计测试—〉实施运行测试。
前文已述,第一类测试是以需求和设计为本来验证软件的正确性。大家很自然的想到,需求和设计本身也有正确性的问题。依据不正确的需求和设计不可能开发出正确的软件产品,测试也将是徒劳的。因此验证需求和设计是微软进行第一类测试的第一步。有必要指出的是,这里所说的需求和设计具体说来它一般包括:(1)由项目经理根据用户要求(信息来源于市场部门,用户支持部门等等)而编写的需求文本(Requirement Specification);(2)由项目经理根据需求文本而编写的功能设计文本(Functional Design Specification);(3)由开发人员根据功能文本而编写的实施设计文本(Implementation Design Specification)。微软的测试人员要参与所有这些文本的审核。作为测试人员,审核重点是检查文本对用户需求定义的完整性、严密性和功能设计的可测性。同时这种审核对于测试人员也是一种热身活动,使他们尽早地进入技术和业务状态。
第二步,测试人员要根据已审核通过的需求和设计编制测试计划,设计测试用例。在前面提到的三种文本中,功能设计文本是主要依据。原因很简单,这类测试关心的是软件是否能正确地实现功能,而不是这些功能如何被具体实施的。从这里大家可以看出这是典型的“黑盒测试”。确实微软的测试主要是从用户角度进行的黑盒测试。这一步的完成就意味着“测试计划”和“测试用例设计”两个文本的完成。“测试计划” 文本主要阐述测试的范畴、领域、方法、工具、资源和计划时间表等等。“测试用例设计”文本要列出测试用例、每个用例的设置、执行步骤和预期结果。测试的这两个文本也要被项目经理和开发人员审核。这样经过各种相互的审核,大家对项目形成了基本的共识。
第三步的实施运行测试是整个开发过程中最长最复杂的一个阶段。从总体上说就是将上一步设计的测试用例按计划付诸实施的过程。这包括编写自动化测试程序、反复运行自动化测试程序,也包括阶段性执行手动测试用例。这一阶段的测试必须在周密的计划下进行,在前面我已提到,这正是第一类测试的特点和长处。这种计划性首先体现在开发和测试的相互协调配合,根据产品的架构和功能模块的依赖关系,按照项目的总体计划共同推进。从测试的过程来看,总是先运行或执行简单用例,然后再复杂用例;先验证单一的基本功能,再综合的端到端的功能;先发现解决表面的,影响面大的Bug,再深层的,不容易重现的Bug。因此随着项目开发和测试的进程,产品的功能不断完善,质量不断提高。这里有一点要特别指出,有很多测试用例是要反复运行的,特别是基本的自动化测试每一天,每一个Build上都要运行。尽管这些测试大多数情况下都是通过的,很少再发现新的Bug,但其价值是显而易见的,就是为了防止质量回归。可见Myers的理论在这里是不适用的。这一阶段测试人员还有一项繁琐但却很重要的工作,就是对已有的测试用例的维护。比如通常以下两种情况下要新增一些测试用例,一是对于当初测试设计不周全的领域,二是对于外部的Bug(比如从Beta客户报告来的),没有被现有测试用例所覆盖。当产品的功能设计出现更改时(在微软这是常事),所涉及的测试用例当然也要相应地修改。

微软的第二类测试

微软的第二类测试是阶段性的,常常根据需要而带有随机性和突击性。对于这类测试,在微软有一个专门的名称:“Bug Bash(Bug大扫除)”。
Bug Bash通常发生在项目开发各阶段(微软叫里程碑)的末期,比如Beta版发布前,划出一个专门的时间段(通常1-3天),在这期间所有参与项目的人员,集中全部精力,运用各方面的知识,尽全部智慧来搜寻项目的Bug。这是一个非常有意思的活动,但要组织好这样的活动并非易事。一般有以下要点:(1)尽管这是一个测试活动,但参与者并不仅限于测试人员。项目经理,开发人员甚至于高层管理人员都应参加,如同全民动员。目的是要集思广益;(2)要鼓励各部门,领域交叉搜索,因为新的思路和视角通常有助于发现更多的Bug;(3)为调动积极性,增强趣味性,可以适当引入竞争机制,比如当活动结束时,评出发现Bug最多,发现最严重Bug的个人,给以物质和精神奖励。(4)可以分专题展开,比如安全性、用户界面可用性、国际化和本地化等等。
微软的第二类测试除了Bug Bash外,经常还有一些专业性的测试,最典型的是针对安全性攻击测试。一般会邀请公司内部,或业界的专家来搜寻产品的安全漏洞。

以上我从传统软件测试概念的角度,介绍了微软的策略和两类传统测试方法的具体做法,及其侧重点。这其实仅仅是一个基础,一个很原始的基础。软件测试在微软软件产品开发中的作用、地位远不是这些原始的方法所能达到的,也不是传统软件测试概念所函盖的。微软在软件测试方面有很多特有的做法,和概念上的突破,比如“软件测试的信息服务功能”、“以用户为中心的宏观质量体系”、“分级测试”、“项目的质量管理系统”、“Bug三方会审”、“测试自动化”和“软件测试的软硬件—部门、团队、人和基础设施”等等。这些我会在以后的讨论中分专题进行介绍。

 -------------------------------------------------------------------------------

Jeff Wang[MSFT]

本贴子以“现状”提供且没有任何担保,同时也没有授予任何权利
 
 bitter
 oined: 06 May 2004
Total Posts: 30 
  Re: 微软的软件测试方法
Posted: 29 Nov 2004 04:37 PM
Posted: 29 Nov 2004 04:37 PM
很长见识,感谢jeff w.

我想请教一个老话题, 你们是怎样决定测试何时结束的呢? 比如你说的bug bash, 这种方法我虽然没实践过, 也能确信它的价值. 但是怎么保证不会过度投入呢?

我所经历的项目测试资源都比较有限(时间,人月), 所以一般都是在资源耗尽的时候就自然结束了, 当然也会考察覆盖率,风险, 发现bug数量的变化(越来越少), 但是主要是以资源耗尽为主要理由来停止测试的.

不知道微软在这个问题上有什么经验和方法?

  TL_geong
  
Joined: 20 Aug 2003
Total Posts: 251
 
 Re: 微软的软件测试方法
Posted: 30 Nov 2004 01:38 PM
Posted: 30 Nov 2004 01:38 PM
首先,我觉得这是一个策略性的问题。
一般来说,大多数公司都是用的第一类的测试策略。目的很简单,就是满足客户的期望。
但另一方面客户的期望有可能超过需求的定义,而且最终用户的期望往往比客户(客户是付钱的,最终用户是使用的)所想象的要高。最终用户的问题往往会给客户带来压力,进而影响客户满意度。
出于产品本身的质量提高的角度,我们一般会增加一个随机测试的工作。类似Bug大扫除的性质。这个随机测试有时候效果会很不错,有时候会没有成果,还有的时候会发现已经收敛的缺陷趋势出现严重的发散现象。由于这个随机测试可能给项目组带来很多压力(比如,客户看到这么多问题后会有想法),因此管理和疏导压力是比较困难的一件事。

--------------------------------------------------------------------------------
沈滔 MSN:t628shen@hotmail.com 
 bitter
 oined: 06 May 2004
Total Posts: 30
 
 Re: 微软的软件测试方法
Posted: 30 Nov 2004 01:49 PM
Posted: 30 Nov 2004 01:49 PM
我觉得随机测试和bug bash的区别还是挺大的. 

--------------------------------------------------------------------------------
http://groups.yahoo.com/group/china-testing 
 Jeff W
 oined: 19 Dec 2002
Total Posts: 91
 
 Re: 微软的软件测试方法
Posted: 30 Nov 2004 04:42 PM
Posted: 30 Nov 2004 04:42 PM
测试何时结束?
在按计划结束的那一天结束!

我这个答案你听了一定不满意。但这个答案告诉你微软所依据的最基本的原则,这就是计划。在我前面介绍微软的第一类测试时我提到“测试计划”,这个“测试计划”实际上就是要回答测试的投入问题,包括人力资源、时限和过程。确定测试计划有这么几个依据:1)产品的功能。功能的量和复杂性直接影响测试的工作量;2)质量标准,有公司的标准、行业的标准、市场反馈的标准和客户要求的标准等;3)以往的经验,有以往的产品的经验,也有个人的经验。这一“测试计划”还要被项目的各方(开发,项目管理)审核通过,从而在整个产品部门形成一种共识,这种共识最终被纳入项目总体计划的一部分。对于第二类测试,它也是总项目总体计划的一部分,而且量也是可知的。一般地说在每个里程碑都会有几个分专题的“Bug Bash”,每次历时1-3天。在微软的项目计划书中总有那么一天,叫做“测试完成日 Test Complete Day”。它标志着所有计划的测试活动已全部完成,所有被发现的Bug被全部解决,并被测试所验证(有一些会因为某些原因被研究决定推迟解决)。

对于以上的分析你也许仍然不满意:难道微软的计划总能按期完成吗?
当然不是,逾期的情况时常会有。几乎可以肯定,项目的实际执行与预先的计划一定会有或多或少的差距。微软会在项目过程中采取一些方法来感知这种差距,比如bitter提到的代码“覆盖率”分析和bug数量的变化趋势分析等。目的是为了尽早地发现差距,重新评估和修订计划。这样计划可以变化,但测试总是在计划结束的那一天结束。

--------------------------------------------------------------------------------
Jeff Wang[MSFT]

本贴子以“现状”提供且没有任何担保,同时也没有授予任何权利 
 bitter
 Joined: 06 May 2004
Total Posts: 30
 
 Re: 微软的软件测试方法
Posted: 01 Dec 2004 11:35 AM
Posted: 01 Dec 2004 11:35 AM
jeff , 非常感谢,你讲解的很清楚. 希望早日看到你后继的内容。 你的帖子是我目前为止在国内论坛看到的最有价值的内容。 你的表达能力也很让人赞赏。 --------------------------------------------------------------------------------
http://groups.yahoo.com/group/china-testing 
 Jeff W
 Joined: 19 Dec 2002
Total Posts: 91
 
 Re: 微软的软件测试方法
Posted: 01 Dec 2004 04:18 PM
Posted: 01 Dec 2004 04:18 PM
感谢bitter的称赞。

对于TL_geong提到的随机测试造成收敛的缺陷趋势出现严重的发散现象,在微软也有。通常Bug Bash会产生超乎寻常数量的Bug。一般我们认为,产生Bug的量越大越好。因为,如果产生Bug的数量少,你很难判断是因为产品的质量确实很高,还是Bug Bash做得不彻底。而且事实往往是后者。

那么对Bug Bash所产生的大量Bug该怎么办?在微软,我们有“Bug Triage (测试,开发和项目管理,三方会审)”的制度。对于每个Bug,经过会审后不外乎有以下三中归宿(总体上来说):

(1)被确认为“缺陷性”Bug,这样的Bug必须交开发人员解决,然后由原发现人验证。

(2)被调整为非“缺陷性”Bug,不用开发人员作任何更改,但必须将问题纳入产品用户文档,明确向用户解释,并告诉用户如何避免和应对。比如这里举一个假想的例子:产品的某个功能在系统内存严重不足的情况下,会暂时停止工作,并生成很多不易被用户理解的警告信息。这显然是个Bug(按微软的标准),正确的应该是,首先软件不应该完全停止工作,其次不应该多次警告,第三,警告信息应简明易懂,并给用户以措施和建议。但是考虑到,一方面这种情况在用户实际使用产品时发生的机率很低,而另一方面,从开发角度,解决这个问题有很大的技术难度,影响面也太大。这种情况下会把这个Bug改为“文本性”Bug,也就是要求文本遍写人员将这一情况作一技术性解释,并建议用户不要将此产品同其他消耗大量内存的软件同时使用。这类的Bug在Bug Bash中很常见,因为大家在这种测试活动中思维方式比较超常。

(3)被完全否定,立刻关闭,不再纠缠。这类的情况在Bug Bash中也很常见。因为参与Bug Bash人并不都很了解产品功能的准确用法,误报是难免的。尽管对这类问题没有直接的后续措施,但这些信息仍然是有一定价值的,因为将来用户中的新手很可能会犯同样的毛病,而产品支持部门如果预先有这样的经验,就能及时准确地提供帮助。所以这些信息要保存在Bug的管理库中,以备将来产品支持部门查询。

经过这样的会审,筛选,如果(1)(2)类Bug,特别是(1)类Bug仍然很多,那测试部门很可能需要重新论证原先的测试计划和测试用例设计,看是否需要增加测试用例。必要时还要尽早提出更改项目总体计划和发布日期。

大量Bug的出现也许不是件愉快的事,但和把这些Bug留给用户相比,代价要小得太多了。总之对于产品的Bug,要相对待身体的疾病一样,切末讳疾忌医。

--------------------------------------------------------------------------------
Jeff Wang[MSFT]

本贴子以“现状”提供且没有任何担保,同时也没有授予任何权利 
 TL_geong
 Joined: 20 Aug 2003
Total Posts: 251 
 Re: 微软的软件测试方法
Posted: 01 Dec 2004 05:26 PM
Posted: 01 Dec 2004 05:26 PM
我以前做无线产品的产品类测试,现在做J2EE的项目类测试。
在产品类测试中,几乎所有既定计划完成后的时间都可以用来找缺陷,因此也没有Bug大扫除的说法。
不过做项目类的测试就不一样了。项目测试中每个人员所受到的进度和成本的压力和不平衡的问题要超过产品测试。因此,我暂时叫它“随机测试”。这2个之间的区别肯定会有,甚至有时候很大。另一方面,做项目时,测试人员和客户的软件水平参差不齐、相差很大。要让他们理解测试是需要使用不同的语言的。相对来说,“随机测试”更容易理解。

经常遇到的情况是,项目开发进度Delay、Bug来不及改,因此出现测试可用时间不充分的风险,这是基本上无法组织“随机测试”。开发和修正效率较低时,往往会增加测试的成本,此时还会出现成本超支,无法组织“随机测试”的现象。

在项目类测试中,缺陷发散的问题所带来的压力要远比产品类的大。客户多半都能看到缺陷的情况,而且很多客户都会直接问基层员工:“这么简单的一个问题为什么现在才发现?为什么不修正?为什么要这么长时间来修正?”。这样一来,本身进度和质量压力已经很大的项目组,受到这么一折腾,很可能会“爆掉”。这个是公司所不愿看到的。

我们目前的做法是:
无论是随机测试的问题,还是其它测试的问题,只要它没有被正确Closed,那么都需要测试和开发Manager进行沟通,相关测试和开发人员陈述意见和建议。如果Manager之间还不能解决,那么问题要上升到类似CCB的组织进行裁决。一般这个时间是在做最后一轮测试前,也就是上线前一段时间。
已经正确Closed的问题,谁都不会去纠缠。 --------------------------------------------------------------------------------
沈滔 MSN:t628shen@hotmail.com 
  Jeff W
 Joined: 19 Dec 2002
Total Posts: 91
 
 Re: 微软的软件测试方法
Posted: 02 Dec 2004 04:25 PM
Posted: 02 Dec 2004 04:25 PM
TL_geong,感谢你提供了一些项目开发的经验,确实它与产品开发有一些不同。这里我有些疑问向你请教:

首先,你们为什么把“随机测试”放在最后,等几乎所有既定计划完成后才进行?难道是认为“随机测试”不如“既定计划测试”重要?根据我的经验,很少有项目会在后期阶段有所谓的空余时间来做些随意性的工作。放在最后有时间再做,结果往往是取消或者草草了事。我们认为一类,二类测试是同等重要的,第二类测试对于验证第一类测试的覆盖性起很大的作用(没有哪种工具能取代),第二类测试若发现大量真正的Bug,那第一类测试的原先设计和计划就一定要相应调整。所以微软会在每个理程碑都有“Bug Bash”,而不是把它放在最后。我感到把“随机测试”放在最后就像一场赌博,赌你们的测试计划很完备周密。若不是这样,最后,一场成功的“随机测试”会给你揭露出一大堆问题,而恰恰这时,项目交货的日子到了。该如何收拾这场残局呢?要知道这还不是最坏的结局。最坏情况是你们最后没有机会做“随机测试”,或做了但不成功,结果那一大堆Bug溜到了你们的客户手中。这对你们或你们的用户支持将是一场灾难。

第二个问题是,你们为什么会把缺陷发散的压力加在基层员工身上?难道当初的测试计划没有经过大家审查吗?如果经过了大家的审查,即使有不周全,甚至范了低级错误也不应该由个人承担。

第三个问题是关于你提到的CCB组织,这是个上层权利部门吗?在微软,Bug命运由测试部门作主,若开发和管理不服,一般会请市场部门或客户支持部门提供进一步的信息,因为他们更接近客户。

--------------------------------------------------------------------------------
Jeff Wang[MSFT]

本贴子以“现状”提供且没有任何担保,同时也没有授予任何权利 
  mslgn
 Joined: 13 Dec 2004
Total Posts: 44
 
 Re: 微软的软件测试方法
Posted: 13 Dec 2004 11:19 PM
Posted: 13 Dec 2004 11:19 PM
思路大开,谢谢Mr. W --------------------------------------------------------------------------------
Maxwell Liu[HWTC] 
  Jeff W
 Joined: 19 Dec 2002
Total Posts: 91
 
 Re: 微软的软件测试方法
Posted: 16 Jan 2005 01:42 PM
Posted: 16 Jan 2005 01:42 PM
微软的软件测试方法(二)

我在前一篇“微软的软件测试方法”中介绍了微软的两类基本测试方法,其基本思想大家应该是比较熟悉的,因为它们还只是传统的软件测试方法的综合。所以单从形式上,它并没有体现出对传统框架的突破。但是从另一个层面来考察微软软件测试时,你会对一些基本的事实感到惊讶。比如,“微软的测试人员和开发人员数量大致相等或略多”,“微软的产品成本中测试大约占40%以上”等等。人们会有疑问,仅仅是作为功能验证和搜寻Bug的测试能消耗这么大量的资源吗?有必要付出如此大的代价吗?应该有理由相信,微软作为一个软件企业,其每一份投入都是有意义的,因此也可断定微软在软件测试方面的努力一定超出传统测试方法的范畴。
历史回顾
为了更好的理解微软件测试在方法和理念上的突破,我想首先回顾一下软件开发和软件测试的发展历史,并从中揭示其必然性。Edward Kit 在他的畅销书“Software Testing In The Real World : Improving The Process(1995, ISBN: 0201877562)”中将整个软件开发历史分为三个阶段:

第一个阶段是60年代及其以前,那时软件规模都很小、复杂程度低,软件开发的过程随意。开发人员的Debug过程被认为是唯一的测试活动。其实这并不是现代意义上的软件测试,当然一阶段也还没有专门测试人员的出现。

第二个阶段是70年代,这个阶段开发的软件仍然不复杂,但人们已开始思考开发流程问题,并提出“软件工程Software Engineering”的概念。但是这一阶段人们对软件测试的理解仅限于基本的功能验证和Bug搜寻,而且测试活动仅出现在整个软件开发流程的后期,虽然测试由专门的测试人员来承担,但测试人员都是行业和软件专业的入门新手。

第三个阶段是80年代及其以后,软件和IT行业进入了大发展。软件趋向大型化。与之相应,人们为软件开发设计了各种复杂而精密的流程和管理方法(比如CMM和MSF),并将“质量”的概念融入其中。软件测试已有了行业标准(IEEE/ANSI ),它再也不是一个一次性的,而且只是开发后期的活动,而是与整个开发流程融合成一体。软件测试已成为一个专业,需要运用专门的方法和手段,需要专门人才和专家来承担。

测试与开发的融合

在这一历史发展过程中,最值得注意的是测试与开发流程融合的趋势。人们对这种融合也许并不陌生。比如测试活动的早期展开,让测试人员参与用户需求的验证,参加功能设计和实施设计的审核。再比如测试人员与开发人员的密切合作,随着开发进展而逐步实施单元测试、模块功能测试和系统整合测试。的确这些都是测试与开发融合的表现形式,而且初期的融合也只反映在这个层次上。90年代以后,软件的规模和复杂程度迅速提高,这种形式上的融合也迅速走向更深层次,更具实际意义。具体地说这种融合就是整个软件开发活动对测试的依赖性。传统上认为,只有软件的质量控制依赖于测试,但是现代软件开发的实践证明,不仅软件的质量控制依赖于测试,开发本身离开测试也将无法推进,项目管理离开了测试也从根本上失去了依据。在微软,测试的确有这样的地位和作用。这就是为什么微软在软件测试上有如此大的投入。

开发对测试的依赖

现代软件开发,特别是大型软件开发通常会遇到以下两个问题:

(1) 在开发初期,如何能够展开大规模团队,群体齐头并进,而同时保持开发的有序性。从而有效利用资源,缩短开发周期。
(2) 在开发后期,如何解决深层次的Bug,如何面对设计更改,而能够保证产品的质量不出现或少出现回落。

对于小型简单的软件,这两个问题也存在,但不突出,而且容易解决。但对于复杂的大型软件的开发,这两个问题常常会成为难以逾越的障碍。

通常大型项目的功能丰富,但架构、层次也会相当复杂。稳妥的开发方式是,一次投入少量的人员,逐层开发,逐层稳定。但这种方式显然资源利用率低,开发周期长,不能满足现代软件和IT行业高速发展、瞬息万变的需要。因此大型项目需要大型团队。在微软,产品开发团队(主要包括开发、测试和项目管理)一般都有百人以上规模,有些产品甚至上几千人(Windows2000的开发部门曾有3000多人)。这样大规模的人力资源作用在一个动态的,内部相互联系的系统中,若没有有效的协同,其混乱是不可避免的。试想,有两个开发人员,分别在开发两个不同的功能模块,其相互有依赖关系。为了相互协调,他们可以随时进行当面讨论。如果这种关系发生在五个开发人员和五个功能模块之间,这种协调就只能通过定期的会议来进行。而一个大型项目,会有许许多多这样的关系,而且很多时候这种关系有着不确定性和不可预见性。当一个开发人员编写一段新的代码或对已有代码进行改动和调整时,他(或她)常常无法确定,或无法完全确定究竟有哪些相关的模块会受到影响,以及在什么请况下这种影响会带来什么结果。因为系统的复杂性已远远超出了人的逻辑思维、技能和经验所能力及的范畴。因此这种传统的协调手段是远不能满足需要的。
         在微软,这种协调是通过测试来实现的。具体来说就是:每日建造+自动化测试。关于每日编译和自动化测试,我将来会作专门介绍,这里简单的说就是每天都建造一个新版本,每个版本都要运行通过一定量的自动测试用例,以检验当天工作的质量。这里所说的质量当然有一般意义上质量的概念,但同时它也反映项目在开发过程中的整体协调性。
         自动测试的最大优点在于它的高度可重复性。一个理想的自动测试系统能够让人随时、方便和迅速的运行大量的测试用例。因此一个开发人员可以通过检查当天的自动测试结果来分析前一天代码的质量(事后检查),也可以在当天存入代码前,先运行自动测试以进一步确保存入代码的质量(事前检查)。
        在微软,每日建造都是在午夜开始,完成后紧接着就是全面的自动测试,到早晨上班时间之前就会把结果自动通过e-mail等方式发送出来。开发人员上班后的第一件事往往就是检查测试结果。如果没有问题就会开始新的工作。如果有测试有用例没有通过,开发人员则必须协同测试人员一起立刻找出原因,解决后才能开始新的代码。有时一个小的失误会引起大面积的测试用例失败,很大一部分开发团队会受到影响。为尽量避免这种情况,要求开发人员在存入代码之前先在自己的个人建造版本上运行一定量的自动测试,全部通过后在存入。如开发人员没有按照这样的要求,而擅自存入质量不高的代码而造成大量测试失败,这种不负责任的行为是要受到严厉批评的。从这一过程可以看出,开发人员依赖测试来保证开发工作的质量,使开发整体地协调地向前推进。

当开发进入后期阶段,尽管项目已总体成型,开发人员也会不时遇到一些技术上的挑战。比如一些Bug的解决涉及对项目深层次结构的调整;再比如由于客户反馈的意见造成设计的修改。每一次这样的修改和调整事实上都是对一个稳定系统的破坏,如果处理不当往往一个Bug的修改会生成很多新的Bug,就像一系列联锁的恶性循环。很多项目工期的延误都是这样造成的。要避免或至少将这种破坏减少到最低限度,开发人员首先需要知道这种破坏的影响面。在这里单靠开发人员自身的逻辑思维、技能和经验是远远不够的,自动测试再一次成为一种有效的工具。往往开发人员会制定不止一个方案,对每个方案上都运行一遍同样一套自动测试用例,然后比较结果,选出最佳方案。自动测试在这方面所起的作用不仅在产品的开发过程中,它还延续到产品发布后。产品支持部门在为客户提供应急解决方案时也要依赖自动测试。


管理对测试的依赖


在微软,软件项目管理的主要线索就是Bug的管理,其中最直接具体的管理活动就是“Bug三方讨论会(Bug Triage)”。会议一般由项目管理Program Manager(简称PM)来主持,有开发人员和测试人员参加(所以叫三方会议)。会上对每个新生成的Bug进行讨论,并决定(1)是否接受这个Bug;(2)Bug的严重级别和优先级别;(3)Bug由谁来负责,是由测试提供进一步详细信息,还是交由开发人员解决,以及大致的解决方案等等。会议还要对老的Bug检查解决进度。这种讨论会常常会发生争论,要求测试人员具有足够的技术基础和用户经验,来捍卫产品的质量。可以说项目开发到了某一阶段后就是由这种Bug的管理所驱动的。这其中的原动力来自测试。

项目管理中一项非常重要但也十分困难的工作是衡量项目的进度,包括判断项目的状态,确定项目是否能预期完成。这方面,测试提供了两个非常重要的参数,一个是Bug数量的趋势,另一个是测试结果的趋势。

Bug趋势就是将每天新生成的Bug数和每天被解决的Bug数标成一个趋势图表。一般在项目的开始阶段新生Bug数曲线会呈上升趋势,到项目中后期被解决Bug数曲线会趋于上升,而新生Bug数曲线应下降,到项目最后,两条曲线都趋向于零。PM会持续观察这张图表,确保项目健康发展,同时通过分析预测项目Bug趋于零的时间。在一定的历史经验的基础上分析使用这一图表会得到很多有价值的信息,比如说,可分析开发和测试在人力资源的配比上是否恰当,可以分析出某个严重的Bug所造成的项目质量的波动。

每天的自动测试结果同样可以形成类似的图表。它同样非常有助于了解当前项目的质量状况,开发测试进度。

由测试产生的这些数据不仅在项目开发过程中为项目管理提供有效的依据,而且也是产品通过发布的必要条件。在微软,每个产品都要经过评审才能通过发布。前面介绍的几个图表是发布评审的重要内容,如果从图表中发现临评审前还出现过较大的质量波动,评审人员一定会对此提出质疑。

因此软件项目管理依赖软件测试提供其基本的管理素材。


可以说,现代大型软件开发过程中开发和管理对测试的依赖性是测试与开发流程融合的一个根本因素。从另一个角度看,测试与开发流程融合决不仅仅是简单的时间上的同步,更不是双方空间上的接近,而是这种内在的依存关系的外在表现。开发对测试的这种依赖性对测试和测是人员提出了更高的要求。在理念上,软件测试已远不仅仅只是软件功能的验证和Bug的搜寻;在具体方法上,自动测试和测试工具的使用已成为基本的要求。在微软,测试不仅使用一些通用的工具,每一个产品还有专门开发的专用工具库,测试的代码量常常超过项目本身的代码量。

一个软件企业要提高其软件开发的能力,特别是针对大型软件的大规模的快速开发能力,在测试方面对传统理念和方法进行突破是必要的。微软的实践就是一个很好的印证。

--------------------------------------------------------------------------------
Jeff Wang[MSFT]

本贴子以“现状”提供且没有任何担保,同时也没有授予任何权利  

 liuyang630_630
 
Joined: 12 Nov 2004
Total Posts: 14
 
 Re: 微软的软件测试方法
Posted: 17 Jan 2005 10:32 PM
Posted: 17 Jan 2005 10:32 PM
读了你的文章的确让我这种初学者收益非浅,希望以后有机会与你交流学习. 
 
  
 dfg
 
 
Joined: 12 Dec 2002
Total Posts: 5
 
 Re: 微软的软件测试方法
Posted: 18 Jan 2005 09:56 AM
Posted: 18 Jan 2005 09:56 AM
感谢Jeff Wang的详细讲解,给我提供了理论和方法的指导! 
  carol mo
 
Joined: 19 Jan 2005
Total Posts: 1
 
 Re: 微软的软件测试方法
Posted: 19 Jan 2005 07:57 PM
Posted: 19 Jan 2005 07:57 PM
茅塞顿开阿!尤其是开发和测试的关系这一点!期待jeff大师下一个精彩的论题 
  
 herah
  
Joined: 30 Jul 2004
Total Posts: 41
 
 Re: 微软的软件测试方法
Posted: 24 Jan 2005 12:46 PM
Posted: 24 Jan 2005 12:46 PM
跟踪 
  
 TL_geong
 
Joined: 20 Aug 2003
Total Posts: 251
 
 Re: 微软的软件测试方法
Posted: 26 Jan 2005 03:00 PM
Posted: 26 Jan 2005 03:00 PM
顶 --------------------------------------------------------------------------------
沈滔 MSN:t628shen@hotmail.com 
  
 xalee
 
Joined: 31 Jan 2005
Total Posts: 2
 
 Re: 微软的软件测试方法
Posted: 31 Jan 2005 02:56 PM
Posted: 31 Jan 2005 02:56 PM
的确,好的测试需要理论的指导和实践的检验,只有处理好理论和实践的平衡才可能取得测试工作的成功。我觉得微软还是比较重视第二种理论的,在微软的hr网站上对测试工作的描述就是“We break it to build it”。:)

谢谢Jeff的分享。

如果有时间,Jeff能否请你谈谈微软的测试团队是如何管理的呢?从管理的角度如何提高测试工作的质量?

thanks.
xalee   
 DeltaDavi
 
Joined: 01 Feb 2005
Total Posts: 4
 
 Re: 微软的软件测试方法
Posted: 02 Feb 2005 10:28 AM
Posted: 02 Feb 2005 10:28 AM
特意为您申请用户来回帖!
偶看到的最好的一篇论述。期待您继续跟大家分享。
yumen1
  
Joined: 16 Feb 2004
Total Posts: 15 
  本文引用通告地址: http://blog.csdn.net/okli/services/trackbacks/314653.aspx
[点击此处收藏本文]
发表于 2005年03月08日 2:02 PM

 

posted @ 2005-08-29 17:34 X-Axis 阅读(214) | 评论 (0)编辑

asp.net中的服务器控件是在服务器端解析的,默认是支持IE的,但如果用NETSCAPE,Firefox浏览的话可能会出现页面元素失真的情况,解决办法如下。在web.config中加入如下:

 



        
<browserCaps>


        
<!-- 
        Name:        BrowserCaps update for modern browsers, http://slingfive.com/pages/code/browserCaps/
        Author:    Rob Eberhardt, http://slingfive.com/
        History:
            2004-11-19    improved detection of Safari, Konqueror &amp; Mozilla variants, added Opera detection
            2003-12-21    updated TagWriter info
            2003-12-03    first published
        
-->

            
<!-- GECKO Based Browsers (Netscape 6+, Mozilla/Firefox, ) //-->
            
<case match="^Mozilla/5\.0 \([^)]*\) (Gecko/[-\d]+)(?'VendorProductToken' (?'type'[^/\d]*)([\d]*)/(?'version'(?'major'\d+)(?'minor'\.\d+)(?'letters'\w*)))?">
                browser=Gecko
                
<filter>
                    
<case match="(Gecko/[-\d]+)(?'VendorProductToken' (?'type'[^/\d]*)([\d]*)/(?'version'(?'major'\d+)(?'minor'\.\d+)(?'letters'\w*)))">
                        type=${type}
                    
</case>
                    
<case> <!-- plain Mozilla if no VendorProductToken found -->
                        type=Mozilla
                    
</case>
                
</filter>
                frames=true
                tables=true
                cookies=true
                javascript=true
                javaapplets=true
                ecmascriptversion=1.5
                w3cdomversion=1.0
                css1=true
                css2=true
                xml=true
                tagwriter=System.Web.UI.HtmlTextWriter
                
<case match="rv:(?'version'(?'major'\d+)(?'minor'\.\d+)(?'letters'\w*))">
                    version=${version}
                    majorversion=0${major}
                    minorversion=0${minor}
                    
<case match="^b" with="${letters}">
                        beta=true
                    
</case>
                
</case>
            
</case>

            
<!-- AppleWebKit Based Browsers (Safari) //-->
            
<case match="AppleWebKit/(?'version'(?'major'\d?)(?'minor'\d{2})(?'letters'\w*)?)">
                browser=AppleWebKit
                version=${version}
                majorversion=0${major}
                minorversion=0.${minor}
                frames=true
                tables=true
                cookies=true
                javascript=true
                javaapplets=true
                ecmascriptversion=1.5
                w3cdomversion=1.0
                css1=true
                css2=true
                xml=true
                tagwriter=System.Web.UI.HtmlTextWriter
                
<case match="AppleWebKit/(?'version'(?'major'\d)(?'minor'\d+)(?'letters'\w*))(.* )?(?'type'[^/\d]*)/.*( |$)">
                    type=${type}
                
</case>
            
</case>

            
<!-- Konqueror //-->
            
<case match=".+[K|k]onqueror/(?'version'(?'major'\d+)(?'minor'(\.[\d])*)(?'letters'[^;]*));\s+(?'platform'[^;\)]*)(;|\))">
                browser=Konqueror
                version=${version}
                majorversion=0${major}
                minorversion=0${minor}
                platform=${platform}
                type=Konqueror
                frames=true
                tables=true
                cookies=true
                javascript=true
                javaapplets=true
                ecmascriptversion=1.5
                w3cdomversion=1.0
                css1=true
                css2=true
                xml=true
                tagwriter=System.Web.UI.HtmlTextWriter
            
</case>

            
<!-- Opera //-->
            
<case match="Opera[ /](?'version'(?'major'\d+)(?'minor'\.(?'minorint'\d+))(?'letters'\w*))">
                
<filter match="[7-9]" with="${major}">
                    tagwriter=System.Web.UI.HtmlTextWriter
                
</filter>
                
<filter>
                    
<case match="7" with="${major}">
                        
<filter>
                            
<case match="[5-9]" with="${minorint}">
                                ecmascriptversion=1.5
                            
</case>
                            
<case>
                                ecmascriptversion=1.4
                            
</case>
                        
</filter>
                    
</case>
                    
<case match="[8-9]" with="${major}">
                        ecmascriptversion=1.5
                    
</case>
                
</filter>
            
</case>


        
</browserCaps>

posted @ 2005-08-29 10:56 X-Axis 阅读(201) | 评论 (0)编辑
  2005年8月27日
        大家遇到过这种情况吗?在你做单元测试的时候,需要手动的往数据库中插入那些测试数据,字段少的表还好,如果遇到了200多个字段的表的话,简直是一个字“晕”了得。这个时候,你是不是想找一个工具,定义好规则,然后自动生成这些测试数据呢?我是遇到了这种情况了,为了偷懒,就编了这个TestDataBuilder,与大家分享(绝对Free)。希望能够也为我们程序员兄弟姐妹们减少一些无畏的无聊的劳动:)
       先看帮助文件,可能会有很大的帮助哦:)
      若发现BUG,欢迎发mail到cegcegceg@56.com

下载地址:http://www.cnblogs.com/Files/cegcegceg/TestDataBuilder401.rar

======================================
系统描述:
 本程序是一款自动化测试辅助工具;
 可以帮助程序员或测试人员自动生成数据库表中的测试数据;
 可以通过配置文件配置规则;
 可以结合单元测试工具使用;
 可以根据规则,用户可以自己开发GUI外挂;
 可以备份和恢复SQLServer中的数据;
 可以运行自定义的VB脚本和SQL脚本;
     支持中、日、英三个语言版本;
posted @ 2005-08-27 11:58 X-Axis 阅读(485) | 评论 (0)编辑
人生宛如一段程序

 有时一帆风顺

 有时面临选择

 而有时却循规蹈矩

 你,就是这段程序的编写者!
posted @ 2005-08-27 11:37 X-Axis 阅读(52) | 评论 (0)编辑
<2008年9月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

与我联系

搜索

 

常用链接

留言簿

随笔档案

最新随笔

最新评论

阅读排行榜

评论排行榜