Reputation: 1
I'm new to pytest and new-ish to python. I am doing some testing to try and figure this out with a pretty basic python script and I've been banging my head against a wall for the last few days trying to figure this out.
The python script is a basic math quiz that I pulled down from Github that provides a series of questions in a timed window. The python script is here:
#!/usr/bin/python3
import time
import random
import operator
import argparse
from builtins import input
from argparse import RawTextHelpFormatter
def build_questions():
"""Define and parse command line arguments to generate a list of dictionaries.
Each dictionary defines a first and second term, and math operator method and symbol
:return: List of questions
"""
questions = []
operators = {}
description = (
"Description:\n"
"\n"
"Runs a timed quiz of math equations based on a range from 1 to 10. "
"User can specify the start and end of the range for both terms.\n"
)
epilog = (
"Examples:\n"
"\n"
"python3 math_quiz.py \n"
"python3 math_quiz.py -r Randomize entire set of terms\n"
"python3 math_quiz.py -as Add and Subtract entire set of terms\n"
"python3 math_quiz.py -asr Add and Subtract randomized entire set of terms\n"
"python3 math_quiz.py -s1 5 -e1 5 Add 5's\n"
"python3 math_quiz.py -s1 5 -e1 5 -as Add and Subtract 5's\n"
"python3 math_quiz.py -s1 5 -e1 5 -e2 5 -md Multiply and Divide 5 with 1 - 5\n"
)
parser = argparse.ArgumentParser(prog = 'python3 math_quiz.py', usage = '%(prog)s [options]',
description = description, epilog = epilog, formatter_class = RawTextHelpFormatter)
parser.add_argument("-r", "--random", help = "Randomize set of questions.", action = "store_true")
parser.add_argument("-s1", "--start_first", help = "Specify start of range for first term",
type = int, default = 1)
parser.add_argument("-e1", "--end_first", help = "Specify end of range for first term",
type = int, default = 10)
parser.add_argument("-s2", "--start_second", help = "Specify start of range for second term",
type = int, default = 1)
parser.add_argument("-e2", "--end_second", help = "Specify end of range for second term",
type = int, default = 10)
parser.add_argument("-a", "--add", help = "(Default) Add the terms", action = "store_true")
parser.add_argument("-s", "--subtract", help = "Subtract the terms", action = "store_true")
parser.add_argument("-m", "--multiply", help = "Multiply the terms", action = "store_true")
parser.add_argument("-d", "--divide", help = "Divide the terms", action = "store_true")
parser.add_argument("-n", "--negative", help = "Allow negative equations", action = "store_true")
args = parser.parse_args()
if args.add or not (args.subtract or args.multiply or args.divide):
operators['add'] = '+'
if args.subtract:
operators['sub'] = '-'
if args.multiply:
operators['mul'] = 'x'
if args.divide:
operators['floordiv'] = '/'
terms_1 = list(reversed(range(args.start_first, args.end_first + 1)))
terms_2 = list(reversed(range(args.start_second, args.end_second + 1)))
for term_1 in terms_1:
for term_2 in terms_2:
for method, symbol in operators.items():
tmp_1, tmp_2 = term_1, term_2
if method == 'floordiv':
tmp_1 = term_1 * term_2
if not args.negative and method == 'sub' and term_2 > term_1:
tmp_1, tmp_2 = term_2, term_1
questions.append({'first': tmp_1, 'second': tmp_2, 'method': method, 'symbol': symbol})
if args.random:
random.shuffle(questions)
return questions
def run_quiz(questions):
"""Loop through and display questions for user responses, and evaluate their correct answer.
:param questions:
:return:
"""
time_0 = time.time()
for question in questions:
# evaluate an expression for the given terms and operation, e.g. operator.add(3, 4)
expression = "operator.{}({}, {})".format(question['method'], question['first'], question['second'])
correct = eval(expression)
# prompt user with a neatly formatted math question
question_str = "{} {} {} = ".format(str(question['first']), question['symbol'], str(question['second']))
user_response = input(question_str)
if str(correct) != str(user_response):
# note the user's incorrect response
print("Incorrect :( . . . The answer is " + str(correct))
time_delta = time.time() - time_0
m, s = divmod(time_delta, 60)
print('Time: %02d:%02d' % (m, s))
def main():
questions = build_questions()
run_quiz(questions)
if __name__ == "__main__":
main()
I am trying to build a fairly simple unit test to run against this python script. Based on reading the pytest documentation, this is what I have come up with:
"""
Math quiz pytest
"""
import math_quiz
def run_quiz():
assert 20 == math_quiz.add(10,10)
def run_quiz1():
assert 20 == math_quiz.add(11,11)
I would expect that I would have one passed test and one failed test, as one assertion is correct and one is wrong. However, this is my output when I run pytest:
================================= test session starts ================================
platform darwin -- Python 3.11.3, pytest-7.3.1, pluggy-1.0.0
rootdir: /Users/smquintard/Documents/Training/DevOps/GitHub/math_quiz
collected 0 items
==================== no tests ran in 0.00s =========================
I'm doing something wrong with the setup of the pytest file...can someone point me in the right direction of what I'm doing here that is incorrect? TIA for the help!
Upvotes: 0
Views: 64
Reputation: 329
Name of your file with tests must start with "test_" as well as names of your test functions:
"""
Math quiz pytest
"""
import math_quiz
def test_run_quiz():
assert 20 == math_quiz.add(10,10)
def test_run_quiz1():
assert 20 == math_quiz.add(11,11)
See https://docs.pytest.org/en/7.1.x/explanation/goodpractices.html#conventions-for-python-test-discovery for additional details
Upvotes: 1