黑盒测试总结和反思
从2月初写黑盒测试代码,到现在已经有超过写了超过50个测试类、700个测试方法的代码,从最开始的不知道怎么写、为什么写,到后来的为什么这样写、怎样把测试写好、思考背后的逻辑方法的执行(结合MyBatis)。在这里写下自己对黑盒测试的体会。
黑盒测试也称功能测试,它是通过测试来检测每个功能是否都能正常使用。在测试中,把程序看作一个不能打开的黑盒子,在完全不考虑程序内部结构和内部特性的情况下,在程序接口进行测试,它只检查程序功能是否按照需求规格说明书的规定正常使用,程序是否能适当地接收输入数据而产生正确的输出信息。黑盒测试着眼于程序外部结构,不考虑内部逻辑结构,主要针对软件界面和软件功能进行测试。黑盒测试是以用户的角度,从输入数据与输出数据的对应关系出发进行测试的。
我写的测试是代码,省略了产品的页面输入环节,直接在代码上“赋值”输入数据,下一步就调用已经写好的CRUD方法对数据库进行操作,测试的目的也是检查每一个“方法”是否能成功执行,也就是产品的需求细节有没有达到预期目标。
从最单一的方法说起,以在数据库里面添加一个数据为例:
添加银行数据
public void AddBank()
{
string token = "";
Bank bank = new Bank();
bank.Abbreviation ="CCB";//suoxie
bank.AccessToken = "AccessToken";//fangwenlingpai
bank.AlipayFinanceAccountCode = "0001";
bank.BankCode = "0001";
bank.BankName = "中国建设银行";
_svr.AddBank(token, bank);
}
AddBank(token, bank)方法返回值为Void,无法通过测试属性直接检查该银行数据是否插入数据库,在这种情况下,我们看似写了测试代码,实际上并没有真正的检测出AddBank()方法是否能够满足项目需求,所以需要把刚才“写入”到数据库的数据,重新“提取”出来,查看是否相同:
/// 获取银行
///
[Test]
public void GetBank()
{
string token = "";
string code = "0001";
Bank ret = _svr.GetBank(token, code);
Assert.IsNotNull(ret, "执行失败");
}
根据银行的唯一标识查出银行信息,GetBank()方法返回的是一个“银行”对象,但由于Assert.IsNotNull(ret, "执行失败")方法只能检查查询结果是否为空,也不能检查出数据是否与原始数据相同,此时,我们可以采用一下方法来判断数据的真实性:
//这里的”0001”为原始数据
if (ret.AlipayFinanceAccountCode=="0001")
{
Assert.IsNotNull(ret, "执行失败");
}
else {
ret = null;
Assert.IsNotNull(ret, "执行失败");
}
以上是我在测试过程中总结的测试技巧,由于是黑盒测试,我们并不能看见执行过程,更不可能随意添加测试接口,只能在现有的基础上,尽可能的让测试代码完善。但如果测试代码没有相应的“查询逻辑”,那么插入到数据库的数据是很难检测到的。
当写完一个测试类后,就可以按照分类,对数据进行测试,比如一个测试类有银行,物业小区,居委会等模块,那么可以给银行类的方法添加前缀“A_01”,物业类的就为“B_01”,以此类推。
以上是单一“对象”问题,但我们在测试中会经常遇到对个对象同时出现,即对象依赖问题
,比如说创建报修单:创建保修单对象需要一个eaAreaCode数据,而这个数据没有,不管以前有没有过eaAreaCode对象数据,都最好是自己在该测试代码里面自己创建一个,如果你以前测试过eaAreaCode类的相关方法,一方面我们去找这个数据时会耽搁时间(测试数据越多越耽搁),另一方面每个测试类几乎都有增删查改方法,我们可能在当时测试的时候删除了测试数据,所以哪怕就算你拿到了当时的数据,也会出现各种问题。
/// 创建报修单
///
[Test]
public void A01CreateRepairOrders()
{ //创建eaAreaCode对象
EaAreaQueryParaEx queryPara = new EaAreaQueryParaEx();
var eaAreaList = _iEstateAreaBaseSvr.GetAllEaAreaList("", queryPara,true,0,100,true);
Assert.True(eaAreaList.Count > 0);
var eaArea = (EaArea)eaAreaList[0];
/*************************************************/
string token = "";
string eaAreaCode = eaArea.EaAreaCode;//"0001";
string repairContent = "abc";
AttachMentList list = new AttachMentList();
var attachMent = new AttachMent();
attachMent.KeyID = Guid.NewGuid().ToString();
attachMent.FileType = ".jpeg";
attachMent.FileName = "file.jpeg";
list.Add(attachMent);
string repPeople = "张三";
string ret = _svr.CreateRepairOrders(token, eaAreaCode, repairContent, list, repPeople);
Assert.IsNotNull(ret, "执行失败");
}
最后来说一下数据的包含逻辑:
如图,可以看出两个方法之间的关系:表决对象作为表决对象列表的一个属性保存在列表中。在新增表决对象方法里面,没有把具体的保存方法实现(这里就检测出方法错误了),而在增加列表中,只需要创建列表List,list中存的元素必为VoteObject对象(见后面的代码)。
public void AddVoteObjectList()
{
string token = "";
//VoteObjectList是 VoteObject 的List集合,所以List中存储的是VoteObject对象
VoteObjectList data = new VoteObjectList();
VoteObject obj = new VoteObject();
obj.Address = "aaa";
obj.AreaName = "天府二街";
obj.BuildId = "0001";
obj.CantonCode = "0001";
obj.CreateTime = DateTime.Now;
obj.KeyId = "0001";
obj.TopicVoteId = "0001";
data.Add(obj);
_svr.AddVoteObjectList(token, data);
}
总结:在测试的时候要尽量做到测试数据的范围广阔,通过写测试代码,不仅要测试出代码的问题,更要让自己达到以下几点目标:
1. 在项目逻辑上,能够理解项目的模块划分,比如银行、街道、物业公司等模块,理清楚他们之间的联系,在没有看项目说明书之前,能大致预测他们的功能,更深刻的理解项目本身;
2. 由于是黑盒测试,看不到代码执行的逻辑(过程),但对每一次的CRUD,结合项目所用的ORM框架,要知道逻辑是怎么实现的,数据库语句是怎么写的;
3. 要养成良好的测试习惯,每发现一次错误,及时记录下来,反馈到项目组。
2018.3.5