inkex.tester package

Submodules

inkex.tester.decorators module

inkex.tester.filters module

Comparison filters for use with the ComparisonMixin.

Each filter should be initialised in the list of filters that are being used.

compare_filters = [
CompareNumericFuzzy(), CompareOrderIndependentLines(option=yes),

]

class inkex.tester.filters.Compare(**options)[source]

Bases: object

Comparison base class, this acts as a passthrough unless the filter staticmethod is overwritten.

static filter(contents)[source]

Replace this filter method with your own filtering

class inkex.tester.filters.CompareNumericFuzzy(**options)[source]

Bases: inkex.tester.filters.Compare

Turn all numbers into shorter standard formats

1.2345678 -> 1.2346 1.2300 -> 1.23, 50.0000 -> 50.0 50.0 -> 50

static filter(contents)[source]

Replace this filter method with your own filtering

class inkex.tester.filters.CompareOrderIndependentBytes(**options)[source]

Bases: inkex.tester.filters.Compare

Take all the bytes and sort them

static filter(contents)[source]

Replace this filter method with your own filtering

class inkex.tester.filters.CompareOrderIndependentLines(**options)[source]

Bases: inkex.tester.filters.Compare

Take all the lines and sort them

static filter(contents)[source]

Replace this filter method with your own filtering

class inkex.tester.filters.CompareOrderIndependentStyle(**options)[source]

Bases: inkex.tester.filters.Compare

Take all styles and sort the results

static filter(contents)[source]

Replace this filter method with your own filtering

class inkex.tester.filters.CompareOrderIndependentStyleAndPath(**options)[source]

Bases: inkex.tester.filters.Compare

Take all styles and paths and sort them both

static filter(contents)[source]

Replace this filter method with your own filtering

class inkex.tester.filters.CompareOrderIndependentTags(**options)[source]

Bases: inkex.tester.filters.Compare

Sorts all the XML tags

static filter(contents)[source]

Replace this filter method with your own filtering

class inkex.tester.filters.CompareSize(**options)[source]

Bases: inkex.tester.filters.Compare

Compare the length of the contents instead of the contents

static filter(contents)[source]

Replace this filter method with your own filtering

class inkex.tester.filters.CompareWithPathSpace(**options)[source]

Bases: inkex.tester.filters.Compare

Make sure that path segment commands have spaces around them

static filter(contents)[source]

Replace this filter method with your own filtering

class inkex.tester.filters.CompareWithoutIds(**options)[source]

Bases: inkex.tester.filters.Compare

Remove all ids from the svg

static filter(contents)[source]

Replace this filter method with your own filtering

inkex.tester.mock module

Any mocking utilities required by testing. Mocking is when you need the test to exercise a piece of code, but that code may or does call on something outside of the target code that either takes too long to run, isn’t available during the test running process or simply shouldn’t be running at all.

class inkex.tester.mock.ManualVerbosity(test, okay=True, dots=False)[source]

Bases: object

Change the verbosity of the test suite manually

flip(exc_type=None, exc_val=None, exc_tb=None)[source]

Swap the stored verbosity with the original

result
class inkex.tester.mock.MockCommandMixin[source]

Bases: inkex.tester.mock.MockMixin

Replace all the command functions with testable replacements.

This stops the pipeline and people without the programs, running into problems.

static add_call_file(msg, filename)[source]

Add a single file to the given mime message

add_call_files(msg, args, kwargs)[source]

Gather all files, adding input files to the msg (for hashing) and output files to the returned files list (for outputting in debug)

clean_paths(data, files)[source]

Clean a string of any files or tempdirs

classmethod cmddir()[source]

Returns the location of all the mocked command results

get_all_tempfiles()[source]

Returns a set() of all files currently in any of the tempdirs

get_call_filename(program, key, create=False)[source]

Get the filename for the call testing information.

get_call_path(program, create=True)[source]

Get where this program would store it’s test data

ignore_command_mock(program, arglst)[source]

Return true if the mock is ignored

load_call(program, key, files)[source]

Load the given call

mock_call(program, *args, **kwargs)[source]

Replacement for the inkex.command.call() function, instead of calling an external program, will compile all arguments into a hash and use the hash to find a command result.

mocks = [(<module 'inkex.command' from '/home/docs/checkouts/readthedocs.org/user_builds/inkscape-extensions-guide/checkouts/latest/inkex/command.py'>, '_call', 'mock_call'), (<module 'tempfile' from '/home/docs/checkouts/readthedocs.org/user_builds/inkscape-extensions-guide/envs/latest/lib/python3.7/tempfile.py'>, 'mkdtemp', 'record_tempdir')]
record_tempdir(*args, **kwargs)[source]

Record any attempts to make tempdirs

recorded_tempdirs = []
save_call(program, key, stdout, files, msg, ext='output')[source]

Saves the results from the call into a debug output file, the resulting files should be a Mime msg file format with each attachment being one of the input files as well as any stdin and arguments used in the call.

save_key(program, key, keystr, ext='key')[source]

Save the key file if we are debugging the key data

setUp()[source]

For each mock instruction, set it up and store the return

class inkex.tester.mock.MockMixin[source]

Bases: object

Add mocking ability to any test base class, will set up mock on setUp and remove it on tearDown.

Mocks are stored in an array attached to the test class (not instance!) which ensures that mocks can only ever be setUp once and can never be reset over themselves. (just in case this looks weird at first glance)

class SomeTest(MockingMixin, TestBase):
mocks = [(sys, ‘exit’, NoSystemExit(“Nope!”)]
mocks = []
old_call(name)[source]

Get the original caller

setUp()[source]

For each mock instruction, set it up and store the return

setUpMock(owner, name, new)[source]

Setup the mock here, taking name and function and returning (name, old)

tearDown()[source]

For each returned stored, tear it down and restore mock instruction

inkex.tester.svg module

SVG specific utilities for tests.

inkex.tester.svg.svg(svg_attrs='')[source]

Returns xml etree based on a simple SVG element.

svg_attrs: A string containing attributes to add to the
root <svg> element of a minimal SVG document.
inkex.tester.svg.svg_file(filename)[source]

Parse an svg file and return it’s document root

inkex.tester.svg.uu_svg(user_unit)[source]

Same as svg, but takes a user unit for the new document.

It’s based on the ratio between the SVG width and the viewBox width.

inkex.tester.word module

Generate words for testing.

inkex.tester.word.sentencecase(word)[source]

Make a word standace case

inkex.tester.word.word_generator(text_length)[source]

Generate a word of text_length size

inkex.tester.xmldiff module

Allow two xml files/lxml etrees to be compared, returning their differences.

inkex.tester.xmldiff.text_compare(test1, test2)[source]

Compare two text strings while allowing for ‘*’ to match anything on either lhs or rhs.

inkex.tester.xmldiff.xmldiff(xml1, xml2)[source]

Create an xml difference, will modify the first xml structure with a diff

Module contents

All extensions should come with tests, this package provides you will all the tools you need in order to create tests and make sure your extension continues to work with new versions of Inkscape, the Inkex python modules and other python and non-python tools you may use.

Make sure your extension is a python extension and is using the inkex.generic base classes. As these provide the greatest amount of functionality for testing.

You should start by creating a folder in your repository called tests with an empty file inside called __init__.py to turn it into a module folder.

For each of your extensions, you should create a file called test_{myextension}.py where the name reflects the name of your extension.

There are two types of tests:

  1. Full-process Comparison tests - These are tests which envoke your

    extension will various arguments and attempt to compare the output to a known good state. These are useful for testing that your extension would work, if it was used in Inkscape.

    Good example of writing comparison tests can be found in the inkscape core repository, each test which inherits from the ComparisonMixin class are running comparison tests.

  2. Unit tests - These are individual test functions which call out to

    specific functions within your extension. These are typical python unit testing and many good python documents exist to describe how to write them well. For examples here you can find the tests that test the inkex modules themsleves to be the most instructive.

Your tests will hit a cetain amount of code, this is called it’s coverage and the higher the coverage, the better your tests are at stretching all the options and varients your code has.

class inkex.tester.ComparisonMixin[source]

Bases: object

Add comparison tests to any existing test suite.

assertCompare(infile, outfile, args)[source]

Compare the output of a previous run against this one.

  • infile: The filename of the pre-proccessed svg (or other type of file)
  • outfile: The filename of the data we expect to get, if not set
    the filename will be generated from the effect name and kwargs.
  • args: All the arguments to be passed to the effect run
compare_file = 'ref_test.svg'
compare_filters = []
comparisons = [(), ('--id=p1', '--id=r3')]
get_compare_outfile(args, addout=None)[source]

Generate an output file for the arguments given

test_all_comparisons()[source]

Testing all comparisons

class inkex.tester.InkscapeExtensionTestMixin[source]

Bases: object

Automatically setup self.effect for each test and test with an empty svg

setUp()[source]

Check if there’s an effect_class set and create self.effect is it is

test_default_settings()[source]

Extension works with empty svg file

class inkex.tester.NoExtension(*args, **kwargs)[source]

Bases: inkex.base.InkscapeExtension

Test case must specify ‘self.effect_class’ to assertEffect.

run(args=None, output=None)[source]

Fake run

class inkex.tester.TestCase(*args, **kw)[source]

Bases: inkex.tester.mock.MockCommandMixin, unittest.case.TestCase

Base class for all effects tests, provides access to data_files and test_without_parameters

assertAlmostTuple(found, expected, precision=8)[source]

Floating point results may vary with computer architecture; use assertAlmostEqual to allow a tolerance in the result.

assertDeepAlmostEqual(first, second, places=7, msg=None, delta=None)[source]
assertEffect(*filename, **kwargs)[source]

Assert an effect, capturing the output to stdout.

filename should point to a starting svg document, default is empty_svg

assertEffectEmpty(effect, **kwargs)[source]

Assert calling effect without any arguments

classmethod data_file(filename, *parts)[source]

Provide a data file from a filename, can accept directories as arguments.

classmethod datadir()[source]

Get the data directory (can be over-ridden if needed)

effect_class

alias of NoExtension

empty_svg

Returns a common minimal svg file

classmethod rootdir()[source]

Return the full path to the extensions directory

setUp()[source]

Make sure every test is seeded the same way

stderr_output = False
tearDown()[source]

For each returned stored, tear it down and restore mock instruction

temp_file(prefix='file-', template='{prefix}{name}{suffix}', suffix='.tmp')[source]

Generate the filename of a temporary file

tempdir

Generate a temporary location to store files