Flink测试指南官方文档(v1.7.0)

单元测试

通常,我们假设Flink在用户定义的函数(Function)之外都能够产生正确的结果。因此,推荐大家尽可能多的测试包含主要业务逻辑的函数(Function)类。

比如,如果有人实现了下面的ReduceFunction:

public class SumReduce implements ReduceFunction<Long> {

    @Override
    public Long reduce(Long value1, Long value2) throws Exception {
        return value1 + value2;
    }
}
复制代码

你可以很方便的使用自己喜欢的测试框架测试这个类。

public class SumReduceTest {

    @Test
    public void testSum() throws Exception {
        // instantiate your function
        SumReduce sumReduce = new SumReduce();

        // call the methods that you have implemented
        assertEquals(42L, sumReduce.reduce(40L, 2L));
    }
}
复制代码

集成测试

为了端到端测试Flink流管道(streaming pipeline),你也可以写一个在本地小型集群上执行的集成测试。

为此要首先添加依赖flink-test-utils:

<dependency>
  <groupId>org.apache.flink</groupId>
  <artifactId>flink-test-utils_2.11</artifactId>
  <version>1.7.0</version>
</dependency>
复制代码

举例来说,你想测试下面的MapFunction:

public class MultiplyByTwo implements MapFunction<Long, Long> {

    @Override
    public Long map(Long value) throws Exception {
        return value * 2;
    }
}
复制代码

你可以写如下的集成测试:

public class ExampleIntegrationTest extends AbstractTestBase {

    @Test
    public void testMultiply() throws Exception {
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        // configure your test environment
        env.setParallelism(1);

        // values are collected in a static variable
        CollectSink.values.clear();

        // create a stream of custom elements and apply transformations
        env.fromElements(1L, 21L, 22L)
                .map(new MultiplyByTwo())
                .addSink(new CollectSink());

        // execute
        env.execute();

        // verify your results
        assertEquals(Lists.newArrayList(2L, 42L, 44L), CollectSink.values);
    }

    // create a testing sink
    private static class CollectSink implements SinkFunction<Long> {

        // must be static
        public static final List<Long> values = new ArrayList<>();

        @Override
        public synchronized void invoke(Long value) throws Exception {
            values.add(value);
        }
    }
}
复制代码

CollectSink里使用静态变量是因为Flink在将其分发到集群上之前会序列化所有的算子(operators)。使用静态变量与本地Flink小型集群实例化的算子(operators)通信是这个问题的一种解决方案。或者,你也可以让测试sink把数据写到一个临时目录下的文件里。你也可以实现自定义的source来发出水印(wartermark)。

测试checkpointing和状态处理

状态测试的一种方式是在集成测试里打开checkpointing

你可以在测试中配置StreamExecutionEnvironment来做到这一点。

env.enableCheckpointing(500);
env.setRestartStrategy(RestartStrategies.fixedDelayRestart(3, 100));
复制代码

例如,向Flink应用程序添加一个身份映射器算子,该算子将每1000毫秒抛出一次异常。但是,由于动作之间存在时间依赖关系,因此编写此类测试可能会非常棘手。

另一种方法是使用flink-streaming-java模块下的Flink内部测试实用程序AbstractStreamOperatorTestHarness编写单元测试。

有关如何执行此操作的示例,请在flink-streaming-java模块中查看org.apache.flink.streaming.runtime.operators.windowing.WindowOperatorTest

请注意,AbstractStreamOperatorTestHarness当前不是公共API的一部分,可能会有所变化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值