← back to section

Every test comes down to one thing: compare what you expected with what you got. Comparisons and conditions are the part of the language that does exactly that.

A comparison gives "yes" or "no"

live example

code = 200
print(code == 200)     # True
print(code == 404)     # False
Run

Running examples is part of paid access. There the same code runs inside the article: editor, run and check next to the paragraph. Three free days →

Two equals signs == ask "are these equal?", one sign = stores a value. Say it out loud: one stores, two ask.

Comparison operators:

live example

a, b = 200, 404
print(a == b)     # False — equal?
print(a != b)     # True  — not equal?
print(a > b)      # False — greater?
print(a < b)      # True  — less?
print(a >= b)     # False — greater or equal?
print(a <= b)     # True  — less or equal?
Run

Running examples is part of paid access. There the same code runs inside the article: editor, run and check next to the paragraph. Three free days →

The result is always True or False. Python writes them capitalised — it does not know true.

Practice here: Compare expected with actual

A condition: do one thing or the other

live example

code = 404

if code == 200:
    print("All good")
else:
    print("Something went wrong")
Run

Running examples is part of paid access. There the same code runs inside the article: editor, run and check next to the paragraph. Three free days →

The indent here is part of the language. What belongs to the if is shifted four spaces to the right. Get it wrong and the program either fails with IndentationError or does the wrong thing.

There can be more than two branches — then elif in the middle:

live example

code = 500
if code == 200:
    print("Success")
elif code == 404:
    print("Not found")
elif code == 500:
    print("Server error")
else:
    print(f"Unexpected code: {code}")
Run

Running examples is part of paid access. There the same code runs inside the article: editor, run and check next to the paragraph. Three free days →

The first matching check wins, the rest are skipped. The final else catches what you did not expect: without it an unexpected response passes silently.

Practice here: The if/else condition

Several conditions at once

live example

code, total, found = 200, 4990, False

if code == 200 and total > 0:
    print("Order created and not empty")

if code == 404 or code == 410:
    print("Order is gone")

if not found:
    print("Nothing found")
Run

Running examples is part of paid access. There the same code runs inside the article: editor, run and check next to the paragraph. Three free days →

  • and — true when both are true;
  • or — when at least one is true;
  • not — flips it: True becomes False.

The second half of an or often goes missing — and then the branch fires every time:

live example

code = 200

# the wrong way: 410 is not a comparison but a number, and Python calls it true
if code == 404 or 410:
    print("order is gone")

# the right way: write the comparison out for every value
if code == 404 or code == 410:
    print("order is gone")
else:
    print("order is there")
Run

Running examples is part of paid access. There the same code runs inside the article: editor, run and check next to the paragraph. Three free days →

The first if prints "order is gone" even for code 200 — a check that is always true checks nothing.

and is evaluated before or, so a mixed condition takes brackets: (code == 404 or code == 410) and not found.

Practice here: Several branches by status code

What counts as empty

A condition can hold a value, not just a comparison. Empty counts as false, non-empty as true:

live example

response = ""
items = []

if not response:
    print("the string is empty")
if not items:
    print("the list is empty")
Run

Running examples is part of paid access. There the same code runs inside the article: editor, run and check next to the paragraph. Three free days →

False values: 0, the empty string "", the empty list [], the empty dict {} and None — the special "no value at all". Everything else is true.

None is not zero and not an empty string, it is "no value at all": that is how a response field that was never filled looks. It is compared with its own operator:

live example

paid_at = None
if paid_at is None:
    print("Order is not paid")
Run

Running examples is part of paid access. There the same code runs inside the article: editor, run and check next to the paragraph. Three free days →

is None, not == None — that is the convention and it is safer.

How this looks in a check

live example

expected = 200
actual = 404

if actual == expected:
    print("OK")
else:
    print(f"FAIL: expected {expected}, got {actual}")
Run

Running examples is part of paid access. There the same code runs inside the article: editor, run and check next to the paragraph. Three free days →

That is already a check, only written by hand: in a test you write assert instead of if, and the language builds the failure message for you — see assert and errors.

Practice here: Validate an order number

Common mistakes

A missing colon at the end of the if line — SyntaxError. The colon is required, it opens the block.

Comparing a string with a number: "200" == 200 is always False. Convert to one type — int(code) == 200.

Writing = instead of ==: inside an if Python answers SyntaxError, while in a plain line it silently stores a value instead of comparing.

In short

  • = stores, == asks; the result of a comparison is True or False.
  • if / elif / else picks a branch; the first match wins and else catches the rest — without it an unexpected response passes silently.
  • A four-space indent is part of the language, not formatting.
  • and, or, not combine conditions, and the comparison after or is written out in full: code == 404 or code == 410.
  • Empty string, empty list, 0 and None count as false; "no value" is checked with is None.