WEB自动化测试中针对验证码的解决方案(4)

发表于:2011-12-02来源:未知作者:领测软件测试网采编点击数: 标签:Web自动化测试
!--[if !vml]--!--[endif]--验证码给自动测试带来了很大的问题,但也并不是完全不能解决。结合我们在上文讨论的验证码实现的方法,图4给出了验证码实现的大

<!--[if !vml]--><!--[endif]-->验证码给自动测试带来了很大的问题,但也并不是完全不能解决。结合我们在上文讨论的验证码实现的方法,图4给出了验证码实现的大致原理图。

  从图4中可以看到,从技术的角度来看,至少设计两种不同的方法来实现自动测试工具对验证码的处理:

  <!--[if !supportLists]-->1、 <!--[endif]-->完全从客户端角度考虑,靠模式识别的方法识别出验证码图片对应的字符串;

  <!--[if !supportLists]-->2、 <!--[endif]-->从服务端角度考虑,如果自动测试工具可以获取Session中存储的随机数,也就能正确处理验证码了。

  这两种方法是解决自动化测试中验证码问题的主要方法,我们分别称其为识别法和服务端插入法。这两种方法在实现方法上侧重点不同,适用的场合也不同。

  识别法完全不用考虑服务端应用的实现,通过各种技术方法对显示的验证码图片进行“破译”,这样,即使完全不能接触到服务端代码,也能让自动化测试在有验证码的情况下进行下去;但这种方法当然也有其致命的缺点:只能对简单的验证码进行识别,对复杂的验证码,根本就无法识别。

  而服务端插入法则从服务端入手,通过提供一个额外的客户端接口,向客户端只需要知道该接口的调用方法,就能通过该接口来获取该页面的验证码图片对应的实际数据,并使用该数据继续测试。

  另一方面,除了技术角度解决问题的方法以外,还可以通过一些非技术的方法来解决验证码问题。

  <!--[if !supportLists]-->4.1 <!--[endif]-->识别法的实现

  识别法适用于不能获得和改变服务器端代码的情况下,在这种情况下,由于服务端代码本身不可获得,或是不能对其进行修改,测试者只能完全从客户端的角度想办法解决验证码的问题。

  识别法的核心是对验证码图片的模式识别算法,该算法的可实现性基本取决于图片本身的复杂程度。以本文前面列举的验证码示例来说,类似Gmail和Hotmail的验证码基本上是无法通过程序来识别的。而最简单的验证码实现,例如ASP下用xbm技术生成的图片,就可以很容易地通过算法来识别;在PHP、dotNET等平台上完全使用图形库函数生成的图片,同样可以通过对某个区域内的图片分析,识别出图片对应的实际数字或是字母。

  下面以处理xbm格式的验证码为例,介绍对其进行识别的算法。

  本文的2.1节对xbm文件格式进行了深入的探讨,用xbm实现验证码的方法在ASP和dotNET平台上非常常见,由于xbm文件格式的规则性,因此很容易通过程序对其进行识别。一般的识别过程如下:

  <!--[if !supportLists]-->多次访问带有验证码的页面,分析每次获得的xbm文件和显示的图片之间的对应关系,获得验证码中所有符号对应的十六进制串;

  <!--[if !supportLists]-->编写识别验证码的代码,识别代码根据获得的xbm文件,将其按照编码方式分组,然后与上一步骤中获得的对应的十六进制串进行比较,这样就可以识别出该xbm文件对应的验证码的实际数据。

  下面这段代码是用于将xbm图片文件识别为相应的验证码内容的C语言代码:

  int getDigital(char dig[10])

  {

  const char orgdig[10][10] = {

  {0x3c,0x66,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0x66,0x7e}, //0

  {0x18,0x1c,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00}, //1

  {0x3c,0x66,0x60,0x60,0x30,0x18,0x0c,0x06,0x06,0x7e}, //2

  {0x3c,0x66,0xc0,0x60,0x1c,0x60,0xc0,0xc0,0x66,0x38}, //3

  {0x38,0x3c,0x36,0x33,0x33,0x33,0xff,0x30,0x30,0xfe}, //4

  {0xfe,0xfe,0x06,0x06,0x3e,0x60,0xc0,0xc3,0x66,0x3c}, //5

  {0x60,0x30,0x18,0x0c,0x3e,0x63,0xc3,0xc3,0x66,0x3c}, //6

  {0xff,0xc0,0x60,0x30,0x18,0x18,0x18,0x18,0x18,0x18}, //7

  {0x3c,0x66,0xc3,0x66,0x3c,0x66,0xc3,0xc3,0x66,0x3c}, //8

  {0x3c,0x66,0xc3,0xc3,0x66,0x3c,0x18,0x0c,0x06,0x03} //9

  };

  int i=0, j=0;

  int ret = 1;

  for(i=0; i<10; i++)

  {

  ret = 1;

  for(j=0; j<10; j++)

  {

  if(orgdig[i][j]!= dig[j])

  {

  ret = 0;

  break;

  }

  }

  if(ret)

  return i;

  }

  return -1;

  }

  主函数:

  char picc[500], t[40], od[10];

  char separators[] = ",";

  char *token, *endstr;

  int i=0, j=0;

  //获取需要识别的图片中的数据描述部分,内容为

  //0x3c, 0x3c, 0x18, 0x3c, 0x66 …

  //将其存放在字符串picc中

  …………

  //分解获得的串

  token = (char *)strtok(picc, separators); /* Get the first token */

  if(!token)

  {

  return( -1 );

  }

  while( token != NULL )

  {

  if(!strcmp(token , "")) //处理为“空”的内容,将其替换成0x00

  t[i] = 0x00;

  else

  t[i] = strtol(token, &endstr, 16);

  i++;

  token = (char *)strtok(NULL, separators);

  }

  for(i=0; i<4; i++) //一共4个数字,分别调用getDigital函数进行处理

  {

  for(j=0; j<10; j++)

原文转自:http://www.ltesting.net