In this class, you will complete a daily Program of the Day (POTD) assignment to build your coding skills. These short programs are graded using automated tests - another program that runs your program and checks whether its behavior is correct. We provide you with this test program so you can check your work. This way, you will know when you have arrived at a correct and working solution to the POTD.
This guide walks you through:
The prompt for each POTD is linked from the Schedule table on the course webpage; these are labeled P##, where ## is the number of the lecture when the program is assigned. The program is due before the following class (not counting exam days).
As an example, here’s the link to the first POTD prompt: P01. Throughout this document, we’ll use P01 as a running example, but the process applies for all POTDs.
You can find the skeleton code and test program for each POTD at this url:
https://github.com/csci141/POTD/tree/2520_wehrwein/skel.
This link can also be found in the Quick Links above the Schedule
table on the course webpage. On this page, you’ll see a list of files.
All the files that pertain to P01 have filenames with the prefix
P01_
. Usually, you’ll find a skeleton file
(P01_quiz1.py
) and a test program
(P01_quiz1_test.py
).
To download the files, click on the file you’d like to download;
you’ll see a preview of the file in a pane. At the top right, click the
“Download raw file” button to download
the file to your computer.
Download the skeleton, test program, and any others with the corresponding prefix, to the lab computer or personal computer you’re working on. It’s strongly recommended to you set up a folder to hold all your code for this class. You may want to create a subfolder for each POTD. Move the files from your downloads folder (or wherever they landed) into your CSCI 141 folder.
You may need to install the pytest
package, which our
test code relies on. In Thonny:
Make sure that both files (P01_quiz1.py
and
P01_quiz1_test.py
) are in the same directory, and that
there are no other python files in this directory. If they are not in
the same folder or other python files are present in that folder, the
test program will may run correctly.
Open the test program (P01_quiz1_test.py
) in Thonny and
press the friendly green run button to run the tests on your
solution.
If your program passes the tests, you’ll see an output like this (there will be some other output prior to this that you can safely ignore):
P01_quiz1_test.py::test_quiz1 PASSED [100%]
============================== 1 passed in 0.09s ===============================
Consider this test program for P01:
#POTD 1 test
import pytest
import subprocess
import sys
= "P01_quiz1"
basename
def test_quiz1():
= subprocess.Popen(
process "P01_quiz1.py"],
[sys.executable, =subprocess.PIPE,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=True
text
)#When prompted for input, enter newline
= process.communicate(input="\n")
stdout, stderr
#verify that the input prompt had 'What if' in the text string (capitalization and spacing matters!).
assert "What is" in stdout
"P01_quiz1_test.py", "-vv", "--showlocals", "-p", "no:faulthandler"]) pytest.main([
There’s plenty of unfamiliar stuff here, and that’s fine; but notice
the assert
statement near the bottom: this indicates what
the program is testing for. In this case, it is looking for the string
"What is"
to be printed to the screen as part of a user
input request (the variable stdout
holds a string with the
program’s output).
Here we’re not testing the fully specified functionality of the
program, but in general the tests will be more comprehensive. You should
always make sure your code’s output matches the specified format
exactly. If it doesn’t match exactly (e.g., in this case if you’d
printed What's
instead of What is
), the
program will fail tests.
I rarely write working code on the first try. If your code isn’t passing the tests, the test program provides output that can be helpful in understanding why. Understanding this output can be intimidating at first, but it gets easier as you get used to knowing what to look for.
Let’s run with the example above, where I wrote a P01 solution that
prints What's 4 * 6?
instead of
What is 4 * 6?
. Running the test program, I see this
output:
=================================== FAILURES ===================================
__________________________________ test_quiz1 __________________________________
def test_quiz1():
process = subprocess.Popen(
[sys.executable, "P01_quiz1.py"],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True
)
#When prompted for input, enter newline
stdout, stderr = process.communicate(input="\n")
#verify that the input prompt had 'What if' in the text string (capitalization and spacing matters!).
> assert "What is" in stdout
E assert 'What is' in "What's 4 * 6?\n4 * 6 is 24\n"
process = <Popen: returncode: 0 args: ['/Applications/Thonny.app/Contents/Frameworks/P...>
stderr = ''
stdout = "What's 4 * 6?\n4 * 6 is 24\n"
P01_quiz1_test.py:22: AssertionError
=========================== short test summary info ============================
FAILED P01_quiz1_test.py::test_quiz1 - assert 'What is' in "What's 4 * 6?\n4 * 6 is 24\n"
============================== 1 failed in 0.10s ===============================
This is a lot of output! Let’s look carefully at a few parts:
The first section of the ouptut (after the header line
test_quiz1
) shows the code of the test program with an
arrow (>
) pointing at the line where the assertion
failed, causing the test to fail. Here, it’s the line
assert "What is" in stdout
.
More details are provided on the line below: the line beginning
with E
shows the string that the program expected to find
(What is
) and the string it expected to find it in (in this
case, the program’s output, stored in stdout
):
"What's 4 * 6?\n4 * 6 is 24\n"
With experience, looking carefully at this will immediately clue you in to the bug: the output isn’t as expected.
On the line before the short test summary info line, it shows the
test file and line number (P01_quiz1_test.py:22
) where the
error happened, as well - we can also use this to locate the assertion
that failed on line 22 of that file.
You may encounter a variety of errors that cause tests to fail. Here’s a little more detail about the most common ones.
When encountering an error, you may find it helpful to switch back to running your program “manually” with inputs similar to what the test program is using - this may make it easier to catch bugs. However, understanding what cases the test program is checking can be helpful in narrowing down the source of the error.
This is the vaguest error. This will frequently happen when your code does not meet the requirements. It could mean that your code is not returning or outputting the correct thing at all. The test program is case sensitive and cares about all commas and periods. Make sure that it has all of those. Review the exact output of the test program and check to see if your program’s output matches the exact output the program is looking for. This error is likely to occur because your code does not match the exact syntax of the output. Make sure to go and review the exact syntax of the output in the test program. There are POTDs where you will be expected to exactly match a program with newlines and placement of print statements.
In this case, the program threw a type-related error while running. This is usually because you tried to do an operation that isn’t valid, such as divide a string by a number. The fix is usually making sure that you’ve done the proper type conversions before performing the operations.
This is a more generic kind of error for other reasons your program may have thrown an error while running. The test program will output the error message, which can help you understand the reason for the error.
These errors means that you have some syntax-related error, such as incorrect indentation, a prohibited variable name, unmatched parentheses, etc. The test program will output the error message, which can help you understand the reason for the error.