Kotlin 中的 BDD:编写管理者和开发者都能读懂的测试
\n\n你是否曾向产品经理展示过 单元测试?很可能没有。因为这就像向飞行员展示喷气发动机图纸——有用,但难以理解。行为驱动开发 (BDD) 在 Kotlin 中恰好解决了这个问题:它将枯燥的断言转变为描述系统行为的人类语言场景。
\n\n在本文中,我们将探讨如何使用现代框架——Kotest 和 Spek——来实现 Kotlin 中的 BDD。你会看到如何以 Given-When-Then 风格编写测试,这些测试既是文档,也是自动化验证。没错,即使是没有受过专门培训的团队负责人也能读懂它们。
\n\n什么是 BDD,它与 TDD 有何不同?
\n\n很多人混淆了 TDD(测试驱动开发) 和 BDD(行为驱动开发)。区别很简单:
\n\n- \n
- TDD 关注的是“我如何验证这个方法?” \n
- BDD 关注的是“用户如何从这个功能中获得价值?” \n
行为驱动开发 关注的是系统行为,而非实现细节。你描述一个场景:给定某些条件(Given),当某个动作发生时(When),系统产生预期结果(Then)。
\n\n例如,与其写:assertEquals(42, calculator.add(20, 22)),
不如写:
Given("I have a calculator") {\n val calc = Calculator()\n When("I add 20 and 22") {\n val result = calc.add(20, 22)\n Then("the result should be 42") {\n result shouldBe 42\n }\n }\n}\n\n\n你会同意,第二个选项读起来像故事,而不是技术说明。
\n\n为什么 Kotlin 是 BDD 的理想选择
\n\nKotlin 是一种天生适合编写可读代码的语言。扩展函数、中缀表示法、带接收者的 lambda——所有这些都使得 Kotlin 中的 BDD 测试 尽可能自然。你可以编写 shouldBe、shouldThrow 和其他看起来像英语的匹配器。
此外,Kotlin 支持多种范式,允许你使用不同的 BDD 框架。让我们看看两个最流行的框架。
\n\nKotest 框架:开箱即用的 BDD
\n\nKotest(原名 KotlinTest)是一个强大的多平台测试框架。它支持多种风格,包括非常适合 BDD 的 BehaviorSpec。
\n\n以下是使用 Kotest 的完整 Kotlin BDD 场景 示例:
\n\nimport io.kotest.core.spec.style.BehaviorSpec\nimport io.kotest.matchers.shouldBe\n\nclass CartSpec : BehaviorSpec({\n given("an empty cart") {\n val cart = ShoppingCart()\n `when`("adding an item with a price of 100") {\n cart.addItem(Item("Book", 100.0))\n then("the cart should have 1 item") {\n cart.itemCount shouldBe 1\n }\n then("the total should be 100") {\n cart.total shouldBe 100.0\n }\n }\n `when`("adding an item and applying a 10% discount") {\n cart.addItem(Item("Book", 100.0))\n cart.applyDiscount(10.0)\n then("the final total should be 90") {\n cart.total shouldBe 90.0\n }\n }\n }\n})\n\n\n注意 when 周围的反引号。这是 Kotlin 的一个特性:when 是一个保留字,但在反引号中它可以作为标识符使用。有些开发者更喜欢使用大写的 When。
Spek:适用于 Kotlin 的结构化 BDD
\n\nSpek