Git & the Command Line
The moment your tests become code, they need to live somewhere a team can share, track, and undo — and you reach that place through a terminal. This lesson teaches you to get around the command line and use the handful of Git commands you will run every day.
1 The Hook
Mere had just written her first proper batch of automated tests for a Dunedin council web app — a week of work, twelve solid tests. She kept them in a folder on her laptop. On Friday she tidied up, renamed some files, deleted a couple she thought were duplicates, and saved over an old version to “keep things clean.” On Monday she realised two of the tests she had deleted were the only ones covering a tricky rates-payment edge case. They were gone. No recycle bin, no backup, no way to get them back. A week’s thinking, lost to a Friday tidy-up.
Across the room, a developer shrugged when she explained. “If they were in Git, you’d just roll back.” Every change he made to code was recorded — every version saved, every deletion reversible, every line traceable to who wrote it and why. He could stand on any point in the project’s history and walk back to it. Mere had been treating test code like a Word document; he was treating it like code, with a full, undoable history.
There was a second problem she had not even noticed yet. Her tests lived only on her laptop. Nobody else on the team could run them, review them, or build on them. The moment test work becomes a team asset — shared, reviewed, run on a build server — it has to live somewhere central, and that somewhere is a Git repository.
Here is the lesson hidden in that story: as soon as your tests are code, “a folder on my laptop” is not good enough. You need version control to track and undo changes, and a shared repository so the team can work together. Git gives you both, and you reach it through the command line. That is what this lesson teaches.
2 The Rule
Test code is code, so it belongs in version control — not a folder on your laptop. Git records every change so nothing is ever truly lost and the team can share one source of truth. You drive it from a terminal with a small set of commands you will use every day: get around, save your changes, share them, and pull in everyone else’s.
3 The Analogy
A tramping hut logbook in the Tararuas.
In a backcountry hut there is a logbook by the door. Every party that passes through signs it: who came in, when, which way they were headed, and a note about conditions. Anyone arriving later can read the whole history — who was here, what they did, what to watch out for. If someone goes missing, search and rescue can trace exactly where they were and when, because every entry is dated and signed.
A Git repository is that logbook for your test code. Every commit is a signed, dated entry: this change, by this person, for this reason. The whole team reads from and writes to the same logbook, so everyone knows the current state and the full history. And because every entry is preserved, you can always walk back to how things were — the thing Mere desperately needed and her laptop folder could not give her.
4 The Terminal — Getting Around
The terminal (also called the command line) is a text window where you type commands instead of clicking. It feels intimidating at first, but for our purposes it is just a way to move between folders and run Git. The two commands you need to get around are tiny:
dir or also ls.cd folder-name — change directory: move into a folder.
cd .. — move up one folder (the two dots mean “the folder above”).
pwd — print working directory: show which folder you are in right now, if you get lost.
A typical opening move when you sit down to work looks like this — read it as “list what’s here, move into the tests folder, confirm where I am, list again”:
cd council-app-tests
pwd
ls
That is the whole of “getting around.” You move into the project folder with cd, check what is there with ls, and from inside that folder you run Git. You do not need to be a terminal wizard — you need to navigate to your project and back.
5 Why Version Control Matters for Test Code
Version control is a system that records every change to a set of files over time. Git is by far the most common one. For a tester moving into automation, three things make it non-negotiable the moment your tests become code:
- Nothing is lost. Every saved change (a commit) is kept forever. Deleted a test by mistake on a Friday? Roll back to Thursday. Mere’s whole disaster simply does not happen with Git.
- The team shares one source of truth. The tests live in a central repository everyone clones, so the whole team runs the same tests, reviews each other’s changes, and never wonders whose laptop has the latest version.
- Every change is traceable. Each commit records who made the change, when, and why (the commit message). When a test starts behaving oddly, you can see exactly what changed and who to ask — the hut logbook, signed and dated.
There is a fourth reason that arrives quickly: automated tests usually run on a build server (continuous integration). That server gets the tests from the shared repository — not your laptop — so if your tests are not in Git, the automation pipeline cannot even see them.
6 The Core Git Commands
You can do a great deal of day-to-day work with just six commands. Here they are in the order you naturally meet them, with what each one actually does:
git status — show what you have changed and what state things are in. Run this constantly — it is your “where am I?”
git add <file> — stage a changed file: mark it to be included in your next save.
git add . stages everything.git commit -m "message" — save the staged changes as one logbook entry, with a message saying why.
git push — send your commits up to the shared repository so the team can see them.
git pull — bring everyone else’s latest commits down onto your machine, so you are up to date.
The everyday rhythm is: pull to get up to date, do your work, add the files you changed, commit them with a clear message, then push to share. The one part that surprises newcomers is the two-step save: you add (choose what goes in) and then commit (save it). That separation lets you commit just the files you mean to, not every stray change in the folder.
7 Reading git status
git status is the command you will run more than any other, because it answers “what have I changed and what happens next?” Learning to read its output is the single most useful Git skill for a beginner. Here is a typical example after a morning’s work:
Your branch is up to date with 'origin/rates-payment-tests'.
Changes to be committed:
modified: tests/login.spec.js ← staged (added), will be in next commit
Changes not staged for commit:
modified: tests/payment.spec.js ← changed but NOT yet added
Untracked files:
tests/refund.spec.js ← brand-new file Git is not tracking yet
Read it from the top: you are on a branch called rates-payment-tests and you are level with the shared copy. Then three groups of files, which is the whole point of status:
- Changes to be committed — files you have
added (staged). These will be saved when you nextcommit. Here,login.spec.js. - Changes not staged for commit — files you changed but have not
added yet. They will not be in the next commit until you add them. Here,payment.spec.js. - Untracked files — brand-new files Git has never seen. They are not in version control at all until you
addthem. Here, the newrefund.spec.js.
So to save all three, you would git add . to stage the two unstaged files, then git commit -m "...". Reading this output correctly is how you avoid the classic beginner trap of committing and pushing, then wondering why a file you changed never made it — you never staged it.
8 Branches — Working Safely
A branch is your own parallel copy of the project where you can work without disturbing anyone else. The team keeps a main branch (often called main) that holds the agreed, working version. When you start a piece of work, you make a branch off it, do your changes there, and only merge back into main once it is reviewed and working.
... do your work, add and commit ...
git push // share your branch for review
Why this matters for a tester: branches mean your half-finished test work never breaks the shared main branch that other people and the build server rely on. Your changes stay isolated until they are ready. It is the same instinct as testing in a safe environment rather than poking production — do your risky work somewhere it cannot hurt anyone, then merge once it is sound.
rates-payment-tests tells the team what is on it; mere-branch tells them nothing. A clear branch name is part of the same logbook discipline as a clear commit message.9 Common Mistakes
🚫 Keeping test code in a folder on your laptop
Why it happens: It is how you have always kept documents, and it works — until it doesn’t.
The fix: Once tests are code, put them in a Git repository. You get an undoable history and a shared source of truth, and the build server can actually find them. Mere’s lost week is the cost of skipping this.
🚫 Committing without staging the file you changed
Why it happens: You assume commit saves everything you touched.
The fix: A commit only includes files you have added (staged). Run git status first and read it — anything under “Changes not staged” or “Untracked files” will be left out until you add it.
🚫 Writing vague commit messages
Why it happens: “update” or “fix” is quick to type and feels good enough.
The fix: The message is the logbook entry the team reads later. Say why the change exists — “Add login test for locked-account case” — so future you, and your teammates, can understand the history without guessing.
🚫 Working directly on main
Why it happens: Making a branch feels like an extra step when you just want to write a test.
The fix: Half-finished work on main can break the shared version everyone relies on. Make a branch named after the work, do your changes there, and merge back only once it is reviewed and working.
10 Now You Try
Three graded exercises — spot it, fix it, build it. Write your answer, run it for AI feedback, then compare to the model answer.
A tester on a fictional Wellington govtech project runs git status and sees the output below. In plain English, explain the state of each file, and say exactly what commands they need to run to save all three changes.
Changes to be committed:
modified: tests/search.spec.js
Changes not staged for commit:
modified: tests/filter.spec.js
Untracked files:
tests/sort.spec.js
Explain each file's state and the commands to save all three:
Show model answer
search.spec.js is: STAGED — it has been git add-ed and will be included in the next commit. filter.spec.js is: MODIFIED BUT NOT STAGED — it has been changed, but not git add-ed yet, so it will NOT be in the next commit until it is added. sort.spec.js is: UNTRACKED — a brand-new file Git has never seen. It is not in version control at all and will not be committed until it is added. Commands to save all three: git add . (stages filter.spec.js and the new sort.spec.js; search.spec.js is already staged) git commit -m "Add sort tests and update search and filter specs" git push (to share with the team) Key point: if you committed right now WITHOUT git add ., only search.spec.js would be saved — the other two would be silently left out. That is the classic beginner trap, and reading git status is how you catch it.
A new tester on a fictional Kiwibank test repo describes how they work below. Several habits will cause problems. Identify what is wrong and rewrite their workflow into a safe, correct sequence of Git steps with brief reasons.
git commit -m "stuff" and that’s it. I’ve never run git status or git push, and I’ve never pulled anyone else’s changes.”
List what's wrong, then write a correct daily workflow:
Show model answer
What's wrong:
- Tests live in a desktop folder, not a Git repo — no history, no sharing, the build server can't see them, and a stray delete loses them for good.
- Working straight on main — half-finished work can break the shared, agreed version everyone relies on.
- Vague commit message ("stuff") — tells the team nothing later.
- Never staging properly / never running git status — likely commits the wrong files or misses changes, with no check of the state.
- Never pushing — nobody else ever gets their work; it only exists locally.
- Never pulling — they fall behind the team's latest changes and will hit conflicts.
Correct daily workflow (in order):
1. git pull — get the team's latest changes first.
2. git checkout -b login-tests — make a branch named after the work, so main stays safe.
3. ... write tests ... then git status — check what changed before saving.
4. git add . then git commit -m "Add login tests for locked-account case" — stage, then save with a clear, why-focused message.
5. git push — share the branch for review.
Core idea: code in Git, work on a branch, status before commit, clear message, push to share, pull to stay current.
For each plain-English situation on a fictional MSD benefits test repo, write the exact Git or terminal command(s) you would run. One line each is fine.
https://git.example.nz/msd-tests.git onto your machine for the first time.B. Move into the
msd-tests folder you just copied.C. Make and switch to a new branch called
eligibility-tests.D. Check what you’ve changed before saving.
E. Stage everything, save it with a clear message, and share it with the team.
Show model answer
A. git clone https://git.example.nz/msd-tests.git B. cd msd-tests C. git checkout -b eligibility-tests D. git status E. git add . git commit -m "Add eligibility tests for income-threshold cases" git push Marking guide: full marks for the right command on each line. Common slips: forgetting cd into the folder (B) before running Git; trying to commit without git add first (E); a vague commit message instead of a why-focused one. The whole sequence A→E is a realistic first day on a new test repo.
11 Self-Check
Click each question to reveal the answer.
Q1: Why is a folder on your laptop not good enough for test code?
It has no history (a stray delete is gone for good), no sharing (only you have it), and the build server can’t reach it. Version control with Git gives you an undoable history, a shared source of truth the whole team uses, and a place the automation pipeline can find the tests.
Q2: What is the difference between git add and git commit?
git add stages a file — it chooses which changes go into the next save. git commit saves the staged changes as one logbook entry with a message. The two-step split lets you commit exactly the files you mean to, not every stray change in the folder.
Q3: In git status, what is the difference between “not staged” and “untracked”?
“Changes not staged” are files Git already tracks that you’ve changed but not yet added. “Untracked files” are brand-new files Git has never seen at all. Both are left out of the next commit until you add them — which is why reading status before committing matters.
Q4: What do git push and git pull do, and how are they opposites?
git push sends your commits up to the shared repository so the team can see them. git pull brings everyone else’s commits down onto your machine so you’re up to date. Push shares your work; pull collects theirs.
Q5: Why work on a branch instead of directly on main?
A branch is your own parallel copy where half-finished work can’t break the shared main branch that teammates and the build server rely on. You do your risky work in isolation, then merge into main only once it’s reviewed and working — the same instinct as not poking production.
12 Interview Prep
Real questions asked in NZ QA interviews for junior automation roles. Read the model answers, then practise your own version.
“Walk me through your daily Git workflow on a test repo.”
I start by pulling the latest changes so I’m up to date with the team. I make a branch named after the work I’m doing, so main stays safe while I’m mid-change. I write my tests, then run git status to see exactly what changed before I save anything. I stage with git add, commit with a clear message that says why the change exists, and push the branch so it can be reviewed. Then it’s merged into main once it’s sound. Pull, branch, status, add, commit, push — that’s the rhythm.
“You changed three test files and committed, but only one made it into the commit. What happened?”
I almost certainly only staged that one file. A commit includes only what’s been git added — the other two were probably sitting under “Changes not staged” or “Untracked files” in git status. The fix is to run git status, see what was left out, git add those files, and commit again. The lesson I’d take is to always read git status before committing so I know exactly what’s going in.
“Why does version control matter so much for automated tests specifically?”
Because automated tests are code, and code needs the things version control gives you: a full undoable history so nothing’s lost, a shared repository so the whole team runs the same tests and reviews each other’s work, and traceability so when a test changes you can see who changed it and why. On top of that, the CI build server pulls tests from the repository, not from anyone’s laptop — so if the tests aren’t in Git, the automation pipeline can’t even run them.