本文的这一部分将讨论在开发过程中拥有有效工作流程的影响,以及适当的测试代码质量如何使我们能够创建可维护的测试,尤其是对于复杂项目。
开发工作流程和管道
编程是一项流程活动,我们开发人员应该对保持工作流程高效和缩短周转时间感兴趣,以免因等待时间而分心。
通常,我们要确保测试的总运行时间不超过几秒钟,至少对于我们在“更改-验证-重复”周期内执行的所有测试而言。 在开发过程中,至关重要的是要对此周期进行快速周转,这涵盖了从对项目进行一些更改到验证这些更改在类生产环境中按预期工作的过程。
如果我们仅通过每次都从头开始构建和部署我们的应用程序的管道来进行此验证,那就太慢了,无论该管道是否在本地运行。 因此,建议创建一个开发设置来侦听文件更改,然后通过重新部署整个应用程序或更新单个类或文件来修改应用程序以反映我们的代码更改,然后快速重新执行连接的测试方案到更新的被测应用程序。 这个想法是,通常只重新部署应用程序或应用程序的一部分要快得多,而不是从头开始启动进程并保持潜在的其他本地服务运行。 这种方法使本地运行的系统测试变得更加有趣,因为我们可以针对正在运行的系统重新执行测试方案,并立即验证我们的更改。
更具体地说,本地工作流可以是: 重新编译类,执行单元测试,(热)部署应用程序以及执行幂等集成测试。 整个周期不应超过一秒或两秒,否则我们的注意力会转移到其他地方。 由于集成测试的启动和执行时间,花费较长时间的系统测试或任何其他更复杂的场景,我们有可能将其拆分为一个执行频率较低或仅在CI / CD管道中运行的单独的测试套件。
对于Java Enterprise项目,请查看WAD或Liberty插件开发模式 。
测试代码质量和可维护的测试
导致项目测试不足的最大问题是缺乏可维护的测试代码。 在许多情况下,编写测试,或更确切地说,复制并粘贴测试,使得一旦对生产代码进行了较大的更改,就很难更改它们。 这意味着测试代码通常在处理过程中对其质量的关注较少。 只要测试用例很少,那就很好。 但是,您通常会在项目中看到的是,随着代码库变得越来越复杂,如果我们不应用重构,则测试套件的可维护性就会越来越少,就像生产代码一样。
这就是进行可维护的测试的重点:应用相同的代码质量原则,尤其是分离关注点并引入抽象层。 如果要注意不要引入泄漏的抽象,那么在您的测试范围内创建可重用的组件是可行且高度明智的。
让我们来看一个进一步说明这一点的示例。 我们从有时被称为“注释优先编程”的地方开始,在此我们用代码注释,伪代码甚至在纸上书写,我们的测试场景应在纯概念,业务逻辑层面上验证哪些内容。 例如,“创建尺寸较大的Espresso咖啡订单”。 或者“验证订单是否在Espresso类型且尺寸较大的系统中 ”。就是这样。 如何创建订单不是该级别的一部分,而是以较低的抽象,单独的方法或通常单独的委托来实现。 对于低级验证也是如此,例如,检查是否已发送回正确的HTTP状态代码和期望的JSON结构。 我们应注意不要将仅在详细级别上相关的信息(例如JSON结构)泄漏给委托方法。
您可以观看此视频,以查看实现该流程的示例流程。 从测试人员或领域专家的角度来看,这种方法很有意义,因为我们开始的是要测试的场景,而不是如何实现。 如果实现发生更改,例如与系统的通信从HTTP更改为其他内容,则仅需要调整一个位置。 此外,我们的测试用例方法变得非常易读,因为它们准确表达了要测试的内容的概念。 如果我们对操作方法感兴趣,我们会在较低级别中找到。
例如,以下系统测试将验证咖啡订单的创建:
class CreateOrderTest {
private CoffeeOrderSystem coffeeOrderSystem;
private BaristaSystem baristaSystem;
@BeforeEach
void setUp() {
coffeeOrderSystem = new CoffeeOrderSystem();
baristaSystem = new BaristaSystem();
}
@Test
void createVerifyOrder() {
List originalOrders = coffeeOrderSystem.getOrders();
Order order = new Order( "Espresso" , "Colombia" );
URI orderUri = coffeeOrderSystem.createOrder(order);
Order loadedOrder = coffeeOrderSystem.getOrder(orderUri);
assertThat(loadedOrder).isEqualToComparingOnlyGivenFields(order,
"type" , "origin" );
assertThat(coffeeOrderSystem.getOrders()).hasSize(originalOrders.size() + 1 );
}
... }
即使他们是非技术领域的专家,如果他们不了解Java,也可以了解该测试方案的执行情况,只要他们了解订单 , 咖啡类型和产地的背后领域,并且他们是否愿意忽略Java特定的语法。
这就是为什么我声称重点放在测试代码模式而不是特定的测试框架上的原因。 对于实际项目,至关重要的是引入适当的测试代码质量,主要是设计抽象层并将关注点分离为委托。 特别是当项目变得更加复杂时,这种差异会很快显示出来。
本系列文章的下一部分将介绍测试框架以及何时应用它们。
翻译自: https://www.javacodegeeks.com/2019/10/efficient-enterprise-testing-workflows-code-quality.html