Skip to content

Instantly share code, notes, and snippets.

@elyezer
Created September 14, 2017 14:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save elyezer/c63d75e996156555c148e3798dc59ca6 to your computer and use it in GitHub Desktop.
Save elyezer/c63d75e996156555c148e3798dc59ca6 to your computer and use it in GitHub Desktop.
.\" Man page generated from reStructuredText.
.
.TH "BETELGEUSE" "1" "Sep 14, 2017" "0.12.0" "Betelgeuse"
.SH NAME
betelgeuse \- Betelgeuse Documentation
.
.nr rst2man-indent-level 0
.
.de1 rstReportMargin
\\$1 \\n[an-margin]
level \\n[rst2man-indent-level]
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
-
\\n[rst2man-indent0]
\\n[rst2man-indent1]
\\n[rst2man-indent2]
..
.de1 INDENT
.\" .rstReportMargin pre:
. RS \\$1
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
. nr rst2man-indent-level +1
.\" .rstReportMargin post:
..
.de UNINDENT
. RE
.\" indent \\n[an-margin]
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
.nr rst2man-indent-level -1
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.SS Topics
.INDENT 0.0
.IP \(bu 2
\fI\%What is Betelgeuse?\fP
.IP \(bu 2
\fI\%Prerequisites\fP
.IP \(bu 2
\fI\%Quick Start\fP
.IP \(bu 2
\fI\%How it works?\fP
.INDENT 2.0
.IP \(bu 2
\fI\%How steps and expectedresults work together\fP
.UNINDENT
.IP \(bu 2
\fI\%Usage Examples\fP
.INDENT 2.0
.IP \(bu 2
\fI\%help command\fP
.IP \(bu 2
\fI\%requirement command\fP
.IP \(bu 2
\fI\%test\-case command\fP
.IP \(bu 2
\fI\%test\-plan command\fP
.IP \(bu 2
\fI\%test\-results command\fP
.IP \(bu 2
\fI\%test\-run command\fP
.IP \(bu 2
\fI\%xml\-test\-case command\fP
.IP \(bu 2
\fI\%xml\-test\-run command\fP
.UNINDENT
.IP \(bu 2
\fI\%Case Study \- A real world sample Test Case\fP
.IP \(bu 2
\fI\%Advanced Usage\fP
.UNINDENT
.SH WHAT IS BETELGEUSE?
.sp
Betelgeuse is a python program that reads standard Python test cases and offers
tools to interact with Polarion. Possible interactions are:
.INDENT 0.0
.IP \(bu 2
Automatic creation/update of Requirements and Test Cases from a Python
project code base.
.IP \(bu 2
Automatic creation/update of Test Runs based on a jUnit XML file.
.UNINDENT
.sp
Betelgeuse uses Pylarion project to communicate with Polarion.
.SH PREREQUISITES
.sp
Login to Polarion in a browser to check if the login user has permissions to
create/update the following entities in Polarion:
.INDENT 0.0
.IP \(bu 2
requirement
.IP \(bu 2
test case
.IP \(bu 2
test run
.UNINDENT
.sp
If you want Betelgeuse to automatically approve the test cases, then make sure
the user has permission to approve them. Betelgeuse will check if the user is
on the allowed approvers list, and, if that is the case, will set the approvee
and approve the test case.
.SH QUICK START
.INDENT 0.0
.IP 1. 3
Betelgeuse uses Pylarion to interact with Polarion. Install Pylarion from its
source.
.sp
\fBNOTE:\fP
.INDENT 3.0
.INDENT 3.5
.INDENT 0.0
.IP \(bu 2
It may be possible that the latest version of Betelgeuse may not work
correctly with some versions of Pylarion. In this case, please use an
alternate working version of Pylarion.
.IP \(bu 2
Read Pylarion documentation and set up \fB\&.pylarion\fP config file as
required.
.UNINDENT
.UNINDENT
.UNINDENT
.IP 2. 3
Install betelguese from pypi.
.INDENT 3.0
.INDENT 3.5
.sp
.nf
.ft C
$ pip install betelgeuse
.ft P
.fi
.UNINDENT
.UNINDENT
.IP 3. 3
Alternatively you can install from source:
.INDENT 3.0
.INDENT 3.5
.sp
.nf
.ft C
$ git clone https://github.com/SatelliteQE/betelgeuse.git
$ cd betelgeuse
$ pip install \-e .
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
\fBNOTE:\fP
.INDENT 3.0
.INDENT 3.5
It is always recommended to use python virtual environment
.UNINDENT
.UNINDENT
.UNINDENT
.SH HOW IT WORKS?
.sp
Assuming that you have a \fBtest_user.py\fP file with the following content:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
import entities
import unittest
class EntitiesTest(unittest.TestCase):
def test_positive_create_user(self):
user = entities.User(name=\(aqDavid\(aq, age=20)
self.assertEqual(user.name, \(aqDavid\(aq)
self.assertEqual(user.age, 20)
def test_positive_create_car(self):
car = entities.Car(make=\(aqHonda\(aq, year=2016)
self.assertEqual(car.make, \(aqHonda\(aq)
self.assertEqual(car.year, 2016)
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
Using the example above, Betelgeuse will recognize that there are 2 test cases
available, and the following attributes will be derived:
.INDENT 0.0
.IP \(bu 2
Title: this attribute will be derived from the name of the test method itself:
.INDENT 2.0
.INDENT 3.5
.INDENT 0.0
.IP \(bu 2
test_positive_create_user
.IP \(bu 2
test_positive_create_car
.UNINDENT
.UNINDENT
.UNINDENT
.IP \(bu 2
ID: this attribute will be derived from the concatenation of the
\fImodule.test_name\fP or \fImodule.ClassName.test_name\fP if the test method is
defined within a class. In other words, \fIthe Python import path\fP will be used
to derived the ID. Using our example, the values generated would be:
.INDENT 2.0
.INDENT 3.5
.INDENT 0.0
.IP \(bu 2
test_user.EntitiesTest.test_positive_create_user
.IP \(bu 2
test_user.EntitiesTest.test_positive_create_car
.UNINDENT
.UNINDENT
.UNINDENT
.UNINDENT
.sp
By default, the values automatically derived by Betelgeuse are not very
flexible, specially in the case when you rename an existing test case or move
it to a different class or module. It is recommended, therefore, the use of
field list fields to provide a bit more information about the tests.
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
import entities
import unittest
class EntitiesTest(unittest.TestCase):
def test_positive_create_user(self):
"""Create a new user providing all expected attributes.
:id: 1d73b8cc\-a754\-4637\-8bae\-d9d2aaf89003
:title: Create a new user providing all expected attributes
"""
user = entities.User(name=\(aqDavid\(aq, age=20)
self.assertEqual(user.name, \(aqDavid\(aq)
self.assertEqual(user.age, 20)
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
Now Betelgeuse can use the \fB:title:\fP field to derive a friendlier name for
your test (instead of using \fItest_positive_create_user\fP) and a specific value
for its ID. Other information can also be added to the docstring to provide
more information, and this can be handled by adding more fields (named after
Polarion fields and custom fields).
.sp
\fBNOTE:\fP
.INDENT 0.0
.INDENT 3.5
.INDENT 0.0
.IP 1. 3
Make sure that your \fBIDs\fP are indeed unique per test case.
.IP 2. 3
You can generate a unique UUID using the following code snippet.
.INDENT 3.0
.INDENT 3.5
.sp
.nf
.ft C
import uuid
uuid.uuid4()
.ft P
.fi
.UNINDENT
.UNINDENT
.UNINDENT
.UNINDENT
.UNINDENT
.SS How steps and expectedresults work together
.sp
Betelgeuse will look for some fields when parsing the test cases but there is
an special case: when both \fBsteps\fP and \fBexpectedresults\fP are defined
together.
.sp
Betelgeuse will try to match both and create paired step with an expected
result. For example in the following docstring:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
"""Create a new user providing all expected attributes.
:id: 1d73b8cc\-a754\-4637\-8bae\-d9d2aaf89003
:steps: Create an user with name and email
:expectedresults: User is created without any error being raised
"""
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
A pair of \fBCreate an user with name and email\fP step with \fBUser is created
without any error being raised\fP expected result will be created. If multiple
steps and multiple expected is wanted, then a list can be used:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
"""Create a new user providing all expected attributes.
:id: 1d73b8cc\-a754\-4637\-8bae\-d9d2aaf89003
:steps:
1. Open the user creation page
2. Fill name and email
3. Submit the form
:expectedresults:
1. A page with a form with name and email will be displayed
2. The fields will be populated with the information filled in
3. User is created without any error being raised
"""
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
On the above example three pairs will be created. The first will match the
first item on \fBsteps\fP and first item on \fBexpectedresults\fP, the second pair
will be the second item on \fBsteps\fP and the second item on
\fBexpectedresults\fP, so on and so forth.
.sp
\fBNOTE:\fP
.INDENT 0.0
.INDENT 3.5
If the number of items are not the same, then only one pair will be
created. The step will be the HTML generated by the value of \fBsteps\fP and
the expected result will be the HTML generate by the value of
\fBexpectedresults\fP\&.
.UNINDENT
.UNINDENT
.SH USAGE EXAMPLES
.sp
\fBNOTE:\fP
.INDENT 0.0
.INDENT 3.5
1. For easy understanding of Betelgeuse, this repository is already included with
\fBsample_project\fP folder. This folder contains sample tests and XML results which
will help in setting up and testing Betelgeuse for your project. The sample
commands used below also use this data.
.sp
2. Always run the test runner and Betelgeuse on the same directory to make
sure that the test run ID mapping works fine. Otherwise Betelgeuse may
report ID errors. More info can be found in \fI\%test\-run command\fP section
.UNINDENT
.UNINDENT
.SS help command
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
$ betelgeuse \-\-help
.ft P
.fi
.UNINDENT
.UNINDENT
.SS requirement command
.sp
Creates/updates requirements in Polarion. This command will grab all
requirements (defined by the \fB:requirement:\fP field) and will create/update
them. Also it will approve the requirements which are not approved yet.
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
$ betelgeuse requirement sample_project/tests/ PROJECT_CLOUD
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
\fBNOTE:\fP
.INDENT 0.0
.INDENT 3.5
Requirements must be created in order to link test cases to them. Make sure
to run this before importing the test cases.
.UNINDENT
.UNINDENT
.SS test\-case command
.sp
The \fBtest\-case\fP command generates an XML file suited to be imported by the
Test Case XML Importer. It reads the Python test suite source code and
generates a XML file with all the information necessary for the Test Case XML
Importer.
.sp
The \fBtest\-case\fP command requires you to pass:
.INDENT 0.0
.IP \(bu 2
The path to the Python test suite source code
.IP \(bu 2
The Polarion project ID
.IP \(bu 2
The output XML file path (it will override if the file already exists)
.UNINDENT
.sp
\fBNOTE:\fP
.INDENT 0.0
.INDENT 3.5
Even though \fB\-\-response\-property\fP is optional, it is highly recommended
to pass it because will be easier to monitor the importer messages (which
is not handled by Betelgeuse).
.UNINDENT
.UNINDENT
.sp
The example below shows how to run the command:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
$ betelgeuse test\-case \e
\-\-automation\-script\-format "https://github.com/SatelliteQE/betelgeuse/tree/master/{path}#L{line_number}" \e
sample_project/tests \e
PROJECT \e
betelgeuse\-test\-cases.xml
.ft P
.fi
.UNINDENT
.UNINDENT
.SS test\-plan command
.sp
The test\-plan command allows creating a parent or child test plans. This is
done by using –parent\-name option.
.INDENT 0.0
.TP
.B Create a parent test plan
If \fBparent\-name\fP option is not specified, then just a parent test plan
will be created.
.TP
.B Create a child test plan
If \fBparent\-name\fP option is specified, then a child test plan will be
created and linked to the specified parent test plan.
.UNINDENT
.sp
Betelgeuse will automatically generate the test plan IDs from the passed test
plan names by replacing special characters and converting spaces to \fB_\fP\&.
.sp
\fBWARNING:\fP
.INDENT 0.0
.INDENT 3.5
Make sure to pass the right names for the test plans in order to find the
expected work items in Polarion. Otherwise, you may see an error.
.UNINDENT
.UNINDENT
.sp
Examples:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
$ betelgeuse test\-plan \-\-name "Parent Name" PROJECT_CLOUD
Created new Test Plan Parent Name with ID Parent_Name.
$ betelgeuse test\-plan \e
\-\-name "Child Name" \e
\-\-parent\-name "Parent Name" \e
PROJECT_CLOUD
Created new Test Plan Child Name with ID Child_Name.
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
\fBNOTE:\fP
.INDENT 0.0
.INDENT 3.5
Use \fB\-\-plan\-type\fP to set the plan type of a test plan to \fBrelease\fP or
\fBiteration\fP\&. The default value is \fBrelease\fP\&.
.UNINDENT
.UNINDENT
.sp
The test\-plan command can also be used to update custom fields in a test plan.
The \fB\-\-custom\-fields\fP option can be used with a \fBkey=value\fP format or a JSON
format as explained in \fI\%test\-run command\fP section.
.sp
To create a new test plan and update its \fBstatus\fP:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
$ betelgeuse test\-plan \e
\-\-name="Iteration 1" \e
\-\-custom\-fields status=inprogress \e
PROJECT_CLOUD
Created new Test Plan Iteration 1 with ID Iteration_1.
Test Plan iteration 1 updated with status=inprogress.
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
The test\-plan command is smart enough to check if a test plan with the given
name already exists before creating it. For example, to update an already
existing test plan:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
$ betelgeuse test\-plan \e
\-\-name="Iteration 1" \e
\-\-custom\-fields status=done \e
PROJECT_CLOUD
Found Test Plan Iteration 1.
Test Plan iteration 1 updated with status=done.
.ft P
.fi
.UNINDENT
.UNINDENT
.SS test\-results command
.sp
Gives a nice summary of test cases/results in the given jUnit XML file.
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
$ betelgeuse test\-results \-\-path \e
sample_project/results/sample\-junit\-result.xml
Passed: 1
.ft P
.fi
.UNINDENT
.UNINDENT
.SS test\-run command
.sp
The \fBtest\-run\fP command generates an XML file suited to be imported by the
Test Run XML importer. It takes:
.INDENT 0.0
.IP \(bu 2
A valid xUnit XML file
.IP \(bu 2
A Python test suite where test case IDs can be found
.UNINDENT
.sp
And generates a resulting XML file with all the information necessary for the
Test Run XML importer.
.sp
The \fBtest\-run\fP command only requires you to pass:
.INDENT 0.0
.IP \(bu 2
The path to the xUnit XML file
.IP \(bu 2
The path to the Python test suite source code
.IP \(bu 2
The Polarion user ID
.IP \(bu 2
The Polarion project ID
.IP \(bu 2
The output XML file path (it will override if the file already exists)
.UNINDENT
.sp
\fBNOTE:\fP
.INDENT 0.0
.INDENT 3.5
Even though \fB\-\-response\-property\fP is optional, it is highly recommended
to pass it because will be easier to monitor the importer messages (which
is not handled by Betelgeuse).
.UNINDENT
.UNINDENT
.sp
The example below shows how to run \fBtest\-run\fP command:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
$ betelgeuse test\-run \e
\-\-response\-property property_key=property_value \e
sample_project/results/sample\-junit\-result.xml \e
sample_project/tests/ \e
testuser \e
PROJECT \e
betelgeuse\-test\-run.xml
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
Polarion custom fields can be set by using the \fB\-\-custom\-fields\fP option.
There are two ways to define custom fields:
.INDENT 0.0
.TP
.B \fBkey=value\fP format
This a shortcut when you want to define plain strings as the value of a
custom field.
.TP
.B JSON format
This approach suits better when the type of the custom field matters. For
example, if a custom field expects a boolean as a value.
.UNINDENT
.sp
Example using \fBkey=value\fP format:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
$ betelgeuse test\-run \e
\-\-custom\-fields arch=x8664 \e
\-\-custom\-fields variant=server \e
\-\-response\-property property_key=property_value \e
sample_project/results/sample\-junit\-result.xml \e
sample_project/tests/ \e
testuser \e
PROJECT \e
betelgeuse\-test\-run.xml
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
Example using JSON format:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
$ betelgeuse test\-run \e
\-\-custom\-fields \(aq{"isautomated":"true","arch":"x8664"}\(aq \e
\-\-response\-property property_key=property_value \e
sample_project/results/sample\-junit\-result.xml \e
sample_project/tests/ \e
testuser \e
PROJECT \e
betelgeuse\-test\-run.xml
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
\fBWARNING:\fP
.INDENT 0.0
.INDENT 3.5
Make sure to pass the the custom field ID (same as in Polarion) and its
value. Also, pass custom field values as string since they will be
converted to XML where there is no type information.
.UNINDENT
.UNINDENT
.SS xml\-test\-case command
.sp
Alias to the \fI\%test\-case command\fP\&.
.sp
\fBWARNING:\fP
.INDENT 0.0
.INDENT 3.5
This alias is deprecated and will be removed on a future version.
.UNINDENT
.UNINDENT
.SS xml\-test\-run command
.sp
Alias to the \fI\%test\-run command\fP\&.
.sp
\fBWARNING:\fP
.INDENT 0.0
.INDENT 3.5
This alias is deprecated and will be removed on a future version.
.UNINDENT
.UNINDENT
.SH CASE STUDY - A REAL WORLD SAMPLE TEST CASE
.sp
Field list fields can be used to provide more information about a test case.
The more information one provides via these fields, the more accurate the data
being imported into Polarion. For example:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
import entities
import unittest
class EntitiesTest(unittest.TestCase):
def test_positive_create_user(self):
"""Create a new user providing all expected attributes.
:id: 1d73b8cc\-a754\-4637\-8bae\-d9d2aaf89003
:expectedresults: User is successfully created
:requirement: User Management
:caseautomation: Automated
:caselevel: Acceptance
:casecomponent: CLI
:testtype: Functional
:caseimportance: High
:upstream: No
"""
user = entities.User(name=\(aqDavid\(aq, age=20)
self.assertEqual(user.name, \(aqDavid\(aq)
self.assertEqual(user.age, 20)
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
When the above test case is collected, Betelgeuse will make use of all 9 fields
provided and generates a more meaningful test case.
.sp
Ok, this is cool. But wait, there is more! Betelgeuse will reuse fields defined
in different levels, namely:
.INDENT 0.0
.INDENT 3.5
.INDENT 0.0
.IP \(bu 2
function level
.IP \(bu 2
class level
.IP \(bu 2
module level
.IP \(bu 2
package level
.UNINDENT
.UNINDENT
.UNINDENT
.sp
This feature can be leveraged to minimize the amount of information that needs
to be written for each test case. Since most of the time, test cases grouped in
a module usually share the same generic information, one could move most of
these fields to the \fBmodule\fP level and every single test case found by
Betelgeuse will inherit these attributes. For example:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
"""Test cases for entities.
:caseautomation: Automated
:casecomponent: CLI
:caseimportance: High
:caselevel: Acceptance
:requirement: User Management
:testtype: functional
:upstream: no
"""
import entities
import unittest
class EntitiesTest(unittest\&.TestCase):
def test_positive_create_user(self):
"""Create a new user providing all expected attributes.
:id: 1d73b8cc\-a754\-4637\-8bae\-d9d2aaf89003
:expectedresults: User is successfully created
"""
user = entities\&.User(name=\(aqDavid\(aq, age=20)
self\&.assertEqual(user\&.name, \(aqDavid\(aq)
self\&.assertEqual(user\&.age, 20)
def test_positive_create_car(self):
"""Create a new car providing all expected attributes.
:id: 71b9b000\-b978\-4a95\-b6f8\-83c09ed39c01
:caseimportance: Medium
:expectedresults: Car is successfully created and has no owner
"""
car = entities\&.Car(make=\(aqHonda\(aq, year=2016)
self\&.assertEqual(car\&.make, \(aqHonda\(aq)
self\&.assertEqual(car\&.year, 2016)
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
Now all discovered test cases will inherit the attributes defined at the module
level. Furthermore, the test case attributes can be overridden at the \fIclass
level\fP or at the \fItest case level\fP\&. Using the example above, since
\fBtest_positive_create_car\fP has its own \fIcaseimportance\fP field defined,
Betelgeuse will use its value of \fIMedium\fP for this test case alone while all
other test cases will have a value of \fIHigh\fP, derived from the module.
.SH ADVANCED USAGE
.sp
Betelgeuse allows configuring the field processing to your own needs, check the
Betelgeuse Configuration Module documentation for more
information.
.SH AUTHOR
Satellite QE
.SH COPYRIGHT
2015, Satellite QE
.\" Generated by docutils manpage writer.
.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment