>> hintFile = "./tests/unit_test_files/hint.txt">>> f = iniFileGenerator(hintFile)>>> print f.hintFilePath./tests/unit_test_files/hint.txt"""class iniFileGenerator:" name="description" /> >> hintFile = "./tests/unit_test_files/hint.txt">>> f = iniFileGenerator(hintFile)>>> print f.hintFilePath./tests/unit_test_files/hint.txt"""class iniFileGenerator:" />
5752

object reuse in python doctest

Question:

I have a sample doctest like this one.

""" This is the "iniFileGenerator" module. >>> hintFile = "./tests/unit_test_files/hint.txt" >>> f = iniFileGenerator(hintFile) >>> print f.hintFilePath ./tests/unit_test_files/hint.txt """ class iniFileGenerator: def __init__(self, hintFilePath): self.hintFilePath = hintFilePath def hello(self): """ >>> f.hello() hello """ print "hello" if __name__ == "__main__": import doctest doctest.testmod()

When I execute this code, I got this error.

Failed example: f.hello() Exception raised: Traceback (most recent call last): File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/doctest.py", line 1254, in __run compileflags, 1) in test.globs File "<doctest __main__.iniFileGenerator.hello[0]>", line 1, in <module> f.hello() NameError: name 'f' is not defined

This error is caused by accessing 'f' which was not accessible when testing hello() method.

Is there any way to share the object which is created before? Without it, one need to create object all the time when it's necessary.

def hello(self): """ hintFile = "./tests/unit_test_files/hint.txt" >>> f = iniFileGenerator(hintFile) >>> f.hello() hello """ print "hello"

Answer1:

You can use testmod(extraglobs={'f': initFileGenerator('')}) to define a reusable object globally.

As the <a href="http://docs.python.org/library/doctest.html#doctest.testmod" rel="nofollow">doctest doc</a> says,

<blockquote>

<em>extraglobs</em> gives a dict merged into the globals used to execute examples. This works like dict.update()

</blockquote>

But I used to test all methods in __doc__ of class before all methods.

class MyClass(object): """MyClass >>> m = MyClass() >>> m.hello() hello >>> m.world() world """ def hello(self): """method hello""" print 'hello' def world(self): """method world""" print 'world'

Answer2:

To obtain literate modules with tests that all use a shared execution context (i.e. individual tests that can share and re-use results), one has to look at the relevant part of <a href="https://docs.python.org/3/library/doctest.html#what-s-the-execution-context" rel="nofollow">documentation on the execution context</a>, which says:

<blockquote>

... each time doctest finds a docstring to test, it uses a <em>shallow</em> <strong>copy</strong> of M‘s globals, so that running tests doesn’t change the module’s real globals, and so that one test in M can’t leave behind crumbs that accidentally allow another test to work.

...

You can <strong>force use of <em>your own</em> dict</strong> as the execution context by passing globs=your_dict to testmod() or testfile() instead.

</blockquote>

Given this, <a href="https://gist.github.com/kernc/0dccae6542465d59a331" rel="nofollow">I managed to reverse-engineer</a> from doctest module that besides using copies (i.e. the dict's copy() method), it also clears the globals dict (using clear()) after each test.

Thus, one can patch their own globals dictionary with something like:

class Context(dict): def clear(self): pass def copy(self): return self

and then use it as:

import doctest from importlib import import_module module = import_module('some.module') doctest.testmod(module, # Make a copy of globals so tests in this # module don't affect the tests in another glob=Context(module.__dict__.copy()))

Recommend

  • Passing Objects to fragment without argument
  • Replace the product name by the Sku in the order received page
  • Get a list of who has what access to git repositories
  • C# Spell checker Problem
  • MVC RC “File” ActionResult, performant?
  • Preventing Internet-accessing-method from delaying a toast popup
  • Eclipse ADT Plugin crashed after updating to version 22.0
  • How to Include CSS style when converting svg to png
  • Displaying XML file data in a HTML table
  • Window-select multiple artists and drag them on canvas
  • ng-sidebar (Angular 2) implementation issue
  • Existing data serialized as hash produces error when upgrading to Rails 5
  • JSF validateLength question
  • Coin change recursive approach
  • Repeatable job for Laravel json api
  • Adding custom message on Thank You page by shipping method
  • iOS: Address Book
  • Read specific column from Parquet without using Spark
  • Bulk loading into PostgreSQL from a remote client
  • Force outer SELECT to fail if the inner SELECT contains an invalid identifier
  • When i select a Textfield the keyboard moves over it
  • Google Compute instance receiving email
  • Python Equivalent of Java's 'Keystore'?
  • integrity constraint violation: NOT NULL check constraint
  • javax.net.ssl.SSLException: SSL handshake aborted Connection reset by peer while calling webservice
  • How to put an object in the air?
  • Defer unused CSS
  • Sample deviceQuery cuda program
  • Android studio import problems. (Apktool)
  • playing mp3 from nsbundle
  • Building JavaFX 2.0 App on Mac, deploying on Windows
  • Add checkbox dynamically using angular 2
  • Ajax call on Multiple selection in Select box
  • How to create subsets of a single set of elements with XSLT?
  • Angular FormGroup won't update it's value immediately after patchValue or setValue