Arrays — Storing Lists of Test Data

8 min read

Test data is rarely a single value. You have a list of browsers to test against, a list of accepted status codes, a list of test users with different roles. The structure that holds those lists in JavaScript is the array — an ordered collection of values you can index into, walk through, add to, and shrink. This lesson covers the syntax, the operations, and the 0-based-index detail that catches every beginner once.

Creating an array

The most common way to make an array is the literal syntax — square brackets with comma-separated values:

const browsers = ["Chrome", "Firefox", "Safari", "Edge"];
console.log(browsers);

Output:

[ 'Chrome', 'Firefox', 'Safari', 'Edge' ]

Empty arrays are useful when you'll add items later:

const failures = [];
console.log(failures.length);  // 0

Arrays can technically hold mixed types — [200, "OK", true] is legal — but in test code you almost always want one consistent type per array. Mixed-type arrays make it harder to use the array methods you'll meet in the next lesson.

Indexing — and the 0-based gotcha

You access items by their index — a number in square brackets. JavaScript counts from 0, not 1:

const browsers = ["Chrome", "Firefox", "Safari", "Edge"];
 
console.log(browsers[0]);  // Chrome   ← first item
console.log(browsers[1]);  // Firefox
console.log(browsers[2]);  // Safari
console.log(browsers[3]);  // Edge     ← last item
console.log(browsers[4]);  // undefined ← past the end

The array has 4 items, but their indices run from 0 to 3. The first item is index 0, the last item is index length-1. Forgetting that off-by-one is the source of a vast number of beginner bugs — and a few experienced ones too.

Negative indices don't work in JavaScript the way they do in some other languages — browsers[-1] returns undefined, not the last item. To get the last item, use browsers[browsers.length - 1] or the modern browsers.at(-1).

Length

.length is the number of items in the array — not the highest index, but the count.

const browsers = ["Chrome", "Firefox", "Safari"];
console.log(browsers.length);  // 3

length is also writable. Setting arr.length = 0 empties the array; setting it shorter than the current length truncates. You'll rarely need this in test code, but it's a useful trick to know about.

Adding and removing items

Four built-in methods cover the four corners — adding/removing at the start/end of the array:

const queue = ["login", "checkout"];
 
queue.push("logout");        // add to end:    ["login", "checkout", "logout"]
queue.unshift("setup");      // add to start:  ["setup", "login", "checkout", "logout"]
const last = queue.pop();    // remove end:    "logout" — array now ["setup", "login", "checkout"]
const first = queue.shift(); // remove start:  "setup"  — array now ["login", "checkout"]
 
console.log(queue);

Output:

[ 'login', 'checkout' ]

For a more surgical insert/remove, splice operates at a specific index:

const tests = ["login", "checkout", "logout"];
tests.splice(1, 1);  // at index 1, remove 1 item
console.log(tests);  // ["login", "logout"]
 
tests.splice(1, 0, "search");  // at index 1, remove 0 items, insert "search"
console.log(tests);  // ["login", "search", "logout"]

splice mutates the array in place. If you need a non-mutating version, use the spread operator (covered two lessons from now).

Searching — includes and indexOf

To check whether something is in an array, includes returns a boolean:

const acceptedStatuses = [200, 201, 204];
console.log(acceptedStatuses.includes(200));  // true
console.log(acceptedStatuses.includes(404));  // false

To find where an item is, indexOf returns the index — or -1 if it isn't there:

const browsers = ["Chrome", "Firefox", "Safari"];
console.log(browsers.indexOf("Firefox"));  // 1
console.log(browsers.indexOf("Opera"));    // -1

includes was added later for exactly this readability win — arr.indexOf(x) !== -1 is uglier than arr.includes(x). Use includes when you only need a yes/no answer.

Both use strict equality (===) under the hood, so the type-coercion warnings from chapter 2 still apply: [200].includes("200") is false.

A real test fixture as an array

The shape of test data you'll actually see — an array of objects, each representing one test case.

const testCases = [
  { name: "login",     suite: "auth",      priority: "P1" },
  { name: "checkout",  suite: "commerce",  priority: "P0" },
  { name: "search",    suite: "discovery", priority: "P2" },
  { name: "logout",    suite: "auth",      priority: "P2" }
];
 
console.log(testCases.length);          // 4
console.log(testCases[0].name);         // "login"   — array index, then object key
console.log(testCases[1].priority);     // "P0"

Two layers — array indexing (testCases[1]) gets you the object, then object access (.priority) gets you the field. This nested shape is where 90% of test data lives.

A look at the structure

(The bars encode priority — a higher number means lower priority. The labels carry the array index, the test name, and the priority — all the bits that matter when reading a test fixture at a glance.)

⚠️ Common mistakes

  • Using index 1 to mean "the first item." Index 1 is the second item. The first item lives at index 0. The same off-by-one bites in for loop bounds: i <= arr.length reads one past the end.
  • Mixing types in a single array. [200, "OK", true] is legal but confuses every array method that follows. Keep arrays homogeneous in test code — an array of status codes, an array of user objects, an array of test names.
  • Forgetting that splice mutates. arr.splice(0, 1) modifies arr in place. If something else has a reference to the same array, that reference now sees the change. Be deliberate when you mutate; consider [...arr].splice(...) or the modern toSpliced to avoid it.

🎯 Practice task

Build a small list of test users. 15-20 minutes.

  1. In your js-for-qa folder, create users.js.
  2. Declare a const users = [] (empty array).
  3. Use push to add 4 user objects, each with { name, role }. Mix the roles: at least one admin, two members, one guest.
  4. Print users.length and each user with their index — console.log(0, users[0]), etc.
  5. Build an array of just the names: const names = users.map(u => u.name);. Use names.includes("Alice") to check whether Alice is in the list. (includes does strict equality, so it works on primitive strings but not on object literals.)
  6. Use splice to remove the second user. Print the array again.
  7. Stretch: print the last user using users.length - 1 and again using users.at(-1). Confirm both give the same result. Then try users[-1] — confirm it returns undefined (not the last item).

The next lesson introduces the array methods that replace most for-loops in test code: forEach, map, filter, and find.

// tip to track lessons you complete and pick up where you left off across devices.