Test Helpers
The framework includes a few nuggets to support unit testing using unittest
.
WizLibTestCase
A subclass of unittest.TestCase
to simplify patching inputs and outputs.
Because WizLib applications sometimes depend on user interaction, and other times depend on a stream on standard input, unit testing can require complicated patching. Inherit from WizLibTestCase
to make it easier.
Here's an example of how to use it. In this example, we send the word 'laughter' to the standard input stream and capture standard output in a variable for assertion.
# Inherit from WizLibTestCase - get everything in TestCase plus some
class DummyTest(WizLibTestCase):
# Test function - ass
def test_input_stdin(self):
# Use with instead of decorators (to take advantage of 'as') and combine them (if you like that style)
with \
self.patch_stream('laughter'), \
self.patchout() as o:
# Get going with the test
DummyApp.start('dance')
o.seek(0)
self.assertIn('laughter', o.read())
The actual methods that can be used are:
patch_stream(val: str)
- Patch stream input such as pipes for stream handlerpatch_ttyin(val: str)
- Patch input typed by a user in shell uipatcherr()
- Capture output from standard errorpatchout()
- Capture output from standard output
They are convenience methods; feel free to patch those objects separately if you prefer.
Fake values
Framework-aware mock objects
ConfigHandler.fake
Generates a fake WizLib configuration for testing. Example:
def test_fake_config(self):
a = DummyApp()
a.config = ConfigHandler.fake(dummy_vehicle='boat')
c = DriveCommand(a)
r = c.execute()
self.assertIn('Driving a boat', r)
Note that the keys passed to the fake
method contain hyphens, where values are referenced using hyphens, for example:
self.app.config.get('dummy-vehicle')
StreamHandler.fake
Generates a fake standard input stream. Example:
def test_fake_input(self):
a = DummyApp()
a.stream = StreamHandler.fake('madly')
c = DanceCommand(a)
r = c.execute()
self.assertEqual('Dancing madly', r)
Testing commands
Since much of the framework-specific functionality in a WizLib app lives in commands, some special guidelines and provisions apply.
Testing command execution only
To test only the execution of a command's functionality (independent of argument parsing), instantiate the command directly. It still requires a WizApp object as the first parameter, and arguments as successive parameters. Example:
def test_only_command(self):
a = DummyApp()
c = MathCommand(a, value=10.0)
r = c.execute()
self.assertEqual(6.0, r)
Testing a command with parsing
The WizLibApp.parse_run
method provides a quick entry point into the parsing and execution of a full command, without having to go through the class-level start/initialize steps. Just pass in the command and its arguments as function arguments, and the selected command will run. Used to test not just the functionality of the command itself, but also that arguments are correctly parsed. Example:
def test_parse_run(self):
with self.patchout() as o:
DummyApp().parse_run('draw', '-c', 'straight')
o.seek(0)
self.assertIn('Curve was straight', o.read())