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

javascriptjavascript
function logDivider() {
  console.log("----------");
}

logDivider();

2. Parameters

javascriptjavascript
function logSum(left, right) {
  console.log(left + right);
}

logSum(10, 20);

3. Default parameters

If an argument is missing or undefined, the default applies.

javascriptjavascript
function logSquare(base = 0) {
  console.log(base ** 2);
}

logSquare(4); // 16
logSquare();  // 0

4. return and nested calls

javascriptjavascript
function toSquare(n) {
  return n ** 2;
}

let nested = toSquare(toSquare(3));
console.log(nested); // ((3^2)^2) = 81

5. Function that loops internally

javascriptjavascript
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

javascriptjavascript
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.

javascriptjavascript
console.log(early()); // works

function early() {
  return "hoisted";
}

Function expression

javascriptjavascript
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).

javascriptjavascript
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.

javascriptjavascript
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.

javascriptjavascript
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.

javascriptjavascript
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 true to keep it or false to skip it
  • Output: new array (possibly shorter than the original)

map vs filter in one QA example

javascriptjavascript
const failedTestNames = testResults
  .filter((result) => result.status === "failed")
  .map((result) => result.name);

console.log(failedTestNames);
// ["checkout"]
MethodKeeps same length?Typical QA use
mapYesExtract IDs, emails, URLs from objects
filterNo (usually)Keep only failed cases, active users

Official docs


Quick recap

PatternUse case
function foo() {}Top-level helpers, hoisted name
Default arg = 1Optional timeout, retries, flags
returnFeed expect, assign to const
const fn = () => {}Short helpers, compact callbacks
HOF (map, filter)Transform or narrow arrays of test data

Suggested exercises

  1. Create a function clamp(n, min, max) that returns n, but never smaller than min and never larger than max.
  2. Create a function buildUrl(host, path) where path automatically becomes "/" if no value is provided.
  3. Rewrite the function sumOneToFive into sumUpTo(max) with a default value of 10. Log the function result to the console.
  4. In one or two sentences, explain why some teams prefer const fn = () => {} instead of function fn() {}.
  5. Given const results = [{ name: "login", status: "passed" }, { name: "checkout", status: "failed" }], use filter then map to 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 = "") {})