Skip to content

Commit

Permalink
Added more doc-strings and parameter checks.
Browse files Browse the repository at this point in the history
  • Loading branch information
Paebbels committed Oct 4, 2024
1 parent a8e965c commit e740136
Show file tree
Hide file tree
Showing 11 changed files with 979 additions and 254 deletions.
32 changes: 16 additions & 16 deletions doc/Unittesting/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ the unified data model.

:ref:`UNITTEST/DataModel/Testcase`
^^^
A :dfn:`test case` is the leaf-element in the test entity hierarchy and describes a single test run. Test
cases are grouped by test suites.
A :dfn:`test case` is the leaf-element in the test entity hierarchy and describes an individual test run.
Test cases are grouped by test suites.

.. grid-item-card::
:columns: 6
Expand Down Expand Up @@ -136,16 +136,16 @@ Common
test suite's :data:`~pyEDAA.Reports.Unittesting.TestsuiteBase.Kind` field.

:data:`~pyEDAA.Reports.Unittesting.Base.StartTime`
Every test entity has a time when it was started. In case of a test case, it's the time when a single test was
run. In case of a test suite, it's the time when the first test within this test suite was started. In case of a
test suite summary, it's the time when the whole regression test was started.
Every test entity has a time when it was started. In case of a test case, it's the time when an individual test
was run. In case of a test suite, it's the time when the first test within this test suite was started. In case
of a test suite summary, it's the time when the whole regression test was started.

If the start time is unknown, set this value to ``None``.

:data:`~pyEDAA.Reports.Unittesting.Base.SetupDuration`
Every test entity has a field to capture the setup duration of a test run. In case of a test case, it's the time
spend on setting up a single test run. In case of a test suite, it's the duration spend on preparing the group
of tests for the first test run.
Every test entity has a field to capture the setup duration of a test run. In case of a test case, it's the
time spend on setting up an individual test run. In case of a test suite, it's the duration spend on preparing
the group of tests for the first test run.

If the setup duration can't be distinguished from the test's runtime, set this value to ``None``.

Expand All @@ -156,8 +156,8 @@ Common

:data:`~pyEDAA.Reports.Unittesting.Base.TeardownDuration`
Every test entity has a field to capture the teardown duration of a test run. In case of a test case, it's the
time spend on tearing down a single test run. In case of a test suite, it's the duration spend on finalizing the
group of tests after the last test run.
time spend on tearing down an individual test run. In case of a test suite, it's the duration spend on
finalizing the group of tests after the last test run.

If the teardown duration can't be distinguished from the test's runtime, set this value to ``None``.

Expand Down Expand Up @@ -338,8 +338,8 @@ Testcase
.. grid-item::
:columns: 6

A :class:`~pyEDAA.Reports.Unittesting.Testcase` is the leaf-element in the test entity hierarchy and describes a
single test run. Test cases are grouped by test suites.
A :class:`~pyEDAA.Reports.Unittesting.Testcase` is the leaf-element in the test entity hierarchy and describes an
individual test run. Test cases are grouped by test suites.

:data:`~pyEDAA.Reports.Unittesting.Testcase.Status`
The overall status of a test case.
Expand Down Expand Up @@ -577,10 +577,10 @@ Document
:data:`~pyEDAA.Reports.Unittesting.Document.ModelConversionDuration`
tbd

:meth:`~pyEDAA.Reports.Unittesting.Document.Read`
:meth:`~pyEDAA.Reports.Unittesting.Document.Analyze`
tbd

:meth:`~pyEDAA.Reports.Unittesting.Document.Parse`
:meth:`~pyEDAA.Reports.Unittesting.Document.Convert`
tbd

.. grid-item::
Expand All @@ -606,11 +606,11 @@ Document
...
@abstractmethod
def Read(self) -> None:
def Analyze(self) -> None:
...
@abstractmethod
def Parse(self):
def Convert(self):
...
Expand Down
12 changes: 6 additions & 6 deletions doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,12 @@ Report Formats
* :ref:`Transform the hierarchy of reports <UNITTEST/Feature/Transform>`
* :ref:`Write Ant JUnit reports (also to other dialects) <UNITTEST/Feature/Write>`

.. rubric:: Supported file formats

* :ref:`Ant JUnit4 XML format and various dialects <UNITTEST/FileFormats/AntJUnit4>`
* :ref:`JUnit5 XML format (Open Test Reporting) <UNITTEST/FileFormats/JUnit5>`
* :ref:`OSVVM YAML format <UNITTEST/FileFormats/OSVVM>`

.. rubric:: Supported tools

* :ref:`CTest <UNITTEST/Tool/CTest>`
Expand All @@ -140,12 +146,6 @@ Report Formats
* :ref:`OSVVM <UNITTEST/Tool/OSVVM>`
* :ref:`pyTest <UNITTEST/Tool/pytest>`

.. rubric:: Supported file formats

* :ref:`Ant JUnit4 XML format and various dialects <UNITTEST/FileFormats/AntJUnit4>`
* :ref:`JUnit5 XML format (Open Test Reporting) <UNITTEST/FileFormats/JUnit5>`
* :ref:`OSVVM YAML format <UNITTEST/FileFormats/OSVVM>`


.. #grid-item-card::
:columns: 4
Expand Down
6 changes: 3 additions & 3 deletions pyEDAA/Reports/OSVVM/AlertLog.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ def __init__(self, filename: Path, parse: bool = False) -> None:
self._modelConversion = -1.0

if parse:
self.Read()
self.Analyze()
self.Parse()

@property
Expand All @@ -246,7 +246,7 @@ def AnalysisDuration(self) -> timedelta:
def ModelConversionDuration(self) -> timedelta:
return timedelta(seconds=self._modelConversion)

def Read(self) -> None:
def Analyze(self) -> None:
if not self._path.exists():
raise OSVVMException(f"OSVVM AlertLog YAML file '{self._path}' does not exist.") \
from FileNotFoundError(f"File '{self._path}' not found.")
Expand Down Expand Up @@ -327,7 +327,7 @@ def _ParseIntFieldFromYAML(node: CommentedMap, fieldName: str) -> Nullable[int]:
def Parse(self) -> None:
if self._yamlDocument is None:
ex = OSVVMException(f"OSVVM AlertLog YAML file '{self._path}' needs to be read and analyzed by a YAML parser.")
ex.add_note(f"Call 'Document.Read()' or create document using 'Document(path, parse=True)'.")
ex.add_note(f"Call 'Document.Analyze()' or create the document using 'Document(path, parse=True)'.")
raise ex

startConversion = perf_counter_ns()
Expand Down
65 changes: 36 additions & 29 deletions pyEDAA/Reports/Unittesting/JUnit/AntJUnit.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,28 +108,6 @@ def Aggregate(self, strict: bool = True) -> TestsuiteAggregateReturnType:

return tests, skipped, errored, failed, passed

def Iterate(self, scheme: IterationScheme = IterationScheme.Default) -> Generator[Union[TestsuiteType, Testcase], None, None]:
assert IterationScheme.PreOrder | IterationScheme.PostOrder not in scheme

if IterationScheme.PreOrder in scheme:
if IterationScheme.IncludeSelf | IterationScheme.IncludeTestsuites in scheme:
yield self

if IterationScheme.IncludeTestcases in scheme:
for testcase in self._testclasses.values():
yield testcase

for testsuite in self._testsuites.values():
yield from testsuite.Iterate(scheme | IterationScheme.IncludeSelf)

if IterationScheme.PostOrder in scheme:
if IterationScheme.IncludeTestcases in scheme:
for testcase in self._testclasses.values():
yield testcase

if IterationScheme.IncludeSelf | IterationScheme.IncludeTestsuites in scheme:
yield self

@classmethod
def FromTestsuite(cls, testsuite: ut_Testsuite) -> "Testsuite":
juTestsuite = cls(
Expand Down Expand Up @@ -250,9 +228,19 @@ def ToTestsuiteSummary(self) -> ut_TestsuiteSummary:

@export
class Document(ju_Document):
_TESTCASE: ClassVar[Type[Testcase]] = Testcase
_TESTCLASS: ClassVar[Type[Testclass]] = Testclass
_TESTSUITE: ClassVar[Type[Testsuite]] = Testsuite
"""
A document reader and writer for the Ant + JUnit4 XML file format.
This class reads, validates and transforms an XML file in the Ant + JUnit4 format into a JUnit data model. It can then
be converted into a unified test entity data model.
In reverse, a JUnit data model instance with the specific Ant + JUnit4 file format can be created from a unified test
entity data model. This data model can be written as XML into a file.
"""

_TESTCASE: ClassVar[Type[Testcase]] = Testcase
_TESTCLASS: ClassVar[Type[Testclass]] = Testclass
_TESTSUITE: ClassVar[Type[Testsuite]] = Testsuite

@classmethod
def FromTestsuiteSummary(cls, xmlReportFile: Path, testsuiteSummary: ut_TestsuiteSummary):
Expand All @@ -271,9 +259,19 @@ def FromTestsuiteSummary(cls, xmlReportFile: Path, testsuiteSummary: ut_Testsuit

return doc

def Read(self) -> None:
def Analyze(self) -> None:
"""
Analyze the XML file, parse the content into an XML data structure and validate the data structure using an XML
schema.
.. hint::
The time spend for analysis will be made available via property :data:`AnalysisDuration`..
The used XML schema definition is specific to the Ant JUnit4 dialect.
"""
xmlSchemaFile = "Ant-JUnit.xsd"
self._Read(xmlSchemaFile)
self._Analyze(xmlSchemaFile)

def Write(self, path: Nullable[Path] = None, overwrite: bool = False, regenerate: bool = False) -> None:
if path is None:
Expand All @@ -294,10 +292,19 @@ def Write(self, path: Nullable[Path] = None, overwrite: bool = False, regenerate
with path.open("wb") as file:
file.write(tostring(self._xmlDocument, encoding="utf-8", xml_declaration=True, pretty_print=True))

def Parse(self) -> None:
def Convert(self) -> None:
"""
Convert the parsed and validated XML data structure into a JUnit test entity hierarchy.
.. hint::
The time spend for model conversion will be made available via property :data:`ModelConversionDuration`.
:raises UnittestException: If XML was not read and parsed before.
"""
if self._xmlDocument is None:
ex = UnittestException(f"JUnit XML file '{self._path}' needs to be read and analyzed by an XML parser.")
ex.add_note(f"Call 'JUnitDocument.Read()' or create document using 'JUnitDocument(path, parse=True)'.")
ex.add_note(f"Call 'JUnitDocument.Analyze()' or create the document using 'JUnitDocument(path, parse=True)'.")
raise ex

startConversion = perf_counter_ns()
Expand Down
65 changes: 36 additions & 29 deletions pyEDAA/Reports/Unittesting/JUnit/CTestJUnit.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,28 +108,6 @@ def Aggregate(self, strict: bool = True) -> TestsuiteAggregateReturnType:

return tests, skipped, errored, failed, passed

def Iterate(self, scheme: IterationScheme = IterationScheme.Default) -> Generator[Union[TestsuiteType, Testcase], None, None]:
assert IterationScheme.PreOrder | IterationScheme.PostOrder not in scheme

if IterationScheme.PreOrder in scheme:
if IterationScheme.IncludeSelf | IterationScheme.IncludeTestsuites in scheme:
yield self

if IterationScheme.IncludeTestcases in scheme:
for testcase in self._testclasses.values():
yield testcase

for testsuite in self._testsuites.values():
yield from testsuite.Iterate(scheme | IterationScheme.IncludeSelf)

if IterationScheme.PostOrder in scheme:
if IterationScheme.IncludeTestcases in scheme:
for testcase in self._testclasses.values():
yield testcase

if IterationScheme.IncludeSelf | IterationScheme.IncludeTestsuites in scheme:
yield self

@classmethod
def FromTestsuite(cls, testsuite: ut_Testsuite) -> "Testsuite":
juTestsuite = cls(
Expand Down Expand Up @@ -250,9 +228,19 @@ def ToTestsuiteSummary(self) -> ut_TestsuiteSummary:

@export
class Document(ju_Document):
_TESTCASE: ClassVar[Type[Testcase]] = Testcase
_TESTCLASS: ClassVar[Type[Testclass]] = Testclass
_TESTSUITE: ClassVar[Type[Testsuite]] = Testsuite
"""
A document reader and writer for the CTest JUnit XML file format.
This class reads, validates and transforms an XML file in the CTest JUnit format into a JUnit data model. It can then
be converted into a unified test entity data model.
In reverse, a JUnit data model instance with the specific CTest JUnit file format can be created from a unified test
entity data model. This data model can be written as XML into a file.
"""

_TESTCASE: ClassVar[Type[Testcase]] = Testcase
_TESTCLASS: ClassVar[Type[Testclass]] = Testclass
_TESTSUITE: ClassVar[Type[Testsuite]] = Testsuite

@classmethod
def FromTestsuiteSummary(cls, xmlReportFile: Path, testsuiteSummary: ut_TestsuiteSummary):
Expand All @@ -271,9 +259,19 @@ def FromTestsuiteSummary(cls, xmlReportFile: Path, testsuiteSummary: ut_Testsuit

return doc

def Read(self) -> None:
def Analyze(self) -> None:
"""
Analyze the XML file, parse the content into an XML data structure and validate the data structure using an XML
schema.
.. hint::
The time spend for analysis will be made available via property :data:`AnalysisDuration`.
The used XML schema definition is specific to the CTest JUnit dialect.
"""
xmlSchemaFile = "CTest-JUnit.xsd"
self._Read(xmlSchemaFile)
self._Analyze(xmlSchemaFile)

def Write(self, path: Nullable[Path] = None, overwrite: bool = False, regenerate: bool = False) -> None:
if path is None:
Expand All @@ -294,10 +292,19 @@ def Write(self, path: Nullable[Path] = None, overwrite: bool = False, regenerate
with path.open("wb") as file:
file.write(tostring(self._xmlDocument, encoding="utf-8", xml_declaration=True, pretty_print=True))

def Parse(self) -> None:
def Convert(self) -> None:
"""
Convert the parsed and validated XML data structure into a JUnit test entity hierarchy.
.. hint::
The time spend for model conversion will be made available via property :data:`ModelConversionDuration`.
:raises UnittestException: If XML was not read and parsed before.
"""
if self._xmlDocument is None:
ex = UnittestException(f"JUnit XML file '{self._path}' needs to be read and analyzed by an XML parser.")
ex.add_note(f"Call 'JUnitDocument.Read()' or create document using 'JUnitDocument(path, parse=True)'.")
ex.add_note(f"Call 'JUnitDocument.Analyze()' or create the document using 'JUnitDocument(path, parse=True)'.")
raise ex

startConversion = perf_counter_ns()
Expand Down
Loading

0 comments on commit e740136

Please sign in to comment.