Quick Reference Pages

Testing Reference

The optimism.py module that we provide allows you to easily set up tests for your code, and establish expectations for their results. It also has a trace function which is useful for debugging. This page provides a brief overview of the functions in that module and how to use them.

You can download the latest version of optimism.py at this link:

optimism.py

Getting Started

To use the module, you will need to import it, like this:

from optimism import *

Or like this:

import optimism as opt

If you use the second version, you'll have to write opt. in front of every function from the module.

Then you'll want to define some tests using the testCase function and establish some expectations for each test using expectResult and/or expectOutputContains (but make sure to call captureOutput if you want to use expectOutputContains).

Here's a small example:

import optimism as opt

x = 5
opt.testCase(x + 3)
opt.expectResult(8) # this expectation will be met

opt.testCase(x - 3)
opt.expectResult(3) # this expectation will not be met

# A custom function which prints something
def display(message):
    print('-' + message + '-')

# Using captureOutput
opt.captureOutput()
opt.testCase(display('Hello'))
opt.expectOutputContains("-Hello-")

If your expectations aren't met, the trace function can be helpful in figuring out more about why. Given any expression, it returns the value of that expression, but also prints a message about what the expression was and what value it got. A small example:

import optimism as opt

x = opt.trace(1 + 2) * 4
opt.trace(x)

y = opt.trace(x // 20)
opt.trace(y)

z = opt.trace(x / y)

This will result in the following output:

3 1 + 2 ⇒ 3
4 x ⇒ 12
6 x // 20 ⇒ 0
7 y ⇒ 0
Traceback (most recent call last):
  File "t.py", line 9, in <module>
    z = opt.trace(x / y)
ZeroDivisionError: division by zero

Each line begins with the line number of the code that called trace, followed by the expression it was given and then an arrow and the resulting value. Note that the final trace doesn't happen, because Python crashes before that point. However, the trace of the variable y shows why: since y has the value 0, we cannot divide by it.

Reference

Optimism Testing Functions
Basic Functions
Function Effect Example(s)
trace Show the line number, an expression, and its result. Use it to figure out what's happening in your code.
x = trace(1 + 2)
y = trace(x + 3)
trace(y)
testCase Establish a test case: the code to be tested. testCase(1+1) testCase(myFunction(x, y))
expectResult Establish an expectation for the result of the most recent test case.
x = 3
testCase(x+1)
expectResult(4)
expectOutputContains Establish an expectation for part of the printed output of the most recent test case. The expectation will succeed as long as the text you give it appears somewhere in the captured output. You can use this multiple times per test case.
captureOutput()
testCase(print('Hello'))
expectOutput('ell')
expectOutput('lo')
Managing Output
Function Effect Example(s)
captureOutput Begin capturing output. Anything printed will be captured for testing (via expectOutput) instead of showing up. Call before testCase. Output will be captured for ALL subsequent test cases until restoreOutput is called.
captureOutput()
testCase(print('Hi')
expectOutput('Hi')
showOutput / suppressOutput Show (or hide again) the output that's being captured. By default, captured output is not displayed as normal. showOutput will cause it to be both captured and displayed, while suppressOutput will reverse that and cause it to be hidden again.
captureOutput()
print('hidden')
showOutput()
print('visible')
suppressOutput()
print('hidden')
resetOutput Erases all currently captured output. This happens automatically when testCase is called, but you can call this function yourself if you need to.
captureOutput()
print('erased')
resetOutput()
print('captured')
restoreOutput Stops capturing output. Further output will show up as normal, and unlike showOutput, that output will no longer be available for testing using expectOutput.
captureOutput()
testCase(print('hi'))
expectOutput('hi')
restoreOutput()
print('visible')
Supplying Input
Function Effect Example(s)
provideInput Specifies what input values will be used when input is called (as a multi-line string, one input per line). Ignores a blank first line and adds a newline at the end if there isn't one.
provideInput('''
one
two
''')
testCase(input('0+1? '))
expectResult('one')
testCase(input('1+1? '))
expectResult('two')
restoreInput Resumes normal input behavior, where the program pauses and the keyboard is used to supply input. This undoes the effect of provideInput.
provideInput('Hi')
x = input('?')
restoreInput()
y = input('??')
Testing Entire Files
Function Effect Example(s)
runFile Runs the currrent file, minus any testing calls (including this one!). Use it inside testCase to test behavior of the whole file. Using captureOutput and provideInput probably also makes sense.
print('hello')
captureOutput()
testCase(runFile())
expectOutput('hello')
expectOutput('goodbye')
restoreOutput()
print('goodbye')
Other Controls
Function Effect Example(s)
detailLevel Sets the detail level for messages about expectations. Use an integer between -1 and 1, where higher numbers are more detailed. 0 is the default. detailLevel(-1) detailLevel(1)
showSummary Prints a summary of the expectation results so far. Call it at the end of all of your tests to quickly see how many passed or failed.
testCase(1+1)
expectResult(1)
testCase(2+2)
expectResult(4)
showSummary()