Assertions and pytest.raises

RoadmapsPython

Overview

An **assertion** is a statement that checks if a condition is true. If it is false, the test fails. When we expect our code to fail and raise an error, we use **pytest.raises** to check that the error happens. Here is a worked example checking a student's score: ```python import pytest def get_grade(score): if score < 0: raise ValueError('Score cannot be negative') return 'Pass' if score >= 40 else 'Fail' def test_get_grade_pass(): assert get_grade(50) == 'Pass' def test_get_grade_negative(): with pytest.raises(ValueError): get_grade(-10) ``` The `assert` line checks that 50 returns 'Pass'. The `with pytest.raises` block checks that passing -10 correctly causes a `ValueError`. Now, look at this faded example where one step is blank: ```python import pytest def divide(a, b): if b == 0: raise ZeroDivisionError('Cannot divide by zero') return a / b def test_divide_by_zero(): with pytest._______(ZeroDivisionError): divide(10, 0) ``` To make this test check for the error, we fill in the blank with `raises`.

We must prove our code works when given good data, and that it safely catches bad data. Assertions handle the good, and pytest.raises handles the bad.

Where used: pytest test suites

Why learn this

Code walkthrough

import pytest

def test_catch():
  with pytest.raises(KeyError):
    my_dict = {'name': 'Rahul'}
    bad_key = my_dict['age']
  print('Caught the error')

test_catch()

Focus: with pytest.raises(KeyError):

Aha moment

import pytest

def test_no_error():
  with pytest.raises(ValueError):
    number = 5 + 5
  print('Done')

test_no_error()

Prediction: What happens when this test runs?

Common guess: It passes and prints 'Done'.

`pytest.raises` expects an error to happen. Since `5 + 5` does not raise a `ValueError`, the test actually fails because the expected error never occurred.

Common mistakes

Recall questions

Understanding checks

Where is the bug in this test?

The division `x = 1 / 0` happens outside the `pytest.raises` block.

The code that raises the error must be indented inside the `with pytest.raises` block so pytest can catch it. Otherwise, it just crashes the test.

What happens when this test runs?

The assertion fails and the print statement never runs.

When an `assert` statement fails, it immediately raises an AssertionError, stopping the rest of the code in that block from running.

Practice tasks

Check the error

Given this code, change the test to correctly check that `IndexError` is raised.

Challenge

Write an assertion and an error check

Write a test function named `test_logic` that first asserts `10 > 5`, and then uses `pytest.raises` to check that `int('abc')` raises a `ValueError`.

Continue learning

Previous: Test discovery and naming conventions

Previous: Custom exception classes

Return to Python Roadmap