Lesson 7 of 14
Lesson 07 — Functions for QA automation
Title: Declarations, Parameters, Defaults, return, and Function Expressions
Description: Test code is often split into small reusable functions, such as helpers for parsing cookies, building URLs, retry logic, or reusable checks. This lesson covers function declarations, parameters, default values, return statements, function composition, and function expressions stored in const. It also explains how hoisting works for function declarations and not for function expressions.
Why it matters for QA: Reusable functions reduce duplication and keep test logic consistent. Default parameters help handle optional test data, and return values allow helpers to be used directly inside assertions like expect(...).
1. Simple declaration and call
function logDivider() {
console.log("----------");
}
logDivider();
2. Parameters
function logSum(left, right) {
console.log(left + right);
}
logSum(10, 20);
3. Default parameters
If an argument is missing or undefined, the default applies.
function logSquare(base = 0) {
console.log(base ** 2);
}
logSquare(4); // 16
logSquare(); // 0
4. return and nested calls
function toSquare(n) {
return n ** 2;
}
let nested = toSquare(toSquare(3));
console.log(nested); // ((3^2)^2) = 81
5. Function that loops internally
function sumOneToFive() {
let acc = 0;
for (let i = 1; i <= 5; i++) {
acc += i;
}
return acc;
}
console.log(sumOneToFive()); // 15
6. Difference between declarations
Two common ways to define a function are a function declaration and a function expression.
Function declaration
function greet(name) {
return `Hello, ${name}`;
}
console.log(greet("QA"));
A function declaration is hoisted — the name exists for the whole scope before execution reaches the line where it is written.
console.log(early()); // works
function early() {
return "hoisted";
}
Function expression
const greet = function (name) {
return `Hello, ${name}`;
};
console.log(greet("QA"));
The function value is stored in a variable. With const or let, calling greet() before that line throws (temporal dead zone / ReferenceError).
let ping = function () {
console.log("pong");
};
ping();
Difference: a declaration hoists the function name; an expression assigns the function value only when execution reaches that line.
7. Arrow function
Arrow functions are another const-bound expression form. Use a block body when you need multiple statements; for a single expression you can omit {} and return.
const logSum = (left, right) => {
console.log(left + right);
};
logSum(10, 20);
const toSquare = (n) => n ** 2;
console.log(toSquare(4)); // 16
Like other const bindings, an arrow function is not callable until its line runs.
8. Higher-order functions: map and filter
A higher-order function (HOF) is a function that either:
- takes another function as an argument, or
- returns a function.
In QA automation you use HOFs every day when you transform lists of test data or API results.
Array.prototype.map
map creates a new array with the same length as the original. Each element is the return value of your callback.
const users = [
{ id: 1, email: "admin@example.com" },
{ id: 2, email: "viewer@example.com" },
];
const emails = users.map((user) => user.email);
console.log(emails);
// ["admin@example.com", "viewer@example.com"]
Operational reading:
- Input: array of items
- Callback: receives one item, returns one transformed value
- Output: new array (original array is not changed)
Array.prototype.filter
filter creates a new array that contains only items where the callback returns a truthy value.
const testResults = [
{ name: "login", status: "passed" },
{ name: "checkout", status: "failed" },
{ name: "profile", status: "passed" },
];
const failedResults = testResults.filter((result) => {
return result.status === "failed";
});
console.log(failedResults);
// [{ name: "checkout", status: "failed" }]
Operational reading:
- Input: array of items
- Callback: receives one item, returns
trueto keep it orfalseto skip it - Output: new array (possibly shorter than the original)
map vs filter in one QA example
const failedTestNames = testResults
.filter((result) => result.status === "failed")
.map((result) => result.name);
console.log(failedTestNames);
// ["checkout"]
| Method | Keeps same length? | Typical QA use |
|---|---|---|
map | Yes | Extract IDs, emails, URLs from objects |
filter | No (usually) | Keep only failed cases, active users |
Official docs
Quick recap
| Pattern | Use case |
|---|---|
function foo() {} | Top-level helpers, hoisted name |
Default arg = 1 | Optional timeout, retries, flags |
return | Feed expect, assign to const |
const fn = () => {} | Short helpers, compact callbacks |
HOF (map, filter) | Transform or narrow arrays of test data |
Suggested exercises
- Create a
function clamp(n, min, max)that returnsn, but never smaller thanminand never larger thanmax. - Create a
function buildUrl(host, path)where path automatically becomes"/"if no value is provided. - Rewrite the function
sumOneToFiveintosumUpTo(max)with a default value of10. Log the function result to the console. - In one or two sentences, explain why some teams prefer
const fn = () => {}instead offunction fn() {}. - Given
const results = [{ name: "login", status: "passed" }, { name: "checkout", status: "failed" }], usefilterthenmapto build an array of failed test names.
Homework
Short tasks (about 10–15 minutes). Click a task title to reveal the prompt.
Task 1: clamp
Write function clamp(value, min, max) that returns value if it is between min and max inclusive; if below min, return min; if above max, return max.
Test:
clamp(5, 0, 10)clamp(-3, 0, 10)clamp(99, 0, 10)
Task 2: sum from 1 to N
Create a function sumFromOneTo(n = 10) that calculates and returns the sum of all integers from 1 to n using a loop inside the function.
After that:
- log the result of
sumFromOneTo() - log the result of
sumFromOneTo(4)to the console.
Task 3: boolean helper
Create a function isPassing(score, min = 60) that checks whether a given score is greater than or equal to min.
The function should return true if score >= min
Otherwise, it should return false
After defining the function, log the results for:
isPassing(55)isPassing(72)
Task 4: nested calls
Rewrite or reuse the function toSquare(n) from the lesson.
Then calculate and log the result of toSquare(toSquare(2)).
Task 5: expression binding
Assign a function expression to const echo = function (x) { return x; }; and log echo("ping").
In one sentence, explain why echo cannot be called on a line above where it is declared.
Task 6: validate input early
Write a function normalizePort(port) that first checks the input:
If port is not a number, return null immediately (early return)
Otherwise return Math.trunc(port) to remove the decimal part.
( if (typeof port !== "number"){} )
Task 7: options object parameter
Write function makeRequestUrl(host, path = "/") that returns host + path. Call it with two arguments and with one argument only.
Task 8: expression with default argument
Assign a function expression to const toUpper that converts text to uppercase and uses a default empty string:
(function (text = "") {})