
資料內(nèi)容:
Categories 
Fitness functions exist across a variety of categories related to their scope, cadence, result, 
invocation, proactivity, and coverage. 
Scope: Atomic Versus Holistic 
Atomic fitness functions run against a singular context and exercise one particular aspect of the 
architecture. An excellent example of an atomic fitness function is a unit test that verifies some 
architectural characteristic, such as modular coupling (we show an example of this type of fitness 
function in Chapter 4). Thus, some application-level testing falls under the heading of fitness 
functions, but not all unit tests serve as fitness functions—only the ones that verify architecture 
characteristic(s). The example in Figure 2-3 represents an atomic fitness function: it checks only 
for the presence of cycles between components. 
For some architectural characteristics, developers must test more than each architectural 
dimension in isolation. Holistic fitness functions run against a shared context and exercise a 
combination of architectural aspects. Developers design holistic fitness functions to ensure that 
combined features that work atomically don’t break in real-world combinations. For example, 
imagine an architecture has fitness functions around both security and scalability. One of the key 
items the security fitness function checks is staleness of data, and a key item for the scalability 
tests is number of concurrent users within a certain latency range. To achieve scalability, 
developers implement caching, which allows the atomic scalability fitness function to pass. 
When caching isn’t turned on, the security fitness function passes. However, when run 
holistically, enabling caching makes data too stale to pass the security fitness function, and the 
holistic test fails. 
We obviously cannot test every possible combination of architecture elements, so architects use 
holistic fitness functions selectively to test important interactions. This selectivity and 
prioritization also allows architects and developers to assess the difficulty in implementing a 
particular testing scenario, thus allowing an assessment of how valuable that characteristic is. 
Frequently, the interactions between architectural concerns determine the quality of the 
architecture, which holistic fitness functions address.Cadence: Triggered Versus Continual Versus Temporal 
Execution cadence is another distinguishing factor between fitness functions. Triggered fitness 
functions run based on a particular event, such as a developer executing a unit test, a deployment 
pipeline running unit tests, or a QA person performing exploratory testing. This encompasses 
traditional testing, such as unit, functional, and behavior-driven development (BDD) testing, 
among others. 
Continual tests don’t run on a schedule but instead execute constant verification of architectural 
aspect(s), such as transaction speed. For example, consider a microservices architecture in which 
the architects want to build a fitness function around transaction time—how long it takes for a 
transaction to complete, on average. Building any kind of triggered test provides sparse 
information about real-world behavior. Thus, architects build a continual fitness function that 
simulates a transaction in production while all the other real transactions run, often using a 
technique called synthetic transactions. This allows developers to verify behavior and gather real 
data about the system “in the wild.” 
 
                