自动化测试常用的数据驱动方式
来源:互联网 发布:网络教学综合平台 编辑:程序博客网 时间:2024/06/08 08:09
在日常的测试工作中,从理论上来说,一个接口方法可以用一个用例就搞定测试,然后传入不同的参数的不同组合,在用例方法里做不同的分支判断校验。看似很美好,包罗万象的参数组合,实现其来很麻烦,且有如下缺点:
- 且需要花大量的精力去判断分支路径,并做不同的断言,破坏了方法的原子性,不要指望一个方法干所有事情,我们一直强调模块化编程。
- 脚本存在大量的if-else分支,for循环等,脚本可读性差 维护成本高。
- 测试没有侧重点。
那么,有什么好的方法来避免这个问题呢?首先,我们要明白为什么要做数据驱动,数据驱动的原则是什么?这个问题,相同字段,输入不同的数据,通过调取被测代码,获取不同的测试结果。每组数据都是相同的字段,进一步可以把一组参数抽象为一个对象,这一组参数组合就是这个对象的不同元素。我们要做的工作就是不断创建这样的对象,并传递给测试方法。那么数据驱动怎么做呢?有哪些数据驱动方式呢?一般来说,主要有以下几种方式传入数据:
- 以硬编码的方式写在代码里,简单直观,但代码和数据未分离,不方便以后维护。
- 从文件读取数据,如csv,excel、txt、xml等格式文件。不用修改测试逻辑,只需要维护测试数据。
- 直接调用接口获取数据源。
- 本地封装一些生成数据的方法。
以上几种方式生成的数据,在@DataProvider方法中以Object二位数组返回数据,测试用例可以直接获取。通过@datapovider方法数据驱动有以下几点优点:
1.像在循环里一样,自动遍历所有数据组合
2.某一组数据执行测试方法失败,不会影响其他数据组合继续执行。
3.测试代码不用加过多的数据判断,要的只是对被测代码的数据输出和结果断言。
例如要测试一个列表查询的接口,有很多查询条件,那么需要测试,默认查询、单一条件查询、组合条件查询等场景,其实就是设置不同的查询参数,其余测试步骤及校验大抵相同。
1.单一条件查询,遍历所有查询条件,传入测试方法,数据的获取需要封装成合适的方法,可读性好,例如这里buildQueryParmGroup方法就是封装构造查询参数的方法
private static Map<String, String> buildQueryParmGroup() { HashMap<String, String> map = new HashMap<String, String>(); map.put("id", "1003266"); map.put("type", "1"); map.put("venderId", "20032"); map.put("businessId", "100073920"); map.put("title", "砍价活动api测试"); map.put("skuId", "1200039810"); map.put("oneCategory", "1315"); map.put("twoCategory", "1342"); map.put("threeCategory", "9733"); map.put("beginTime", "2017-01-04 16:19:45"); map.put("endTime", "2017-02-03 16:19:45"); map.put("status", "1"); map.put("pin", "test_sop01"); map.put("customerPin", "sop_order_new"); return map;}
@DataProvider(name = "queryParamProperties") public static Object[][] queryParamProperties() { Map<String, String> queryParmGroup = buildQueryParmGroup(); Set<Map.Entry<String, String>> entrySet = queryParmGroup.entrySet(); Object[][] objects = new Object[entrySet.size()][]; Object[] objects1 = entrySet.toArray(); for (int i = 0; i < objects.length; i++) { objects[i] = new Object[]{objects1[i]}; } return objects; } @Test(dataProvider = "queryParamProperties") @Description(description = "单一条件查询砍价列表") public void testGetByBargainList_2(Map.Entry<String, String> entry) throws Exception {// ConvertUtils.register(new DateLocaleConverter(), Date.class); ConvertUtils.register(new Converter() { public Object convert(Class type, Object value) { if (value == null) { return null; } if (!(value instanceof String)) { throw new ConversionException("传入的不是字符串"); } if (((String) value).trim().equals("")) { return null; } DateFormat df = new SimpleDateFormat(PromoConstant.YYYYMMDDHHMMSS); try { return df.parse((String) value); } catch (ParseException e) { throw new RuntimeException(e); } } }, Date.class); BargainQueryParm queryParam = new BargainQueryParm(); BeanUtils.setProperty(queryParam, entry.getKey(), entry.getValue()); Result<List> bargainList = this.invoke(bargainReadService, "getBargainList", List.class, clientInfo, queryParam); Assert.assertTrue(bargainList.isSuccess()); }组合条件查询,随机生成参数组合,查询条件放到一个map里,封装一个buildQueryParmSubMap方法用于随机生成查询条件组合,返回一个map<条件参数名,条件参数值>
private static Map<String, String> buildQueryParmSubMap(Map<String, String> map, int size) { Set<Map.Entry<String, String>> entries = map.entrySet(); ImmutableSet<Map.Entry<String, String>> subSet = ImmutableSet.copyOf(Iterables.limit(entries, size)); Map<String, String> subMap = new HashMap<String, String>(); Iterator<Map.Entry<String, String>> iterator = subSet.iterator(); while (iterator.hasNext()) { Map.Entry<String, String> entry = iterator.next(); subMap.put(entry.getKey(), entry.getValue()); } return subMap;}数据驱动方法:
@DataProvider(name = "queryParmGroup")public static Object[][] queryParmGroup() { Map<String, String> queryParmGroup = buildQueryParmGroup(); Object[][] objects = new Object[100][]; for (int i = 0; i < objects.length; i++) { objects[i] = new Object[]{buildQueryParmSubMap(queryParmGroup, RandomUtils.nextInt(queryParmGroup.size()))}; } return objects;}
@Test(dataProvider = "queryParmGroup")@Description(description = "组合条件查询砍价列表")public void testGetByBargainList_3(Map<String, String> map) throws Exception { ConvertUtils.register(new Converter() { public Object convert(Class type, Object value) { if (value == null) { return null; } if (!(value instanceof String)) { throw new ConversionException("传入的不是字符串"); } if (((String) value).trim().equals("")) { return null; } DateFormat df = new SimpleDateFormat(PromoConstant.YYYYMMDDHHMMSS); try { return df.parse((String) value); } catch (ParseException e) { throw new RuntimeException(e); } } }, Date.class); BargainQueryParm queryParam = new BargainQueryParm(); BeanUtils.populate(queryParam, map); Result<List> getBargainList = this.invoke(bargainReadService, "getBargainList", List.class, clientInfo, queryParam); Assert.assertTrue(getBargainList.isSuccess());}
0 0
- 自动化测试常用的数据驱动方式
- 自动化测试---被玩坏的数据驱动
- 基于数据驱动的接口自动化测试解决方案
- 基于数据驱动的web UI自动化测试
- 关键字+数据驱动自动化测试框架
- Excel+Httpclient,数据驱动接口自动化测试
- 自动化测试里的数据驱动和关键字驱动思路的理解
- 自动化测试里的数据驱动和关键字驱动思路的理解
- 常用的自动化测试框架
- 自动化测试之 数据驱动 和 关键字驱动
- seleniumWebDriver自动化测试框架_01TestNG数据驱动测试
- 自动化测试的数据框架
- 自动化测试的数据框架
- Python-基于数据驱动模式的自动化测试框架搭建的的逐步实现(一)
- Python-基于数据驱动模式的自动化测试框架搭建的的逐步实现(二)
- 自动化测试远程驱动静默方式(Jenkins+Selenium+Chrome+Docker)
- 脚本驱动模式的自动化测试初探
- 基于模型驱动的自动化测试设计
- 使用纯CSS3实现转动时钟案例
- 一致性hash的c++简单实现
- Scala学习笔记之`map`、`reduce`和`foreach`
- eclipse添加jre
- 微信小程序详细图文教程-10分钟完成微信小程序开发部署发布(3元获取腾讯云服务器带小程序支持系统)
- 自动化测试常用的数据驱动方式
- Linux学习之XShell与虚拟机的连接
- 系统吞吐量(TPS)、用户并发量、性能测试概念和公式
- Linux下Tomcat 启动报错touch
- 写在计划写作之后
- Java的方法重载和重写
- 重拾书本
- java方法重写原则
- HTML入门学习笔记--CSS背景和精灵图(5)