从零到生产:Kotlin应用的端到端测试

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

为什么端到端测试是你最好的朋友(以及如何在Kotlin中与它交朋友)

\n\n

想象一下:你写了一个很棒的Kotlin服务,一切编译通过,单元测试全部通过,代码审查也完成了。你部署到生产环境,然后……用户抱怨“购买”按钮不工作,尽管单元测试已经测试过它。熟悉吗?欢迎来到一个Kotlin应用端到端测试不是奢侈品,而是必需品的世界。

\n\n

端到端测试是对整个用户路径的检查:从点击按钮到数据库写入再返回。在本文中,我们不只是谈论理论。我们将为Kotlin应用编写真实的测试,分析各种工具,并展示如何在配置基础设施时保持理智。系好安全带,会有代码和咖啡。

\n\n

什么是端到端测试,它与其他类型的测试有何不同

\n\n

让我们立即澄清这一点。端到端测试从用户的角度全面检查系统。与以下测试不同:

\n\n
    \n
  • 单元测试——隔离地测试单个方法/类。
  • \n
  • 集成测试——测试两到三个组件之间的交互(例如,控制器+服务)。
  • \n
  • UI测试——经常与端到端测试混淆,但UI测试可能不检查后端,只检查界面渲染。
  • \n
\n\n

Kotlin应用的端到端测试是一个完整的周期:用户界面(如果有)、API、业务逻辑、数据库、外部服务。所有部分必须像钟表一样协同工作。

\n\n

Kotlin端到端测试工具

\n\n

工具的选择取决于你测试的内容:Android应用、Ktor Web服务还是桌面应用。以下是Kotlin开发者的首选:

\n\n
    \n
  • Selenide + Kotlin——用于Web界面。它是Selenium的封装,但语法简洁,非常适合Kotlin。
  • \n
  • Ktor Client + TestContainers——用于后端。在Docker中启动测试基础设施(数据库、缓存)并发送HTTP请求。
  • \n
  • Espresso + Compose Test——用于Android。随Android SDK提供的原生工具。
  • \n
  • Cucumber + Kotlin——如果需要用客户能理解的语言编写BDD场景。
  • \n
\n\n

我们将专注于前两个场景,因为它们最通用。

\n\n

为Kotlin Web应用编写端到端测试(Selenide)

\n\n

假设我们有一个基于Spring Boot + Kotlin的简单在线商店。我们需要测试一个场景:用户访问网站,将商品添加到购物车,并完成结账。

\n\n

首先,在build.gradle.kts中添加依赖项:

\n\n
dependencies {\n    testImplementation("com.codeborne:selenide:6.19.1")\n    testImplementation("org.junit.jupiter:junit-jupiter:5.10.0")\n    testImplementation("io.github.bonigarcia:webdrivermanager:5.6.2")\n}
\n\n

现在编写测试本身。请注意:我们使用Kotlin的扩展函数使代码更具可读性:

\n\n
import com.codeborne.selenide.Condition.visible\nimport com.codeborne.selenide.Selenide.`$`\nimport com.codeborne.selenide.Selenide.open\nimport org.junit.jupiter.api.BeforeEach\nimport org.junit.jupiter.api.Test\n\nclass ShopE2ETest {\n\n    @BeforeEach\n    fun setUp() {\n        // 在每个测试之前打开浏览器\n        open("https://test-shop.example.com")\n    }\n\n    @Test\n    fun `user can add product to cart and checkout`() {\n        // 步骤1:找到商品并添加到购物车\n        `$`("[data-testid='product-1']").shouldBe(visible).click()\n        `$`("[data-testid='add-to-cart']").click()\n\n        // 步骤2:检查购物车不为空\n        `$`("[data-testid='cart-badge']").shouldHave(text("1"))\n\n        // 步骤3:前往结账\n        `$`("[data-testid='checkout-btn']").click()\n\n        // 步骤4:填写表单\n        `$`("[                

博客

书籍推荐