I try to use function assert, but it's doesn't working. Writing "Assertion error". Can you explain why.
def parse(query: str) -> dict:
return {}
if __name__ == '__main__':
assert parse('https://example.com/path/to/page?name=ferret&color=purple') == {'name': 'ferret', 'color': 'purple'}
assert parse('https://example.com/path/to/page?name=ferret&color=purple&') == {'name': 'ferret', 'color': 'purple'}
assert parse('http://example.com/') == {}
assert parse('http://example.com/?') == {}
assert parse('http://example.com/?name=John') == {'name': 'John'}
def parse_cookie(query: str) -> dict:
return {}
if __name__ == '__main__':
assert parse_cookie('name=John;') == {'name': 'John'}
assert parse_cookie('') == {}
assert parse_cookie('name=John;age=28;') == {'name': 'John', 'age': '28'}
assert parse_cookie('name=John=User;age=28;') == {'name': 'John=User', 'age': '28'}
assert does exactly that - it asserts that the expression following it is true. In your case it means that this expression is false (it returned None or a non-truthy value). It is typically used in testing code to, well, assert that test condition is true and fail a test otherwise.
Normally you do not use assert outside of tests though, the only exception would be a case where you test for a condition that absolutely must not happen and the program should be stopped if the control flow ever comes to evaluate that particular assert as true.
Assert is used when debugging code, meaning if the condition is true then nothing will happen and if the condition is false then AssertionError is raised.
But keep in mind that stackoverflow is not a toturial website and you need to ask the question more specificly so we can help you with your code, Hope i helped :)
Related
I'm trying to write examples of how NOT to write tests in pytest. For this, I'd like to be able to somehow mod test functions so that they fail if any assert passes. This is easy with one assert using a decorator:
def faulty_test(test_fn):
def new_test_fn():
try:
test_fn()
except AssertionError:
pass
else:
raise AssertionError
return new_test_fn
#faulty_test
def test_sth():
assert 1 == 2
but I'd like to do it for a function with any number of asserts. The test should fail if any of the asserts pass. It doesn't have to be a decorator
Perhaps you should think about it this way: At the point of the exception, execution leaves the try block and enters the except block. You cannot, at least in any simple way I can think of, re-enter the try block from within the except block.
And perhaps I'm misunderstanding the question, but couldn't you simply replace your assertions with the inverse of those assertions? If you want to assert that a thing is false, you can:
assert not (1 == 2)
If for some reason you're dealing with a situation where you assume that the given functions will, for some reason, always fail their asserts and you cannot change that, there does not seem to be any way to ensure all the asserts run, since the design of assertions is to intentionally abort immediately on failure.
I guess it doesn't have to be multiple asserts. You can write:
assert a == b or c == d or # so on
Any condition is True will cause the assertion to pass.
If you "number" the assertions, catching an assertion with a value greater than 0 implies the previous assertions passed.
def faulty_test(test_fn):
def new_test_fn():
try:
test_fn()
except AssertionError as exc:
if exc.args[0] > 0:
# Assertions 0 through exc.args[0]-1 all passed
raise AssertionError
else:
raise AssertionError
return new_test_fn
#faulty_test
def test_sth():
assert 1 == 2, 0
assert 2 == 3, 1
assert 3 == 4, 2
You should probably handle that in the function code by using a _debug or other (hidden) argument. Then you can use a decorator on that. What I would do:
def deco(inF):
def wrapper(*args, **kwargs):
kwargs['_debug'] = True
output = inF(*args, **kwargs)
#print(output)
for i, _ in enumerate(zip(*output)):
condition, msg = _
# this will raise the first passed assert. Otherwise loop again to print all "passed" assertions, then raise
if not condition:
raise AssertionError('Condition {} succeded: {} is False'.format(1 + i, msg))
return output
return wrapper
#deco
def f(i, j , k, _debug=False):
cond1, msg1 = i == 1, 'i is not 1'
cond2, msg2 = j == 2, 'j is not 2'
cond3, msg3 = k == 3, 'k is not 3'
assert cond1 or _debug, msg1
assert cond2 or _debug, msg2
assert cond3 or _debug, msg3
if _debug:
return (cond1, cond2, cond3), (msg1, msg2, msg3)
return i + j + k
f(1,1,5)
>>AssertionError: Condition 2 succeded: j is not 2 is False
def fn():
return {'Name': 'John'}, False #, {'extra': 'welcome', 'to': 'dev#dsds.com'}
results, *returns = fn()
is_multiple = returns[0] if len(returns) > 0 else False
extra_params = returns[1] if len(returns) > 1 else None
print(is_multiple)
print(extra_params)
Any other alternative ways to check whether the extra_params is empty or not?
Except the above len solution or without using the try catch IndexError exception handler..
A better solution would be to define your value returned by your function as a three value tuple and use None or an empty dict if you don't have a value eg:
def fn():
return {'Name': 'John'}, False, None
results, is_multiple, extra_params = fn()
This is much simpler and avoids the need for checking lengths.
If you are writing backwards-compatible code, for example, an alternative is to not do the tuple unpacking up front eg:
def fn():
return {'Name': 'John'}, False, # {}
response = fn()
# At least two items must be returned else length might not be valid.
if len(response) == 2:
results, is_multiple = response
extra_params = None
elif len(response) == 3:
results, is_multiple, extra_params = response
else:
raise ValueError("Unexpected response...")
Although I would recommend the first much simpler design, there are lots of ways to mess up the second design and cause unexpected errors.
I have the following Python dict. I'm trying to do a check with n if statement that payload contains "token"
{'payload': {'token': '3u4td7393493d9304'}, 'type': 'send'}
Below is the python code
if message['payload'] == 'token':
print("GOT IT");
print(message)
elif message['payload']['type'] == 'timedout':
print("TIMEDOUT!")
elif message['payload'] == 'locked':
print("LOCKED!")
done.set()
The current if statement for token is wrong. What is the proper way of checking if payload has "token" inside it?
To check whether a dictionary d contains key k, use k in d:
message = {'payload': {'token': '3u4td7393493d9304'}, 'type': 'send'}
# {'payload': {'locked': 'lockId'}, 'type': 'send'}
if 'token' in message['payload']:
print("GOT IT");
print(message)
print(f"token: {message['payload']['token']}")
elif message['type'] == 'timedout':
print("TIMEDOUT!")
elif 'locked' in message['payload']:
print("LOCKED!")
print(f"locked value: {message['payload']['locked']}")
# done.set()
Since you have nested dictionaries, message['payload'] is itself a dictionary, therefore to check whether it has key 'token', you have to use 'token' in message['payload'].
I've also added an example that demonstrates how to access the value that corresponds to the key 'token'.
Side note: this if-else does not seem to be exhaustive, and it lacks the default case. Maybe you should approach it a bit more systematically, and first make sure that you deal with every possible type of the message, and then for each type deal with each kind of payload.
The way i understand your question is you want to find whether or not 'token' exist in payload, regardless of the token value?
If yes, simple in array would suffice:
dc = {'payload': {'token': '3u4td7393493d9304'}, 'type': 'send'}
'token' in dc['payload'] # this would result in True
Just create a function which return True or False , now whenever you want to check pass value to that function and check :
def check_token(data_):
if 'token' in data_['payload']:
return True
else:
return False
Now back to your code , you can simply check by passing value to this function :
if check_token(data)==True:
print("GOT IT")
output:
GOT IT
I am trying to do a unit-test but don't quite get why these 2 dicts show up as not equal. I was wondering if someone could give me an explanation for this occurrence. My code is...
import unittest
class TestEmailValidator(unittest.TestCase):
def test(self):
known_dict = {
'debo#foobar.com': True,
'debo#gmail.com': False
}
result_dict = {}
for key in known_dict.keys():
result_dict[key] = is_email_valid(key)
# debugger results
# result_dict = {
# 'debo#foobar.com': True,
# 'debo#gmail.com': False
# }
if self.assertEqual(known_dict, result_dict):
print "is_email_valid passed"
else:
print "is_email_valid failed"
if __name__ == '__main__':
unittest.main()
I get the same result for assertEqual, assertEquals and assertDictEquals. I have tried assigning result_dict to known_dict before the test, but that did not pass either.
It would be great if someone could point me to why this could be happening.
You are misusing the assert. All the assertXYZ methods don't return a boolean value, they just raise an exception if the assertion fails. As these methods don't return anything, they implicitly return None. When evaluating None as a boolean it's treated as false, and hence your test prints is_email_valid failed, even though the test actually passes.
Could you help me to figure out the anti patterns and problems in my code. I can't seem to figure out the anti patterns of this code and the solution. I've fixed some errors but I believe there are still many mistakes:
class Stringchecker():
def __init__(self):
pass
def check_pass(people_text):
result = []
for k in people_text:
if people_text[k] =="pass":
result.append(k)
else:
return result
if __name__== "__main__":
people_text = {'Mia': 'pass', 'Mike': 'fail', 'Jack': 'pass')
sc = StringChecker()
print sc.check_pass(people_text)
Your code has several syntax issues and some logic problem. Also you are not using class constructor properly, just giving it a pass is not a good practice. Another thing is to use list comprehension for your check_pass method. I made some corrections to your code:
class StringChecker(object):
def __init__(self, people_text):
self.people_text = people_text
def check_pass(self):
return [k for k, v in self.people_text.items() if v == "pass"]
if __name__ == "__main__":
sc = StringChecker({'Mia': 'pass', 'Mike': 'fail', 'Jack': 'pass'})
print sc.check_pass()
Output:
['Mia', 'Jack']
Note: Updated list comprehension with suggestion from #JLPeyret
Errors:
not using self as first parameter to check_pass
returning the result after the first failure (if no failures, result will not be returned; if a failure occurs before successes would, result won't have all the data)
return result should be at the same indentation level as for k in ...
Anti-patterns:
a class with only one non-__init__ method (just use a function)
(assuming else branch has a pass instead) - useless else branch