电子书 – Spring Cloud 指南 – NPI EA (分类=Spring Cloud)
announcement - icon

让我们开始使用 Spring Cloud 的微服务架构

>> 加入 Pro 并下载电子书

电子书 – Mockito – NPI EA (标签 = Mockito)
announcement - icon

模拟是单元测试的重要组成部分,Mockito 库使编写 清晰直观的单元测试 变得容易,用于您的 Java 代码。

通过我们的 Mockito 指南 开始模拟,并改进您的应用程序测试

下载电子书

电子书 – Java 并发 – NPI EA (分类=Java 并发)
announcement - icon

在应用程序中处理并发可能是一个棘手的过程,其中包含许多 潜在的陷阱。 扎实的掌握基本知识将有助于最大程度地减少这些问题。

通过我们的 Java 并发 指南开始了解多线程应用程序

>> 下载电子书

电子书 – 响应式 – NPI EA (分类=响应式)
announcement - icon

Spring 5 增加了对使用 Spring WebFlux 模块进行响应式编程的支持,此支持自那时起不断改进。 开始使用 Reactor 项目基础知识和 Spring Boot 中的响应式编程

>> 加入 Pro 并下载电子书

电子书 – Java Streams – NPI EA (分类=Java Streams)
announcement - icon

自从 Java 8 引入以来,Stream API 已成为 Java 开发的基础。 基本操作,例如迭代、过滤、映射元素序列,使用起来看似很简单。

但这些也可能被过度使用并陷入一些常见陷阱。

更好地了解 Stream 的工作方式 以及如何将其与其他语言功能结合使用,请查看我们关于 Java Streams 的指南

>> 加入 Pro 并下载电子书

电子书 – Jackson – NPI EA (分类=Jackson)
announcement - icon

用 Jackson 正确处理 JSON

下载电子书

电子书 – HTTP 客户端 – NPI EA (分类=Http 客户端)
announcement - icon

充分利用 Apache HTTP 客户端

下载电子书

电子书 – Maven – NPI EA (分类 = Maven)
announcement - icon

开始使用 Apache Maven

下载电子书

电子书 – 持久化 – NPI EA (分类=持久化)
announcement - icon

您在努力实现正确的持久化层 Spring 吗?

探索电子书

电子书 – RwS – NPI EA (分类=Spring MVC)
announcement - icon

使用 Spring 构建 REST API 吗?

下载电子书

课程 – LS – NPI EA (分类=Jackson)
announcement - icon

通过 Learn Spring 课程开始学习 Spring 和 Spring Boot

>> 学习 SPRING
课程 – RWSB – NPI EA (分类=REST)
announcement - icon

通过构建一个完整的 REST API,深入了解 Spring Boot 3 和 Spring 6,使用该框架

>> 全新的“REST With Spring Boot”

课程 – LSS – NPI EA (分类=Spring Security)
announcement - icon

是的,Spring Security 可能很复杂,从核心内的更高级功能到框架中深入的 OAuth 支持。

我将安全材料构建为 两个完整的课程 - 核心和 OAuth,以针对这些更复杂的场景进行实践。 我们探索何时以及如何使用每个功能,并 在后台项目中对其进行编码

您可以在这里探索该课程

>> 学习 Spring Security

课程 – LSD – NPI EA (标签=Spring Data JPA)
announcement - icon

Spring Data JPA 是处理 JPA 复杂性的绝佳方式,它具有 Spring Boot 的强大简洁性

通过引导式参考课程开始使用 Spring Data JPA

>> 查看课程

合作伙伴 – Moderne – NPI EA (类别=Spring Boot)
announcement - icon

使用 OpenRewrite 安全且自动地重构 Java 代码。

手动重构大型代码库既缓慢、有风险,又容易拖延。OpenRewrite 应运而生。这个用于大规模、自动化代码转换的开源框架可以帮助团队安全、一致地进行现代化改造。

每个月,OpenRewrite 的创建者和维护者 Moderne 都会举办现场、实践培训课程——一个面向初学者,一个面向经验丰富的用户。您将了解配方的运作方式、如何将其应用于项目,以及如何自信地进行代码现代化改造。

参加下一次课程,带来您的问题,并学习如何自动化通常会占用您 sprint 时间的工作。

合作伙伴 – LambdaTest – NPI EA (类别=测试)
announcement - icon

回归测试是发布流程中的重要步骤,以确保新代码不会破坏现有功能。随着代码库的不断发展,我们希望频繁运行这些测试,以便尽早发现任何问题。

确保这些测试以自动化的方式频繁运行的最佳方法当然是将其包含在 CI/CD 管道中。 这样,每次向仓库提交代码时,回归测试将自动执行。

在本教程中,我们将学习如何使用 Selenium 创建回归测试,然后使用 GitHub Actions 将它们包含在我们的管道中,在 LambdaTest 云网格上运行

>> 如何使用 GitHub Actions 运行 Selenium 回归测试

课程 – LJB – NPI EA (类别 = Core Java)
announcement - icon

通过编码方式构建 Java 的坚实、实用的基础

>> 学习 Java 基础

合作伙伴 – LambdaTest – NPI (类别 = 测试)
announcement - icon

回归测试是发布流程中的重要步骤,以确保新代码不会破坏现有功能。随着代码库的不断发展,我们希望频繁运行这些测试,以便尽早发现任何问题。

确保这些测试以自动化的方式频繁运行的最佳方法当然是将其包含在 CI/CD 管道中。 这样,每次向仓库提交代码时,回归测试将自动执行。

在本教程中,我们将学习如何使用 Selenium 创建回归测试,然后使用 GitHub Actions 将它们包含在我们的管道中,在 LambdaTest 云网格上运行

>> 如何使用 GitHub Actions 运行 Selenium 回归测试

课程 – LJU – NPI (标签 = JUnit)
announcement - icon

通过Learn JUnit课程掌握最流行的 Java 测试框架

>> 学习 JUnit

1. 概述

默认情况下,JUnit 使用确定性的但不可预测的顺序运行测试 (MethodSorters.DEFAULT)。

在大多数情况下,这种行为完全可以接受。但有时我们需要强制执行特定顺序。

2. JUnit 5 中测试方法的排序

JUnit 5 中,我们可以使用 @TestMethodOrder 来控制测试的执行顺序。

我们可以使用我们自己的 MethodOrderer,如稍后所示。

或者我们可以选择三个内置排序器中的一个

  1. 字母数字 排序
  2. @Order 注解
  3. 随机顺序

2.1. 使用 字母数字 排序

JUnit 5 包含一组内置的 MethodOrderer 实现,以字母数字顺序运行测试。

例如,它提供了 MethodOrderer.MethodName根据其名称和形式参数列表对测试方法进行排序

@TestMethodOrder(MethodOrderer.MethodName.class)
public class AlphanumericOrderUnitTest {
    private static StringBuilder output = new StringBuilder("");
    
    @Test
    void myATest() {
        output.append("A");
    }
    
    @Test
    void myBTest() {
        output.append("B");        
    }
    
    @Test
    void myaTest() {
        output.append("a");
    }
 
    @AfterAll
    public static void assertOutput() {
        assertEquals("ABa", output.toString());
    }
}

类似地,我们可以使用 MethodOrderer.DisplayName 根据其显示名称按字母数字顺序对方法进行排序。

请记住 MethodOrderer.Alphanumeric 是另一种选择。但是,此实现已被弃用,将在 6.0 中删除。

2.2. 使用 @Order 注解

我们可以使用 @Order 注解来强制测试以特定顺序运行。

在下面的示例中,方法将运行 firstTest(),然后 secondTest(),最后 thirdTest()

@TestMethodOrder(OrderAnnotation.class)
public class OrderAnnotationUnitTest {
    private static StringBuilder output = new StringBuilder("");
    
    @Test
    @Order(1)    
    void firstTest() {
        output.append("a");
    }
    
    @Test
    @Order(2)    
    void secondTest() {
        output.append("b");
    }
 
    @Test
    @Order(3)    
    void thirdTest() {
        output.append("c");
    }
 
    @AfterAll
    public static void assertOutput() {
        assertEquals("abc", output.toString());
    }
}

2.3. 使用 随机顺序

我们还可以使用 MethodOrderer.Random 实现以伪随机方式对测试方法进行排序

@TestMethodOrder(MethodOrderer.Random.class)
public class RandomOrderUnitTest {

    private static StringBuilder output = new StringBuilder("");

    @Test
    void myATest() {
        output.append("A");
    }

    @Test
    void myBTest() {
        output.append("B");
    }

    @Test
    void myCTest() {
        output.append("C");
    }

    @AfterAll
    public static void assertOutput() {
        assertEquals("ACB", output.toString());
    }

}

事实上,JUnit 5 使用 System.nanoTime() 作为默认种子来对测试方法进行排序。 这意味着方法的执行顺序在可重复测试中可能不相同。

但是,我们可以使用 junit.jupiter.execution.order.random.seed 属性配置自定义种子以创建可重复构建。

我们可以在 junit-platform.properties 文件中指定自定义种子的值

junit.jupiter.execution.order.random.seed=100

2.4. 使用自定义顺序

最后,我们可以通过实现 MethodOrderer 接口来使用我们自己的顺序。

在我们的 CustomOrder 中,我们将根据测试名称以不区分大小写的字母数字顺序对测试进行排序

public class CustomOrder implements MethodOrderer {
    @Override
    public void orderMethods(MethodOrdererContext context) {
        context.getMethodDescriptors().sort(
         (MethodDescriptor m1, MethodDescriptor m2)->
           m1.getMethod().getName().compareToIgnoreCase(m2.getMethod().getName()));
    }
}

然后我们将使用 CustomOrder myATest(), myaTest(),最后 myBTest() 的顺序运行我们之前示例中的相同测试

@TestMethodOrder(CustomOrder.class)
public class CustomOrderUnitTest {

    // ...
 
    @AfterAll
    public static void assertOutput() {
        assertEquals("AaB", output.toString());
    }
}

2.5. 设置默认顺序

JUnit 5 提供了通过 junit.jupiter.testmethod.order.default 参数设置默认方法排序器的便捷方法。

同样,我们可以在 junit-platform.properties 文件中配置我们的参数

junit.jupiter.testmethod.order.default = org.junit.jupiter.api.MethodOrderer$DisplayName

默认排序器将应用于所有未通过 @TestMethodOrder 限定的测试。

另一件重要的事情是,指定的类必须实现 MethodOrderer 接口。

3. JUnit 4 中测试方法的排序

对于仍然使用 JUnit 4 的人来说,用于排序测试的 API 略有不同。

让我们也来看看如何在以前的版本中实现这些选项。

3.1. 使用 MethodSorters.DEFAULT

这种默认策略使用它们的哈希码来比较测试方法。

如果发生哈希冲突,则使用词法顺序

@FixMethodOrder(MethodSorters.DEFAULT)
public class DefaultOrderOfExecutionTest {
    private static StringBuilder output = new StringBuilder("");

    @Test
    public void secondTest() {
        output.append("b");
    }

    @Test
    public void thirdTest() {
        output.append("c");
    }

    @Test
    public void firstTest() {
        output.append("a");
    }

    @AfterClass
    public static void assertOutput() {
        assertEquals(output.toString(), "cab");
    }
}

当我们运行上面的类中的测试时,我们会看到它们都通过了,包括 assertOutput()

3.2. 使用 MethodSorters.JVM

另一种排序策略是 MethodSorters.JVM

这种策略利用自然的 JVM 排序,每次运行都可能不同:

@FixMethodOrder(MethodSorters.JVM)
public class JVMOrderOfExecutionTest {    
    // same as above
}

每次我们运行此类中的测试时,都会得到不同的结果。

3.3. 使用 MethodSorters.NAME_ASCENDING

最后,可以使用这种策略以词法顺序运行测试

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class NameAscendingOrderOfExecutionTest {
    // same as above
    
    @AfterClass
    public static void assertOutput() {
        assertEquals(output.toString(), "abc");
    }
}

当我们运行此类中的测试时,我们会看到它们都通过了,包括 assertOutput()。这证实了我们使用注解设置的执行顺序。

4. 使用 @TestClassOrder 对测试类进行排序

我们还可以使用 @TestClassOrder 控制测试类的执行顺序。

Junit 5 带有 ClassOrderer 接口,类似于 MethodOrderer。我们可以像在前面的章节中使用方法排序一样使用它。 ClassOrderer 支持以下测试排序方式

  • ClassName – 根据类名对类进行字母数字排序
  • DisplayName – 根据显示名称对类进行字母数字排序
  • OrderAnnotation – 根据 @Order 注解对类进行排序
  • Random – 对类进行随机排序
  • 自定义顺序 – 根据自定义排序顺序对类进行排序

4.1. 使用 ClassName

它能够按照类别的完全限定类名以字母顺序执行类。 这是基于代码中实际类名的默认排序机制。

让我们定义一些我们将用于运行不同测试的测试类

public class TestA {
    @Test
    void testA() {
        System.out.println("Running TestA");
    }
}

public class TestB {
    @Test
    void testB() {
        System.out.println("Running TestB");
    }
}

public class TestC {
    @Test
    void testC() {
        System.out.println("Running TestC");
    }
}

要使用 @TestClassOrder, 类需要属于同一个层次结构。为此,通过使用 @Nested继承,我们创建了一个灵活的结构,允许我们将测试在套件中进行逻辑分组

@TestClassOrder(ClassOrderer.ClassName.class)
public class ClassNameOrderUnitTest {
    @Nested
    class C extends TestC {}

    @Nested
    class B extends TestB {}

    @Nested
    class A extends TestA {}
}

在上面的示例中,我们创建了一个父测试套件,ClassNameOrderUnitTest,它充当测试类的容器。

@TestClassOrder(ClassOrderer.ClassName.class) 允许我们强制执行字母顺序。运行程序后,输出将是

Running TestA
Running TestB
Running TestC

4.2. 使用 DisplayName

ClassOrderer.DisplayName 如果显式设置,则按其显示名称对类进行排序。 如果我们没有设置任何显示名称,JUnit 将回退到类名。

在下面的示例中,我们将在嵌套包装类上设置 @DisplayName 注解,而不是在原始测试类 TestA、TestB TestC 上:

@TestClassOrder(ClassOrderer.DisplayName.class)
public class DisplayNameOrderUnitTest {
    @Nested
    @DisplayName("Class C")
    class Z extends TestC {}

    @Nested
    @DisplayName("Class B")
    class A extends TestA {}

    @Nested
    @DisplayName("Class A")
    class B extends TestB {}
}

对于上面的程序,JUnit 将按字母顺序对这些显示名称进行排序。 显示名称的排序顺序将是“Class A”、“Class B”和“Class C”,这会导致以下输出

Running TestB
Running TestA
Running TestC

4.3. 使用 OrderAnnotation

@Order 注解允许我们显式定义测试套件中执行测试类的顺序。 当我们想要对执行顺序进行一些显式控制或需要以特定顺序运行测试时,它很有用。

在下面的示例中,@Order 注解指定了嵌套类的优先级

@TestClassOrder(ClassOrderer.OrderAnnotation.class)
public class OrderAnnotationUnitTest {
    @Nested
    @Order(3)
    class A extends TestA {}

    @Nested
    @Order(1)
    class B extends TestB {}

    @Nested
    @Order(2)
    class C extends TestC {}
}

具有较低@Order值的类将首先执行。因此,我们得到以下输出

Running TestB
Running TestC
Running TestA

4.4. 随机

有时,我们希望以随机顺序运行测试,以检测测试之间的依赖关系。这使我们能够确保我们的测试不依赖于执行顺序。

ClassOrderer.Random.class允许我们配置套件,以随机化测试类的执行。 每次测试套件运行时,都会应用这种随机性

@TestClassOrder(ClassOrderer.Random.class)
public class RandomOrderUnitTest {
    @Nested
    class C extends TestC {}

    @Nested
    class B extends TestB {}

    @Nested
    class A extends TestA {}
}

当执行上述测试时,输出将以随机顺序显示,并且每次运行都会有所不同。

运行 1 输出

Running TestA
Running TestC
Running TestB

运行 2 输出

Running TestC
Running TestA
Running TestB

4.5. 使用自定义顺序

我们可以实现自己的ClassOrderer来定义基于元数据、类名长度、配置等标准来排序逻辑。ClassOrderer接口允许我们定义自定义逻辑来基于特定标准对测试类进行排序。

让我们实现一个自定义ClassOrderer,该ClassOrderer根据类名的长度对测试类进行排序

public class CustomClassOrderer implements ClassOrderer {
    @Override
    public void orderClasses(ClassOrdererContext context) {
        context.getClassDescriptors().sort(
            Comparator.comparingInt(descriptor ->
                descriptor.getTestClass().getSimpleName().length()
            )
        );
    }
}

让我们使用CustomClassOrderer根据类名的长度对测试类进行排序。排序顺序将从短到长

@TestClassOrder(CustomClassOrderer.class)
public class CustomOrderUnitTest {
    @Nested
    class Longest extends TestA {}

    @Nested
    class Middle extends TestB {}

    @Nested
    class Short extends TestC {}
}

输出按类名长度排序,即LongestMiddleShort:

Running TestC
Running TestB
Running TestA

由于Short 在这些类中具有最短的名称,因此测试运行器首先执行它,导致“Running TestC”首先出现。随后,测试运行器按顺序执行MiddleLongest类。

5. 结论

在这篇简短的文章中,我们了解了JUnit中可用的设置执行顺序的方法。

支持本文的代码可在 GitHub 上获取。 一旦你Baeldung Pro 会员 身份登录,就开始学习并在项目上进行编码。
Baeldung Pro – NPI EA (类别 = Baeldung)
announcement - icon

Baeldung Pro 具有完全无广告以及最终具有深色模式,提供干净的学习体验

>> 探索干净的 Baeldung

一旦早期采用者的席位全部用完,价格将上涨并保持在每年 33 美元。

电子书 – HTTP 客户端 – NPI EA (类别=HTTP 客户端)
announcement - icon

Apache HTTP Client 是一个非常强大的库,适用于简单和高级用例,在测试 HTTP 端点时尤其适用。 查看我们的指南,涵盖基本请求和响应处理,以及安全性、Cookie、超时等。

>> 下载电子书

电子书 – Java 并发 – NPI EA (分类=Java 并发)
announcement - icon

在应用程序中处理并发可能是一个棘手的过程,其中包含许多 潜在的陷阱。 扎实的掌握基本知识将有助于最大程度地减少这些问题。

通过我们的 Java 并发 指南开始了解多线程应用程序

>> 下载电子书

电子书 – Java Streams – NPI EA (分类=Java Streams)
announcement - icon

自从 Java 8 引入以来,Stream API 已成为 Java 开发的基础。 基本操作,例如迭代、过滤、映射元素序列,使用起来看似很简单。

但这些也可能被过度使用并陷入一些常见陷阱。

更好地了解 Stream 的工作方式 以及如何将其与其他语言功能结合使用,请查看我们关于 Java Streams 的指南

>> 加入 Pro 并下载电子书

电子书 – 持久化 – NPI EA (分类=持久化)
announcement - icon

您在努力实现正确的持久化层 Spring 吗?

探索电子书

课程 – LS – NPI EA (类别=REST)

announcement - icon

从 Spring Boot 开始,通过 Learn Spring 课程了解核心 Spring。

>> 查看课程

合作伙伴 – Moderne – NPI EA (标签=重构)
announcement - icon

现代 Java 团队行动迅速——但代码库并不总是跟上。 框架会发生变化,依赖关系会漂移,技术债务会累积,直到它开始拖慢交付速度。 OpenRewrite 就是为此而构建的:一个开源重构引擎,可在保持开发人员意图不变的同时自动化重复的代码更改。

由 Moderne 的 OpenRewrite 创建者和维护者领导的每月培训系列,将介绍实际的迁移和现代化模式。 无论您是重构配方的新手,还是准备编写自己的配方,您都将学习以安全且可扩展的方式进行重构的实用方法。

如果您曾经希望重构感觉像编写代码一样自然——并且一样快速——这是一个很好的起点

电子书 Jackson – NPI EA – 3 (类别 = Jackson)
© .