Module 1: Introduction to Git and Version Control for Testing
Understand why version control is critical for test automation projects. Learn the fundamental concepts of Git, set up your environment, and make your first commits with test scripts. Explore how Git solves common problems test engineers face: tracking changes in test cases, collaborating on automation frameworks, and maintaining test data.
Why Test Engineers Need Git: Tracking Your Test Automation Journey
Why This Matters
The Test Automation Chaos Problem
Imagine this: You’ve spent weeks building a robust test automation suite. Everything works perfectly. Then, a week later, tests start failing mysteriously. What changed? You try to remember—was it the login test you modified? The test data you updated? Or maybe that framework refactoring you did three days ago?
Without version control, you’re stuck. You might have a folder called test_scripts_backup_final_v2_REALLY_FINAL
(we’ve all been there), but you can’t remember what changed between versions or why you made those changes.
This is the reality for test engineers working without Git. You face:
- Lost work: Accidentally overwriting test scripts with no way to recover previous versions
- Collaboration nightmares: Multiple team members editing the same test file, manually merging changes via email or shared drives
- Mystery failures: Tests break and you can’t identify what changed or when
- Audit gaps: No record of who modified test data or why critical test cases were removed
- Framework evolution chaos: Unable to track how your automation framework evolved or revert problematic changes
When You’ll Use This Skill
Git isn’t just for developers—it’s a fundamental tool for modern test engineers. You’ll use Git daily when you:
- Write and maintain automated test scripts (Selenium, Cypress, Playwright, etc.)
- Update test data files (JSON, CSV, XML)
- Modify automation frameworks and utilities
- Collaborate with other test engineers or developers
- Document test approaches and configurations
- Share test automation code during code reviews
- Deploy tests to CI/CD pipelines
- Investigate when and why tests started failing
Whether you’re working solo on a small project or part of a large QA team, Git provides the safety net and collaboration foundation you need.
Pain Points Git Solves
For Individual Test Engineers:
- Track every change to your test scripts with complete history
- Experiment safely—try new approaches knowing you can always go back
- Understand your own work from weeks or months ago
For Test Teams:
- Work on the same automation framework without stepping on each other’s toes
- Review each other’s test code before it goes live
- Maintain a single source of truth for all test assets
For Test Automation Projects:
- Keep test code, test data, and configurations synchronized
- Create reproducible test environments
- Integrate seamlessly with CI/CD tools like Jenkins, GitHub Actions, or GitLab CI
What You’ll Accomplish in This Lesson
By the end of this lesson, you’ll transform from someone who manages test scripts in folders to someone who professionally tracks and manages test automation assets using industry-standard tools.
Your Learning Journey
First, you’ll understand the “why” behind version control. We’ll explore real scenarios test engineers face and see how Git provides solutions. You’ll learn the core concepts that make Git work—repositories, commits, and tracking—without getting lost in jargon.
Next, you’ll install and configure Git on your machine. We’ll walk through the complete setup process for Windows, Mac, or Linux, and configure Git with your identity and preferences. This is hands-on—you’ll actually set up your Git environment.
Then, you’ll create your first test repository. You’ll initialize a real test automation project, understanding what happens behind the scenes when you turn a folder into a Git repository.
After that, you’ll track actual test scripts. You’ll add test files, make your first commits, and see how Git captures snapshots of your work. We’ll use realistic test automation examples so you can immediately apply this to your projects.
Finally, you’ll solve real test engineering problems using Git. We’ll tackle scenarios like tracking test case changes over time, managing test data files, and handling framework modifications—all the challenges that make version control critical for test automation.
Hands-On Approach
This isn’t a theory lesson. You’ll be typing commands, creating files, and seeing results. Every concept comes with practical examples using test automation scenarios you’ll recognize. By the lesson’s end, you’ll have a working test repository and the confidence to start using Git in your daily testing work.
Let’s begin your Git journey and take control of your test automation projects! 🚀
Core Content
Core Content
Core Concepts Explained
What is Version Control and Why Git Matters for Test Engineers
Version control is a system that tracks changes to files over time. Think of it as a “time machine” for your code that lets you:
- See what changed, when, and by whom
- Revert to previous versions if something breaks
- Work on different features simultaneously
- Collaborate with team members without overwriting each other’s work
Git is the most popular version control system, and it’s essential for test automation because:
- Test Code is Code: Your automation scripts need the same care as production code
- Collaboration: Multiple testers can work on different test suites simultaneously
- Traceability: Link test changes to specific application versions or bug fixes
- Safety Net: Quickly recover if a test refactor goes wrong
- CI/CD Integration: Modern pipelines require Git to automatically run your tests
How Git Works: The Three States
Git tracks your test files through three main states:
graph LR
A[Working Directory<br/>Your test files] -->|git add| B[Staging Area<br/>Files ready to commit]
B -->|git commit| C[Repository<br/>Permanent snapshot]
C -->|git checkout| A
- Working Directory: Where you write and modify your test code
- Staging Area: Where you prepare files before saving a snapshot
- Repository: Where Git permanently stores snapshots of your work
Step-by-Step: Installing Git
Windows Installation
-
Download Git from git-scm.com
-
Run the installer with these recommended settings:
- Use Git from Git Bash and also from Windows Command Prompt
- Use default line ending conversions
- Use MinTTY as terminal emulator
-
Verify installation:
$ git --version
git version 2.42.0
macOS Installation
Using Homebrew (recommended):
$ brew install git
Or download from git-scm.com
Verify:
$ git --version
git version 2.42.0
Linux Installation
Ubuntu/Debian:
$ sudo apt-get update
$ sudo apt-get install git
Fedora/RHEL:
$ sudo dnf install git
Verify:
$ git --version
git version 2.42.0
Step-by-Step: Configuring Git
After installation, configure your identity. This information appears in every commit you make:
# Set your name
$ git config --global user.name "Your Name"
# Set your email
$ git config --global user.email "your.email@example.com"
# Set default branch name to 'main'
$ git config --global init.defaultBranch main
# Verify your configuration
$ git config --list
user.name=Your Name
user.email=your.email@example.com
init.defaultbranch=main
Optional but recommended configurations:
# Enable colored output for better readability
$ git config --global color.ui auto
# Set your default editor (example: VS Code)
$ git config --global core.editor "code --wait"
# Set up line endings (Windows)
$ git config --global core.autocrlf true
# Set up line endings (Mac/Linux)
$ git config --global core.autocrlf input
Step-by-Step: Initializing Your First Test Repository
Creating a New Repository
Let’s create a repository for a Playwright test project:
# Create project directory
$ mkdir ecommerce-tests
$ cd ecommerce-tests
# Initialize Git repository
$ git init
Initialized empty Git repository in /Users/yourname/ecommerce-tests/.git/
# Verify repository creation
$ ls -la
drwxr-xr-x .git/
Understanding the .git Directory
The .git
directory contains all version control information. Never manually modify this directory.
$ ls .git/
HEAD
config
objects/
refs/
Step-by-Step: Creating Your First Test and Committing
1. Create a Test File
Create a simple Playwright test:
// tests/login.spec.js
const { test, expect } = require('@playwright/test');
test('user can login successfully', async ({ page }) => {
// Navigate to login page
await page.goto('https://practiceautomatedtesting.com/login');
// Fill in credentials
await page.fill('#username', 'testuser@example.com');
await page.fill('#password', 'Test123!');
// Click login button
await page.click('button[type="submit"]');
// Verify successful login
await expect(page).toHaveURL(/dashboard/);
});
2. Check Repository Status
$ git status
On branch main
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
tests/
nothing added to commit but untracked files present (use "git add" to track)
Git sees your new file but isn’t tracking it yet.
3. Stage Your Changes
# Add specific file
$ git add tests/login.spec.js
# Or add all files in directory
$ git add tests/
# Check status again
$ git status
On branch main
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: tests/login.spec.js
4. Create Your First Commit
$ git commit -m "Add login test for practice site"
[main (root-commit) a3f7d9c] Add login test for practice site
1 file changed, 15 insertions(+)
create mode 100644 tests/login.spec.js
Commit message best practices:
- Use present tense: “Add test” not “Added test”
- Be descriptive: “Add login validation test” vs “Update tests”
- Keep first line under 50 characters
- Add details in body if needed (leave blank line after first line)
5. View Commit History
$ git log
commit a3f7d9c8f2e1b4a7c9d3e5f6a8b2c4d6e8f0a1b3
Author: Your Name <your.email@example.com>
Date: Mon Jan 15 10:30:45 2024 -0800
Add login test for practice site
# One-line format for cleaner view
$ git log --oneline
a3f7d9c Add login test for practice site
Practical Example: A Complete Test Automation Workflow
Let’s walk through a realistic scenario: adding a new checkout test.
Step 1: Create the Test
// tests/checkout.spec.js
const { test, expect } = require('@playwright/test');
test.describe('Checkout Process', () => {
test('user can complete purchase', async ({ page }) => {
// Add product to cart
await page.goto('https://practiceautomatedtesting.com/products');
await page.click('.product-item:first-child .add-to-cart');
// Navigate to checkout
await page.click('.cart-icon');
await page.click('button:has-text("Proceed to Checkout")');
// Fill shipping information
await page.fill('#shipping-name', 'John Doe');
await page.fill('#shipping-address', '123 Test Street');
await page.fill('#shipping-city', 'Test City');
await page.fill('#shipping-zip', '12345');
// Complete payment
await page.fill('#card-number', '4242424242424242');
await page.fill('#card-expiry', '12/25');
await page.fill('#card-cvc', '123');
await page.click('button:has-text("Place Order")');
// Verify success
await expect(page.locator('.success-message')).toBeVisible();
await expect(page.locator('.order-confirmation')).toContainText('Thank you');
});
});
Step 2: Create a .gitignore File
Before committing, exclude files that shouldn’t be tracked:
# .gitignore
node_modules/
test-results/
playwright-report/
.env
*.log
.DS_Store
Step 3: Stage and Commit Everything
$ git status
On branch main
Untracked files:
.gitignore
tests/checkout.spec.js
$ git add .gitignore tests/checkout.spec.js
$ git commit -m "Add checkout test with payment validation
- Tests complete purchase flow
- Validates shipping information form
- Verifies payment processing
- Checks order confirmation message"
Step 4: View Your Progress
$ git log --oneline
b7e2f8a Add checkout test with payment validation
a3f7d9c Add login test for practice site
Using Git: Common Daily Commands
Checking What Changed
# See modified files
$ git status
# See actual changes in files (before staging)
$ git diff
# See changes in staged files
$ git diff --staged
Example: Modifying a Test
// Before: tests/login.spec.js
test('user can login successfully', async ({ page }) => {
await page.goto('https://practiceautomatedtesting.com/login');
await page.fill('#username', 'testuser@example.com');
await page.fill('#password', 'Test123!');
await page.click('button[type="submit"]');
await expect(page).toHaveURL(/dashboard/);
});
// After: tests/login.spec.js
test('user can login successfully', async ({ page }) => {
await page.goto('https://practiceautomatedtesting.com/login');
// Updated selectors for new login form
await page.fill('[data-testid="email-input"]', 'testuser@example.com');
await page.fill('[data-testid="password-input"]', 'Test123!');
await page.click('[data-testid="login-button"]');
// More specific assertion
await expect(page.locator('.dashboard-header')).toBeVisible();
await expect(page.locator('.user-profile')).toContainText('testuser');
});
Check the changes:
$ git diff tests/login.spec.js
diff --git a/tests/login.spec.js b/tests/login.spec.js
@@ -2,8 +2,12 @@ test('user can login successfully', async ({ page }) => {
await page.goto('https://practiceautomatedtesting.com/login');
- await page.fill('#username', 'testuser@example.com');
- await page.fill('#password', 'Test123!');
- await page.click('button[type="submit"]');
- await expect(page).toHaveURL(/dashboard/);
+
+ // Updated selectors for new login form
+ await page.fill('[data-testid="email-input"]', 'testuser@example.com');
+ await page.fill('[data-testid="password-input"]', 'Test123!');
+ await page.click('[data-testid="login-button"]');
+
+ // More specific assertion
+ await expect(page.locator('.dashboard-header')).toBeVisible();
+ await expect(page.locator('.user-profile')).toContainText('testuser');
});
Commit the update:
$ git add tests/login.spec.js
$ git commit -m "Update login test to use data-testid selectors"
Viewing History and Changes
# View commit history
$ git log --oneline --graph
* c9d4e5f Update login test to use data-testid selectors
* b7e2f8a Add checkout test with payment validation
* a3f7d9c Add login test for practice site
# See what changed in a specific commit
$ git show c9d4e5f
# View history of a specific file
$ git log --oneline tests/login.spec.js
c9d4e5f Update login test to use data-testid selectors
a3f7d9c Add login test for practice site
Common Mistakes and How to Avoid Them
Mistake 1: Forgetting to Configure Git
Problem:
$ git commit -m "Add test"
*** Please tell me who you are.
fatal: unable to auto-detect email address
Solution:
$ git config --global user.name "Your Name"
$ git config --global user.email "your.email@example.com"
Mistake 2: Committing Without Staging
Problem:
$ git commit -m "Add new test"
On branch main
Untracked files:
tests/new-test.spec.js
nothing added to commit but untracked files present
Solution: Always use git add
first:
$ git add tests/new-test.spec.js
$ git commit -m "Add new test"
Mistake 3: Committing Sensitive Data
Problem: Accidentally committing passwords, API keys, or credentials:
// WRONG!
const API_KEY = 'sk_live_abc123xyz789';
Solution: Use .gitignore
and environment variables:
# .gitignore
.env
secrets.json
// CORRECT!
const API_KEY = process.env.API_KEY;
Mistake 4: Poor Commit Messages
Bad:
$ git commit -m "fix"
$ git commit -m "updates"
$ git commit -m "asdfgh"
Good:
$ git commit -m "Fix login test selector for email field"
$ git commit -m "Update checkout test to handle new payment modal"
$ git commit -m "Add smoke tests for critical user flows"
Mistake 5: Committing node_modules or Test Reports
Problem: Huge commits with thousands of dependency files.
Solution: Always create .gitignore
before first commit:
# .gitignore
node_modules/
test-results/
playwright-report/
allure-report/
coverage/
*.log
Debugging: How to Undo Mistakes
Undo changes before staging:
# Discard changes in a specific file
$ git checkout -- tests/login.spec.js
# Discard all changes
$ git checkout -- .
Unstage files (keep changes):
$ git reset HEAD tests/login.spec.js
Amend last commit (fix message or add forgotten files):
$ git add tests/forgotten-file.spec.js
$ git commit --amend -m "Add login and validation tests"
Check what you’re about to commit:
# Always review before committing
$ git diff --staged
Quick Reference: Essential Commands
# Setup (one-time)
git config --global user.name "Your Name"
git config --global user.email "your@email.com"
# Starting a project
git init # Initialize repository
# Daily workflow
git status # Check what changed
git add <file> # Stage specific file
git add . # Stage all changes
git commit -m "message" # Save snapshot
git log --oneline # View history
git diff # See unstaged changes
git diff --staged # See staged changes
# Checking history
git log # Full history
git log --oneline --graph # Visual history
git show <commit-id> # See specific commit
This foundation prepares you to track your test automation work effectively. In the next lessons, you’ll learn about branching, remote repositories, and collaborative workflows.
Hands-On Practice
Hands-On Exercise
🎯 Exercise: Create Your First Test Automation Repository
In this exercise, you’ll set up a Git repository for a simple test automation project and practice the fundamental Git workflow that test engineers use daily.
Task
Create a Git repository, add test files, make changes, and track your automation journey using basic Git commands.
Prerequisites
- Git installed on your computer
- A text editor (VS Code, Notepad++, or any editor)
- Terminal/Command Prompt access
Step-by-Step Instructions
Step 1: Initialize Your Test Repository
# Create a new directory for your test project
mkdir my-first-test-automation
cd my-first-test-automation
# Initialize Git repository
git init
# Verify Git is tracking this folder
git status
Step 2: Create Your First Test File
Create a file named test_login.py
with the following content:
# test_login.py
def test_valid_login():
# TODO: Add test for valid credentials
pass
def test_invalid_login():
# TODO: Add test for invalid credentials
pass
Step 3: Add and Commit Your First Test
# Check the status (you should see untracked files)
git status
# Add the file to staging area
git add test_login.py
# Commit with a descriptive message
git commit -m "Add initial login test cases"
# View your commit history
git log
Step 4: Make Changes to Your Test
Update test_login.py
to implement one test:
# test_login.py
def test_valid_login():
username = "testuser@example.com"
password = "SecurePass123"
# Simulate login validation
assert username and password, "Login should succeed with valid credentials"
def test_invalid_login():
# TODO: Add test for invalid credentials
pass
Step 5: Track Your Changes
# See what changed
git diff
# Stage and commit the changes
git add test_login.py
git commit -m "Implement valid login test case"
Step 6: Add Test Documentation
Create a README.md
file:
# Login Test Suite
## Test Cases
- test_valid_login: Verifies successful login with correct credentials
- test_invalid_login: Verifies error handling with wrong credentials
## How to Run
Coming soon...
Step 7: Commit Multiple Files
# Add all files at once
git add .
# Commit with descriptive message
git commit -m "Add test documentation"
# View your complete history
git log --oneline
Step 8: Create a .gitignore File
Create .gitignore
to exclude unnecessary files:
# Python
__pycache__/
*.pyc
*.pyo
# Test Reports
reports/
*.log
# IDE
.vscode/
.idea/
git add .gitignore
git commit -m "Add gitignore for Python test project"
Expected Outcome
By the end of this exercise, you should have:
- ✅ A Git repository initialized in your test project folder
- ✅ At least 4 commits in your history
- ✅ A test file, README, and .gitignore tracked by Git
- ✅ Understanding of the basic Git workflow: modify → add → commit
- ✅ Ability to check status and view history
Verification Commands
# Verify you have multiple commits
git log --oneline
# Should show at least 4 commits:
# - Add initial login test cases
# - Implement valid login test case
# - Add test documentation
# - Add gitignore for Python test project
# Verify all files are tracked
git ls-files
# Should show: test_login.py, README.md, .gitignore
Bonus Challenge 🌟
- Implement the
test_invalid_login()
function - Create a new file
test_logout.py
with logout test cases - Make at least 2 more commits with meaningful messages
- Use
git log --oneline --graph
to visualize your commit history
Key Takeaways
🔑 Essential Points to Remember:
-
Version Control is Essential for Test Automation: Git tracks every change to your test scripts, allowing you to see what changed, when, and why—critical for maintaining test suites over time.
-
The Basic Git Workflow: The core cycle every test engineer uses is: make changes → check status (
git status
) → stage files (git add
) → commit with message (git commit -m
) → review history (git log
). -
Meaningful Commit Messages Matter: Descriptive commit messages like “Add validation for empty password field” are far more valuable than vague ones like “updated tests” when debugging or reviewing test changes months later.
-
Git Tracks Files, Not Folders: You must explicitly tell Git which files to track using
git add
, and you can exclude generated files (like test reports or logs) using.gitignore
. -
Your Repository is Your Test History: Your commit history becomes a complete log of your testing journey—documenting what tests were added, modified, or removed, making it easier to collaborate with other QA engineers and developers.
Next Steps
🎯 What to Practice
- Daily Git Habit: For the next week, create a Git repository for any small test project and make at least one commit daily
- Descriptive Commits: Practice writing clear, specific commit messages that explain what and why
- Explore History: Use
git log
,git diff
, andgit show
to examine your test changes - Clean Repositories: Practice creating
.gitignore
files for different test frameworks (Selenium, Playwright, etc.)
📚 Related Topics to Explore
Immediate Next Steps:
- Branching: Learn to create branches for new test features (
git branch
,git checkout
) - Remote Repositories: Push your tests to GitHub/GitLab for backup and collaboration
- Undoing Changes: Learn to revert mistakes with
git checkout
,git reset
, andgit revert
Intermediate Topics:
- Collaborating with Developers: Pull requests and code reviews for test automation
- CI/CD Integration: Connecting your Git repository to automated test runs
- Git for Test Data: Managing test data files and configuration with version control
Resources:
- GitHub’s “Hello World” guide for practicing with remote repositories
- Git branching tutorials for managing test feature development
- Your team’s Git workflow documentation (if available)
🎉 Congratulations! You’ve taken your first step into version-controlled test automation. Git will become one of your most valuable tools as a test engineer!