Effective testing in console application

原创 2010年12月26日 03:29:00

“开发控制台应用程序,怎么有效地对输出进行测试?”这是我带给TWU的coach的第一个问题,因为我那时受到这个问题的折磨。

 

虽然使用控制台作为UI的简陋的交互式应用程序项目已经鲜见了,但我们仍然常常会用控制台程序来设计工具或者做简单输入输出的小项目。作为控制台程序的功能测试,它结合用户输入,根据控制台的输出来判断程序结果的正确与否。当来到TDD篝火前的我们头一回写这样的测试时,心中可能会有些困惑

 

控制台又不像既接受参数又有返回值的函数,如何把我的测试数据填入控制台,之后再取出控制台输出的结果来做断言呢?

我不赞成只为准备输出数据的函数添加单元测试,虽然这是必要的,但它是不够的。就像隔靴搔痒,没有直接测到控制台输出结果。

我不赞成在测试中粘贴大段的期望的输出字符串,我们心里都清楚,那其中只有寥寥几行是真正有用的。代码丑陋,而且看不到测试的重点。

 

我们如何有效地进行测试?

 

讨论两种情况:

1、我们面对的是一个清爽的应用程序,它得到用户输入后能得出简洁的输出结果,如加法计算器接受“1+2”返回“3”;

2、我们不得不面对一个输出内容庞杂的应用程序,其中被用来做断言的只是其中只言片语,如若干段说明中的一行公式。

 

 

对于情况一

(下文以Java为例讲解)

 

控制台使用标准流System.out和System.in来完成输出输入,我们虽然不得不在产品代码中使用它们,但在测试中可以用易控制的替代品代替它们,以设定输入并截获输出。为此,需要在程序的开始处做抽象,以方便产品代码和测试代码指定不同的输入输出方式。

 

改造后的程序开始处,代码示例如下:

 

System.out是字节流(byte streams, 参考[1]),但它被定义为PrintStream类对象,此类组合了一个内部的字符流(character streams, 参考[1])对象以实现字符流的特性。

我们可以在程序的开始处指定负责输出的对象类型为PrintStream,再在测试代码中实例化一个PrintStream对象,并为其加入一个指定的字节流对象作为记录输出内容的载体(如ByteArrayOutputStream对象)。

 

 

System.in也是字节流,它没那么好运气,其自身不具备字符流的特性,所以需要使用InputStreamReader来包装,之后作为字符流使用。但InputStreamReader没有方便的方法按行读取输入数据,为了进一步使用readLine()方法,我们在它之外再用缓冲流(buffered streams, 参考[1])的BufferedReader类对象包装。

所以,在程序的开始处我们指定负责输入的对象类型为BufferedReader,再在测试代码中实例化一个的BufferReader类对象,为其添入含有测试输入数据的StringBuilder对象。

 

测试代码示例如下:

测试的输入是“5 14“,输出是“5 plus 14 is 19”加换行。

 

产品代码中,程序入口的示例如下:

 

情况一总结:我们通过从程序开始就替换输入输出流对象的方法,获得指定控制台输入对应的输出结果,完成控制台的功能测试。

 

情况二

 

如果单纯为获得程序输出的话,我们还可以采用直接重定向标准输出到文件而不是到控制台的方法。

 

测试可通过扫描截获的输出内容来匹配测试要求的模式,并限定超时时间,以此完成功能测试。这种功能测试方法的缺点是测试时间也许会慢,但功能测试有有多少是很快的呢?呵呵呵

 

当然这种方法已经不单单适用于控制台程序了。

 

 

参考

[1] 关于byte streams、character streams和buffered streams,请参考链接

http://download.oracle.com/javase/tutorial/essential/io/index.html

TextHello - 在 Console Application 下创建第一个C#程序

哈哈,终于开始写第一篇技术博客,初入IT行业,加油! 创建一个 Console Application ,输入以下代码。 using System; /...
  • seattle1215
  • seattle1215
  • 2011年08月03日 18:35
  • 1490

Win32 Console Application、Win32 Application、MFC三者之间的联系和区别

本文主要介绍了MFC、Win32(SDK程序,控制台程序)的区别和联系。
  • xiao3404
  • xiao3404
  • 2016年08月26日 23:07
  • 1330

Vs2010 环境下Qt5学习笔记(1)---Qt console Application

Qt一个脱离平台的GUI,好处不多说了,由于开始做毕设,考虑到MFC的纷繁复杂,主要是还是自己功力尚浅,所以为了避繁就简开始了Qt的学习,而由于项目开发的过程中需要用到许多第三方的东西,所以不能脱离V...
  • shiyanwei1989
  • shiyanwei1989
  • 2014年01月03日 21:59
  • 2846

vc++6.0中创建工程时选Win32 Application和Win32 console Application的区别

我想好多朋友在刚使用vc++6.0创建工程时不知道是选Win32 Application或是选Win32 console Application,有的就选择了 Win32 Application,然而...
  • cjjwwss
  • cjjwwss
  • 2014年01月15日 16:04
  • 1225

Codeblocks中的empty project和console application

empty project:只有空工程,需要自己添加源文件 console application:貌似给写好了主函数...
  • u014791046
  • u014791046
  • 2016年06月05日 02:00
  • 538

winEdt找不到指定的文件

当使用WinEdt时,本来运行良好,但是当重新使用的时候,发现出现以下错误 Error launching Console Application PDFLaTeX ... Command Lin...
  • wjcquking
  • wjcquking
  • 2014年02月17日 14:31
  • 27749

Win32 Application和Win32 Console Application、MFC APPWIZARD区别

VC: Win32 Application和Win32 Console Application、MFC APPWIZARD区别转) 都是工作在32位Windows环境的程序。 Win32 Applic...
  • caoeryingzi
  • caoeryingzi
  • 2010年06月24日 17:13
  • 928

2.建立一个Win32 Console Application工程,编译好的exe文件在其他的电脑直接运行而不需要安装任何其他的package.

首先建立一个空的win32 console Application工程项目.   然后在Resource Files中Add一个新的item输入: #include usin...
  • tianhaichuang
  • tianhaichuang
  • 2014年05月05日 09:20
  • 747

C# Console Application 带参数调试

1. 双击 Console Application 的 "Properties"   2. 单击左侧 "Debug”("调试")选项卡   3. 在 "Start Options" ("启动选...
  • emixo
  • emixo
  • 2012年10月11日 14:51
  • 2653

如何隐藏win32 console application的console窗口

一    subsystem和可执行文件的启动LINK的时候需要指定/subsystem,这个链接选项告诉Windows如何运行可执行文件。我们知道用VC编写的程序,运行的时候是需要 C/C++运行库...
  • zhaozy55555
  • zhaozy55555
  • 2009年03月12日 11:47
  • 3358
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Effective testing in console application
举报原因:
原因补充:

(最多只允许输入30个字)