Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
weiwei committed Oct 23, 2016
0 parents commit 684936f
Show file tree
Hide file tree
Showing 8 changed files with 859 additions and 0 deletions.
62 changes: 62 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]

# C extensions
*.so

# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover

# Translations
*.mo
*.pot

# Django stuff:
*.log

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# IDE Specific
.vs/
*.pyproj
*.sln
13 changes: 13 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
language: python
python:
- "3.2"
- "3.3"
- "3.4"
- "3.5"
- "3.5-dev" # 3.5 development branch
- "3.6-dev" # 3.6 development branch
- "nightly" # currently points to 3.7-dev
# command to install dependencies
install: "pip install -r requirements.txt"
# command to run tests
script: py.test test.py
13 changes: 13 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Copyright 2016 Joel Wang

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
155 changes: 155 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
junitparser -- Pythonic JUnit/xUnit Result XML Parser
======================================================

.. image:: https://travis-ci.org/gastlygem/junitparser.svg?branch=master

What does it do?
----------------

junitparser is a JUnit/xUnit Result XML Parser. Use it to parse and manipulate
existing Result XML files, or create new JUnit/xUnit result XMLs from scratch.

There are already a lot of modules that converts JUnit/xUnit XML from a
specific format, but you may run into some proprietory or less-known formats
and you want to convert them and feed the result to another tool. This is where
junitparser come into handy.

Why junitparser?
----------------

* Functionality. There are various JUnit/xUnit XML libraries, some does
parsing, some does XML generation, some does manipulation. This module tries
to do most functions in a single package.
* Extensibility. JUnit/xUnit is hardly a standardized format. The base format
is somewhat universally agreed with, but beyond that, there could be "custom"
elements and attributes. junitparser aims to support them all, by
monkeypatching and subclassing some base classes.
* Pythonic. You can manipulate test cases and suites in a pythonic way.
* Simplicity. No external dependencies. Though it will use lxml if available.

Installation
-------------

pip install junitparser

Usage
-----

Create Junit XML format reports from scratch
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. code-block:: python
from junitparser import TestCase, TestSuite, JunitXml, Skipped, Error
# Create cases
case1 = TestCase('case1')
case1.result = Skipped()
case2 = TestCase('case2')
case2.result = Error('Example error message', 'the_error_type')
# Create suite and add cases
suite = TestSuite('suite1')
suite.add_property('build', '55')
suite.add_testcase(case1)
suite.add_testcase(case2)
suite.delete_testcase(case2)
# Add suite to JunitXml
xml = JunitXml()
xml.add_testsuite(suite)
xml.write('junit.xml')
Read and manipulate exiting JUnit/xUnit XML files
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. code-block:: python
from junitparser import JUnitXml
xml = JUnitXml('/path/to/junit.xml')
for suite in result:
# handle suites
for case in suite:
# handle cases
xml.write() # Writes back to file
Merge XML files
~~~~~~~~~~~~~~~

.. code-block:: python
from junitparser import JUnitXml
xml1 = JUnitXml('/path/to/junit1.xml')
xml2 = JUnitXml('/path/to/junit2.xml')
newxml = xml1 + xml2
# Alternatively, merge inplace
xml1 += xml2
Create XML with custom attributes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. code-block:: python
from junitparser import TestCase, Attr
# The id attribute is not supported by default
# But we can support it by monky patching
TestCase.id = Attr('id')
case = TestCase()
case.id = '123'
print(case.tostring())
And you get the following output::

b'<testcase id="123"/>\n'

Create XML with custom element
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

There may be once in 1000 years you want to it this way, but anyways::

.. code-block:: python
from junitparser import Element, Attr, TestSuite
# Suppose you want to add element Custom to TestSuite.
# You can create the new element by subclassing Element,
# Then add custom attributes to it.
class Custom(Element):
_tag = 'custom'
foo = Attr()
bar = Attr()
# Then monkeypatch TestSuite to handle Custom
# TODO: Tricky part, update later
TODO
----


Notes
-----

Python 2 is not supported. Currently there is no plan to support Python 2.

There are some other packages providing similar functionalities,
https://pypi.python.org/pypi/xunitparser/
https://pypi.python.org/pypi/xunitgen
https://pypi.python.org/pypi/xunitmerge
https://pypi.python.org/pypi/junit-xml




Usage
-----


_`junit-xml`: https://pypi.python.org/pypi/junit-xml
Loading

0 comments on commit 684936f

Please sign in to comment.