Join us and get access to hundreds of tutorials and a community of expert Pythonistas.

Unlock This Lesson

This lesson is for members only. Join us and get access to hundreds of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Hint: You can adjust the default video playback speed in your account settings.
Hint: You can set the default subtitles language in your account settings.
Sorry! Looks like there’s an issue with video playback 🙁 This might be due to a temporary outage or because of a configuration issue with your browser. Please see our video player troubleshooting guide to resolve the issue.

doctest Module and assert Statements

In this lesson, you’ll learn about the doctest module and assert statements.

The doctest module is very useful to test code in a quick and easy manner by specifying an input and the correct output in the docstring and running python3 -m doctest file.py. You can check out the Python documentation on the doctest module.

assert statements are useful to write tests and check conditions in real time. The syntax looks like this:

assert <cond>, ([error_msg])

The error message is optional. Here’s an example:

>>>
>>> x = 5
>>> assert x > 0, "x is not positive"
>>> x = -1
>>> assert x > 0, "x is not positive"
AssertionError: x is not positive

To learn more about assert statements and Python exceptions, check out Assertions and Try/Except.

00:00 In this video, you’ll learn how to test your code in an interview. Obviously, you could use print statements—that’s probably your go-to to make sure that the output is correct. But here are some better ways.

00:10 Let’s first talk about the doctest module. The doctest module is a great quick way for you to make sure that the output of your code matches the correct output. Let’s define a class, class A.

00:23 Let’s have a f() function that just takes in no arguments, just self. Put our docstring, and here you’d probably write the function description, the argument types, maybe, the return type, anything else here.

00:38 And then this is where your test would go. Imagine you are running these lines in the Python interpreter—that’s why these ticks (>>>) sort of remind you of the Python interpreter.

00:48 You would write exactly the output that you would want. Let’s create an instance of our class and then just call a.f(). Let’s say we want a print statement and a return value.

00:59 We want it to print out Hello world, and it should return the string 'Hello world'. Remember, print() removes the quotes in the REPL, and when you return a string, it will have the quotes. So, our code would look something like print('Hello world') return 'Hello World'.

01:18 Save. python3 -m doctest testing.py.

01:24 Oh, it errored. Well, it said Expected: this, but Got: this. Well, I put a capital 'W' instead of lowercase 'w'.

01:34 Run it again. It worked. You can use the -v flag, which means verbose, which will actually print all the tests that were run. Let’s write another function that is just going to error.

01:46 Let’s make it a property. Let’s call it error().

01:51 Again, you’d put, maybe, "This function just errors". Then, A().error.

02:00 Traceback (most recent call last): ... Exception: I am an error.

02:11 Close the docstring, raise the Exception("I am an error"). So, you can use the doctest module to test if code errors by following this format. So, when we run it, 3 passed and 0 failed.

02:31 Again, you can do this with a function. def f() takes in an x. Maybe we want to validate input now. So, if we pass in a positive number, our function will print out Args: 10 and then just return a string 'Valid Input'. But if you pass in a negative number, it should throw an error. And let’s say you’d want to throw a ValueErrorbecause that’s a good error to throw when you have wrong arguments—and instead, say Invalid input.

03:02 So then, the code would be if x <= 0 raise ValueError("Invalid input").

03:11 Otherwise, print()—and then I’ll use an f-string—

03:18 f"Args: {x}". return 'Valid input'. Save, run. We see that 5 passed and 0 failed. So, doctests are really useful if, one, they give you a take-home coding project, where you actually have to write your own classes and write your own docstrings and your own tests, and give it back to them, and then they’ll look at whatever criteria. Or, if there’s a phone interview and they’re actually screen sharing your screen, and so you can actually run the doctest module.

03:44 Or maybe, you’re on an onsite and you’re using their computer and you actually have access to a terminal and a text editor. But what if you’re at a phone interview and the text code-sharing editor doesn’t have doctest module or a terminal? Well, then it’s really useful to use assert statements.

04:00 So, let’s have another function g() that takes in an x and is similar to the f() right here, but uses an assert statement.

04:07 The syntax is assert <condition> and then <error>. And this <error> is optional to pass in. But basically, what happens is if the condition is True, then you keep going with the code. If the condition is False, then you raise the error. So it’s almost the opposite of this. This, if the condition is True you raise the error, while this, if the condition is True you keep going.

04:30 So if you want to do the same thing as this, then you would do something like assert x >= 0—oops, sorry. Strictly greater than, because it has to be positive. And then, "Invalid input".

04:43 So if you run the file interactively…

04:51 and then do g(10), nothing happens. g(-1), you get an AssertionError: Invalid input. This is useful for checking arguments or maybe raising errors, but how would you use asserts to test your code? Let’s write a function lst_one_more(). Not the best function name, but it’ll basically take in two lists, and let’s write a docstring—not a doctest, but just a docstring—saying "This will mutate lst1"which means change it—"so that at index `i`, lst1[i] = lst2[i] + 1".

05:28 So basically, you change lst1 to be whatever the corresponding index’s element + 1, in lst2. So, "lst1 and lst2 should be the same length".

05:40 So, even if the interviewer tells you something should be something, you should still always get in the habit of checking arguments. You could use the assert statement to check the arguments—len(lst1) == len(lst2), and then just raise some error like "Length of lists not the same".

05:57 So, look how quick that was to just write that really easy assert statement, and then let’s write our code. for i in range(len(lst1)) lst1[i] = lst2[i] + 1.

06:11 Let’s save. And now below, I’ll write some tests using assert. lst1 = [1, 1, 1]. lst2 = [1, 2, 3]. Call the function lst_one_more(lst1, lst2).

06:27 Then, for i, x in enumerate(lst1): assert x == lst2[i] + 1. Now exit this, run our code—nothing happened, which is good. That means that this assert statement never raised an error, but let’s remove this + 1 here, run our code again, and now you get an AssertionError with the line number.

06:52 This is really useful because in an interview, many of the times, they want you to write your own tests and they want you to run the tests as you’re working on the problem. And as the tests grow, it’s very hard to just eyeball if your output is correct. For example, if I used a print statement—x, lst2[i]—saved it, print it—I mean, it’s a little easy to eyeball that it’s 1 +, but you can imagine with a bunch of different lines, a bunch of different output—it’s hard to eyeball and every minute counts, so using an assert will guarantee that you’re doing this check automatically instead of eyeballing it. As always, I will link the documentation for doctest and the assert statement down below.

07:31 In the next section, you’ll be using all of the tools that you learned in the previous three sections to go through an easy, medium, and hard coding interview question.

James Uejio RP Team on April 27, 2020

Here is a Real Python walkthrough on assert statements and Python Exceptions: Assertions and Try/Except

Become a Member to join the conversation.