Lesson 2 of 14
Lesson 02 — Arrays for QA automation
Title: Ordered Lists, Indexing, Length, and Safe Updates
Description: Arrays are used to store values in order, such as test data rows, API results, lines from a file, or related UI elements. This lesson shows how to access and update elements using indexes, how to add items with push, and why using delete for array items is usually not a good idea.
Why it matters for QA: In tests, you often compare lists (expect(actual).toEqual(expected)). Knowing how length works, how to get the last item, and how arrays behave helps you understand bugs like unexpected array size or missing values (undefined).
How to practice: Run snippets in the browser console or Node.
1. Creating arrays
An array is an ordered list. Elements can be any type.
let empty = [];
let tags = ["smoke", "regression", "api"];
console.log(tags);
let mixed = [1, 2, "ok", "fail", null, true, false];
console.log(mixed);
2. Indexing (0-based)
First element is at index 0.
let steps = ["open", "login", "assert"];
console.log(steps[0]); // "open"
console.log(steps[1]); // "login"
console.log(steps[2]); // "assert"
3. Length and last element
let ids = ["u-100", "u-101", "u-102"];
console.log(ids.length); // 3
console.log(ids[ids.length - 1]); // "u-102"
4. Replacing and updating elements
Unlike strings, array slots are mutable—you assign a new value to a position.
let statuses = ["pending", "pending", "done"];
statuses[0] = "failed";
console.log(statuses); // ["failed", "pending", "done"]
5. Updating string elements in the array
Each element is still a string: you replace the whole element, not one character inside it.
let names = ["suite", "case", "step"];
names[0] = names[0] + "A";
names[1] = names[1] + "B";
names[2] = names[2] + "C";
console.log(names);
let labels = ["a", "b", "c"];
labels[0] += "!";
labels[1] += "!";
labels[2] += "!";
console.log(labels);
6. Increment and decrement on numeric elements
let counts = [2, 3, 4, 5];
counts[0]++;
++counts[1];
counts[2]--;
--counts[3];
console.log(counts); // [3, 4, 3, 4]
7. Growing by index
You can assign past the current end; missing indices become empty slots (sparse array).
let row = [];
row[0] = "id";
row[1] = "name";
row[2] = "role";
console.log(row);
Sparse gap (easy to create by mistake):
let letters = ["x", "y", "z"];
letters[5] = "!";
console.log(letters);
// ["x", "y", "z", empty × 2, "!"] — indices 3 and 4 are holes
console.log(letters[3]); // undefined
8. push — add to the end
Preferred way to append.
let queue = [];
queue.push("first");
queue.push("second");
queue.push("third");
console.log(queue);
9. Pitfall: using delete to remove an element by index
delete arr[i] removes the property at that index but does not shift the remaining elements. The array’s length stays the same, so you end up with a hole (an empty slot), not a shorter array.
let items = ["alpha", "beta", "gamma"];
delete items[1];
console.log(items); // [ 'alpha', <1 empty item>, 'gamma' ]
console.log(items.length); // still 3
Better patterns for QA code:
- Remove by index and re-pack:
items.splice(1, 1) - Or build a new array:
items.filter(item => item !== "gamma")
10. Finding values: indexOf and lastIndexOf
When the same value appears more than once (for example duplicate "done" in a status log), indexOf returns the first index and lastIndexOf returns the last. Both return -1 if the value is not in the array.
let statuses = ["done", "new", "running", "done"];
console.log(statuses.indexOf("done")); // 0
console.log(statuses.lastIndexOf("done")); // 3
QA note: Use these when you need the position of an item before splice, or to check that a string appears at least once (indexOf("error") !== -1).
11. Non-destructive ranges: slice
slice(start, end) returns a new array from start up to but not including end. The original array is unchanged—handy for taking a subset to assert on without mutating test data.
let statuses = ["done", "new", "running", "done"];
console.log(statuses.slice(0, 2)); // ["done", "new"]
console.log(statuses.slice(1, 3)); // ["new", "running"]
console.log(statuses.slice(0, 1)); // ["done"]
QA note: slice(0, 1) has length 1 (only index 0). End index is exclusive, same rule as in many APIs.
Official docs
Quick recap
| Topic | Takeaway |
|---|---|
arr[i] | 0-based; read and write slots |
length | Not always “count of defined values” if the array is sparse |
push | Append; keeps indices contiguous |
delete | Leaves holes; usually wrong for “remove this list item” |
indexOf / lastIndexOf | First / last index of a value; -1 if missing |
slice | New sub-array; original unchanged; end index is exclusive |
Suggested exercises
- Given
let runs = [10, 20, 30];, log the sum of first and last element without hard-coding30. - Start with
[]andpushthree test names; then replace the middle one with"skipped". - Predict the output of
let a = [1]; a[3] = 2; console.log(a.length, a[1]);. - Rewrite the
deleteexample usingspliceso the array becomes["alpha", "gamma"]with length2.
Homework
Short tasks (about 10–15 minutes). Click a task title to reveal the prompt.
Task 1: first plus last
Create an array of five numbers. Log the sum of the first and last elements without hard-coding the last index (use length).
Task 2: build a tiny suite list
Start with [], push three test case names, replace the middle one with "skipped", then log the whole array.
Task 3: sparse length
Run let a = ["x"]; a[3] = "y"; and log a.length and a[1]. In one sentence, explain why a[1] looks like that.
Task 4: pop vs shift
Create let tailDemo = ["a", "b", "c"], call pop() once, log tailDemo. Separately create let headDemo = ["a", "b", "c"], call shift() once, log headDemo. In one sentence, say which end each method removes from.
Task 5: increment a slot
Given let counts = [1, 2, 3], increment only index 1 using ++ on the element, then log counts.
Task 6: splice instead of delete
Turn ["alpha", "beta", "gamma"] into ["alpha", "gamma"] with splice (length must be 2). Log the result.
Task 7: empty check
Declare let queue = [] and log whether queue.length === 0 is true. Then push one item and log the same check again.
Task 8: clone before update
Create let queue = ["A", "B", "C"]. Remove the first item with shift(), add "D" with push(), then log the final array.
Task 9: position of an element
Create let statuses = ["new", "running", "done"]. Log the second element by index, then replace it with "skipped" and log the array.
Task 10: Removing the last element with .pop()
Create let values = [10, 20, 30, 40]. Remove the last element with pop(), then log the new length and the array itself.