wip-6.6
zeroSummary
总结
Output-based testing is a style of testing where you feed an input to the SUT and check the output it produces. This style of testing assumes there are no hidden inputs or outputs, and the only result of the SUT’s work is the value it returns.
基于输出的测试是一种测试风格:你向 SUT 提供输入,并检查它产生的输出。这种测试风格假设不存在隐藏输入或输出,SUT 工作的唯一结果就是它返回的值。State-based testing verifies the state of the system after an operation is completed.
基于状态的测试会在操作完成后验证系统状态。In communication-based testing, you use mocks to verify communications between the system under test and its collaborators.
在基于通信的测试中,你使用 mock 验证被测系统与其协作者之间的通信。The classical school of unit testing prefers the state-based style over the communication-based one. The London school has the opposite preference. Both schools use output-based testing.
单元测试经典学派偏好基于状态的风格,而不是基于通信的风格。伦敦学派偏好相反。两个学派都会使用基于输出的测试。Output-based testing produces tests of the highest quality. Such tests rarely couple to implementation details and thus are resistant to refactoring. They are also small and concise and thus are more maintainable.
基于输出的测试会产出质量最高的测试。这类测试很少耦合到实现细节,因此具备抗重构能力。它们也小而简洁,因此更易维护。State-based testing requires extra prudence to avoid brittleness: you need to make sure you don’t expose a private state to enable unit testing. Because state-based tests tend to be larger than output-based tests, they are also less maintainable. Maintainability issues can sometimes be mitigated (but not eliminated) with the use of helper methods and value objects.
基于状态的测试需要额外谨慎以避免脆弱性:你需要确保不会为了启用单元测试而暴露私有状态。由于基于状态的测试往往比基于输出的测试更大,它们也更难维护。使用辅助方法和值对象有时可以缓解(但不能消除)可维护性问题。Communication-based testing also requires extra prudence to avoid brittleness. You should only verify communications that cross the application boundary and whose side effects are visible to the external world. Maintainability of communication-based tests is worse compared to output-based and state-based tests. Mocks tend to occupy a lot of space, and that makes tests less readable.
基于通信的测试也需要额外谨慎以避免脆弱性。你只应该验证跨越应用边界、且副作用对外部世界可见的通信。与基于输出和基于状态的测试相比,基于通信测试的可维护性更差。Mock 往往占用大量空间,这会降低测试可读性。Functional programming is programming with mathematical functions.
函数式编程就是用数学函数进行编程。A mathematical function is a function (or method) that doesn’t have any hidden inputs or outputs. Side effects and exceptions are hidden outputs. A reference to an internal or external state is a hidden input. Mathematical functions are explicit, which makes them extremely testable.
数学函数是不包含任何隐藏输入或输出的函数(或方法)。副作用和异常是隐藏输出。对内部或外部状态的引用是隐藏输入。数学函数是显式的,因此极易测试。The goal of functional programming is to introduce a separation between business logic and side effects.
函数式编程的目标是在业务逻辑与副作用之间引入分离。Functional architecture helps achieve that separation by pushing side effects to the edges of a business operation. This approach maximizes the amount of code written in a purely functional way while minimizing code that deals with side effects.
函数式架构通过把副作用推到业务操作边缘来帮助实现这种分离。这种方法最大化以纯函数式方式编写的代码量,同时最小化处理副作用的代码。Functional architecture divides all code into two categories: functional core and mutable shell. The functional core makes decisions. The mutable shell supplies input data to the functional core and converts decisions the core makes into side effects.
函数式架构把所有代码分为两类:函数式核心和可变壳。函数式核心做出决策。可变壳向函数式核心提供输入数据,并把核心做出的决策转换为副作用。The difference between functional and hexagonal architectures is in their treatment of side effects. Functional architecture pushes all side effects out of the domain layer. Conversely, hexagonal architecture is fine with side effects made by the domain layer, as long as they are limited to that domain layer only. Functional architecture is hexagonal architecture taken to an extreme.
函数式架构与六边形架构的区别在于它们对副作用的处理。函数式架构把所有副作用都推出领域层。相反,六边形架构允许领域层产生副作用,只要这些副作用仅限于领域层内部。函数式架构是走向极致的六边形架构。The choice between a functional architecture and a more traditional one is a trade-off between performance and code maintainability. Functional architecture concedes performance for maintainability gains.
在函数式架构和更传统架构之间选择,是性能与代码可维护性之间的取舍。函数式架构用性能换取可维护性收益。Not all code bases are worth converting into functional architecture. Apply functional architecture strategically. Take into account the complexity and the importance of your system. In code bases that are simple or not that important, the initial investment required for functional architecture won’t pay off.
并非所有代码库都值得转换为函数式架构。要战略性地应用函数式架构。请考虑系统的复杂性和重要性。对于简单或不太重要的代码库,函数式架构所需的初始投入不会得到回报。