目的:spring
能夠使map,json,bean混合驗證 - assertEqual(Object,Object)json
擴展各類驗證類型,spring管理實現集。如json驗證,優化各個action調用方式。api
在testng Assert類基礎上重寫部分方法ide
(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)spa
原理是都轉換成map作驗證:
json-map (原則:只取第一層的keyvalue,若是有多層請處理後再傳入)
map-map
bean-mapcode
Amap(actual)- Bmap(expect)blog
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; }