当前位置: 首页 > 工具软件 > Awaitility > 使用案例 >

接口自动化-使用 Awaitility 测试异步代码

方昊
2023-12-01

对于那些实时性要求不高,但却计算密集或者需要处理大数据量的耗时较长的任务,或是有较慢 I/O 的任务,选择异步化是一个不错的选择。在系统层面,像引入消息中间件来解耦系统,将耗时长的任务放在中间件后异步执行。在方法层面,像把耗时较长的任务放到其他线程中去异步执行。

异步任务的两种类型:

(1)列表异步任务执行后对任务发起方或调用方有感知,比如发出一个事件或通知
(2)列表异步任务执行后对任务发起方或调用方没有感知,只是改变了系统中的某些状态

招商店铺中目前存在的都是第2种情况,在业务上的异步主要分以下两类:
1.订单导出类的功能:导出的订单数据较多,使用异步进行交互
2.提交到batch批处理进行处理

像这样异步场景怎么进行自动化集成呢?

之前也有做法就是通过Thread.sleep(经验值)来进行等待异步任务处理,但中间等待的时间是不确定的。

现介绍一款开源工具awaitility:https://github.com/awaitility/awaitility,
该工具提供轮询的方式,判断操作是否完成,以最短的时间获取异步任务结果。

以下用订单批量受理场景进行举例:

点击【批量受理】后,提交任务到batch落地任务流水。
具体的受理动作由batch批处理中心进行受理。

awaitility 使用步骤:
(1)maven工程在pom.xml添加awaitility依赖:

<dependency>
      <groupId>org.awaitility</groupId>
      <artifactId>awaitility</artifactId>
      <version>2.0.0</version>
</dependency>

(2)测试类import相关Class:

import java.util.concurrent.Callable;
import static java.util.concurrent.TimeUnit.*;
import static org.awaitility.Awaitility.*;
import static org.awaitility.Duration.*;
import static org.awaitility.pollinterval.FibonacciPollInterval.*;

(3)订单受理的测试脚本,如下:

@Test(dataProvider = "DefaultDataProvider", dataProviderClass = DataProviderDriver.class)
    public void TestAcceptByIdList(String testcase[]) {
        dal.setTitle("订单受理-批量受理_" + testcase[0])
                .setPriority("P0")
                .setTest_object("com.hipac.seller.hop.order.api.HopTradeAcceptApi")
                .setIs_exception("false")
                .setCase_name(Thread.currentThread().getStackTrace()[1].getMethodName());
        String data = testcase[1];
        String user = testcase[2];
        String password = testcase[3];
        String exceptCode = testcase[4];
        String exceptMsg = testcase[5];
        String orderAcceptFlag = testcase[6];
        supplyId = testcase[7];
        String queryOrderData = testcase[8];

        //1.设置供应商isv配置订单推送开关 ->关闭
        if(!isvManagerUtil.isOrderAccecptOpen(supplyId)) {
            //设置供应商推单开关为 - 》 关
            isvManagerUtil.setOrderAccecpt(supplyId,"orderPush","0");
        }
        //2.创建订单
        orderNo = OrderUtil.createOrder(user,15461,"已支付订单");
        queryOrderData = queryOrderData.replace("\n","").replace("${orderNo}",orderNo);

        //3.调用订单查询接口 获取订单交易id
        String orderId = getOrderIdByNo(user,password,queryOrderData);
        //4.check供应商isv配置是否与场景预期的前置一致
        if(orderAcceptFlag.equals("1")) { //推单
            if(!isvManagerUtil.isOrderAccecptOpen(supplyId)) {
                //设置供应商推单开关为 - 》 开
                isvManagerUtil.setOrderAccecpt(supplyId,"orderPush","1");
            }
        } else if(orderAcceptFlag.equals("0")) {
            if(isvManagerUtil.isOrderAccecptOpen(supplyId)) {
                //设置供应商推单开关为 - 》 关
                isvManagerUtil.setOrderAccecpt(supplyId,"orderPush","0");
            }
        }
        //5.进行批量订单受理
        data =  data.replace("${orderId}",orderId);
        String result = PostRequestAPI("hipac.seller.order.hpc.batch.accept",user,password,data);
        String actCode = HttpUtil.checkHttpResCode(result);
        String actMsg = JsonUtil.parseJson2Map(result).get("message");
        //6.轮询进行订单状态检测:是否已到达已受理状态
        // 轮询5s 每隔500毫秒进行轮询,延迟100毫秒后进行校验
        await().atMost(5, TimeUnit.SECONDS).pollInterval(FIVE_HUNDRED_MILLISECONDS).and().with().pollDelay(100, TimeUnit.MILLISECONDS)
                .await().until(new Callable<Boolean>() {
            @Override
            public Boolean call() throws Exception {
                int orderStatus = getOrderStatus(supplyId, orderNo);
                return orderStatus == OrderStatus.ACCEPT.getCode();
            }
        });
    }

这里使用轮询的方式检查订单是否到达已受理状态:
// 轮询5s 每隔500毫秒进行轮询,延迟100毫秒后进行校验

   await().atMost(5, TimeUnit.SECONDS).pollInterval(FIVE_HUNDRED_MILLISECONDS).and().with().pollDelay(100, TimeUnit.MILLISECONDS)
                .await().until(new Callable<Boolean>() {
            @Override
            public Boolean call() throws Exception {
                int orderStatus = getOrderStatus(supplyId, orderNo);
                return orderStatus == OrderStatus.ACCEPT.getCode();
            }
        });

 类似资料: