you could use Python built-in capability to show custom exception message:
assert response.status_code == 200, f"My custom msg: actual status code {response.status_code}"
Or you can built a helper assert functions:
def assert_status(response, status=200): # you can assert other status codes too
assert response.status_code == status, \
f"Expected {status}. Actual status {response.status_code}. Response text {response.text}"
# here is how you'd use it
def test_api_call(self, client):
response = client.get(reverse('api:my_api_call'))
assert_status(response)
also checkout: https://wiki.python.org/moin/UsingAssertionsEffectively
Answer from Dmitry Tokarev on Stack Overflowyou could use Python built-in capability to show custom exception message:
assert response.status_code == 200, f"My custom msg: actual status code {response.status_code}"
Or you can built a helper assert functions:
def assert_status(response, status=200): # you can assert other status codes too
assert response.status_code == status, \
f"Expected {status}. Actual status {response.status_code}. Response text {response.text}"
# here is how you'd use it
def test_api_call(self, client):
response = client.get(reverse('api:my_api_call'))
assert_status(response)
also checkout: https://wiki.python.org/moin/UsingAssertionsEffectively
Improving @Dmitry answer, you also can return tuple of variables using something like this:
assert response.status_code == 200, (response.status_code, response.json())
Videos
Not when using all as it does not expose the "iteration variable". You will need an explicit, nested loop. You also forgot the f'' prefix to denote an f-string:
for l1 in [['a']]:
for l2 in l1:
for e in l2:
assert isinstance(e, int), f"Values of the dictionnary
aren't lists of integers. Assert found in '{l2}'"
AssertionError: Values of the dictionnary aren't lists of integers. Assert found in 'a'
You can use an assignment expression to capture the "witness" to all returning False. To do this, we'll do away with some generators. We'll use map to apply isinstance to each value of l2, which lets us capture the current value of l2 in a variable that will persist for use in the assert message. We'll also use itertools.chain to eliminate the need for the name l1.
from itertools import chain
def is_int(x):
return isinstance(x, int)
sequence = {
'key1': [[1, 2, 3], [4, 5, 6]],
'key2': [[7, 8, 9], ['a', 11, 12]]
}
assert all(all(map(is_int, (witness := l2)))
for l2 in chain(*sequence.values())), \
f"Values of the dictionary aren't lists of integers. Assert found in '{witness}'"
With a little modification, you can iterate over sequence.items() so that you can also capture the key whose list contains the offending l2. I leave that as an exercise for the reader.
The assert statement exists in almost every programming language. It has two main uses:
It helps detect problems early in your program, where the cause is clear, rather than later when some other operation fails. A type error in Python, for example, can go through several layers of code before actually raising an
Exceptionif not caught early on.It works as documentation for other developers reading the code, who see the
assertand can confidently say that its condition holds from now on.
When you do...
assert condition
... you're telling the program to test that condition, and immediately trigger an error if the condition is false.
In Python, it's roughly equivalent to this:
if not condition:
raise AssertionError()
Try it in the Python shell:
>>> assert True # nothing happens
>>> assert False
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError
Assertions can include an optional message, and you can disable them when running the interpreter.
To print a message if the assertion fails:
assert False, "Oh no! This assertion failed!"
Do not use parenthesis to call assert like a function. It is a statement. If you do assert(condition, message) you'll be running the assert with a (condition, message) tuple as first parameter.
As for disabling them, when running python in optimized mode, where __debug__ is False, assert statements will be ignored. Just pass the -O flag:
python -O script.py
See here for the relevant documentation.
Watch out for the parentheses. As has been pointed out in other answers, in Python 3, assert is still a statement, so by analogy with print(..), one may extrapolate the same to assert(..) or raise(..) but you shouldn't.
This is wrong:
assert(2 + 2 == 5, "Houston we've got a problem")
This is correct:
assert 2 + 2 == 5, "Houston we've got a problem"
The reason the first one will not work is that bool( (False, "Houston we've got a problem") ) evaluates to True.
In the statement assert(False), these are just redundant parentheses around False, which evaluate to their contents. But with assert(False,) the parentheses are now a tuple, and a non-empty tuple evaluates to True in a boolean context.