技术开发 频道

详解Python在数据库测试中的应用

  【IT168 文档】Python(派森)语言是一种面向对象的用途非常广泛的编程语言,具有非常清晰的语法特点,适用于多种操作系统,可以在Windows和Unix这样的系统中运行。目前在国际上非常流行,正在得到越来越多的应用。Python可以完成许多任务,功能非常强大。

  对于我们的测试工作而言,Python最吸引我们的特性有如下几个方面:

  1 具备语言粘合剂的能力

  2 解释执行的机制

  3 语法简单易学

  4 相对较高的性能

  语言粘合剂是比较形象的说法,具体的说,Python支持通过引入自带的cytpes库,达到在python脚本中执行已有的动态库中的代码的目标。因此,DM对外提供的基于c/c++的接口都可以通过这个方法得到访问,如果使用Python作为接口测试的载体,得到的测试用将比使用编译型语言的测试程序更易于修改调试。

  以上是针对c/c++接口而言,对于.net平台和JAVA平台,我们可以分别使用Python for .Net 和 Jython。前者使得Python脚本可以直接调用CLR代码,而后者使得Python可以直接调用任何的JAVA类库。

  相信至此,使用Python作为跨越语言的测试工具的优越性,已经十分明显了:

  对于功能与性能测试,我们只需要自己编写一个解释器调用脚本,就可以只需要维护一套测试脚本,而同时可以在任何驱动接口上进行测试,构思大体如下图所示:

  在上面这个图中,测试工程师只需要关新最上层的Testcasen.py就可以,他们所写的用例可以是纯粹的测试逻辑而不需关心不同接口的实现方法,例如一个简单的测例脚本可以是下面这样的:

Testcase1.py:
from dbop
import * #这里的dbop就是odbc版本的连接与支持类
from dmServer
import * #dmServer类用于对被测试的服务器进行启动、停止、配置等操作
from ctypes
import *
rc
= -10;
dmserver1
= dmServer('d:\\dmdbms\\bin\\dmserver.exe','win','12345','service',0);
dmserver1.runserver();
tb1
= dbop();
rc
= tb1.connect('127.0.0.1','SYSDBA','SYSDBA','12345','SYSTEM');
rc
= tb1.exec_sql_ignore("drop table aa;");#执行drop语句而不关心是否执行成功
rc
= tb1.exec_sql("create table aa(c int);");#执行create语句且预期成功
rc
= tb1.exec_sql_failed("create table aa(c int);");#再次执行该语句,预期失败
k
=((1,1),(1,1));
#执行select且预期结果集与上面定义的k相同
rc
= tb1.exec_sql_with_result("select top 2 name,id from systables;",k);
rc
= tb1.disconnect();
dmserver1.stopserver();

  可以看到,如上所示,编写用例的人员完全不需关心connect,exec_sql_ignore,tb1.exec_sql_failed此类的操作细节如何实现,他们只要使用并给出测试的逻辑就可以了。而测试开发人员则要实现例如上面这几个接口的odbc版本、jdbc版本、和ado.net版本。

  位于测例与支持库之间的是一个Testloader程序,这个程序完成这几件事情:

  1、 读取根据要执行的测试的配置文件,确定解释器的位置和将要使用哪种驱动;

  2、 读取测试用例的内容,并将对支持类的引用改为对应驱动,比如上面的脚本中的:

  from dbop import * 可能会被改为:from dbop_jdbc import *

  3、 调用对应的解释器执行这个测试用例。

  一个比较简单的例子如下:

cfg.ini:
py_path
=D:\"ACTIVE Python"\python.exe
jy_path
=C:\jython2.2.1\dmjython.bat
ny_path
=C:\pythonnet-2.0-alpha2\pythonnet-2.0-alpha2\python2.5-UCS2\python.exe
#driver
=dotnet
driver
=odbc
#driver
=jdbc
Testloader:
import os
import string
import sys
def exeascript(sc,driver):
    read_script(sc)
    replace_lib_include(sc,driver)
    write_temp_script();
    cmd
= get_executer_path()+ " " + "temp.py"
    newfile
= file("temp.py","w")
    newfile.write(all_text);
    newfile.
close()
    os.system(cmd);
    os.remove("
temp.py")
mode
=""
scriptfile
=""
lstfile
=""
arg
= sys.argv[1]
tempdriver
=sys.argv[2]
if string.upper(arg[arg.rfind('.')+1:len(arg)])=="PY":
    mode
="py"
    scriptfile
= arg
elif string.
upper(arg[arg.rfind('.')+1:len(arg)])=="LST":
    mode
="lst"
    lstfile
=arg
jyp
="";
nyp
="";
cyp
="";
ininame
= "cfg.ini"
dataList
=[]
caseList
=[]
gbldriver
="odbc"
readini(ininame)
for line in dataList:
    getini();
if mode=="lst":
#
to loop execute testcase
elif mode
=="py":
exeascript(scriptfile,tempdriver)
else:
    
print "Not support"

 

  借助上面的这个脚本,测试执行人员执行用例只需要用

  D:\py\testloader>testloader.py Testcase1.py jdbc

  这样类似的格式就可以自己指定驱动来执行测试用例了。

  如果有大量的用例,可以将这种命令写成批处理文件来执行。而不需要人工干预。

  从上面的可以看到,对于功能或者单项SQL性能,基于Python的测试用例可以提供平台无关的简单的脚本编写环境,同时由于Python本身是一门完整的脚本语言,测例编写人员自己也可以在测试用例中编写出各种结构的程序,正所谓可繁可简。

  对于各种驱动接口,Python来编写测试用例的好处是:由于Python不需要编译,你所执行的也就是你所编写的,当发生异常的时候,你无须打开集成开发环境,加载测试工程、并调试,你能够很方便的看到python测试脚本的内容,什么地方出了异常可以立刻发现,例如:

from ctypes import *
rc
=c_int(-12345);
dll
= windll.LoadLibrary("dmodbc.dll");#加载被测试组件
#
=================#
SQLHANDLE_env
= pointer(c_long(0));
SQLHANDLE_cnn
= pointer(c_long(0));
SQLHANDLE_stmt
= pointer(c_long(0));
pdns
= c_char_p("FASTDB");
puid
= c_char_p("SYSDBA");
ppwd
= c_char_p("SYSDBA");
#env handle
rc
= dll.SQLAllocHandle(1,None,byref(SQLHANDLE_env));
print "result of henv handle alloc :%d" %rc;
#cnn handle
rc
= dll.SQLAllocHandle(2,SQLHANDLE_env,byref(SQLHANDLE_cnn));
print "result of cnn handle alloc :%d" %rc;
#connect!
rc
= dll.SQLConnect(SQLHANDLE_cnn,pdns,-3,puid,-3,ppwd,-3)
print "result of connect :%d" %rc;
#stmt handle
rc
= dll.SQLAllocHandle(3,SQLHANDLE_cnn,byref(SQLHANDLE_stmt));
print "result of stmt handle alloc:%d" %rc;
#
exec
rc
= dll.SQLExecDirect(SQLHANDLE_stmt,"insert into t values(1)",-3);
print "result of exec:%d" %rc;
#free
========================
rc
= dll.SQLFreeHandle(3, SQLHANDLE_stmt);
print rc;
rc
= dll.SQLDisconnect(SQLHANDLE_cnn);
print rc;
rc
= dll.SQLFreeHandle(2, SQLHANDLE_cnn);
print rc;
rc
= dll.SQLFreeHandle(1, SQLHANDLE_env);
print rc;

  在上面我们可以看到,Python调用c/c++接口是十分容易的,只需要把动态库加载进来,然后把这个动态库当作一个对象实例来使用就可以了。下面将是一个使用ado.net接口的例子:

import System;
from Dm
import *#Dm是DMDBMS提供的ado.Net的DataProvider
#print dir(Dm.DmCommand);
i
=0;
cnn
= Dm.DmConnection("server = 127.0.0.1; User ID = SYSDBA; PWD = SYSDBA; Database = SYSTEM; port = 12345");
cmd
= Dm.DmCommand();
cmd.Connection
= cnn;
cmd.CommandText
= "insert into t values(1);";
cnn.Open();
i
=cmd.ExecuteNonQuery();
print i;
cmd.Dispose();
cnn.Close();

  可以看到,.net对象的使用与在VisualStdio上进行开发几乎没有任何区别。

  通过使用Python进行测试用例的开发,最大的好处莫过于:学习成本非常低,测试工程师只需要学习Python,对于其他语言稍有了解就可以了。同时只需要少量的测试开发工程师对Python测试框架进行维护。

  这样的好处就是便于测试人员将精力专精在一个方向,免于“什么都会一点,但什么都不精”的情况。当然测试人员具备广阔的知识面,会使用各种常见的开发工具与平台是好事情,并且也是必要的,不过在短时间内要求迅速能够胜任大多数任务也是企业在人才培养上的期望目标。

0
相关文章