36 / 80 · 12 Programming for QA · Functional Patterns for Testing← prev⊞ allnext →☰ Read as one page
5.2Map, Filter, and Reduce
These three operations form the core of functional data processing. They replace explicit loops with declarative transformations.
Python
# map: transform each item
responses = [requests.get(f"{base_url}/users/{i}") for i in range(1, 11)]
status_codes = list(map(lambda r: r.status_code, responses))
# [200, 200, 404, 200, 500, ...]
# filter: keep items matching a condition
errors = list(filter(lambda r: r.status_code >= 500, responses))
assert len(errors) == 0, f"Server errors found: {[r.url for r in errors]}"
# reduce: aggregate into a single value
from functools import reduce
total_time = reduce(lambda acc, r: acc + r.elapsed.total_seconds(), responses, 0)
print(f"Total request time: {total_time:.2f}s")
# Pythonic alternatives (often preferred)
status_codes = [r.status_code for r in responses] # list comprehension > map
errors = [r for r in responses if r.status_code >= 500] # comprehension > filter
total_time = sum(r.elapsed.total_seconds() for r in responses) # sum > reduce
JavaScript/TypeScript
const responses = await Promise.all(
Array.from({ length: 10 }, (_, i) => fetch(`${baseUrl}/users/${i + 1}`))
);
// map
const codes = responses.map(r => r.status);
// [200, 200, 404, 200, 500, ...]
// filter
const errors = responses.filter(r => r.status >= 500);
expect(errors).toHaveLength(0);
// reduce
const totalTime = responses.reduce((acc, r) => acc + r.duration, 0);
// Chaining: filter, then map, then reduce
const errorMessages = responses
.filter(r => r.status >= 400)
.map(r => `${r.status}: ${r.url}`)
.join("\n");