Testing with unittest

unittest is Python's built-in testing framework for writing small checks that confirm your code produces the right results and keeps producing them as it changes.

Learn Testing with unittest in our free Python course — an interactive lesson with runnable examples, a practice exercise and a quick reference.

Part of the free Python course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

Tests are how professionals ship code with confidence. Write them once and they guard your project forever, catching the bug the instant you introduce it.

Subclass unittest.TestCase and add methods whose names start with test_ . Inside each, call your code and assert the result. The framework discovers and runs every test_ method for you:

Normally you run a test file from the terminal with python -m unittest or by calling unittest.main() . To see results here in the browser editor, we run the suite in-process and inspect the result object — the code editor below does exactly that:

Good code fails loudly on bad input, and good tests check that it does. Use assertRaises as a context manager to confirm a specific exception is raised:

When an assertion is wrong, the test fails — and the result object tells you so. Here is the same machinery detecting a deliberately broken test:

A failure is an assertion that did not hold; an error is an unexpected exception in the test itself. The result object reports both separately via result.failures and result.errors .

When several tests need the same starting object, build it once in setUp — it runs before every test, giving each a fresh, identical fixture so they cannot interfere with one another:

The concepts transfer perfectly: master fixtures, assertions, and isolation here, and pytest will feel like the same ideas with less boilerplate.

Complete the test so it checks a value and a raised exception. Replace each ___ and match the expected output.

First blank: test_ — so the method is def test_basic(self): . Only methods starting with test_ run.

Second blank: assertRaises — so the line is with self.assertRaises(TypeError): .

✅ Start every test method with test_ : def test_add(self): .

✅ Use the context-manager form so the call happens inside: with self.assertRaises(ValueError): divide(1, 0) .

❌ Reversing assertEqual arguments and misreading the message

✅ Convention is assertEqual(actual, expected) — the value from your code first, the expected value second.

Write tests for a small age validator: it returns True for a valid adult age and raises ValueError on a negative age. Cover the happy path, a boundary, and the error case.

Go deeper with the official Python documentation:

Lesson complete — you can prove your code works!

You can write a TestCase with test_ methods, assert with assertEqual , assertTrue , and assertRaises , share fixtures with setUp and tearDown , run a suite in-process to read its result, and you know how unittest maps onto pytest.

🚀 Up next: Advanced Type Hints — generics, Protocol, and TypedDict for safer code.

Practice quiz

What must a unittest test method's name start with to be discovered and run?

  • check_
  • assert_
  • test_
  • unittest_

Answer: test_. Only methods whose names start with test_ are run. A method like check_add silently never runs, so the suite may be testing nothing.

What do you subclass to create a test case?

  • unittest.TestCase
  • unittest.Test
  • unittest.Suite
  • unittest.Runner

Answer: unittest.TestCase. You subclass unittest.TestCase and add test_ methods; the framework discovers and runs each one.

Which assertion passes only when two values are equal?

  • assertTrue(a, b)
  • assertSame(a, b)
  • assertIs(a, b)
  • assertEqual(a, b)

Answer: assertEqual(a, b). assertEqual(a, b) passes when a == b and is the assertion you'll use most often.

How do you assert that code raises a specific exception?

  • self.assertRaises(ValueError, divide(1, 0))
  • with self.assertRaises(ValueError): divide(1, 0)
  • self.assertError(ValueError)
  • with self.expectRaises(ValueError): divide(1, 0)

Answer: with self.assertRaises(ValueError): divide(1, 0). Use the context-manager form so the call happens inside the block. Writing assertRaises(ValueError, divide(1, 0)) calls divide first, letting the error escape.

When does setUp run?

  • Before every single test method
  • Once before the whole test class
  • Only before the first test
  • After each test method

Answer: Before every single test method. setUp runs before each test method, giving every test a fresh, identical fixture so tests cannot interfere with one another.

When does tearDown run?

  • Before each test method
  • Once at the end of all tests
  • After each test method
  • Only if a test fails

Answer: After each test method. tearDown runs after each test method — the place to clean up the fixtures that setUp created.

In unittest, what is the difference between a 'failure' and an 'error'?

  • They are the same thing
  • A failure is an assertion that did not hold; an error is an unexpected exception in the test
  • A failure is in setUp; an error is in tearDown
  • A failure stops the suite; an error does not

Answer: A failure is an assertion that did not hold; an error is an unexpected exception in the test. A failure means an assertion was false; an error means the test code itself raised an unexpected exception. The result reports them separately.

Which method tells you whether a whole test run passed?

  • result.passed()
  • result.isOk()
  • result.success
  • result.wasSuccessful()

Answer: result.wasSuccessful(). result.wasSuccessful() returns True only if there were no failures or errors in the run.

Which assertion passes when its argument is truthy?

  • assertEqual(x)
  • assertTrue(x)
  • assertTruthy(x)
  • assertBool(x)

Answer: assertTrue(x). assertTrue(x) passes when x is truthy — handy for boolean conditions like isinstance checks.

How does unittest differ from pytest in writing assertions?

  • unittest uses plain assert; pytest uses self.assertEqual
  • Both require @pytest.fixture
  • unittest uses self.assertEqual(a, b); pytest uses the plain assert statement
  • Neither supports fixtures

Answer: unittest uses self.assertEqual(a, b); pytest uses the plain assert statement. unittest is class-based with self.assert* methods; pytest lets you write plain functions and use the normal assert statement with less boilerplate.