Assert断言优化

目的:

可以使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;
    }
原文地址:https://www.cnblogs.com/season-xie/p/8287222.html