第 20 章 测试事件驱动的微服务 测试事件驱动型微服务
本作品已使用人工智能进行翻译。欢迎您提供反馈和意见:translation-feedback@oreilly.com
微服务规模小,且专为特定目的而构建,因此测试起来相对容易,尤其是与大型服务相比。事件流、队列和请求-响应 API 提供了输入。状态被本地化到微服务自己的独立状态存储中,输出事件被写入输出流。本章介绍测试原则和策略,包括单元测试、集成测试和性能测试。
一般测试原则
事件驱动型微服务共享所有应用程序共有的测试最佳实践。功能测试,如单元测试、集成测试、系统测试和回归测试,可确保微服务做它应该做的事情,并且不做它不应该做的事情。非功能测试,如性能、负载、压力和恢复测试,可确保微服务在各种环境场景下的表现符合预期。
现在,在继续深入讨论之前,需要注意的是,本章意在与有关测试原理和方法的更广泛著作互为补充。毕竟,关于测试的书籍、博客和文档已经很多了,我当然不可能像他们那样介绍测试。本章主要探讨事件驱动架构特有的测试方法。关于特定语言的测试框架和测试最佳实践,你需要自行查阅相关资料,以补充本章内容。
单元测试微服务功能
单元测试对应用程序中最小的代码片段进行测试,以确保它们按预期运行。单元测试为编写更大、更全面的应用程序功能测试奠定了基础。
事件驱动型微服务由数据驱动,并应用转换、聚合、映射和还原函数。您可以编写单元测试来测试其中的每个阶段,以确保输入的数据和输出的数据都符合预期。
单元测试无状态函数
无状态函数不需要先前函数调用的任何持久状态,因此很容易进行独立测试。下面的代码展示了一个 EDM 拓扑示例,它类似于 MapReduce 风格(如 Kafka Streams)框架:
myInputStream.filter(myFilterFunction).map(myMapFunction).to(outputStream);
myFilterFunction 和myMapFunction 相互独立,都不保留任何状态。您需要编写(至少)两个单元测试--一个用于确保myFilterFunction 为给定的输入提供正确的输出,另一个用于确保myMapFunction 提供正确的映射结果。
下面的代码显示了myFilterFunction 。请注意,有几个逻辑条件应用于MyEventValue 对象,以确定是否应将其过滤掉:
publicbooleanmyFilterFunction(StringeventKey,MyEventValuevalue){if(value.type==7&&value.modifier.equals("valid"))returntrue;elseif(value.type>3&&value.type<6)returntrue;elsereturnfalse;}
在这种情况下,您需要的不仅仅是一个单元测试。如果考虑周全,您还需要测试三个快乐路径情况,以确保逻辑在预期情况下返回true :
-
value.type == 7 && value.modifier.equals("valid") -
value.type == 4 -
value.type == 5
之所以要测试4 和5 ,是因为它们代表了true 预期结果的边界。通常情况下,我们不会测试范围内的每一个有效值。您还需要进行测试,以确保边界情况下的预期结果是false :
-
value.type != 7 ...
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access