172 """The superclass for the different test case categories."""
174 def __init__(self, testCaseName, isNewlyCreated=False):
175 """Initialize the test case.
177 @param testCaseName The name of the test case.
178 @param isNewlyCreated Indicates if the test case is newly created to suppress the warning
179 that no test functions exist.
210 associatedModules = infoDict.get(
"associatedModules",
None)
211 if associatedModules
is not None:
212 deprecatedModules = 0
213 for associatedModule
in associatedModules:
214 moduleInfo = mevis.MLAB.moduleInfo(associatedModule)
215 if "deprecated" in moduleInfo.get(
"group",
"").lower():
216 deprecatedModules += 1
217 if deprecatedModules == len(associatedModules):
218 MLABpriv.ignoreDeprecationWarnings(associatedModules)
222 self.
__xmlRoot.set(
"timeout", infoDict.get(
"timeout",
"0"))
225 etree.SubElement(self.
__xmlRoot,
"Package").text = infoDict[
"package"]
226 etree.SubElement(self.
__xmlRoot,
"Author").text = infoDict[
"author"]
227 etree.SubElement(self.
__xmlRoot,
"Maintainer").text = infoDict.get(
"maintainer",
"")
228 etree.SubElement(self.
__xmlRoot,
"Comment").text = infoDict.get(
"comment",
"")
229 etree.SubElement(self.
__xmlRoot,
"File").text = infoDict[
"file"]
230 etree.SubElement(self.
__xmlRoot,
"Line").text = str(infoDict[
"lineno"])
231 showTestFunctionSortLiterals =
"0"
232 if "showTestFunctionSortingLiterals" in infoDict:
233 shouldShowLiterals = mevis.MLAB.valueIsTrue(infoDict[
"showTestFunctionSortingLiterals"])
234 showTestFunctionSortLiterals =
"1" if shouldShowLiterals
else "0"
235 etree.SubElement(self.
__xmlRoot,
"showTestFunctionSortingLiterals").text = showTestFunctionSortLiterals
236 if "preferredRenderer" in infoDict:
237 etree.SubElement(self.
__xmlRoot,
"preferredRenderer").text = infoDict[
"preferredRenderer"]
240 if "dataDirectory" in infoDict:
243 self.
_dataDirectory = os.path.join(os.path.dirname(infoDict[
"file"]),
"Data")
245 if not (infoDict
and "scriptFile" in infoDict):
246 mevis.MLAB.logError(f
"Missing scriptFile tag in TestCase {testCaseName}.")
258 etree.SubElement(self.
__xmlRoot,
"Documentation").text = self.
_ctx.scriptVariable(
"__doc__")
259 except Exception
as e:
260 mevis.MLAB.logError(f
"Failed to load script file {infoDict['scriptFile']}. No tests created.")
263 if "setUpTestCase" in self.
_ctx.callableFunctions():
267 Utils.SETUP_TEST_CASE_FUNCTION,
268 "Collects messages while the test case is set up",
272 if "tearDownTestCase" in self.
_ctx.callableFunctions():
276 Utils.TEARDOWN_TEST_CASE_FUNCTION,
277 "Collects messages during the teardown phase of the test case",
284 Utils.VIRTUAL_UNLOAD_TEST_CASE_TEST_FUNCTION,
285 "Collects errors while the test case is unloaded",
289 MLABpriv.ignoreDeprecationWarnings()
295 Utils.VIRTUAL_LOAD_TEST_CASE_TEST_FUNCTION,
296 "Collects errors while the test case is loaded",
300 def __createVirtualTestFunction(self, basename, name, documentation, prepend):
301 functionsNode = self.
__xmlRoot.find(
"TestFunctions")
302 if functionsNode
is None:
303 functionsNode = etree.SubElement(self.
__xmlRoot,
"TestFunctions")
304 functionXMLNode = functionsNode.makeelement(
305 "Function", {
"basename": basename,
"name": name,
"is_disabled":
"False"}
308 functionsNode.insert(0, functionXMLNode)
310 functionsNode.append(functionXMLNode)
311 etree.SubElement(functionXMLNode,
"Documentation").text = documentation
314 return mevis.MLABTestCaseDatabase.testCaseInfo(testCaseName)
327 """Registers the test case at the TestHelper. Does not support recursive calls."""
339 """Resets the test helper. Does not support recursive calls."""
360 return self.
_ctx.scriptVariable(funcName)
362 def __callTestFunction(self, funcName):
363 """Call the test function with the given name.
365 @param funcName The name of the function to execute.
367 if Utils.isInternalTestCaseFunction(funcName):
371 raise Exception(
"Unknown function!")
379 if type(callInfo)
in (list, tuple):
380 testFunction, testArguments = callInfo
381 callWithKeywordArguments =
False
382 if len(testArguments) == 1
and isinstance(testArguments[0], dict):
383 signature = inspect.signature(testFunction)
386 signature.bind(**testArguments[0])
387 callWithKeywordArguments =
True
390 if callWithKeywordArguments:
391 result = testFunction(**testArguments[0])
393 result = testFunction(*testArguments)
401 if asyncio.iscoroutine(result):
407 future = asyncio.ensure_future(result)
408 future.add_done_callback(futureDone)
410 QtCore.QCoreApplication.processEvents()
413 if TestSupport.Logging.gStopped:
414 raise CancelTestException
416 except CancelTestException:
419 except TestSupport.Macros.AssertException:
425 mevis.MLAB.logError(f
"Exception occurred in {funcName}:")
430 while self.
_testHelper.getChangeSetStackLength() > changeSetLength:
431 mevis.MLAB.logError(
"You should pop your ChangeSets by yourself!")
435 """Load the test cases script file.
437 @param filename Name of the script file to be loaded.
442 self.
_ctx.setProperty(
"IsTestCase",
True)
446 """Call the given field-value test case from the given field-value test case set.
447 This method is required as the FIELDVALUETEST test methods don't have a
448 valid counterpart in the script file itself.
450 @param filename The field-value test case set.
451 @param testcase The test case to be executed.
454 if not fieldValueTestCaseSet.load(filename):
455 mevis.MLAB.logError(f
"Failed ot load field-value test ({filename}).")
457 testCase = fieldValueTestCaseSet.get(testcase)
458 testCase.applyParameterization(TestHelper.getInstance().getChangeSet(), verbose=
True)
459 if not testCase.verifyExpectedResults(verbose=
True):
460 mevis.MLAB.logError(
"Failed to verify expected results.")
462 def __createNormalTestNode(self, virtualFunctionName, functionName, functionBaseName, functionDict, isDisabled):
463 """Create the XML node for a normal test method.
465 @param functionName The real name of the function.
466 @param functionBaseName The base name (without the TEST_).
467 @param functionDict The dictionary used to prevent duplicated function names.
470 if not functionBaseName
in functionDict[
"names"]:
472 functionBaseName, functionName, isDisabled=isDisabled, sourceName=functionName
474 functionDict[
"names"].append(functionBaseName)
475 functionDict[
"nodes"][virtualFunctionName] = xmlNode
477 mevis.MLAB.logError(f
"Function with name {functionBaseName} already defined!")
482 return self.
_ctx.call(groupFunctionName, [])
484 def __createTestGroupNode(self, groupFunctionName, orderString, groupName, functionDict, isDisabled):
485 """Create the XML information for an item in a test group.
487 @param groupFunctionName The name of the group function.
488 @param orderString The string used to determine the order of test functions.
489 @param groupName The name of the group.
490 @param functionDict The dictionary used to prevent duplicated function names.
492 if groupName
in functionDict[
"names"]:
493 mevis.MLAB.logError(f
"A test group with name {groupName} already exists. No duplicate names allowed.")
499 mevis.MLAB.logError(f
"Failed to build virtual functions for the {groupFunctionName} test.")
502 if type(functionList)
not in (list, tuple):
504 f
"The test group function ({groupFunctionName}) must return a list or tuple with function objects!"
508 virtualGroupName = f
"TEST{orderString}_{groupName}"
509 groupXMLNode = etree.Element(
510 "GroupNode", name=virtualGroupName, basename=groupName, type=
"TestGroup", sourceName=groupFunctionName
512 etree.SubElement(groupXMLNode,
"Documentation").text = self.
_ctx.scriptVariable(f
"{groupFunctionName}.__doc__")
514 nameToFunctionMap = {}
515 for function
in functionList:
517 if isinstance(function, str):
518 function = self.
_ctx.scriptVariable(function)
519 nameToFunctionMap[function.__name__] = function
521 for functionName
in sorted(nameToFunctionMap.keys()):
522 function = nameToFunctionMap[functionName]
524 functionNodeName = functionName
525 if functionNodeName.startswith(
"DISABLED_"):
526 functionNodeName = functionNodeName[len(
"DISABLED_") :]
529 functionNodeName
not in functionDict[
"nodes"]
530 or functionDict[
"nodes"][functionNodeName].tag !=
"Function"
533 f
"Failed to compile function list. Given function {functionNodeName} not a test function "
534 f
"or function already part of a test function group."
540 virtualFunctionName = (
541 f
"{virtualGroupName}_"
542 f
"{functionNodeName[4:] if not functionNodeName.startswith('DISABLED_') else functionNodeName[13:]}"
545 functionNode = functionDict[
"nodes"][functionNodeName]
546 functionNode.set(
"name", virtualFunctionName)
550 functionNode.set(
"is_disabled", str(isDisabled))
553 del functionDict[
"nodes"][functionNodeName]
559 groupXMLNode.append(functionNode)
561 functionDict[
"names"].append(groupName)
562 functionDict[
"nodes"][virtualGroupName] = groupXMLNode
565 def __createFieldValueTestNode(self, virtualFunctionBaseName, functionName, groupName, functionDict, isDisabled):
566 """Create the XML information for the given field-value test.
568 @param virtualFunctionBaseName The base name of the virtual function.
569 @param functionName The real name of the function.
570 @param groupName The name of the group.
571 @param functionDict The dictionary used to prevent duplicated function names.
575 if groupName
in functionDict[
"names"]:
576 mevis.MLAB.logError(f
"A test with name {groupName} already exists. No duplicate names allowed.")
581 retVal = self.
_ctx.call(functionName, [])
584 filename, testCaseList = retVal
if type(retVal)
in (list, tuple)
else (retVal,
None)
586 groupXMLNode = etree.Element(
588 name=virtualFunctionBaseName,
590 type=
"FieldValueTest",
591 sourceName=functionName,
593 etree.SubElement(groupXMLNode,
"Documentation").text = self.
getDocumentation(functionName)
597 functionDict[
"names"].append(groupName)
598 functionDict[
"nodes"][virtualFunctionBaseName] = groupXMLNode
601 if not fvtcs.load(filename):
602 mevis.MLAB.logError(f
"Failed to load the field-value test case set ({filename})!")
606 for testcase
in sorted(fvtcs.getList()):
607 virtualFunctionName = f
"{virtualFunctionBaseName}_{testcase}"
613 isDisabled=isDisabled,
614 sourceName=functionName,
618 availableTestCaseList = fvtcs.getList()
619 for testcase
in sorted(testCaseList):
620 if testcase
in availableTestCaseList:
621 virtualFunctionName = f
"{virtualFunctionBaseName}_{testcase}"
627 isDisabled=isDisabled,
628 sourceName=functionName,
632 mevis.MLAB.logError(f
"The field-value test case {testcase} is unknown!")
642 def __createIterativeTestNode(self, virtualFunctionBaseName, functionName, groupName, functionDict, isDisabled):
645 if groupName
in functionDict[
"names"]:
646 mevis.MLAB.logError(f
"A test with name {groupName} already exists. No duplicate names allowed.")
651 retVal = self.
_ctx.call(functionName, [])
655 iterator, function = retVal
658 f
"The iterative test function ({functionName}) must return a list or dictionary"
659 f
" with parameters and a function to call!"
663 groupXMLNode = etree.Element(
664 "GroupNode", name=virtualFunctionBaseName, basename=groupName, type=
"IterativeTest", sourceName=functionName
666 etree.SubElement(groupXMLNode,
"Documentation").text = self.
getDocumentation(functionName)
670 functionDict[
"names"].append(groupName)
671 functionDict[
"nodes"][virtualFunctionBaseName] = groupXMLNode
672 regExpFunctionNames = re.compile(
r"^[.\w]+$")
675 if isinstance(iterator, (list, tuple)):
678 justificationWidth = len(str(len(iterator) - 1))
679 for item
in iterator:
681 virtualFunctionId = str(ctr).rjust(justificationWidth,
"0")
682 args = [item]
if (type(item)
not in (list, tuple))
else item
683 virtualFunctionName = f
"{virtualFunctionBaseName}_{virtualFunctionId}"
684 if regExpFunctionNames.match(virtualFunctionName):
690 isDisabled=isDisabled,
691 sourceName=functionName,
696 f
"The iterative test function ({functionName}) defines non-alphanumeric virtual "
697 f
"function name {virtualFunctionName}!"
700 elif isinstance(iterator, dict):
701 for item
in sorted(iterator.keys()):
702 args = [iterator[item]]
if (type(iterator[item])
not in (list, tuple))
else iterator[item]
703 virtualFunctionName = f
"{virtualFunctionBaseName}_{item}"
704 if regExpFunctionNames.match(virtualFunctionName):
710 isDisabled=isDisabled,
711 sourceName=functionName,
716 f
"The iterative test function ({functionName}) defines non-alphanumeric virtual "
717 f
"function name {virtualFunctionName}!"
721 f
"The iterative test function ({functionName}) must return a list or dictionary with parameters!"
728 def __createUnitTestWrapperNode(self, virtualFunctionBaseName, functionName, groupName, functionDict, isDisabled):
729 """Create the XML information for the given unit test wrapper, which creates a test function for
730 every unit test function, similar to an iterative test.
732 @param virtualFunctionBaseName The base name of the virtual function.
733 @param functionName The real name of the function.
734 @param groupName The name of the group.
735 @param functionDict The dictionary used to prevent duplicated function names.
740 if groupName
in functionDict[
"names"]:
741 mevis.MLAB.logError(f
"A test with name {groupName} already exists. No duplicate names allowed.")
746 suite = self.
_ctx.call(functionName, [])
749 if not isinstance(suite, unittest.TestSuite):
750 mevis.MLAB.logError(f
"The unit test wrapper function ({functionName}) must return a unittest.TestSuite!")
753 groupXMLNode = etree.Element(
755 name=virtualFunctionBaseName,
757 type=
"UnitTestWrapper",
758 sourceName=functionName,
760 etree.SubElement(groupXMLNode,
"Documentation").text = self.
getDocumentation(functionName)
764 functionDict[
"names"].append(groupName)
765 functionDict[
"nodes"][virtualFunctionBaseName] = groupXMLNode
767 def _isSkipped(test):
768 isClassSkipped = getattr(test.__class__,
"__unittest_skip__",
False)
769 testMethod = getattr(test, test._testMethodName)
770 isMethodSkipped = getattr(testMethod,
"__unittest_skip__",
False)
771 return isClassSkipped
or isMethodSkipped
774 def _unpackSuite(suite):
776 for test
in suite._tests:
777 if isinstance(test, unittest.TestSuite):
778 allTests.extend(_unpackSuite(test))
780 if not _isSkipped(test):
781 allTests.append(test)
784 allTests = _unpackSuite(suite)
787 testCaseName = test.__class__.__name__
788 testFunctionName = test._testMethodName
789 return "{0}_{1}".format(testCaseName, testFunctionName)
791 allTests.sort(key=_makeName)
792 testNames = list(map(_makeName, allTests))
795 def _runUnitTestFunction(testFunction):
806 testFunction.run(testResult)
807 testResult.logResult(
"Test was successful")
809 for testName, testFunction
in zip(testNames, allTests):
810 testMethod = getattr(testFunction, testFunction._testMethodName)
813 "{}_{}".format(virtualFunctionBaseName, testName),
814 (_runUnitTestFunction, [testFunction]),
815 isDisabled=isDisabled,
817 if hasattr(testMethod,
"__func__"):
818 funcXMLNode.attrib[
"sourceFilename"] = testMethod.__func__.__code__.co_filename
819 funcXMLNode.attrib[
"sourceLine"] = str(testMethod.__func__.__code__.co_firstlineno)
820 elif hasattr(testMethod,
"__code__"):
821 funcXMLNode.attrib[
"sourceFilename"] = testMethod.__code__.co_filename
822 funcXMLNode.attrib[
"sourceLine"] = str(testMethod.__code__.co_firstlineno)
824 funcXMLNode.attrib[
"sourceFilename"] =
""
825 funcXMLNode.attrib[
"sourceLine"] =
"0"
826 groupXMLNode.append(funcXMLNode)
829 return self.
_ctx.callableFunctions()
832 """Build an XML node with the virtual functions.
833 The result is an XML node that contains information on all virtual functions
834 including the information on hierarchy i.e. which nodes are aggregated in a group.
835 Returns a Boolean value stating success.
839 functionInformationDict = {
"names": [],
"nodes": {}}
842 "TestFunction": re.compile(
r"^(DISABLED_)?TEST(\d*)_(\w+)$"),
843 "TestGroup": re.compile(
r"^(DISABLED_)?GROUP(\d*)_(\w+)$"),
844 "FieldValueTest": re.compile(
r"^(DISABLED_)?FIELDVALUETEST(\d*)_(\w+)$"),
845 "IterativeTest": re.compile(
r"^(DISABLED_)?ITERATIVETEST(\d*)_(\w+)$"),
846 "UnitTestWrapper": re.compile(
r"^(DISABLED_)?UNITTEST(\d*)_(\w+)$"),
850 functionsNode = etree.SubElement(self.
__xmlRoot,
"TestFunctions")
853 disabledFunctions = self.
_ctx.scriptVariable(
"MLABTC_DISABLED_TEST_FUNCTIONS")
or []
859 "FieldValueTest": [],
861 "UnitTestWrapper": [],
864 for prefix, functionList
in (
865 (
"TEST", functionDict[
"TestFunction"]),
866 (
"GROUP", functionDict[
"TestGroup"]),
867 (
"FIELDVALUETEST", functionDict[
"FieldValueTest"]),
868 (
"ITERATIVETEST", functionDict[
"IterativeTest"]),
869 (
"UNITTEST", functionDict[
"UnitTestWrapper"]),
871 if functionName.startswith(prefix)
or functionName.startswith(
"DISABLED_" + prefix):
872 functionList.append(functionName)
874 for functionName
in sorted(functionDict[
"TestFunction"]):
875 mObj = regExpDict[
"TestFunction"].match(functionName)
877 mevis.MLAB.logError(f
"Name of test function invalid ({functionName})")
879 disabledString, orderString, functionBaseName = mObj.groups()
880 isDisabled = (disabledString
is not None)
or (functionName
in disabledFunctions)
881 fname = f
"TEST{orderString}_{functionBaseName}"
883 fname, functionName, functionBaseName, functionInformationDict, isDisabled=isDisabled
886 for functionName
in sorted(functionDict[
"TestGroup"]):
887 mObj = regExpDict[
"TestGroup"].match(functionName)
889 mevis.MLAB.logError(f
"Name of test group invalid ({functionName})")
891 disabledString, orderString, groupName = mObj.groups()
892 isDisabled = (disabledString
is not None)
or (functionName
in disabledFunctions)
894 functionName, orderString, groupName, functionInformationDict, isDisabled=isDisabled
897 for functionName
in sorted(functionDict[
"FieldValueTest"]):
898 mObj = regExpDict[
"FieldValueTest"].match(functionName)
900 mevis.MLAB.logError(f
"Name of field value test invalid ({functionName})")
902 disabledString, orderString, groupName = mObj.groups()
903 isDisabled = (disabledString
is not None)
or (functionName
in disabledFunctions)
904 fname = f
"TEST{orderString}_{groupName}"
906 fname, functionName, groupName, functionInformationDict, isDisabled=isDisabled
909 for functionName
in sorted(functionDict[
"IterativeTest"]):
910 mObj = regExpDict[
"IterativeTest"].match(functionName)
912 mevis.MLAB.logError(f
"Name of iterative test invalid ({functionName})")
914 disabledString, orderString, groupName = mObj.groups()
915 isDisabled = (disabledString
is not None)
or (functionName
in disabledFunctions)
916 fname = f
"TEST{orderString}_{groupName}"
918 fname, functionName, groupName, functionInformationDict, isDisabled=isDisabled
921 for functionName
in sorted(functionDict[
"UnitTestWrapper"]):
922 mObj = regExpDict[
"UnitTestWrapper"].match(functionName)
924 mevis.MLAB.logError(f
"Name of unit test wrapper invalid ({functionName})")
926 disabledString, orderString, groupName = mObj.groups()
927 isDisabled = (disabledString
is not None)
or (functionName
in disabledFunctions)
928 fname = f
"TEST{orderString}_{groupName}"
930 fname, functionName, groupName, functionInformationDict, isDisabled=isDisabled
935 keys = sorted(functionInformationDict[
"nodes"].keys())
937 for functionName
in keys:
938 functionsNode.append(functionInformationDict[
"nodes"][functionName])
939 elif not isNewlyCreated:
940 mevis.MLAB.logError(f
"No test functions found in TestCase {self._testCaseName}!")
942 def __getFunctionInfo(self, functionBaseName, functionName, calledFunction=None, isDisabled=False, sourceName=""):
943 """Internal method to add a function to the required data-structures.
945 @param functionBaseName The virtual function name.
946 @param functionName The real name of the function.
947 @param calledFunction Information on the function called.
950 functionXMLNode = etree.Element(
951 "Function", basename=functionBaseName, name=functionName, sourceName=sourceName, is_disabled=str(isDisabled)
954 etree.SubElement(functionXMLNode,
"Documentation").text = documentation
if documentation
else ""
955 return functionXMLNode
958 """Return True if the loaded test case is syntactically valid and should be executable."""
962 """Return True if the test case has a network attached."""
966 """Returns the absolute file name of the attached network or an empty string if no network is attached."""
967 return self.
_ctx.network().filename()
970 """Open the files associated with the test case."""
972 for fileName
in self.
_ctx.getScriptSourceFiles():
973 MLABpriv.openRelatedFile(typeName, fileName)
976 """Open the internal network of the test case."""
979 self.
_ctx.showInternalNetwork()
982 """Return the type of this test case (generic or functional)."""
983 raise NotImplementedError(f
"getType() is not implemented in {self.__class__.__name__}")
986 """Return the module representing this test case, or None."""
990 """Return the name of the test case."""
994 """Get the list of test functions in this test."""
998 """Return the identifier of the package the test case is in."""
999 return self.
__xmlRoot.find(
"Package").text
1002 """Return the XML node with the test case's information."""
1005 def __callSetUp(self):
1006 """Call the setup function of the test if available."""
1007 if "setUp" in self.
_ctx.callableFunctions():
1009 self.
_ctx.call(
"setUp", [])
1010 mevis.MLAB.log(Utils.lineSeparator())
1012 def __callSetUpTestCase(self):
1013 """Call the setup function of the test case if available."""
1017 self.
_ctx.call(
"setUpTestCase", [])
1019 def __callTearDown(self):
1020 """Call the teardown function of the test if available."""
1025 elif self.
_ctx is not None and "tearDown" in self.
_ctx.callableFunctions():
1027 mevis.MLAB.log(Utils.lineSeparator())
1028 self.
_ctx.call(
"tearDown", [])
1030 def __callTearDownTestCase(self):
1031 """Call the teardown function of the test case if available."""
1032 if self.
_ctx is not None and "tearDownTestCase" in self.
_ctx.callableFunctions():
1034 self.
_ctx.call(
"tearDownTestCase", [])
1036 def __unloadTestCase(self):
1044 testResult.logResult(
"")
1047 if TestSupport.Logging.gStopped:
1048 raise CancelTestException
1050 mevis.MLAB.log(
"Destroying test case context...")
1053 def run(self, resultNode: etree.Element):
1054 """Run the test case and store results in the given xml data structure.
1056 @param resultNode The node taking the results (call by reference).
1068 funcList = resultNode.findall(
".//Function")
1069 length = len(funcList)
1076 for i, funcNode
in enumerate(funcList):
1077 funcName = funcNode.get(
"name")
1079 isLastTestFunction = i == length - 1
1089 if not (TestSupport.Logging.gStopOnFirstError
and logHandler.numErrors() > 0):
1096 def __prepareRunTestFunction(self, data, availTestFunctions):
1098 funcNameForResultDir = data.funcName
1100 funcNameForResultDir =
None
1101 self.
_testHelper.setTestCaseResultDirectory(self.
getName().replace(
"::", os.sep), funcNameForResultDir)
1103 shouldRunTestFunction =
True
1106 if data.funcName
not in availTestFunctions
and not Utils.isInternalTestCaseFunction(data.funcName):
1107 mevis.MLAB.logError(f
"Function {data.funcName} does not exist in test case {self.getName()}!")
1108 status = Utils.TEST_STATUS_FUNCTION_NOT_FOUND
1109 data.funcNode.set(
"status", str(status))
1110 shouldRunTestFunction =
False
1111 return shouldRunTestFunction
1113 def __runTestFunction(self, data):
1114 data.started = time.time()
1117 data.logHandler.startTestFunction(self.
getType(), self.
getName(), data.funcName)
1121 MLABpriv.clearLogState()
1125 if data.funcName == Utils.VIRTUAL_LOAD_TEST_CASE_TEST_FUNCTION:
1127 elif data.funcName == Utils.SETUP_TEST_CASE_FUNCTION:
1129 if data.funcName == Utils.TEARDOWN_TEST_CASE_FUNCTION:
1131 elif data.funcName == Utils.VIRTUAL_UNLOAD_TEST_CASE_TEST_FUNCTION:
1133 if TestSupport.Logging.gStopped:
1134 raise CancelTestException
1135 except CancelTestException:
1136 data.cancelled =
True
1138 def __finishRunTestFunction(self, data):
1139 for extraTestCaseResult
in self.
_testHelper.takeExtraTestCaseResults():
1142 if not Utils.isInternalTestCaseFunction(data.funcName):
1145 match data.funcName:
1146 case Utils.VIRTUAL_LOAD_TEST_CASE_TEST_FUNCTION:
1148 case Utils.SETUP_TEST_CASE_FUNCTION:
1154 mevis.MLAB.processEvents()
1156 MLABpriv.flushPendingMessages()
1158 duration = time.time() - data.started
1161 if currentLogger.hasErrors:
1162 status = Utils.TEST_STATUS_ERROR
1163 elif currentLogger.hasWarnings:
1164 status = Utils.TEST_STATUS_WARNING
1166 status = Utils.TEST_STATUS_OK
1169 data.logHandler.stopTestFunction(status, duration)
1174 status = Utils.TEST_STATUS_CANCELLED
1175 data.funcNode.set(
"status", str(status))
1176 data.funcNode.set(
"duration", str(duration))
1177 data.funcNode.append(data.logHandler.getMessages())
1179 def __setupTestCaseAndRunTestFunction(self, data):
1180 if data.funcNode.get(
"is_disabled", str(
False)) == str(
False):
1182 if data.funcName == Utils.SETUP_TEST_CASE_FUNCTION
and TestSupport.Logging.gStopped:
1183 raise CancelTestException
1184 if not Utils.isInternalTestCaseFunction(data.funcName):
1189 mevis.MLAB.log(
"Skipping test after error in setUp()")
1191 mevis.MLAB.log(f
"Calling test function {data.funcName}()")
1194 mevis.MLAB.log(f
"Skipping disabled test function {data.funcName}()")
1197 """Get the documentation for the given test function.
1198 The found string will be modified such that all trailing whitespace will be removed.
1200 @param functionName The function to gather documentation for.
1201 @return The function's documentation.
1203 docu = self.
_ctx.scriptVariable(f
"{functionName}.__doc__")
1204 testDocu = docu
if docu
else ""
1205 return re.sub(
r"(?m)^\s+",
"", testDocu)