IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> 如何做到有效的集成测试?新技能get !! -> 正文阅读

[开发测试]如何做到有效的集成测试?新技能get !!

软件产品的构成都是非常复杂的,这也就意味着它将含有多个模块,这些模块通过接口进行交互。针对于这些集成模块的测试,我们称之为集成测试。也可以认为它是由单元测试扩展出来的。

什么是集成测试

集成测试是测试单元模块之间的连接或数据传输的过程。它又称为I&T(集成与测试)。

它分为大爆炸法、自上而下法、自下而上法和三明治或混合集成法(自上而下和自下而上相结合)。这个过程是通过使用名为stub和Drivers的虚拟程序来执行,其不需要实现软件整个模块,而只是模拟与调用模块的数据通信即可。

它通常是在单元测试之后完成之后执行的。集成测试中涉及的每个模块都应该在集成测试之前进行单元测试。通过在集成测试之前进行单元测试,可以提高执行软件集成测试的信心。

集成测试也需要编写相应的测试计划,从而减少了测试的混乱,并为有效执行集成测试提供了清晰的路径。

我们都知道,自动化测试是持续集成必不可少的一部分,基本上,没有自动化测试的持续集成,都很难称之为真正的持续集成。

我们希望持续集成能够尽早的暴露问题,但这远非配置一一个Hudson/Jenkins 服务器那么简单,只有真正用心编写了较为完整的测试用例,并一直维护它们,持续集成才能孜孜不倦地运行测试并第一时间报告问题。?

这里强调的是测试的自动化,并基于具体的技术(Maven、 JUnit、Jetty 等)来介绍一种切实可行的自动化 Web 应用集成测试方案。当然,自动化测试还包括单元测试、验收测试、性能测试等,在不同的场景下,它们都能为软件开发带来极大的价值。

基于 Maven 的一般流程

集成测试与单元测试最大的区别是它需要尽可能的测试整个功能及相关环境,对于测试 Web 应用而言,通常有这么几步:

  • 启动 Web 容器
  • 部署待测试 Web 应用
  • 以 Web 客户端的角色运行测试用例
  • 停止 Web 容器

启动 Web 容器可以有很多方式,例如你可以通过 Web 容器提供的 API 采用编程的方式来启动容器,但在 Maven 的环境下,配置插件显得更简单。

如果你了解maven的生命周期模型,就可能会想到,我们可以在 pre-integration-test 阶段启动容器,部署待测试应用,然后在 integration-test 阶段运行集成测试用例,最后在 post-integrate-test 阶段停止容器。

也就是说,对于步骤 1,2 和 4 我们只须进行一些简单的配置,不必编写额外的代码。第 3 步是以黑盒的形式模拟客户端进行测试,需要注意的是,这里通常要求你理解一些基本的 HTTP 协议知识,例如服务端在什么情况下应该返回 HTTP 代码 200,什么时候应该返回 401 错误,以及所支持的 Content-Type 是什么等等。

至于测试用例该怎么写,除了需要用到一些用来访问 Web 以及解析响应详细的基础设施工具类之外,其他内容与单元测试大同小异,基本就是准备测试数据、访问服务、验证返回值等等。

一个简单的例子

谈了不少理论,现在该给个具体的例子了,譬如现在有个简单的 Servlet,它接受参数 a 和 b,做加法后返回二者之和,如果参数不完整,则返回 HTTP 400 错误,表示客户端的请求有问题。


public class AddServlet
   extends HttpServlet
{
   @Override
   protected void doGet( HttpServletRequest req, HttpServletResponse resp )
       throws ServletException,
           IOException
   {
       String a = req.getParameter( "a" );
       String b = req.getParameter( "b" );

       if ( a == null || b == null )
       {
           resp.setStatus( 400 );
           return;
       }

       int result = Integer.parseInt( a ) + Integer.parseInt( b );

       resp.setStatus( 200 );
       resp.getWriter().print( result );
   }
}

为了测试这段代码,我们需要一个 Web 容器,这里暂且使用 Jetty,因为目前来说它与 Maven 集成的相对最好。Jetty 提供了一个Jetty Maven Plugin,借助该插件,我们可以随时启动 Jetty 并部署 Maven 默认目录布局的 Web 项目,实现快速开发和测试。这里我们需要的是在 pre-integration-test 阶段启动 Jetty,在 post-integrate-test 阶段停止容器,对应的 POM 配置如下:


     <plugin>
       <groupId>org.mortbay.jetty</groupId>
       <artifactId>jetty-maven-plugin</artifactId>
       <version>7.3.0.v20110203</version>
       <configuration>
         <stopPort>9966</stopPort>
         <stopKey>stop-jetty-for-it</stopKey>
       </configuration>
       <executions>
         <execution>
           <id>start-jetty</id>
           <phase>pre-integration-test</phase>
           <goals>
             <goal>run</goal>
           </goals>
           <configuration>
             <daemon>true</daemon>
           </configuration>
         </execution>
         <execution>
           <id>stop-jetty</id>
           <phase>post-integration-test</phase>
           <goals>
             <goal>stop</goal>
           </goals>
         </execution>
       </executions>
     </plugin>

XML 代码中第一处 configuration 是插件的全局配置,stopPort 和 stopKey 是该插件用来停止 Jetty 需要用到的 TCP 端口及消息关键字。

接着是两个 executation 元素,第一个 executation 将 jetty-maven-plugin 的 run 目标绑定至 Maven 的 pre-integration-test 生命周期阶段,表示启动容器,第二个 executation 将 stop 目标绑定至 post-integration-test 生命周期阶段,表示停止容器。

需要注意的是,启动 Jetty 时我们需要配置 deamon 为 true,让 Jetty 在后台运行以免阻塞 mvn 命令。此外,jetty-maven-plugin 的 run 目标也会自动部署当前 Web 项目。

准备好 Web 容器环境之后,我们接着看一下测试用例代码:


public class AddServletIT
{
   @Test
   public void addWithParametersAndSucceed()
       throws Exception
   {
       HttpClient httpclient = new DefaultHttpClient();
       HttpGet httpGet = new HttpGet( "http://localhost:8080/add?a=1&b=2" );
       HttpResponse response = httpclient.execute( httpGet );

       Assert.assertEquals( 200, response.getStatusLine().getStatusCode() );
       Assert.assertEquals( "3", EntityUtils.toString( response.getEntity() ) );
   }

   @Test
   public void addWithoutParameterAndFail()
       throws Exception
   {
       HttpClient httpclient = new DefaultHttpClient();
       HttpGet httpGet = new HttpGet( "http://localhost:8080/add" );
       HttpResponse response = httpclient.execute( httpGet );

       Assert.assertEquals( 400, response.getStatusLine().getStatusCode() );
   }
}

为了能够访问应用,这里用到了HttpClient,两个测试方法都初始化一个HttpClient,然后创建 HttpGet 对象用来访问 Web 地址。

第一个测试方法顾名思义用来测试成功的场景,它提供参数 a=1 和 b=2,执行请求后,验证返回结果成功(HTTP 状态码 200)并且内容为正确的值 3。第二个测试方法则用来测试失败的场景,当不提供参数的时候,服务器应该返回一个 HTTP 400 错误。

该测试类其实是相当粗糙的,例如有硬编码的服务器 URL,这里的目的仅仅是通过尽可能简单的代码来展现一个自动化集成测试的实现过程。

上述代码中,测试类的名称为 AddServletIT,而不是一般的 **Test,IT 表示 IntegrationTest,这么命名是为了和单元测试区分开来,这样,鉴于?maven默认的测试命名约定,Maven 在 test 生命周期阶段执行单元测试时,就不会涉及集成测试。现在,我们希望 Maven 在 integration-test 阶段执行所有以 IT 结尾命名的测试类,配置 Maven Surefire Plugin 如下:


     <plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-surefire-plugin</artifactId>
       <version>2.7.2</version>
       <executions>
         <execution>
           <id>run-integration-test</id>
           <phase>integration-test</phase>
           <goals>
             <goal>test</goal>
           </goals>
           <configuration>
             <includes>
               <include>**/*IT.java</include>
             </includes>
           </configuration>
         </execution>
       </executions>
     </plugin>

通过命名规则和插件配置,我们优雅地分离了单元测试和集成测试,而且我们知道在 integration-test 阶段,Jetty 容器已经启动完成了。如果你在使用 TestNG,那你还可以使用其测试组的特性来分离单元测试和集成测试,Maven Surefire Plugin 对其也有着很好的支持。

一切就绪了,运行?mvn clean install?以自动运行集成测试,我们可以看到如下的输出片段:


[INFO] --- jetty-maven-plugin:7.3.0.v20110203:run (start-jetty) @ webapp-demo ---
[INFO] Configuring Jetty for project: webapp-demo
[INFO] webAppSourceDirectory /home/juven/git_juven/webapp-demo/src/main/webapp does not exist. Defaulting to /home/juven/git_juven/webapp-demo/src/main/webapp
[INFO] Reload Mechanic: automatic
[INFO] Classes = /home/juven/git_juven/webapp-demo/target/classes
[INFO] Context path = /
...
2011-03-06 14:55:15.676:INFO::Started SelectChannelConnector@0.0.0.0:8080
[INFO] Started Jetty Server
[INFO] 
[INFO] --- maven-surefire-plugin:2.7.2:test (run-integration-test) @ webapp-demo ---
[INFO] Surefire report directory: /home/juven/git_juven/webapp-demo/target/surefire-reports

-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.juvenxu.webapp.demo.AddServletIT
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.344 sec

Results :

Tests run: 2, Failures: 0, Errors: 0, Skipped: 0

[INFO] 
[INFO] --- jetty-maven-plugin:7.3.0.v20110203:stop (stop-jetty) @ webapp-demo ---

可以看到 jetty-maven-plugin:7.3.0.v20110203:run 对应了 start-jetty,maven-surefire- plugin:2.7.2:test 对应了 run-integration-test,jetty-maven- plugin:7.3.0.v20110203:stop 对应了 stop-jetty,与我们的配置和期望完全一致。此外两个测试也都成功了!

相对于单元测试来说,集成测试更难编写,因为需要准备更多的环境,本文涉及了Web 容器最简单的情形,实际的开发情形中,你可能会遇到数据库,第三方Web 服务,更复杂的容器配置和数据格式等等,这都使得编写集成测试变得让人畏惧。

然而反过来考虑,无论如何你都需要测试,虽然这个自动化过程的投入很大,但收益往往更加客观,这不仅仅是手动测试时间的节省,更重要的是,你无法保证手动测试能被高频率的反复执行,也就无法保证问题能被尽早暴露。

对于Web 应用来说,编写集成测试有助于你考虑和设计Web 应用对外暴露的接口,这种“开发实现”/“测试审察”之间的角色转换往往能造就更清晰的设计,这也是编写测试最大的好处之一。

Maven 用户能够得益于 Maven 的插件系统,不仅能节省大量的编码,还能得到稳定的工具,Jetty Maven Plugin 和 Maven Surefire Plugin 就是最好的例子。

结语?


在我的QQ技术交流群里整理了我这几年软件测试生涯整理的一些技术资料,包括:电子书,简历模块,各种工作模板,面试宝典,自学项目等。如果在学习或工作中遇到问题,群里也会有大神帮忙解答,群号573261842,或者加我私人v

本文介绍了自动化 Web 应用集成测试在实际工作中用到的基本上大部分内容及其相关知识点,大家可以收藏仔细阅读慢慢看~

  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2021-07-11 16:54:06  更:2021-07-11 16:54:12 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/6 1:07:52-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码