...
 
Commits (40)
dist
MANIFEST
test.xml
build
.testrepository
__pycache__
testrepository.egg-info
./doc/_build
[DEFAULT]
test_command=${PYTHON:-python} -m subunit.run $LISTOPT $IDOPTION testrepository.tests.test_suite
test_id_option=--load-list $IDFILE
test_list_option=--list
;filter_tags=worker-0
This diff is collapsed.
Copyright (c) Robert Collins and Testrepository contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of Robert Collins nor the names of Testrepository
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY ROBERT COLLINS AND TESTREPOSITORY CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
Testrepository is licensed under two licenses, the Apache License, Version 2.0
or the 3-clause BSD License. You may use this project under either of these
licenses - choose the one that works best for you.
We require contributions to be licensed under both licenses. The primary
difference between them is that the Apache license takes care of potential
issues with Patents and other intellectual property concerns that some users
or contributors may find important.
Generally every source file in Testrepository needs a license grant under both
these licenses. As the code is shipped as a single unit, a brief form is used:
----
Copyright (c) [yyyy][,yyyy]* [name or 'Testrepository Contributors']
Licensed under either the Apache License, Version 2.0 or the BSD 3-clause
license at the users choice. A copy of both licenses are available in the
project source as Apache-2.0 and BSD. You may not use this file except in
compliance with one of these two licences.
Unless required by applicable law or agreed to in writing, software
distributed under these licenses is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
license you chose for the specific language governing permissions and
limitations under that license.
----
A concordance of contributors is maintained here to provide an easy reference
for distributions such as Debian that wish to list all the copyright holders
in their metadata:
* Robert Collins <robertc@robertcollins.net>, 2009
* Hewlett-Packard Development Company, L.P., 2013
* IBM Corp., 2013
Code that has been incorporated into Testrepository from other projects will
naturally be under its own license, and will retain that license.
A known list of such code is maintained here:
* No entries.
Installing Test Repository
++++++++++++++++++++++++++
Run time dependencies
~~~~~~~~~~~~~~~~~~~~~
* Python2.4 or newer.
* subunit (0.0.18 or newer).
* fixtures (https://launchpad.net/python-fixtures, or
http://pypi.python.org/pypi/fixtures/).
Test dependencies
~~~~~~~~~~~~~~~~~
* testtools 0.9.8 or newer (the python-testtools package, or
http://pypi.python.org/pypi/testtools/).
* testresources (https://launchpad.net/testresources, or
http://pypi.python.org/pypi/testresources/).
* testscenarios (https://launchpad.net/testscenarios).
Installing
~~~~~~~~~~
* ./setup.py install
include .bzrignore
include .testr.conf
include Apache-2.0
include BSD
include COPYING
include INSTALL.txt
include MANIFEST.in
include Makefile
include NEWS
include README.txt
include doc/*.txt
include testrepository/tests/*.py
recursive-include testrepository/tests *.py
#
# Copyright (c) 2009 Testrepository Contributors
#
# Licensed under either the Apache License, Version 2.0 or the BSD 3-clause
# license at the users choice. A copy of both licenses are available in the
# project source as Apache-2.0 and BSD. You may not use this file except in
# compliance with one of these two licences.
#
# Unless required by applicable law or agreed to in writing, software
# distributed under these licenses is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# license you chose for the specific language governing permissions and
# limitations under that license.
all: README.txt check
.testrepository:
./testr init
check: .testrepository
./testr run --parallel
check-xml:
python -m subunit.run testrepository.tests.test_suite | subunit2junitxml -o test.xml -f | subunit2pyunit
release:
./setup.py sdist upload --sign
README.txt: testrepository/commands/quickstart.py
./testr quickstart > $@
.PHONY: check check-xml release all
This diff is collapsed.
Metadata-Version: 1.1
Name: testrepository
Version: 0.0.20
Summary: A repository of test results.
Home-page: https://launchpad.net/testrepository
Author: Robert Collins
Author-email: robertc@robertcollins.net
License: UNKNOWN
Description: Test Repository
+++++++++++++++
Overview
~~~~~~~~
This project provides a database of test results which can be used as part of
developer workflow to ensure/check things like:
* No commits without having had a test failure, test fixed cycle.
* No commits without new tests being added.
* What tests have failed since the last commit (to run just a subset).
* What tests are currently failing and need work.
Test results are inserted using subunit (and thus anything that can output
subunit or be converted into a subunit stream can be accepted).
A mailing list for discussion, usage and development is at
https://launchpad.net/~testrepository-dev - all are welcome to join. Some folk
hang out on #testrepository on irc.freenode.net.
CI for the project is at http://build.robertcollins.net/job/testrepository-default/.
Licensing
~~~~~~~~~
Test Repository is under BSD / Apache 2.0 licences. See the file COPYING in the source for details.
Quick Start
~~~~~~~~~~~
Create a config file::
$ touch .testr.conf
Create a repository::
$ testr init
Load a test run into the repository::
$ testr load < testrun
Query the repository::
$ testr stats
$ testr last
$ testr failing
Delete a repository::
$ rm -rf .testrepository
Documentation
~~~~~~~~~~~~~
More detailed documentation including design and implementation details, a
user manual, and guidelines for development of Test Repository itself can be
found at https://testrepository.readthedocs.org/en/latest, or in the source
tree at doc/ (run make -C doc html).
Keywords: subunit unittest testrunner
Platform: UNKNOWN
Classifier: Development Status :: 6 - Mature
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: Topic :: Software Development :: Testing
Test Repository
+++++++++++++++
Overview
~~~~~~~~
This project provides a database of test results which can be used as part of
developer workflow to ensure/check things like:
* No commits without having had a test failure, test fixed cycle.
* No commits without new tests being added.
* What tests have failed since the last commit (to run just a subset).
* What tests are currently failing and need work.
Test results are inserted using subunit (and thus anything that can output
subunit or be converted into a subunit stream can be accepted).
A mailing list for discussion, usage and development is at
https://launchpad.net/~testrepository-dev - all are welcome to join. Some folk
hang out on #testrepository on irc.freenode.net.
CI for the project is at http://build.robertcollins.net/job/testrepository-default/.
Licensing
~~~~~~~~~
Test Repository is under BSD / Apache 2.0 licences. See the file COPYING in the source for details.
Quick Start
~~~~~~~~~~~
Create a config file::
$ touch .testr.conf
Create a repository::
$ testr init
Load a test run into the repository::
$ testr load < testrun
Query the repository::
$ testr stats
$ testr last
$ testr failing
Delete a repository::
$ rm -rf .testrepository
Documentation
~~~~~~~~~~~~~
More detailed documentation including design and implementation details, a
user manual, and guidelines for development of Test Repository itself can be
found at https://testrepository.readthedocs.org/en/latest, or in the source
tree at doc/ (run make -C doc html).
testrepository (0.0.20-5) unstable; urgency=medium
[ Ondřej Nový ]
* Use debhelper-compat instead of debian/compat.
[ Thomas Goirand ]
* Uploading to unstable.
-- Thomas Goirand <zigo@debian.org> Mon, 02 Sep 2019 16:28:59 +0200
testrepository (0.0.20-4) experimental; urgency=medium
[ Mattia Rizzolo ]
* Remove Robert Collins from uploaders, as he has retired. Closes: #920506
[ Thomas Goirand ]
* Removed Python 2 support.
-- Thomas Goirand <zigo@debian.org> Thu, 28 Mar 2019 20:57:14 +0100
testrepository (0.0.20-3) unstable; urgency=medium
[ Ondřej Nový ]
* d/copyright: Use https protocol in Format field
* d/watch: Use https protocol
[ Thomas Goirand ]
* Ran wrap-and-sort -bast.
* Add missing dh-python build-depends.
* Standards-Version is now 4.1.3.
* Updated build-depends version and bumped debhelper to 10.
-- Thomas Goirand <zigo@debian.org> Mon, 02 Apr 2018 17:01:33 +0200
testrepository (0.0.20-2) unstable; urgency=medium
* Switch debian/watch to pypi.debian.net redirector.
......
Source: testrepository
Maintainer: Python Applications Packaging Team <python-apps-team@lists.alioth.debian.org>
Uploaders: Robert Collins <robertc@robertcollins.net>,
Thomas Goirand <zigo@debian.org>,
Tristan Seligmann <mithrandi@debian.org>
Uploaders:
Thomas Goirand <zigo@debian.org>,
Tristan Seligmann <mithrandi@debian.org>,
Section: python
Priority: optional
Build-Depends: debhelper (>= 9),
python-all (>= 2.6.6-3~),
python-fixtures,
python-setuptools,
python-subunit,
python-testresources,
python-testscenarios,
python-testtools,
python3-all (>= 3.2),
python3-fixtures,
python3-setuptools,
python3-subunit,
python3-testresources,
python3-testscenarios,
python3-testtools,
subunit
Standards-Version: 3.9.6
Build-Depends:
debhelper-compat (= 10),
dh-python,
python3-all,
python3-fixtures,
python3-setuptools,
python3-subunit,
python3-testresources,
python3-testscenarios,
python3-testtools,
subunit,
Standards-Version: 4.1.3
Vcs-Git: https://salsa.debian.org/python-team/applications/testrepository.git
Vcs-Browser: https://salsa.debian.org/python-team/applications/testrepository
Homepage: https://pypi.python.org/pypi/testrepository
Package: testrepository
Architecture: all
Depends: python-testrepository (>= ${source:Version}), python3-testrepository (>= ${source:Version}), ${misc:Depends}
Description: unit test system with database of test results - metapackage and doc
Testrepository provides a database of test results and supports easy workflows
to be built on top of that database. For instance, running just failing tests
or getting the last test run back to examine again (without running the tests
again). Testrepository is compatible with any test suite that can output
subunit. This includes any TAP test suite and any pyunit compatible test
suite.
.
This package is a metapackage that depends on both Python 2 and 3 packages. It
also contains the documentation.
Package: python-testrepository
Package: python3-testrepository
Architecture: all
Depends: python-subunit, ${misc:Depends}, ${python:Depends}
Provides: ${python:Provides}
Description: Database of test results - Python 2.x library
Depends:
python3-subunit,
${misc:Depends},
${python3:Depends},
Provides:
${python3:Provides},
Description: Database of test results - Python 3.x library
Testrepository provides a database of test results and supports easy workflows
to be built on top of that database. For instance, running just failing tests
or getting the last test run back to examine again (without running the tests
......@@ -50,15 +37,16 @@ Description: Database of test results - Python 2.x library
subunit. This includes any TAP test suite and any pyunit compatible test
suite.
.
The python-testrepository package contains the Python testrepository
library for Python 2.x, which can be used for programmatic access to the
The python3-testrepository package contains the Python testrepository
library for Python 3.x, which can be used for programmatic access to the
database.
Package: python3-testrepository
Package: testrepository
Architecture: all
Depends: python3-subunit, ${misc:Depends}, ${python3:Depends}
Provides: ${python3:Provides}
Description: Database of test results - Python 3.x library
Depends:
python3-testrepository (>= ${source:Version}),
${misc:Depends},
Description: unit test system with database of test results - metapackage and doc
Testrepository provides a database of test results and supports easy workflows
to be built on top of that database. For instance, running just failing tests
or getting the last test run back to examine again (without running the tests
......@@ -66,6 +54,5 @@ Description: Database of test results - Python 3.x library
subunit. This includes any TAP test suite and any pyunit compatible test
suite.
.
The python3-testrepository package contains the Python testrepository
library for Python 3.x, which can be used for programmatic access to the
database.
This package is a metapackage that depends on both Python 2 and 3 packages. It
also contains the documentation.
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: testrepository
Upstream-Contact: Robert Collins <robertc@robertcollins.net>
Source: https://github.com/testing-cabal/testrepository
......
[DEFAULT]
debian-branch=debian/master
#!/bin/sh
set -e
if [ "$1" = "configure" ] ; then
update-alternatives --install /usr/bin/testr testr /usr/bin/testr-python2 300
fi
#DEBHELPER#
exit 0
#!/bin/sh
set -e
if [ "$1" = "remove" ] || [ "$1" = "disappear" ]; then
update-alternatives --remove testr /usr/bin/testr-python2
fi
#DEBHELPER#
exit 0
#!/bin/sh
set -e
if [ "${1}" = "upgrade" ] ; then
if [ ! -h /usr/bin/testr ] && [ -e /usr/bin/testr ] ; then
rm /usr/bin/testr
fi
fi
#DEBHELPER#
exit 0
#!/bin/sh
set -e
if [ "$1" = "remove" ] ; then
update-alternatives --remove testr /usr/bin/testr-python2
fi
#DEBHELPER#
exit 0
#!/bin/sh
set -e
if [ "$1" = "configure" ] ; then
update-alternatives --install /usr/bin/testr testr /usr/bin/testr-python3 200
fi
#DEBHELPER#
exit 0
......@@ -4,17 +4,13 @@ export PYBUILD_NAME=testrepository
export PYBUILD_DISABLE=test
%:
dh $@ --with python2,python3 --buildsystem=pybuild
dh $@ --with python3 --buildsystem=pybuild
override_dh_installchangelogs:
dh_installchangelogs -k NEWS
override_dh_auto_install:
dh_auto_install
mv $(CURDIR)/debian/python-testrepository/usr/bin/testr \
$(CURDIR)/debian/python-testrepository/usr/bin/testr-python2
mv $(CURDIR)/debian/python3-testrepository/usr/bin/testr \
$(CURDIR)/debian/python3-testrepository/usr/bin/testr-python3
override_dh_clean:
dh_clean
......
version=3
opts=uversionmangle=s/(rc|a|b|c)/~$1/,pgpsigurlmangle=s/$/.asc/ \
http://pypi.debian.net/testrepository/testrepository-(.+)\.(?:zip|tgz|tbz|txz|(?:tar\.(?:gz|bz2|xz)))
https://pypi.debian.net/testrepository/testrepository-(.+)\.(?:zip|tgz|tbz|txz|(?:tar\.(?:gz|bz2|xz)))
Design / Architecture of Test Repository
++++++++++++++++++++++++++++++++++++++++
Values
~~~~~~
Code reuse.
Focus on the project.
Do one thing well.
Goals
~~~~~
Achieve a Clean UI, responsive UI, small-tools approach. Simulataneously have
a small clean code base which is easily approachable.
Data model/storage
~~~~~~~~~~~~~~~~~~
testrepository stores subunit streams as subunit streams in .testrespository
with simple additional metadata. See the MANUAL for documentation on the
repository layout. The key design elements are that streams are stored
verbatim, and a testr managed stream called 'failing' is used to track the
current failures.
Code layout
~~~~~~~~~~~
One conceptual thing per module, packages for anything where multiple types
are expected (e.g. testrepository.commands, testrespository.ui).
Generic driver code should not trigger lots of imports: code dependencies
should be loaded when needed. For example, argument validation uses argument
types that each command can import, so the core code doesn't need to know about
all types.
The tests for the code in testrepository.foo.bar is in
testrepository.tests.foo.test_bar. Interface tests for testrepository.foo is
in testrepository.tests.test_foo.
External integration
~~~~~~~~~~~~~~~~~~~~
Test Repository command, ui, parsing etc objects should all be suitable for
reuse from other programs.
Threads/concurrency
~~~~~~~~~~~~~~~~~~~
In general using any public interface is fine, but keeping syncronisation
needs to a minimum for code readability.
Development guidelines for Test Repository
++++++++++++++++++++++++++++++++++++++++++
Coding style
~~~~~~~~~~~~
PEP-8 please. We don't enforce a particular style, but being reasonably
consistent aids readability.
Copyrights and licensing
~~~~~~~~~~~~~~~~~~~~~~~~
Code committed to Test Repository must be licensed under the BSD + Apache-2.0
licences that Test Repository offers its users. Copyright assignment is not
required. Please see COPYING for details about how to make a license grant in
a given source file. Lastly, all copyright holders need to add their name
to the master list in COPYING the first time they make a change in a given
calendar year.
Testing and QA
~~~~~~~~~~~~~~
For Test repository please add tests where possible. There is no requirement
for one test per change (because somethings are much harder to automatically
test than the benfit from such tests). Fast tests are preferred to slow tests,
and understandable tests to fast tests.
http://build.robertcollins.net/ has a job testing every commit made to trunk
of Test Repository, and there is no automated test-before-merge process at the
moment. The quid pro quo for committers is that they should check that the
automated job found their change acceptable after merging it, and either roll
it back or fix it immediately. A broken trunk is not acceptable!
See DESIGN.txt for information about code layout which will help you find
where to add tests (and indeed where to change things).
Running the tests
-----------------
Generally just ``make`` is all that is needed to run all the tests. However
if dropping into pdb, it is currently more convenient to use
``python -m testtools.run testrepository.tests.test_suite``.
Diagnosing issues
-----------------
The cli UI will drop into pdb when an error is thrown if TESTR_PDB is set in
the environment. This can be very useful for diagnosing problems.
Releasing
---------
Update NEWS and testrepository/__init__.py version numbers. Release to pypi.
Pivot the next milestone on LP to version, and make a new next milestone.
Make a new tag and push that to github.
This diff is collapsed.
.. Test Repository documentation master file, created by
sphinx-quickstart on Mon Dec 3 23:24:00 2012.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to Test Repository's documentation!
===========================================
Contents:
.. toctree::
:maxdepth: 2
MANUAL
DESIGN
DEVELOPERS
Indices and tables
==================
* :ref:`genindex`
* :ref:`search`
[egg_info]
tag_build =
tag_date = 0
tag_svn_revision = 0
#!/usr/bin/env python
#
# Copyright (c) 2009-2013 Testrepository Contributors
#
# Licensed under either the Apache License, Version 2.0 or the BSD 3-clause
# license at the users choice. A copy of both licenses are available in the
# project source as Apache-2.0 and BSD. You may not use this file except in
# compliance with one of these two licences.
#
# Unless required by applicable law or agreed to in writing, software
# distributed under these licenses is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# license you chose for the specific language governing permissions and
# limitations under that license.
from setuptools import setup
import email
import os
import testrepository
def get_revno():
import bzrlib.workingtree
t = bzrlib.workingtree.WorkingTree.open_containing(__file__)[0]
return t.branch.revno()
def get_version_from_pkg_info():
"""Get the version from PKG-INFO file if we can."""
pkg_info_path = os.path.join(os.path.dirname(__file__), 'PKG-INFO')
try:
pkg_info_file = open(pkg_info_path, 'r')
except (IOError, OSError):
return None
try:
pkg_info = email.message_from_file(pkg_info_file)
except email.MessageError:
return None
return pkg_info.get('Version', None)
def get_version():
"""Return the version of testrepository that we are building."""
version = '.'.join(
str(component) for component in testrepository.__version__[0:3])
phase = testrepository.__version__[3]
if phase == 'final':
return version
pkg_info_version = get_version_from_pkg_info()
if pkg_info_version:
return pkg_info_version
revno = get_revno()
if phase == 'alpha':
# No idea what the next version will be
return 'next-r%s' % revno
else:
# Preserve the version number but give it a revno prefix
return version + '-r%s' % revno
description = open(os.path.join(os.path.dirname(__file__), 'README.txt'), 'rt').read()
setup(name='testrepository',
author='Robert Collins',
author_email='robertc@robertcollins.net',
url='https://launchpad.net/testrepository',
description='A repository of test results.',
long_description=description,
keywords="subunit unittest testrunner",
classifiers = [
'Development Status :: 6 - Mature',
'Intended Audience :: Developers',
'License :: OSI Approved :: BSD License',
'License :: OSI Approved :: Apache Software License',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Programming Language :: Python :: 3',
'Topic :: Software Development :: Quality Assurance',
'Topic :: Software Development :: Testing',
],
scripts=['testr'],
version=get_version(),
packages=['testrepository',
'testrepository.arguments',
'testrepository.commands',
'testrepository.repository',
'testrepository.tests',
'testrepository.tests.arguments',
'testrepository.tests.commands',
'testrepository.tests.repository',
'testrepository.tests.ui',
'testrepository.ui',
],
install_requires=[
'fixtures',
'python-subunit >= 0.0.18',
'testtools >= 0.9.30',
],
extras_require = dict(
test=[
'bzr',
'pytz',
'testresources',
'testscenarios',
]
),
entry_points={
'distutils.commands': [
'testr = testrepository.setuptools_command:Testr',
],
},
)
#!/usr/bin/env python
#
# Copyright (c) 2009 Testrepository Contributors
#
# Licensed under either the Apache License, Version 2.0 or the BSD 3-clause
# license at the users choice. A copy of both licenses are available in the
# project source as Apache-2.0 and BSD. You may not use this file except in
# compliance with one of these two licences.
#
# Unless required by applicable law or agreed to in writing, software
# distributed under these licenses is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# license you chose for the specific language governing permissions and
# limitations under that license.
"""The CLI entry point to testrepository.
No program logic is in this script - see testrepository.commands.run_argv.
"""
import sys
from testrepository.commands import run_argv
if __name__ == "__main__":
sys.exit(run_argv(sys.argv, sys.stdin, sys.stdout, sys.stderr))
Metadata-Version: 1.1
Name: testrepository
Version: 0.0.20
Summary: A repository of test results.
Home-page: https://launchpad.net/testrepository
Author: Robert Collins
Author-email: robertc@robertcollins.net
License: UNKNOWN
Description: Test Repository
+++++++++++++++
Overview
~~~~~~~~
This project provides a database of test results which can be used as part of
developer workflow to ensure/check things like:
* No commits without having had a test failure, test fixed cycle.
* No commits without new tests being added.
* What tests have failed since the last commit (to run just a subset).
* What tests are currently failing and need work.
Test results are inserted using subunit (and thus anything that can output
subunit or be converted into a subunit stream can be accepted).
A mailing list for discussion, usage and development is at
https://launchpad.net/~testrepository-dev - all are welcome to join. Some folk
hang out on #testrepository on irc.freenode.net.
CI for the project is at http://build.robertcollins.net/job/testrepository-default/.
Licensing
~~~~~~~~~
Test Repository is under BSD / Apache 2.0 licences. See the file COPYING in the source for details.
Quick Start
~~~~~~~~~~~
Create a config file::
$ touch .testr.conf
Create a repository::
$ testr init
Load a test run into the repository::
$ testr load < testrun
Query the repository::
$ testr stats
$ testr last
$ testr failing
Delete a repository::
$ rm -rf .testrepository
Documentation
~~~~~~~~~~~~~
More detailed documentation including design and implementation details, a
user manual, and guidelines for development of Test Repository itself can be
found at https://testrepository.readthedocs.org/en/latest, or in the source
tree at doc/ (run make -C doc html).
Keywords: subunit unittest testrunner
Platform: UNKNOWN
Classifier: Development Status :: 6 - Mature
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: Topic :: Software Development :: Testing
.bzrignore
.testr.conf
Apache-2.0
BSD
COPYING
INSTALL.txt
MANIFEST.in
Makefile
NEWS
README.txt
setup.py
testr
doc/DESIGN.txt
doc/DEVELOPERS.txt
doc/MANUAL.txt
doc/index.txt
testrepository/__init__.py
testrepository/results.py
testrepository/setuptools_command.py
testrepository/testcommand.py
testrepository/testlist.py
testrepository/utils.py
testrepository.egg-info/PKG-INFO
testrepository.egg-info/SOURCES.txt
testrepository.egg-info/dependency_links.txt
testrepository.egg-info/entry_points.txt
testrepository.egg-info/requires.txt
testrepository.egg-info/top_level.txt
testrepository/arguments/__init__.py
testrepository/arguments/command.py
testrepository/arguments/doubledash.py
testrepository/arguments/path.py
testrepository/arguments/string.py
testrepository/commands/__init__.py
testrepository/commands/commands.py
testrepository/commands/failing.py
testrepository/commands/help.py
testrepository/commands/init.py
testrepository/commands/last.py
testrepository/commands/list_tests.py
testrepository/commands/load.py
testrepository/commands/quickstart.py
testrepository/commands/run.py
testrepository/commands/slowest.py
testrepository/commands/stats.py
testrepository/repository/__init__.py
testrepository/repository/file.py
testrepository/repository/memory.py
testrepository/repository/samba_buildfarm.py
testrepository/tests/__init__.py
testrepository/tests/monkeypatch.py
testrepository/tests/stubpackage.py
testrepository/tests/test_arguments.py
testrepository/tests/test_commands.py
testrepository/tests/test_matchers.py
testrepository/tests/test_monkeypatch.py
testrepository/tests/test_repository.py
testrepository/tests/test_results.py
testrepository/tests/test_setup.py
testrepository/tests/test_stubpackage.py
testrepository/tests/test_testcommand.py
testrepository/tests/test_testr.py
testrepository/tests/test_ui.py
testrepository/tests/arguments/__init__.py
testrepository/tests/arguments/test_command.py
testrepository/tests/arguments/test_doubledash.py
testrepository/tests/arguments/test_path.py
testrepository/tests/arguments/test_string.py
testrepository/tests/commands/__init__.py
testrepository/tests/commands/test_commands.py
testrepository/tests/commands/test_failing.py
testrepository/tests/commands/test_help.py
testrepository/tests/commands/test_init.py
testrepository/tests/commands/test_last.py
testrepository/tests/commands/test_list_tests.py
testrepository/tests/commands/test_load.py
testrepository/tests/commands/test_quickstart.py
testrepository/tests/commands/test_run.py
testrepository/tests/commands/test_slowest.py
testrepository/tests/commands/test_stats.py
testrepository/tests/repository/__init__.py
testrepository/tests/repository/test_file.py
testrepository/tests/ui/__init__.py
testrepository/tests/ui/test_cli.py
testrepository/tests/ui/test_decorator.py
testrepository/ui/__init__.py
testrepository/ui/cli.py
testrepository/ui/decorator.py
testrepository/ui/model.py
\ No newline at end of file
[distutils.commands]
testr = testrepository.setuptools_command:Testr
fixtures
python-subunit >= 0.0.18
testtools >= 0.9.30
[test]
bzr
pytz
testresources
testscenarios
\ No newline at end of file
#
# Copyright (c) 2009 Testrepository Contributors
#
# Licensed under either the Apache License, Version 2.0 or the BSD 3-clause
# license at the users choice. A copy of both licenses are available in the
# project source as Apache-2.0 and BSD. You may not use this file except in
# compliance with one of these two licences.
#
# Unless required by applicable law or agreed to in writing, software
# distributed under these licenses is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# license you chose for the specific language governing permissions and
# limitations under that license.
"""The testrepository library.
This library is divided into some broad areas.
The commands package contains the main user entry points into the application.
The ui package contains various user interfaces.
The repository package contains the core storage code.
The tests package contains tests and test specific support code.
"""
# same format as sys.version_info: "A tuple containing the five components of
# the version number: major, minor, micro, releaselevel, and serial. All
# values except releaselevel are integers; the release level is 'alpha',
# 'beta', 'candidate', or 'final'. The version_info value corresponding to the
# Python version 2.0 is (2, 0, 0, 'final', 0)." Additionally we use a
# releaselevel of 'dev' for unreleased under-development code.
#
# If the releaselevel is 'alpha' then the major/minor/micro components are not
# established at this point, and setup.py will use a version of next-$(revno).
# If the releaselevel is 'final', then the tarball will be major.minor.micro.
# Otherwise it is major.minor.micro~$(revno).
__version__ = (0, 0, 20, 'final', 0)
#
# Copyright (c) 2010 Testrepository Contributors
#
# Licensed under either the Apache License, Version 2.0 or the BSD 3-clause
# license at the users choice. A copy of both licenses are available in the
# project source as Apache-2.0 and BSD. You may not use this file except in
# compliance with one of these two licences.
#
# Unless required by applicable law or agreed to in writing, software
# distributed under these licenses is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# license you chose for the specific language governing permissions and
# limitations under that license.
"""'Arguments' for testr.
This is a small typed arguments concept - which is perhaps obsoleted by
argparse in Python 2.7, but for testrepository is an extension used with
optparse.
The code in this module contains the AbstractArgument base class. Individual
argument types are present in e.g. testrepository.arguments.string.
See testrepository.commands.Command for usage of Arguments.
Plugins and extensions wanting to add argument types should either define them
internally or install into testrepository.arguments as somename (perhaps by
extending the testrepository.arguments __path__ to include a directory
containing their argument types - no __init__ is needed in that directory.)
"""
import sys
from testtools.compat import reraise
class AbstractArgument(object):
"""A argument that a command may need.
Arguments can be converted into a summary for describing the UI to users,
and provide validator/parsers for the arguments.
:ivar: The name of the argument. This is used for retrieving the argument
from UI objects, and for generating the summary.
"""
def __init__(self, name, min=1, max=1):
"""Create an AbstractArgument.
While conceptually a separate SequenceArgument could be used, all
arguments support sequencing to avoid unnecessary boilerplate in user
code.
:param name: The name for the argument.
:param min: The minimum number of occurences permitted.
:param max: The maximum number of occurences permitted. None for
unlimited.
"""
self.name = name
self.minimum_count = min
self.maximum_count = max
def summary(self):
"""Get a regex-like summary of this argument."""
result = self.name
if (self.minimum_count == self.maximum_count and
self.minimum_count == 1):
return result
minmax = (self.minimum_count, self.maximum_count)
if minmax == (0, 1):
return result + '?'
if minmax == (1, None):
return result + '+'
if minmax == (0, None):
return result + '*'
if minmax[1] == None:
minmax = (minmax[0], '')
return result + '{%s,%s}' % minmax
def parse(self, argv):
"""Evaluate arguments in argv.
Used arguments are removed from argv.
:param argv: The arguments to parse.
:return: The parsed results as a list.
"""
count = 0
result = []
error = None
while len(argv) > count and (
self.maximum_count is None or count < self.maximum_count):
arg = argv[count]
count += 1
try:
result.append(self._parse_one(arg))
except ValueError:
# argument rejected this element
error = sys.exc_info()
count -= 1
break
if count < self.minimum_count:
if error is not None:
reraise(error[0], error[1], error[2])
raise ValueError('not enough arguments present/matched in %s' % argv)
del argv[:count]
return result
def _parse_one(self, arg):
"""Parse a single argument.
:param arg: An arg from an argv.
:result: The parsed argument.
:raises ValueError: If the arg cannot be parsed/validated.
"""
raise NotImplementedError(self._parse_one)
#
# Copyright (c) 2010 Testrepository Contributors
#
# Licensed under either the Apache License, Version 2.0 or the BSD 3-clause
# license at the users choice. A copy of both licenses are available in the
# project source as Apache-2.0 and BSD. You may not use this file except in
# compliance with one of these two licences.
#
# Unless required by applicable law or agreed to in writing, software
# distributed under these licenses is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# license you chose for the specific language governing permissions and
# limitations under that license.
"""An Argument that looks up a command object."""
from testrepository.arguments import AbstractArgument
from testrepository import commands
class CustomError(ValueError):
def __str__(self):
return self.args[0]
class CommandArgument(AbstractArgument):
"""An argument that looks up a command."""
def _parse_one(self, arg):
try:
return commands._find_command(arg)
except KeyError:
raise CustomError("Could not find command '%s'." % arg)
#
# Copyright (c) 2012 Testrepository Contributors
#
# Licensed under either the Apache License, Version 2.0 or the BSD 3-clause
# license at the users choice. A copy of both licenses are available in the
# project source as Apache-2.0 and BSD. You may not use this file except in
# compliance with one of these two licences.
#
# Unless required by applicable law or agreed to in writing, software
# distributed under these licenses is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# license you chose for the specific language governing permissions and
# limitations under that license.
"""An Argument that checks for '--'."""
from testrepository.arguments import AbstractArgument
class DoubledashArgument(AbstractArgument):
"""An argument that captures '--'."""
def __init__(self):
super(DoubledashArgument, self).__init__('doubledash', min=0)
def _parse_one(self, arg):
if arg != '--':
raise ValueError('not a doubledash %r' % (arg,))
return arg
#
# Copyright (c) 2012 Testrepository Contributors
#
# Licensed under either the Apache License, Version 2.0 or the BSD 3-clause
# license at the users choice. A copy of both licenses are available in the
# project source as Apache-2.0 and BSD. You may not use this file except in
# compliance with one of these two licences.
#
# Unless required by applicable law or agreed to in writing, software
# distributed under these licenses is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# license you chose for the specific language governing permissions and
# limitations under that license.
"""An Argument that gets the name of an existing path."""
import os.path
from testrepository.arguments import AbstractArgument
class ExistingPathArgument(AbstractArgument):
"""An argument that stores a string verbatim."""
def _parse_one(self, arg):
if arg == '--':
raise ValueError('-- is not a valid argument')
if not os.path.exists(arg):
raise ValueError('No such path %r' % (arg,))
return arg
#
# Copyright (c) 2010 Testrepository Contributors
#
# Licensed under either the Apache License, Version 2.0 or the BSD 3-clause
# license at the users choice. A copy of both licenses are available in the
# project source as Apache-2.0 and BSD. You may not use this file except in
# compliance with one of these two licences.
#
# Unless required by applicable law or agreed to in writing, software
# distributed under these licenses is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# license you chose for the specific language governing permissions and
# limitations under that license.
"""An Argument that simply stores a string."""
from testrepository.arguments import AbstractArgument
class StringArgument(AbstractArgument):
"""An argument that stores a string verbatim."""
def _parse_one(self, arg):
if arg == '--':
raise ValueError('-- is not a valid argument')
return arg
#
# Copyright (c) 2009, 2010 Testrepository Contributors
#
# Licensed under either the Apache License, Version 2.0 or the BSD 3-clause
# license at the users choice. A copy of both licenses are available in the
# project source as Apache-2.0 and BSD. You may not use this file except in
# compliance with one of these two licences.
#
# Unless required by applicable law or agreed to in writing, software
# distributed under these licenses is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# license you chose for the specific language governing permissions and
# limitations under that license.
"""'Commands' for testr.
The code in this module contains the Command base class, the run_argv
entry point to run CLI commands.
Actual commands can be found in testrepository.commands.$commandname.
For example, testrepository.commands.init is the init command name, and
testrepository.command.show_stats would be the show-stats command (if one
existed). The Command discovery logic looks for a class in the module with
the same name - e.g. tesrepository.commands.init.init would be the class.
That class must obey the testrepository.commands.Command protocol, but does
not need to be a subclass.
Plugins and extensions wanting to add commands should install them into
testrepository.commands (perhaps by extending the testrepository.commands
__path__ to include a directory containing their commands - no __init__ is
needed in that directory.)
"""
from inspect import getdoc
from optparse import OptionParser
import os
import sys
import subunit
from testtools.compat import _u
from testrepository.repository import file
def _find_command(cmd_name):
orig_cmd_name = cmd_name
cmd_name = cmd_name.replace('-', '_')
classname = "%s" % cmd_name
modname = "testrepository.commands.%s" % cmd_name
try:
_temp = __import__(modname, globals(), locals(), [classname])
except ImportError:
raise KeyError("Could not import command module %s" % modname)
result = getattr(_temp, classname, None)
if result is None:
raise KeyError(
"Malformed command module - no command class %s found in module %s."
% (classname, modname))
if getattr(result, 'name', None) is None:
# Store the name for the common case of name == lookup path.
result.name = orig_cmd_name
return result
def iter_commands():
"""Iterate over all the command classes."""
paths = __path__
names = set()
for path in paths:
# For now, only support regular installs. TODO: support zip, eggs.
for filename in os.listdir(path):
base = os.path.basename(filename)
if base.startswith('.'):
continue
name = base.split('.', 1)[0]
name = name.replace('_', '-')
names.add(name)
names.discard('--init--')
names.discard('--pycache--')
names = sorted(names)
for name in names:
yield _find_command(name)
class Command(object):
"""A command that can be run.
Commands contain non-UI non-domain specific behaviour - they are the
glue between the UI and the object model.
Commands are parameterised with:
:ivar ui: a UI object which is responsible for brokering the command
arguments, input and output. There is no default ui, it must be
passed to the constructor.
:ivar repository_factory: a repository factory which is used to create or
open repositories. The default repository factory is suitable for
use in the command line tool.
Commands declare that they accept/need/emit:
:ivar args: A list of testrepository.arguments.AbstractArgument instances.
AbstractArgument arguments are validated when set_command is called on
the UI layer.
:ivar input_streams: A list of stream specifications. Mandatory streams
are specified by a simple name. Optional streams are specified by
a simple name with a ? ending the name. Optional multiple streams are
specified by a simple name with a * ending the name, and mandatory
multiple streams by ending the name with +. Multiple streams are used
when a command can process more than one stream.
:ivar options: A list of optparse.Option options to accept. These are
merged with global options by the UI layer when set_command is called.
"""
# class defaults to no streams.
input_streams = []
# class defaults to no arguments.
args = []
# class defaults to no options.
options = []
def __init__(self, ui):
"""Create a Command object with ui ui."""
self.ui = ui
self.repository_factory = file.RepositoryFactory()
self._init()
def execute(self):
"""Execute a command.
This interrogates the UI to ensure that arguments and options are
supplied, performs any validation for the same that the command needs
and finally calls run() to perform the command. Most commands should
not need to override this method, and any user wanting to run a
command should call this method.
This is a synchronous method, and basically just a helper. GUI's or
asynchronous programs can choose to not call it and instead should call
lower level API's.
"""
if not self.ui.set_command(self):
return 1
try:
result = self.run()
except Exception:
error_tuple = sys.exc_info()
self.ui.output_error(error_tuple)
return 3
if not result:
return 0
return result
@classmethod
def get_summary(klass):
docs = klass.__doc__.split('\n')
return docs[0]
def _init(self):
"""Per command init call, called into by Command.__init__."""
def run(self):
"""The core logic for this command to be implemented by subclasses."""
raise NotImplementedError(self.run)
def run_argv(argv, stdin, stdout, stderr):
"""Convenience function to run a command with a CLIUI.
:param argv: The argv to run the command with.
:param stdin: The stdin stream for the command.
:param stdout: The stdout stream for the command.
:param stderr: The stderr stream for the command.
:return: An integer exit code for the command.
"""
cmd_name = None
cmd_args = argv[1:]
for arg in argv[1:]:
if not arg.startswith('-'):
cmd_name = arg
break
if cmd_name is None:
cmd_name = 'help'
cmd_args = ['help']
cmd_args.remove(cmd_name)
cmdclass = _find_command(cmd_name)
from testrepository.ui import cli
ui = cli.UI(cmd_args, stdin, stdout, stderr)
cmd = cmdclass(ui)
result = cmd.execute()
if not result:
return 0