Git Checkpoints and Testing Before You Trust a Script

Save points and practice runs for code that touches real files

Intermediate 11 min

In this lesson

Once a script starts changing real files, two habits protect you: Git gives your project save points you can return to, and tests are little practice runs that confirm the important pieces still work. This lesson keeps both practical, just enough Git workflow and just enough testing to make automation trustworthy.

Explain it like I’m 5

Git is the save-point system for your code; tests are quick practice runs that check the risky parts before you let them loose on real files.

Git: save points for your project

Git records snapshots of your project called commits. Each small, well-described commit is a save point you can return to if a change goes wrong, which matters most when a script is rewriting real files. You don’t need full Git training here, just the everyday loop.

Example
git init                                 # start tracking this project
git add file_tool.py                     # stage your changes
git commit -m "Add safe dry-run mode"    # save a checkpoint
git log --oneline                        # see your save points
A tiny Git workflow, small, described commits act as save points.

Tests: practice runs for your helpers

A test checks that a piece of code does what you expect. The cheapest test is an assert: a statement that must be true, or Python raises an AssertionError. Test the pure helper functions, the ones that just compute a result, so you can verify your logic without ever touching real files.

Example
def clean_filename(name):
    return name.strip().lower().replace(" ", "_")

# A few quick checks before trusting it on real files:
assert clean_filename("  My File.TXT ") == "my_file.txt"
assert clean_filename("Report 2024") == "report_2024"
print("All checks passed")
Output
All checks passed
If any assert were false, you'd see an error instead.

Write a test, then trust the helper

Reading a failing test is a skill: the message tells you what was expected versus what happened. Practice by working out the expected result by hand and asserting it.

Here's a helper that turns a title into a URL slug. Add two assert checks with the correct expected results, then keep the success line.

def slugify(title):
    return title.strip().lower().replace(" ", "-")

# TODO: assert slugify("Hello World") == ?
# TODO: assert slugify("  Spaced Out  ") == ?
print("All checks passed")

Common mistake: Making one giant commit after many unrelated changes

Why it happens:

It feels efficient to code for an hour and commit once at the end.

How to fix it:

Commit in small, focused steps with clear messages. Each becomes a clean save point you can roll back to without losing unrelated work.

Common mistake: Testing only the happy path

Why it happens:

The obvious case is easiest to check, so the odd inputs, empty strings, missing extensions, get skipped.

How to fix it:

Add a test for the edge cases too. Bugs usually hide in the inputs you didn’t think to try.

Common mistake: Running tests against real, important folders

Why it happens:

It’s convenient to point a test at the actual files the script will process.

How to fix it:

Test pure helper functions, or use a small folder of throwaway sample data. Never let a test mutate data you can’t afford to lose.

Why prefer small, frequent commits?

What does an assert statement check?

Why test pure helper functions separately from file-moving code?

Mini exercise (medium)

Write a helper safe_name(name) that trims a filename, lowercases it, and replaces spaces with underscores, for example " My Report " becomes "my_report". Then it should pass tests on at least two inputs.

Your turn. Fill in the code below and press Run to test it right here, nothing to install.

def safe_name(name):
    # TODO: trim, lowercase, and replace spaces with underscores
    return name

# TODO: add two asserts that prove it works
print("done")

What to learn next

You saw how small, described Git commits act as save points, and how a quick assert test confirms a pure helper works before it ever touches real files, with a first look at pytest for scaling tests up. You wrote and tested a safe_name() helper.

The last piece of a trustworthy project is making it run the same anywhere. Virtual Environments, requirements.txt, and Reproducibility shows how to isolate and pin your dependencies.