Module 3: Branching and Switching: Isolated Test Development
Learn to create and manage branches for developing new test features, fixing bugs, and experimenting with test frameworks without affecting the main test suite. Understand branch strategies specific to test automation projects and practice switching between different testing contexts.
Creating Your First Test Feature Branch
Why This Matters
Imagine you’re working on a critical test automation suite that runs continuously in your CI/CD pipeline. Your team depends on these tests to catch bugs before they reach production. Now, you need to add a new test feature or experiment with a different assertion library. If you make changes directly to the main branch and something breaks, you’ve just disrupted everyone’s workflow and potentially blocked deployments.
This is the exact problem branches solve.
In real-world test automation projects, you’ll constantly face scenarios like:
- Adding new test cases for upcoming features without breaking existing tests
- Experimenting with new testing frameworks (like switching from unittest to pytest) without risking your stable test suite
- Fixing flaky tests in isolation while others continue working
- Updating test dependencies that might introduce breaking changes
- Creating proof-of-concept tests to validate new testing approaches
Without branches, every change you make directly affects your entire team. Tests that were passing might suddenly fail. Your CI/CD pipeline could break. Other team members might pull your half-finished work and waste time debugging issues that aren’t even their responsibility.
Branches give you a safe sandbox to develop, experiment, and validate your test changes before they impact anyone else. They’re not just a nice-to-have feature—they’re an essential professional practice that separates chaotic test development from disciplined, collaborative test engineering.
What You’ll Learn
By the end of this lesson, you’ll have hands-on experience creating and managing branches specifically for test automation work. This isn’t just theory—you’ll actually create branches, switch between them, and understand how they protect your test suite’s stability.
Here’s How We’ll Cover Each Objective:
Understanding why branches matter for test automation: We’ll start by exploring real test automation scenarios where branches prevent disasters. You’ll see concrete examples of how branches isolate changes and protect your main test suite.
Creating feature branches: You’ll learn the exact Git commands to create new branches for test development. We’ll walk through creating your first branch step-by-step, and you’ll understand what happens behind the scenes when you create a branch.
Switching between branches: You’ll practice moving between different branches, experiencing how Git changes your working directory to match each branch’s context. This skill lets you quickly shift between different test development tasks.
Using test-specific naming conventions: We’ll introduce branch naming patterns designed for test automation projects—patterns that make it instantly clear whether a branch contains new test features, bug fixes, or experimental framework changes. You’ll learn conventions that improve team communication.
Maintaining branch isolation: Finally, you’ll understand how to keep your test branches completely separate from the main suite, ensuring that experimental or in-progress changes never accidentally affect stable tests running in production environments.
Each concept builds on the previous one, giving you a complete mental model of how branching works in test automation contexts. By the lesson’s end, you’ll be confident creating branches for any test development scenario.
Core Content
Core Content: Creating Your First Test Feature Branch
1. Core Concepts Explained
Understanding Feature Branches in Test Automation
A feature branch is an isolated line of development where you can work on new test cases, update existing tests, or experiment with automation frameworks without affecting the main codebase. Think of it as your personal workspace where mistakes won’t break anything for your team.
Why Feature Branches Matter for Test Automation:
- Isolation: Your test changes don’t interfere with working tests on the main branch
- Collaboration: Multiple testers can work on different test suites simultaneously
- Review Process: Changes can be reviewed before merging into the main test suite
- Rollback Safety: Easy to discard changes that don’t work out
The Feature Branch Workflow
graph LR
A[Main Branch] --> B[Create Feature Branch]
B --> C[Write Tests]
C --> D[Commit Changes]
D --> E[Push to Remote]
E --> F[Create Pull Request]
F --> G[Merge to Main]
G --> A
Basic Git Commands for Branching
Before diving into feature branches, let’s understand the essential Git commands:
git branch
- Lists, creates, or deletes branchesgit checkout
- Switches between branchesgit checkout -b
- Creates and switches to a new branch in one commandgit status
- Shows the current state of your working directorygit push
- Uploads local branch commits to remote repository
2. Step-by-Step: Creating Your First Test Feature Branch
Step 1: Check Your Current Branch
Before creating a new branch, verify which branch you’re currently on:
$ git branch
* main
develop
The asterisk (*) indicates your current branch. Always create feature branches from an updated main or develop branch.
Step 2: Update Your Main Branch
Ensure you have the latest changes from the remote repository:
$ git checkout main
Switched to branch 'main'
$ git pull origin main
Already up to date.
# Expected output when updates are available:
$ git pull origin main
remote: Counting objects: 5, done.
Unpacking objects: 100% (5/5), done.
From https://github.com/username/test-automation-repo
* branch main -> FETCH_HEAD
Updating a1b2c3d..e4f5g6h
Fast-forward
tests/login.spec.js | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
Step 3: Create Your Feature Branch
Use a descriptive naming convention. Common patterns for test automation branches:
test/feature-name
- For new test featurestest/bug-fix-123
- For test fixes (with issue number)test/update-login-tests
- For updating existing tests
$ git checkout -b test/add-login-tests
Switched to a new branch 'test/add-login-tests'
This command does two things:
- Creates a new branch called
test/add-login-tests
- Switches to that branch automatically
Step 4: Verify Your New Branch
Confirm you’re on the new branch:
$ git branch
main
* test/add-login-tests
$ git status
On branch test/add-login-tests
nothing to commit, working tree clean
3. Practical Example: Creating a Login Test on a Feature Branch
Let’s create a complete example using Playwright and practiceautomatedtesting.com:
Create the Test File
// tests/login.spec.js
const { test, expect } = require('@playwright/test');
test.describe('Login Functionality Tests', () => {
test.beforeEach(async ({ page }) => {
// Navigate to the practice site before each test
await page.goto('https://practiceautomatedtesting.com/');
});
test('should successfully login with valid credentials', async ({ page }) => {
// Click on account/login link
await page.click('text=Account');
// Fill in login credentials
await page.fill('#username', 'testuser@example.com');
await page.fill('#password', 'SecurePassword123');
// Click login button
await page.click('button[type="submit"]');
// Verify successful login
await expect(page.locator('.welcome-message')).toBeVisible();
await expect(page.locator('.welcome-message')).toContainText('Welcome');
});
test('should show error message with invalid credentials', async ({ page }) => {
// Navigate to login page
await page.click('text=Account');
// Attempt login with invalid credentials
await page.fill('#username', 'invalid@example.com');
await page.fill('#password', 'wrongpassword');
await page.click('button[type="submit"]');
// Verify error message appears
await expect(page.locator('.error-message')).toBeVisible();
await expect(page.locator('.error-message'))
.toContainText('Invalid username or password');
});
test('should validate required fields', async ({ page }) => {
// Navigate to login page
await page.click('text=Account');
// Try to submit without filling fields
await page.click('button[type="submit"]');
// Verify validation messages
await expect(page.locator('#username-error')).toBeVisible();
await expect(page.locator('#password-error')).toBeVisible();
});
});
Step 5: Check Status of Your Changes
$ git status
On branch test/add-login-tests
Untracked files:
(use "git add <file>..." to include in what will be committed)
tests/login.spec.js
nothing added to commit but untracked files present (use "git add" to track)
Step 6: Stage Your Changes
$ git add tests/login.spec.js
$ git status
On branch test/add-login-tests
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: tests/login.spec.js
Step 7: Commit Your Changes
Write a clear, descriptive commit message:
$ git commit -m "Add comprehensive login tests for authentication flows"
[test/add-login-tests a1b2c3d] Add comprehensive login tests for authentication flows
1 file changed, 45 insertions(+)
create mode 100644 tests/login.spec.js
Commit Message Best Practices:
- Use present tense (“Add tests” not “Added tests”)
- Be descriptive but concise
- Reference issue numbers when applicable:
"Add login tests - fixes #123"
Step 8: Push Your Feature Branch to Remote
$ git push origin test/add-login-tests
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 8 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 1.2 KiB | 1.2 MiB/s, done.
Total 4 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), done.
To https://github.com/username/test-automation-repo.git
* [new branch] test/add-login-tests -> test/add-login-tests
Step 9: Making Additional Changes
If you need to add more tests or make changes:
// tests/login.spec.js - Adding a new test
test('should allow password visibility toggle', async ({ page }) => {
await page.click('text=Account');
// Type password
await page.fill('#password', 'SecurePassword123');
// Verify password is hidden
await expect(page.locator('#password')).toHaveAttribute('type', 'password');
// Click visibility toggle
await page.click('.toggle-password-visibility');
// Verify password is now visible
await expect(page.locator('#password')).toHaveAttribute('type', 'text');
});
Commit and push the changes:
$ git add tests/login.spec.js
$ git commit -m "Add password visibility toggle test"
$ git push origin test/add-login-tests
4. Working with Multiple Branches
Switching Between Branches
# Switch back to main
$ git checkout main
Switched to branch 'main'
# Create another test branch
$ git checkout -b test/add-checkout-tests
Switched to a new branch 'test/add-checkout-tests'
# Switch back to your login tests branch
$ git checkout test/add-login-tests
Switched to branch 'test/add-login-tests'
Viewing All Branches
$ git branch -a
main
* test/add-login-tests
test/add-checkout-tests
remotes/origin/main
remotes/origin/test/add-login-tests
5. Common Mistakes and How to Avoid Them
Mistake 1: Creating a Branch from the Wrong Starting Point
Problem:
# Creating a feature branch while on another feature branch
$ git branch
* test/broken-feature
main
$ git checkout -b test/new-feature # ❌ This branches from test/broken-feature!
Solution:
# Always check out main (or develop) first
$ git checkout main
$ git pull origin main
$ git checkout -b test/new-feature # ✅ Now branching from updated main
Mistake 2: Forgetting to Commit Before Switching Branches
Problem:
$ git checkout main
error: Your local changes to the following files would be overwritten by checkout:
tests/login.spec.js
Please commit your changes or stash them before you switch branches.
Solution:
# Option 1: Commit your changes
$ git add tests/login.spec.js
$ git commit -m "WIP: Login tests in progress"
$ git checkout main
# Option 2: Stash your changes (temporary save)
$ git stash
Saved working directory and index state WIP on test/add-login-tests
$ git checkout main
# Later, return to your branch and restore changes
$ git checkout test/add-login-tests
$ git stash pop
Mistake 3: Poor Branch Naming
Bad Examples:
test
(too vague)my-branch
(not descriptive)asdf
(meaningless)john-test-branch
(includes personal name)
Good Examples:
test/add-login-validation
test/fix-checkout-timeout
test/update-api-tests
test/refactor-page-objects
Mistake 4: Not Pulling Latest Changes Before Creating Branch
Problem: Your branch is based on outdated code, leading to merge conflicts later.
Solution:
# Always pull before branching
$ git checkout main
$ git pull origin main # Get latest changes
$ git checkout -b test/new-feature
Mistake 5: Pushing to Wrong Branch
Problem:
$ git push origin main # ❌ Accidentally pushing to main instead of feature branch
Solution:
# Always verify your current branch
$ git branch
* test/add-login-tests
# Push to the correct branch
$ git push origin test/add-login-tests
# Or use this shortcut (pushes current branch)
$ git push origin HEAD
6. Quick Reference: Feature Branch Workflow
# 1. Start from main
git checkout main
git pull origin main
# 2. Create feature branch
git checkout -b test/descriptive-name
# 3. Make changes, then check status
git status
# 4. Stage changes
git add path/to/test-file.js
# 5. Commit with message
git commit -m "Add descriptive message"
# 6. Push to remote
git push origin test/descriptive-name
# 7. Continue working (repeat steps 3-6 as needed)
# 8. When done, create Pull Request on GitHub/GitLab
7. Next Steps
After creating your feature branch and pushing your tests:
- Create a Pull Request - Request to merge your tests into the main branch
- Run CI/CD Tests - Automated tests will run on your branch
- Request Code Review - Team members review your test code
- Address Feedback - Make requested changes and push updates
- Merge - Once approved, merge your tests into main
Your feature branch workflow is now complete! This process ensures your test automation changes are organized, reviewable, and safely integrated into your project.
Hands-On Practice
EXERCISE
Hands-On Exercise: Create Your Test Feature Branch
Task
Create a new feature branch for adding login tests to a test automation project, make changes to a test file, commit your work, and push it to the remote repository.
Prerequisites
- Git installed on your machine
- Access to a test automation repository (or create a new one)
- Basic understanding of command line/terminal
Step-by-Step Instructions
Step 1: Clone or Navigate to Your Repository
# If you don't have a repo yet, create a new directory
mkdir test-automation-practice
cd test-automation-practice
git init
# Or navigate to your existing project
cd your-test-project
Step 2: Check Current Branch and Status
git status
git branch
Step 3: Create and Switch to a New Feature Branch
# Create a new branch for your login tests feature
git checkout -b feature/login-tests
# Verify you're on the new branch
git branch
Step 4: Create or Modify a Test File
# Create a new test file
touch tests/login_test.py
Add the following starter code to tests/login_test.py
:
# tests/login_test.py
import unittest
class LoginTest(unittest.TestCase):
def test_successful_login(self):
"""Test successful login with valid credentials"""
# TODO: Add your test implementation
username = "testuser"
password = "password123"
self.assertEqual(username, "testuser")
def test_invalid_password(self):
"""Test login fails with invalid password"""
# TODO: Add your test implementation
self.assertTrue(True)
if __name__ == '__main__':
unittest.main()
Step 5: Stage and Commit Your Changes
# Check what files have changed
git status
# Stage your new test file
git add tests/login_test.py
# Commit with a descriptive message
git commit -m "Add initial login test cases"
Step 6: Push Your Feature Branch
# Push the branch to remote repository
git push origin feature/login-tests
# If this is your first push, you may need to set upstream
git push -u origin feature/login-tests
Step 7: Verify Your Work
# View your commit history
git log --oneline
# Check your branch status
git status
Expected Outcome
After completing this exercise, you should have:
✅ A new feature branch named feature/login-tests
✅ A test file (login_test.py
) with basic test cases
✅ At least one commit with a clear message
✅ Your feature branch pushed to the remote repository
✅ Your main/master branch unchanged
Solution Verification
Run these commands to verify your work:
# Should show feature/login-tests with an asterisk
git branch
# Should show your commit
git log -1
# Should show your branch exists on remote
git branch -r
Bonus Challenge
- Create another test file for
logout_test.py
- Make a second commit on the same branch
- View the difference between your feature branch and main:
git diff main..feature/login-tests
KEY TAKEAWAYS
What You Learned
🔑 Feature branches isolate your work - Creating separate branches for each feature or test suite keeps your main branch stable and allows multiple team members to work independently without conflicts.
🔑 Naming conventions matter - Using descriptive branch names like feature/login-tests
or test/add-checkout-flow
makes it immediately clear what work is being done and helps with organization.
🔑 Commit early and often - Making small, focused commits with clear messages creates a better history and makes it easier to track changes or revert if needed.
🔑 Push to share and backup - Pushing your feature branch to the remote repository backs up your work and enables collaboration through pull requests and code reviews.
🔑 The main branch stays clean - By working on feature branches, your main/master branch remains deployable while development continues in parallel.
When to Apply This
- Starting any new test development - Always create a feature branch before writing new tests
- Bug fix tests - Create a branch like
bugfix/fix-login-timeout-test
- Refactoring existing tests - Use
refactor/improve-api-tests
- Team collaboration - Before submitting tests for code review
- Experimental tests - Try new approaches without affecting the main codebase
NEXT STEPS
What to Practice
- Create multiple feature branches - Practice switching between different test features using
git checkout
- Write meaningful commit messages - Follow the pattern: “Add/Update/Fix [what] for [why]”
- Review your changes before committing - Use
git diff
to see exactly what you’re committing - Delete merged branches - After branches are merged, clean up with
git branch -d branch-name
Related Topics to Explore
Immediate Next Steps:
- Creating and reviewing pull requests for your test branches
- Merging feature branches back into main
- Resolving merge conflicts in test files
- Using
.gitignore
to exclude test reports and artifacts
Intermediate Topics:
- Git branching strategies (Git Flow, GitHub Flow)
- Rebasing vs merging feature branches
- Using tags for test release versions
- Setting up branch protection rules
Advanced Topics:
- Automating tests on feature branches with CI/CD
- Git hooks for running tests before commits
- Collaborative test development workflows
- Managing test data across branches
Recommended Practice Project
Build a complete test suite over the next week:
- Day 1-2: Create branches for login/logout tests
- Day 3-4: Create branches for user registration tests
- Day 5-6: Create branches for navigation tests
- Day 7: Merge all branches and review your workflow
🎓 Remember: Feature branches are your safety net. They give you the freedom to experiment, make mistakes, and iterate on your tests without fear of breaking the main codebase. Make branch creation a habit in your testing workflow!