一天一个关于测试知识点,5分钟内讲解你最关心的软件测试问题,今天就接着来谈谈关于软件测试中的“通过测试数据优化接口测试代码”。
来讨论一下测试数据,如图4-52所示。
图4-52 关于登录操作测试脚本的测试数据问题
这里探讨的是接口测试,其实在GUI测试下也同样适用。来看一下用户登录操作测试脚本失败,可能由两个以下原因。
l 产品代码有问题:直接报bug。
l 测试数据的问题:比如测试错误用户名,错误密码的时候,在做ET的时候通过手工的方式已经有了这个用户名和密码的用户。再比如正确错误用户名,正确密码的时候,同样做ET的时候通过手工的方式已经将这条记录删除。
现在考虑测试数据的问题,首先会考虑是否可以将注册与登录一起测试,即先测试注册接口,然后用注册的信息进行登录。但是又产生两个问题。
l 测试脚本是否有权限操作产品数据库?
l 在微服务情况下,注册与登录分别作为单独一个services下如何实现?
对于微服务如何进行还没有办法,但是测试脚本操作产品数据库,在许多公司里面是可以这样会操作的,特别是在测试环境中进行测试。
然后还可以考虑一种方法,测试一个正常测试登录的测试数据,在登录之前先到数据库中检查,如果这个用户数据不存在,通过测试脚本把这条数据写入数据库中(注意,写入之后给出相应的日志信息,便于后续数据维护)。然后在进行测试验证;测试一个异常登录的测试数据,在登录之前也先到数据库中检查,如果这个用户数据存在,则将数据库中数据删除(注意,删除之后同样也要给出相应的日志信息,本节后续介绍的方法就是用这种方法实现的)。也有一些大型企业通过测试数据管理服务(Test Data Managent Service)来实现,如果获取的数据不符合测试业务,认为这是一条脏数据,从测试数据库中删除然后取下一条(当然这种情况不会用Excel,XML文件来维护数据,而是通过测试数据数据库来为维护)。另外还会启动一个Jenkins Job。定时从测试数据库中获取数据个数,当测试数据的数量小于某个阈值的时候,自动生成批量的测试数据。现在来看下如何实现前一种方法。
在Util类中建立check_user_existence(self,username,password,tag)方法,用来检查当前产品数据库中是否存在这个用户,然后通过tag(tag=0表示测试一个异常登录,tag=1表示测试一个正常测试登录)采取相应的措施。
案例4-92:接口测试的优化处理。
import xlrd
from xlutils.copy import copy
from xml.dom import minidom
import sqlite3,hashlib
import os
#检查用户数据是否存在,并且根据测试数据特殊处理
def check_user_existence(self,username,password,tag):
condition = "username='"+username+"' and password='"+self.md5(password)+"'"
db =DB()
db.connect()
result = db.searchByCondition("goods_user",condition)
#如果验证的是非法用户项,获得的数据已经在数据库中的处理办法,将这条数据从数据库中删除,输出信息
if tag == 0:
if len(list(result))!=0:
condition = "username='" +username+"'"
db.delete("goods_user",condition)
print(username+","+password+" 由于数据问题被测试程序删除")
#如果验证的是合法用户项,获得的数据不在数据库中,将这条数据插入到数据库中,输出信息
elif tag == 1:
if len(list(result))==0:
value = "'"+username+"','"+self.md5(password)+"','"+username+"@126.com'"
db.insert("goods_user(username,password,email)",value)
print(username+","+password+" 由于数据问题由测试程序自动生成的数据")
else:
print("调入check_user_existence参数错误")
db.close()
为了便于后续的维护,封装了数据库操作和md5加密。
#MD5加密
def md5(self,mystr):
if isinstance(mystr,str):
m = hashlib.md5()
m.update(mystr.encode('utf8'))
return m.hexdigest()
else:
return ""
…
class DB:
#构造函数,获得sqlite3数据库文件的位置
def __init__(self):
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
self.url = BASE_DIR+"\\ebusiness\\db.sqlite3"
#连接数据库连接
def connect(self):
self.con = con = sqlite3.connect(self.url)
self.cur = self.con.cursor()
#关闭数据库连接
def close(self):
self.cur.close()
self.con.close()
#通过主键查询数据库表中的内容
def searchByid(self,tablename,id):
return(self.cur.execute("select * from "+tablename+" where id="+id))
#通过条件查询数据库
def searchByCondition(self,tablename,Condition):
return(self.cur.execute("select * from "+tablename+" where "+Condition))
#向tablename表中插入数据values
def insert(self,tablename,values):
sql = "insert into "+tablename+" values ("+values+")"
self.con.execute(sql)
self.con.commit()
#在tablename表,删除满足condtion条件的记录
def delete(self,tablename,condition):
sql = "delete from "+tablename+" where "+condition
self.con.execute(sql)
self.con.commit()
测试代码最后为。
#使用excel作为驱动,进一步优化
import requests
import unittest
from Util import util
class login(unittest.TestCase):
def setUp(self):
self.myutil=util()
self.correctusername =self.myutil.get_user_data()[0]
self.correctpassword =self.myutil.get_user_data()[1]
self.discorrectusername =self.myutil.get_user_data()[2]
self.discorrectpassword =self.myutil.get_user_data()[3]
self.url="http://localhost:8000/login_action/"
self.token = "RNF3Y04qFeJkMwCDsTMn4gfMcyfQ2vUjXbcENLADEFyCSRp1pBdezZKwHhlSwqgE"
self.cookie = {"csrftoken":self.token}
#正确的用户名,错误的密码
#登录之前,确保数据库中没有这条数据
def test_correctusername_discorrectpassword(self):
username = self.correctusername
password = self.discorrectpassword
self.myutil.check_user_existence(username,password,0)
payload={"username":username,"password":password,"csrfmiddlewaretoken":self.token}
data = requests.post(self.url,data=payload,cookies=self.cookie)
#验证返回码
self.assertEqual("200",str(data.status_code))
#验证返回内容
self.assertIn("用户名或者密码错误",str(data.text))
#错误的用户名,正确的密码
def test_discorrectusername_correctpassword(self):
username = self.discorrectusername
password = self.correctpassword
self.myutil.check_user_existence(username,password,0)
payload={"username":username,"password":password,"csrfmiddlewaretoken":self.token}
data = requests.post(self.url,data=payload,cookies=self.cookie)
#验证返回码
self.assertEqual("200",str(data.status_code))
#验证返回内容
self.assertIn("用户名或者密码错误" ,str(data.text))
def test_discorrectusername_discorrectpassword(self):
#错误的用户名,错误的密码
username = self.discorrectusername
password = self.discorrectpassword
self.myutil.check_user_existence(username,password,0)
payload={"username":username,"password":password,"csrfmiddlewaretoken":self.token}
data = requests.post(self.url,data=payload,cookies=self.cookie)
#验证返回码
self.assertEqual("200",str(data.status_code))
#验证返回内容
self.assertIn("用户名或者密码错误",str(data.text))
#正确的用户名,正确的密码
def test_correctusername_correctpassword(self):
username = self.correctusername
password = self.correctpassword
self.myutil.check_user_existence(username,password,1)
payload={"username":username,"password":password,"csrfmiddlewaretoken":self.token}
data = requests.post(self.url,data=payload,cookies=self.cookie)
#验证返回码
self.assertEqual("200",str(data.status_code))
#验证返回内容
self.assertIn("电子商务系统" ,str(data.text))
if __name__=='__main__':
#构造测试集
suite=unittest.TestSuite()
suite.addTest(login("test_correctusername_discorrectpassword"))
suite.addTest(login("test_discorrectusername_correctpassword"))
suite.addTest(login("test_discorrectusername_discorrectpassword"))
suite.addTest(login("test_correctusername_correctpassword"))
#运行测试集合
runner=unittest.TextTestRunner()
runner.run(suite)
在这里对上述代码进行进一步的优化并且把测试代码对数据校验的代码在util.py中建立方法check_condition_for_user,代码如下。
#用户测试的数据准备
def check_condition_for_user(self,flag):
#初始化变量
username =""
password =""
#根据flag标签提供不同的测试数据
if flag==0:
username =self.get_user_data()[2]
password =self.get_user_data()[1]
elif flag==1:
username =self.get_user_data()[0]
password =self.get_user_data()[3]
elif flag==2:
username =self.get_user_data()[2]
password =self.get_user_data()[3]
elif flag==3:
username =self.get_user_data()[0]
password =self.get_user_data()[1]
else:
print ("方法check_condition_for_user的flag输入参数为0、1、2、3")
return ""#flag参数不对返回空字符串
#检查用户是否存在
if flag==3:
self.check_user_existence(username,password,1)
else:
self.check_user_existence(username,password,0)
return {"username":username,"password":password}#把用户名,密码返回
这样测试代码就简化为。
#正确的用户名,错误的密码
#登录之前,确保数据库中没有这条数据
def test_correctusername_discorrectpassword(self):
info = self.myutil.check_condition_for_user(0)
if not info=="":
payload={"username":info["username"],"password":info["password"],"csrfmiddlewaretoken":self.token}
data = requests.post(self.url_product,data=payload,cookies=self.cookie)
#验证返回码
self.assertEqual("200",str(data.status_code))
#验证返回内容
self.assertIn("用户名或者密码错误",str(data.text))
#错误的用户名,正确的密码
def test_discorrectusername_correctpassword(self):
info = self.myutil.check_condition_for_user(1)
if not info=="":
payload={"username":info["username"],"password":info["password"],"csrfmiddlewaretoken":self.token}
data = requests.post(self.url_product,data=payload,cookies=self.cookie)
#验证返回码
self.assertEqual("200",str(data.status_code))
#验证返回内容
self.assertIn("用户名或者密码错误" ,str(data.text))
def test_discorrectusername_discorrectpassword(self):
#错误的用户名,错误的密码
info = self.myutil.check_condition_for_user(2)
if not info=="":
payload={"username":info["username"],"password":info["password"],"csrfmiddlewaretoken":self.token}
data = requests.post(self.url_product,data=payload,cookies=self.cookie)
#验证返回码
self.assertEqual("200",str(data.status_code))
#验证返回内容
self.assertIn("用户名或者密码错误",str(data.text))
#正确的用户名,正确的密码
def test_correctusername_correctpassword(self):
info = self.myutil.check_condition_for_user(3)
if not info=="":
payload={"username":info["username"],"password":info["password"],"csrfmiddlewaretoken":self.token}
data = requests.post(self.url_product,data=payload,cookies=self.cookie)
#验证返回码
self.assertEqual("200",str(data.status_code))
#验证返回内容
self.assertIn("电子商务系统" ,str(data.text))