Imprimatur
Imprimatur is a tool for performing automated functional testing on web applications. The tests are described in a simple test script. Along with the standard HTTP methods, Imprimatur handles authentication, file uploads and HTTPS. The responses are validated using regular expressions.
Imprimatur runs on Python 3.5+ on both CPython and PyPy.
Licence
Imprimatur is released under the GPL.
Installation
It’s a good idea to set up a virtualenv:
virtualenv venv source venv/bin/activate
then install Imprimatur with pip:
pip install imprimatur
Quickstart
To run an example test script save the following as a file called test.py
:
[ { 'host': 'www.google.com', 'status_code': 200 } ]
then run it with:
imprimatur test.py
and it should come back saying all tests are passed. Here’s another script with some more examples:
[ { 'name': "Single regex", 'port': 5000, 'host': "localhost", 'path': "/text_2", 'status_code': 200, 'regexes': ['inexhaustible'] }, { 'name': "Basic auth", 'path': "/auth", 'auth': ("conrad", "kurtz"), 'status_code': 200 }, { 'name': "File upload", 'path': "/echo", 'method': "post", 'files': {"yellow": "tests/2/crome-file.txt"}, 'regexes': ["yellow", "on the leads"], 'status_code': 200 }, { 'name': "Post name and value with regex.", 'path': "/echo", 'method': "post", 'data': {"quote": "Leisure is the mother of philosophy."}, 'status_code': 200, 'regexes': ["Leisure"] }, { 'name': "Repeat until successful.", 'path': "/counter", # 'max' is maximum number of times to try # 'period' is the number of seconds to wait between tries 'tries': {'max': 3, 'period': 1}, 'status_code': 200, 'regexes': ["The Decline And Fall Of The Roman Empire"] }, { 'name': "Regex on header.", 'path': "/redirect?location=http://localhost:5000/here.html", 'status_code': 302, 'regexes': ["here.html"] }, { 'name': "HTTP HEAD request.", 'path': "/text_1", 'method': "head", 'status_code': 200 }, { 'name': "Allow redirects", 'path': "/text_1", 'allow_redirects': 'True', 'status_code': 200 } ]
Reference
The full list of properties for each request is given below. A * after the property name means that it is carried over to subsequent requests.
Name | Notes |
---|---|
scheme* |
Can be |
host* |
Default is |
port* |
Default is |
auth* |
Sequence of username and password eg. |
verify* |
For an HTTPS request, verify the certificate. Can be |
name |
Used to label the request. |
path |
End of the URL eg. |
method |
An HTTP method. eg. |
data |
Dictionary of post values eg. |
files |
File name and path to upload. Eg. |
tries |
Maximum number of times to try the URL. Eg. |
regexes |
Sequence of regular expressions
eg. |
status_code |
HTTP status code to
check for, eg. |
headers |
Dictionary of HTTP headers eg. |
unzip |
If |
allow_redirects |
If |
Cookies are always retained between requests.
Web Interface
Imprimatur comes with a very basic web interface. You can try it out using Imprimatur’s built-in web server by doing:
python -m imprimatur.web
Don’t run it on a public facing production web server, as it is entirely unsecure.
Release Notes
Version 0.24.0, 2020-04-09
-
Drop support for Python 2.
-
The webserver now listens for external connections.
-
Upgrade dependent libraries.
-
Use TravisCI for testing.
Version 0.23.26, 2019-01-19
-
Upgrade dependecies
requests
andflask
.
Version 0.23.25, 2018-04-10
-
The
path
doesn’t default to/
.
Version 0.23.24, 2016-10-16
-
The new
unzip: True
option will decompress the response.
Version 0.23.23, 2016-10-12
-
Give a better error message if a regular expression is invalid.
Version 0.23.22, 2016-09-24
-
Have all the docs in the readme.adoc file. This means that the Python Hosted site isn’t used any more, since the readme.adoc file is rendered on GitHub.
Version 0.23.21, 2016-09-21
-
Fixed bug where one couldn’t send a binary file as part of an Imprimatur request.
Version 0.23.20, 2016-07-21
-
In the absence of a character encoding in the response, rather than guess assume utf-8 and ignore any errors.
Version 0.23.19, 2016-07-07
-
Fixed bug with custom HTTP headers.
Version 0.23.18, 2016-07-03
-
Added support for specifying HTTP headers.
Version 0.23.17, 2016-05-09
-
Fixed a bug where if a URL is malformed the test is skipped whereas it should fail.
Version 0.23.16, 2015-06-11
-
Now holds a session across requests.
Version 0.23.15, 2015-05-20
-
Fixes a bug where if there’s no body to a response, and it has to be printed out, then fails.
Version 0.23.14, 2015-02-19
-
Make sure
templates
directory is included in the distribution.
Version 0.23.13, 2015-02-15
-
Added the
verify
flag for controlling whether to verify SSL certificates or not. Can beTrue
orFalse
, the default isFalse
.
Version 0.23.11, 2015-02-10
-
Include 'templates' directory in the distribution, this is necessary for the web server.
-
A list of runs is now shown on the home page.
-
Give a good error message if there’s a syntax error in the script.
-
The wheel format distribution if Imprimatur now has the 'universal' flag set which denotes that it runs on Python 2 and 3.
Version 0.23.10, 2015-02-03
-
Fixed bug where regex pattern wasn’t searching the headers.
-
Added the re.DOTALL flag so that a
.
in regular expressions matches line ending characters. -
Added a rudimentary web interface.
Version 0.23.9, 2015-01-31
-
Various improvements to the converter from old style XML test scripts to new style ones.
-
Renamed the ‘tries’ attribute ‘number’ to ‘max’ as it’s a better description of what it does.
-
Fixed bug where Imprimatur always retried max times, even when a request was successful.
Version 0.23.8, 2015-01-26
-
The converter from old style XML test scripts to new style ones now carries over the comments as well.
Version 0.23.7, 2015-01-25
-
Added a converter to convert from old style XML test scripts to new style Python ones.
Version 0.23.5, 2015-01-22
-
The
status_code
attribute is now allowed to be either astr
or anint
. Previously it could only be anint
. -
The ‘Passed all tests!’ message at the end is now followed by a newline character.
-
The
auth
attribute is now carried over from previous requests so that it doesn’t have to be specified explicitly in each subsequent request.
Version 0.23.4, 2015-01-21
-
Imprimatur now requires version 2.5.1 of the ‘requests’ library. It was found that old versions of 'requests' didn’t work.
-
Fixed a bug where the status code check isn’t working.
-
Added in a check for extraneous keys in the test script.
-
Included a lot more examples in the docs.
Version 0.23.3, 2015-01-19
-
Fixed various problems with Python 3.
Version 0.23.2, 2015-01-18
-
Added make sure dependencies (‘flask’ and ‘requests’) are automatically installed.
Version 0.23.1, 2015-01-18
-
Added
imprimatur
as a command-line script that is automatically installed.
Version 0.23.0, 2015-01-17
-
Ported to Python.
-
Moved to GitHub.
-
Has the same features as before, but the script format is no longer an XML file, but evaluatable Python.
-
Can be used as a Python library.
Version 22
-
Removed <session> element.
Version 20
-
Added support for HTTP HEAD requests.
Version 18
-
Gets don’t follow redirects by default.
-
Fixed example given in tests directory.
-
If no arguments are given on the command line, throws an exception saying no file specified.
Version 17
-
Can now set a request to follow redirects.
Version 15
-
Changed so that a regex matches if it’s found anywhere within the string.
-
In regexes, a dot character now matches line terminators as well.
Regression Tests
To run the regression tests, install tox:
pip install tox
then run tox
from the imprimatur
directory:
tox
Building The Documentation
The docs are written using Asciidoctor. To build them, install asciidoctor:
apt-get install asciidoctor
Then type:
asciidoctor readme.adoc
and the doc will appear at docs/index.html
.
Doing A Release Of Imprimatur
Run tox
make sure all tests pass, then update the release notes in
readme.adoc
then do:
git tag -a x.y.z -m "version x.y.z" rm -r build rm -r dist python setup.py sdist bdist_wheel for f in dist/*; do gpg --detach-sign -a $f; done twine upload dist/*