目的:
可以使map,json,bean混合验证 - assertEqual(Object,Object)
扩展各种验证类型,spring管理实现集。如json验证,优化各个action调用方式。
在testng Assert类基础上重写部分方法
(1)要好维护,就先定义接口
public interface AssertActionI<T,R> { /** * * @param assertinfo * @param actual * @param expect * @return */ public boolean api_Assert(Assertinfo assertinfo, T actual, R expect); /** * 是否符合验证类型 * @param assertinfo * @param actual * @param expect * @return */ public boolean matchCheckType(Assertinfo assertinfo, T actual, R expect); }
(2)如下实现 map,json,bean混合验证 - assertEqual(Object,Object)
原理是都转换成map做验证:
json-map (原则:只取第一层的keyvalue,如果有多层请处理后再传入)
map-map
bean-map
Amap(actual)- Bmap(expect)
1.以expect为验证中心,遍历expect的key
2.检查actual是否存在这个key,没有记录错误信息(not check和only check 排除)
3.expect和acutal都存在key,检查key-value
4.有not check和only check关键字处理
5.检查key value对应值(type,value)
public class CommonObjectImpl<T,R> extends AssertBase implements AssertActionI<T,R> { @Override public boolean api_Assert(Assertinfo assertinfo, T request, R Response) { Map<String, Object> actual = convertToMap(Response); Map<String, Object> expect = convertToMap(request); return AssertBase.compareCommon(actual,expect,assertinfo.getAssert_value()); } @Override public boolean matchCheckType(Assertinfo assertinfo, T request, R Response) { return isJsonMapObject(Response); } }
(3)如何调用?放入list, spring管理
用spring注入 <util:list id="customAsserts" value-type="service.responsehandler.verify.CustomAssert"> <ref bean="assertCommonObject"/> <ref bean="assertList"/> </util:list>
@Resource(name = "customAsserts") public void setCustomAsserts(List<CustomAssert> customAsserts) { TestBase.customAsserts = customAsserts; } for(AssertActionI ass: assertList) { if(ass.matchCheckType(ai,actual,expect)){ //符合验证类型就调用 ass.api_Assert(ai,actual,expect); } }
(4)和testng Assert 相结合,继承Assert
/** * @param actual * @param expect * @param message * 当actual和expect不能转换成map做对比的时候,调用testng原生的Asssert */ static public void assertEquals(Object actual, Object expect, String message) { if (!assertMapEquals(actual, expect)) { Assert.assertEquals(actual, expect, message); } }
(5)扩展后的验证点很多,怎么优化调用?
关于每个assert实现的验证点如下:
public enum AssertActions{
EQUAL,CONTAINS,SIZE,ISEMPTY,KEY_VALUE,CONTAINS_KEY,CONTAINS_VALUE; }
用if else判断是十分麻烦的,可以用反射去调用验证方法,只需要输入验证的type和一个统一的验证方法
以action名作为方法名,用反射调用
public static boolean getAction(Class<?> c, String act, Object response, Object assertValue) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException { Object obj = c.newInstance(); Method[] methods=c.getDeclaredMethods(); for (EumAction.AssertActions e : EumAction.AssertActions.values()) { if(e.toString().equals(act.toString())){ for(Method m:methods){ if(m.getName().contains(act.toString())){ Method method=c.getMethod(m.getName(), Object.class,Object.class); boolean str2= (Boolean) method.invoke(obj, new Object[]{response,assertValue}); System.out.println(str2); return str2; } } } } Assert.fail("No assertAction: "+act +" in "+c.getSimpleName()); return true; }