在前一篇文章(http://yong3773.iteye.com/blog/1947109)中,写了在测试方法中循环读取同一参数。今天要介绍的是不同于前一篇文章中写的2种策略。这次的策略更完善,已经付诸实践,在项目测试中取得了成效。
首先介绍一个新概念:执行次序(迭代次序)。
先举个栗子:testA()方法测试的是用户登录,里面有2个变量userName、password。现在我要测试2个不同用户名密码的用户执行testA()方法。
原有的做法:外部数据定义格式(userName1,password1)、(userName2,password2),以此来区分不同时间取不同的变量次数,可缺点也随之而来:逻辑代码里面是userName,数据文件中变成了userName1,容易混淆,不易理解。
现在的做法: 外部数据定义格式(userName,password,1)、(userName,password,2),里面的数字就是迭代的次序。第一次迭代的时候取前面括号里面的变量,第二次的时候取后面括号中的内容。
此次的更新,涉及到数据库表结构变更(数据驱动的数据持久化存在数据库中),数据管理web前端的修改,服务后端的修改。虽然涉及的地方很多,但长痛不如短痛,为了以后更方便,下决心改!
数据管理平台变更如下图:
接口测试工具类中增加如下方法:
//得到测试所需参数的方法 public static String queryValue(String className,String methodName,String paramName,int executeOrder){ String paramValue=null; con.connect(); con.sql="SELECT PARAM_VALUE FROM params WHERE CLASS_NAME = '"+className+"' AND METHOD_NAME='"+methodName+"' AND PARAM_NAME='"+paramName+"' AND `STATUS` = '0' AND EXECUTE_ORDER='"+executeOrder+"';"; con.executeQu(); try { while(con.rs.next()) { paramValue = con.rs.getString("PARAM_VALUE"); } } catch (SQLException e) { e.printStackTrace(); } if(paramValue==null){ try { throw new Exception("数据库没有查到此属性的值,或者此值为null"); } catch (Exception e) { e.printStackTrace(); } } con.closeConnect(); return paramValue; } //得到此测试方法的最大迭代次数方法 public static int getMaxOrder(String className,String methodName,String paramName){ con.connect(); con.sql="SELECT MAX(EXECUTE_ORDER) AS max FROM params WHERE CLASS_NAME = '"+className+"' AND METHOD_NAME='"+methodName+"' AND PARAM_NAME = '"+paramName+"' AND `STATUS` = '0';"; con.executeQu(); int maxRow = 0; con.connect(); String str=con.sql; try { while(con.rs.next()) { maxRow=con.rs.getInt("max"); } } catch (SQLException e) { e.printStackTrace(); } con.closeConnect(); return maxRow; }
具体到接口测试代码中的运用,sample代码如下:
/** * */ package com.cpsdna.saasapi.test.common; import static org.junit.Assert.*; import org.apache.log4j.Logger; import org.junit.Test; import com.cpsdna.test.util.DBUtil; import com.cpsdna.test.util.ParamUtil; /** * @author ChenYong * @time 2013-11-4 下午2:01:49 */ public class ParamTest { private static Logger log = Logger.getLogger(ParamTest.class.getName()); @Test public void testParam() { log.info("START "+ParamUtil.getClassName()+"."+ParamUtil.getMethodName()+"()++++++++++"); try{ int IterationNum=DBUtil.getMaxOrder(ParamUtil.getClassName(), ParamUtil.getMethodName(), "userName"); //首先取得最大的迭代次数 if(IterationNum==0){ log.info("迭代次数为0,直接跳出测试方法"); }else{ log.info("共有"+IterationNum+"次迭代"); } for(int j=1;j<=IterationNum;j++){ //根据迭代次数,循环 String userName=DBUtil.queryValue(ParamUtil.getClassName(), ParamUtil.getMethodName(), "userName",j); String password=DBUtil.queryValue(ParamUtil.getClassName(), ParamUtil.getMethodName(), "password",j); log.info("------第"+j+"次迭代开始------"); if(userName==null || password==null){ log.info("第"+j+"次迭代的时候,数据库缺少此次迭代所需参数,跳出本次迭代"); continue; } //具体的测试逻辑代码写在这里 } }catch (Exception e) { log.error(this, e); fail("Exception Occured"); } log.info("END "+ParamUtil.getClassName()+"."+ParamUtil.getMethodName()+"()++++++++++"); } }
ok,上面就是变更逻辑之后的一些地方。
待改进的地方:
1.数据管理的web端,参数数据输入的时候还是不太方便,一次只能输入一个。
2.准备把数据库中的参数数据保存成json格式,一组对应一次迭代。
一步一步......
相关推荐
- **循环路径覆盖法**: 不属于黑盒测试,而是白盒测试的一种方法。 - **因果图法**: 将输入和输出之间的因果关系转换为图形,然后转化为测试用例。 #### 10. 黑盒测试的特点 - **无需了解内部实现**: 黑盒测试关注...
2. **循环执行**:利用QTP的循环结构,多次执行登录和查询操作。 3. **数据驱动测试**:使用外部数据文件(如Excel)存储不同的测试数据。 #### QTP中的Action作用及类型 QTP中的Action主要用于封装一组测试步骤,...
3. **设置参数**:配置线程组的并发用户数、迭代次数等,采样器中的URL、方法、参数等。 4. **执行测试**:运行测试计划,观察监听器显示的结果。 5. **分析结果**:通过聚合报告、响应时间图等分析性能指标,找出...
计数控制的循环(如for循环)通常用于已知迭代次数的情况,而条件控制的循环(如while和do-while)则适用于未知迭代次数或直到满足特定条件时才结束的情况。嵌套循环则是将一个循环结构置于另一个循环体内,以处理更...
引入测试管理意味着采用系统化的方法和工具来规划、执行和监控测试活动,确保测试过程的效率和效果。这包括但不限于测试计划的制定、测试用例的设计、测试执行的跟踪以及测试结果的分析。 #### 完整的测试由哪些...
### 知识点三:迭代开发中的需求-测试-产品-重构循环 #### 3.1 需求分析 - **需求收集**:通过与客户或利益相关者的沟通来明确需求。 - **需求细化**:将抽象的需求转化为具体的功能点。 - **需求优先级排序**:...
顺序迭代模型:迭代模型允许反复循环。 - C. 线性迭代模型:瀑布模型是非迭代的。 - D. 及早见产品模型:强调快速原型。 - **正确答案:A. 线性顺序模型** **15. 维护副作用** - **选项解析:** - A. 开发时...
- **方法**:通过变量和循环结构实现参数化测试。 ### 结论 Robot Framework 作为一种灵活且强大的自动化测试工具,不仅适合初学者快速上手,也满足了专业测试工程师的需求。其丰富的扩展库和高度定制化的特性使其...
LR测试脚本的增强方法是LoadRunner性能测试过程中的关键环节,它涉及到如何优化和提升测试脚本的效率与准确性,以更好地模拟真实用户行为并找出系统潜在的性能瓶颈。LoadRunner是一款强大的负载和性能测试工具,广泛...
- **`continue`语句**:用于结束当前循环迭代,直接进入下一次循环迭代。 - **`goto`语句和标号**:虽然在结构化编程中不鼓励使用,但`goto`可以无条件地跳转到程序的任意位置,标号定义了跳转的目标。 掌握这些...
6. **测试驱动开发(TDD)**:Peridot适合实践TDD,因为它的快速反馈循环和清晰的失败消息可以帮助开发者快速迭代和修复问题。 7. **插件系统**:Peridot有丰富的插件生态系统,如`--watch`选项,可以监视文件变化并...
- 控制结构:支持IF语句和FOR循环语句,使测试逻辑更加复杂和灵活,可以实现条件判断和迭代操作。 - 标签功能:通过为测试用例添加标签,可以方便地进行分类管理和选择性执行,提高测试的组织效率。 - 驱动方式:...
- **循环语句**:支持迭代操作,可以重复执行某段代码直到满足特定条件为止。 ##### 2.3 TTCN-3测试行为规范 - **行为描述**:使用TTCN-3定义了被测系统的行为,包括正常行为和异常行为。 - **交互序列**:详细...
4. **数据驱动的测试**:通过外部数据源来驱动测试执行,增强了测试的可扩展性和复用性。 5. **使用动作词的测试自动化**:这是一种更高级别的测试自动化方法,通过定义一组预定义的动作词来描述测试步骤,使得测试...
23. **喷泉模型**:喷泉模型适应迭代和敏捷开发,允许开发过程中的循环和重叠,强调灵活性。 这些知识点涵盖了软件工程的基础概念和技术,是软件工程师考试的重要复习内容。理解和掌握这些知识有助于在实际工作中...
- for循环:用于执行固定次数的迭代,适用于已知循环次数的情况。 - while循环:在满足特定条件时持续执行代码块。 - do...while循环:至少执行一次,然后在条件满足时继续执行。 - break和continue语句:用于...
7. **Include Controller**:允许在测试计划中引入外部的JMX文件,方便代码复用和管理大型测试计划。 8. **Simple Controller**:不提供任何逻辑或运行时功能,主要用于组织和分组其他控制器或采样器。 9. **...
其中的循环使用功能对于提高测试脚本的复用性和灵活性具有重要意义。 ### 循环使用在UFT 12中的实现 #### 1. 理解循环使用的基本概念 在UFT中,循环是一种控制结构,用于重复执行一段代码直到满足特定条件为止。...