Customization
Custom Exporter
You can define your exporters by inheriting from the base exporter class and use
them by passing them to @test_plan
decorator via exporters
list.
Custom export functionality should be implemented within export
method.
Each exporter in the exporters
list will get a fresh copy of the original
source (e.g. report
).
from testplan.common.exporters import ExportContext
from testplan.exporters.testing import Exporter
class CustomExporter(Exporter):
def export(
self,
source: TestReport,
export_context: ExportContext,
) -> Optional[Dict]:
# Custom logic goes here
...
@test_plan(name='SamplePlan', exporters=[CustomExporter(...)])
def main(plan):
...
Examples for custom exporter implementation can be seen here.
Output Styles
Certain output processors (e.g. stdout, PDF) make use of the
generic style objects
for
formatting.
A style object can be initialized with 2 arguments, corresponding display levels for
passing and failing tests. These levels should be one of
StyleEnum
values
(e.g. StyleEnum.CASE
) or their lowercase string representations (e.g. 'case'
)
from testplan.report.testing.styles import Style, StyleEnum
# These style declarations are equivalent.
style_1_a = Style(passing=StyleEnum.TEST, failing=StyleEnum.CASE)
style_1_b = Style(passing='test', failing='case')
Style levels are incremental, going from the least verbose to the most verbose:
RESULT = 0 # Plan level output, the least verbose
TEST = 1
SUITE = 2
CASE = 3
ASSERTION = 4
ASSERTION_DETAIL = 5 # Assertion detail level output, the most verbose
This means when we have a declaration like Style(passing=StyleEnum.TESTCASE, failing=StyleEnum.TESTCASE)
the output will include information starting from Plan level down to testcase method level,
but it will not include any assertion information.
Here’s a simple schema that highlights minimum required styling level for viewing related test information:
Testplan -> StyleEnum.RESULT
|
+---- MultiTest 1 -> StyleEnum.TEST
| |
| +---- Suite 1 -> StyleEnum.SUITE
| | |
| | +--- testcase_method_1 -> StyleEnum.CASE
| | | |
| | | +---- assertion statement -> StyleEnum.ASSERTION
| | | +---- assertion statement
| | | ( ... assertion details ...) -> StyleEnum.ASSERTION_DETAIL
| | |
| | +---- testcase_method_2
| | +---- testcase_method_3
| |
| +---- Suite 2
| ...
+---- MultiTest 2
...
Here is a sample usage of styling objects:
from testplan.report.testing.styles import Style, StyleEnum
@test_plan(
name='SamplePlan',
# On console output configuration
# Display down to testcase level for passing tests
# Display all details for failing tests
stdout_style=Style(
passing=StyleEnum.CASE,
failing=StyleEnum.ASSERTION_DETAIL
),
pdf_path='my-report.pdf',
# PDF report configuration
# Display down to basic assertion level for passing tests
# Display all details for failing tests
pdf_style=Style(
passing=StyleEnum.ASSERTION,
failing=StyleEnum.ASSERTION_DETAIL
)
)
def main(plan):
...