首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

8.0  导读

本章所讲述的这些技术展示了如何测试ASP.NET Web Service。你可以把Web Service想象成是位于服务器上的一组方法的集合,这些方法可以由客户机通过网络进行调用。Web Service经常会向外界暴露一些SQL数据库里的数据。例如,设想你有一个从事图书销售的公司。你想让其他公司的网站也能访问你的书籍信息,从而扩展访问量。但是,你并不想让别人直接访问你的数据库。有一个方案可以解决这个问题,就是创建一个ASP.NET Web Service,让这个Web Service以一种简单的、标准化的、加密的方式向外界暴露你的书籍信息。图8-1展示了一个示范性的Web程序。用户可以从数据仓储里查询书籍信息。从图上我们并不能看出Web程序所显示的数据来自ASP.NET Web Service,而不是直接来自SQL数据库。

图8-1  使用ASP.NET Web Service的Web程序

在后台,有一个ASP.NET Web Service在完成这些工作。这个Web Service接受来自BookSearch.aspx这个Web程序的数据请求,并从后端的SQL数据库取出合适的数据,然后它会把这些数据返回给Web程序,最后由Web程序来显示这些数据。这个Web Service有两个方法。第一个是GetTitles(),它接受一个目标字符串作为输入参数并返回一个关于数据信息的数据集(DataSet),这个DataSet里的数据满足的条件是,书籍名称包含目标字符串。这个方法就是图8-1所示的Web程序所调用的方法。第二个Web方法CountTitles(),这个方法也接受一个目标字符串,但仅仅返回书名包含目标字符串的书籍册数。术语Web service和Web method经常可以互换使用。

如何对Web Service的方法进行测试,从概念上来说与第1章所描述的API测试是类似的——把输入参数传给待测方法,取得返回值,把实际的返回值与期望值进行比较。主要的区别在于,因为Web方法位于远程计算机上,它们是通过网络进行调用的,并且可能会有几种不同的调用方法。Web Service最基本的通信协议是SOAP(Simple Object Access Protocol)。正如你将要看到的那样,SOAP其实就是XML的一种特殊形式。因此,Web services有时也叫作XML Web services。尽管Web Service的传输是协议无关的(protocol-independent),但在实践中,Web Service几乎总是与HTTP一起使用。所以,当一个典型的Web Service请求发出以后,这个请求被封装成一个SOAP/XML包(packet)。这个包接下来又会被封装进一个HTTP包。然后这个HTTP请求包会通过TCP/IP发送出去。最终TCP/IP包在两个网络套接字(sockets)之间以字节的形式进行发送。为了隐藏所有这些复杂性,Visual Studio .NET提供了一种叫作Web Service代理(proxy)的机制,通过它我们可以调用Web方法并接受返回值。对于ASP.NET Web Service来说,可以通过4种基本的方式进行Web方法调用。下面的列表按照抽象层次由高到低、编码难度由易到难的顺序列出了这4种方式:

l  使用Proxy机制(8.1节)

l  使用HTTP(8.3节)

l  使用TCP(8.4节)

l  使用套接字(8.2节)

本章所给出的技术分别讲解了这4种方式的用法。图8-2展示了它们的运行情况。

图8-2所示的测试用例#001对应于8-1中的用户输入和响应。每个测试用例都运行了两次:第一次是通过proxy机制在较高的抽象层次上发送测试用例输入并接收返回值,第二次是通过TCP机制在较低的抽象层次上进行发送和接收。使用两种不同的的方法测试同一个系统是为了进行确认(validation)。如果使用同样的测试用例数据,采取两种不同的方法对系统进行测试,应该得到相同的测试结果。如果结果不一致,那么两种测试方法所测试的并不是同一个东西,你需要好好研究一下。请注意,测试用例002在通过TCP调用GetTitles()方法时,产生的结果是pass,而当通过proxy机制进行调用时,则产生fail的结果。(测试用例002包含一个故意制造出来的错误的期望值,我们这样做是为了示范如何进行“确认(validation)”。)确认(validation)与验证(verification)关系非常近。我们常说,verification检验的是受测系统是否工作正常,而validation检验的是测试方法是否正确。但是,这两个术语通常是可以混用的。

图8-2  带验证的Web Service测试运行情况

本章的许多技术都要用到我们定义的一个Web Service,这个Web Service为图8-1所示的Web程序提供数据。它基于一个SQL数据库。下面是用于创建并初始化这个数据库的主要SQL语句:

create database dbBooks

go

use dbBooks

go

create table tblBooks

(

bookid char(3) primary key,

booktitle varchar(50) not null,

bookprice money not null

)

go

insert into tblBooks values('001','First Test Automation Principles',11.11)

insert into tblBooks values('002','Theory and Practice of Testing',22.22)

insert into tblBooks values('003','Build Better Software through Automation',33.33)

insert into tblBooks values('004','Lightweight Testing Techniques',44.44)

insert into tblBooks values('005','Testing Principles and Algorithms',55.55)

go

exec sp_addlogin 'webServiceLogin', 'secret'

go

-- grant execute permissions to webServiceLogin here

数据库dbBooks只包含一个表tblBooks,这个表有3个列:bookid、booktitle,以及bookprice。我们向这个表插入了5条记录。有一个名为webServiceLogin的SQL登录名与这个数据库相关联。这个数据库还包含两个用于数据访问的存储过程:

create procedure usp_GetTitles

@filter varchar(50)

as

  select * from tblBooks where booktitle like '%' + @filter + '%'

go

create procedure usp_CountTitles

  @filter varchar(50)

as

  declare @result int

  select @result = count(*) from tblBooks where booktitle like '%' + @filter + '%'

  return @result

go

存储过程usp_GetTitles()接受一个字符串作为过滤条件并且返回一个SQL记录集(rowset),这个rowset的booktitle列包含作为过滤条件的字符串。存储过程usp_CountTitles()与之类似,只不过它仅仅返回rowset包含的行数,而不是rowset本身。

待测Web Service的名字是BookSearch。它有两个Web方法。第一个方法叫作GetTitles(),其定义如下:

[WebMethod]

public DataSet GetTitles(string filter)

{

  try

  {

    string connStr =

    "Server=(local);Database=dbBooks;UID=webServiceLogin;PWD=secret";

    SqlConnection sc = new SqlConnection(connStr);

    SqlCommand cmd = new SqlCommand("usp_GetTitles", sc);

    cmd.CommandType = CommandType.StoredProcedure;

    cmd.Parameters.Add("@filter", SqlDbType.VarChar, 50);

    cmd.Parameters["@filter"].Direction = ParameterDirection.Input;

    cmd.Parameters["@filter"].Value = filter;

    SqlDataAdapter sda = new SqlDataAdapter(cmd);

    DataSet ds = new DataSet();

    sda.Fill(ds);

    sc.Close();

    return ds;

  }

  catch

  {

    return null;

  }

} // GetTitles

GetTitles()方法调用存储过程usp_GetTitles()用以填充一个DataSet对象,并且返回这个对象。类似地,Web方法CountTitles()调用存储过程usp_CountTitles():

[WebMethod]

public int CountTitles(string filter)

{

  try

  {

    string connString =

      "Server=(local);Database=dbBooks;UID=webServiceLogin;PWD=secret";

    SqlConnection sc = new SqlConnection(connString);

    SqlCommand cmd = new SqlCommand("usp_CountTitles", sc);

    cmd.CommandType = CommandType.StoredProcedure;

    SqlParameter p1 = cmd.Parameters.Add("ret_val", SqlDbType.Int, 4);

    p1.Direction = ParameterDirection.ReturnValue;

    SqlParameter p2 = cmd.Parameters.Add("@filter", SqlDbType.VarChar, 50);

    p2.Direction = ParameterDirection.Input;

    p2.Value = filter;

    sc.Open();

    cmd.ExecuteNonQuery();

    int result = (int)cmd.Parameters["ret_val"].Value;

    sc.Close();

    return result;

  }

  catch

  {

    return -1;

  }

} // CountTitles()

除了[WebMethod]这个attribute,这些Web方法与普通的方法并没有什么不同;.NET环境帮助我们打理了一些细节。这就是我们想要测试的两个方法。现在,尽管还不需要开始编写自动化测试代码,但是看一下Web程序里用于调用Web Service的关键代码还是很有帮助的。

private void Button1_Click(object sender, System.EventArgs e)

{

  try

  {

    TheWebReference.BookSearch bs = new TheWebReference.BookSearch();

    string filter = TextBox1.Text.Trim();

    DataSet ds = bs.GetTitles(filter);

    DataGrid1.DataSource = ds;

    DataGrid1.DataBind();

    Label3.Text = "Found " + ds.Tables["Table"].Rows.Count + " items";

  }

  catch(Exception ex)

  {

    Label3.Text = ex.Message;

  }

}

这段代码展示了如何使用proxy机制。调用Web Service的Web方法与调用普通的方法遵循同样的模式。当通过proxy机制测试Web Service的时候,自动化测试代码会与上面的应用程序代码非常相像。

当Web Service通过存储过程访问数据库的时候,存储过程就成为待测系统的一部分。用于测试存储过程的技术将在第9章讲述。本章的技术讲解了如何在单个的测试用例中调用并测试Web方法。要构造一个完整的测试套件,可以使用第4章所讲述的那些测试套件模式。图8-2所示的程序,其完整的测试套件代码请参见8.7节。

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论