Ejemplo n.º 1
0
def test_timing_return_time():
    timer = Timing()
    names = ['test', 'hello', 'world']
    for name in names:
        timer.takeTime(name)

    assert type(timer.returnTime()) is str
Ejemplo n.º 2
0
def test_timing_take_time_sum_output():
    timer = Timing()
    names = ['test', 'hello', 'world']
    for name in names:
        timer.takeTime(name)

    assert timer.takeTimeSumOutput() is None
Ejemplo n.º 3
0
    def __init__(self, executeDirect=True, **kwargs):
        self.name = None
        self.description = None
        self.testSteps = {}
        self.apiInstance = None
        self.numberOfParallelRuns = None
        self.statistic = Statistic()
        self.kwargs = kwargs

        self.timing = Timing()  # Use own instance of the timing class, so that we can record timing also in
        # parallel runs.

        self.testRunInstance = kwargs.get(GC.KWARGS_TESTRUNINSTANCE)
        self.testRunUtils = self.testRunInstance.testRunUtils
        self.testSequence = self.testRunUtils.getSequenceByNumber(testRunName=self.testRunInstance.testRunName,
                                                                  sequence=kwargs.get(GC.STRUCTURE_TESTCASESEQUENCE))
        self.testCaseSettings = self.testRunUtils.getTestCaseByNumber(self.testSequence,
                                                                      kwargs.get(GC.STRUCTURE_TESTCASE))
        self.testSteps = self.testCaseSettings[2][GC.STRUCTURE_TESTSTEP]
        self.testCaseType = self.testCaseSettings[1][GC.KWARGS_TESTCASETYPE]

        self.sequenceNumber = self.kwargs.get(GC.KWARGS_SEQUENCENUMBER)

        # In Unit-Tests this is a problem. When we run within the main loop of TestRun we are expected to directly
        # execute on __init__.
        if executeDirect:
            try:
                self.executeTestCase()
            except Exception as e:
                logger.warning(f"Uncought exception {e}")
                utils.traceback(exception_in=e)
                self.kwargs[GC.KWARGS_DATA][GC.TESTCASESTATUS_STOPERROR] = True
                self.kwargs[GC.KWARGS_DATA][GC.TESTCASESTATUS] = GC.TESTCASESTATUS_ERROR
Ejemplo n.º 4
0
    def __init__(self,
                 testRunName,
                 globalSettingsFileNameAndPath=None,
                 testRunDict=None,
                 uuid=uuid4(),
                 executeDirect=True,
                 noCloneXls=False):  # -- API support: testRunDict --
        """
        @param testRunName: The name of the TestRun to be executed.
        @param globalSettingsFileNameAndPath: from where to read the <globals>.json
        """

        # Take over importing parameters:
        self.uuid = uuid
        logger.info(f'Init Testrun, uuid is {self.uuid}')
        self.testRunDict = testRunDict
        self.globalSettingsFileNameAndPath = globalSettingsFileNameAndPath
        self.testRunName, self.testRunFileName = \
            self._sanitizeTestRunNameAndFileName(testRunName, executeDirect)

        # Initialize everything else
        self.apiInstance = None
        self.testType = None
        self.networkInfo = None
        self.results = None
        self.browserFactory = None
        self.kwargs = {}
        self.dataRecords = {}
        self.globalSettings = {}
        self.json_dict = {
        }  # Used to maintain records of RLP_ data which will be used will exporting results
        self.managedPaths = ManagedPaths()
        self.classesForObjects = ClassesForObjects(
        )  # Dynamically loaded classes
        self.timing = Timing()
        self.testRunUtils = TestRunUtils()
        self.testCasesEndDateTimes_1D = []  # refer to single execution
        self.testCasesEndDateTimes_2D = [[]]  # refer to parallel execution
        # New way to export additional Tabs to Excel
        # If you want to export additional data, place a Dict with Tabname + Datafields in additionalExportTabs
        # from anywhere within your custom code base.
        self.additionalExportTabs = {}
        self.statistics = Statistic()
        self.noCloneXls = noCloneXls
        signal.signal(signal.SIGINT, self.exit_signal_handler)
        signal.signal(signal.SIGTERM, self.exit_signal_handler)

        # Initialize other values
        self.timing.takeTime(GC.TIMING_TESTRUN)  # Initialize Testrun Duration

        # Usually the Testrun is called without the parameter executeDirect, meaning it default to "Execute"
        # during Unit-Tests we don't want this behaviour:
        if executeDirect:
            self.executeTestRun()
Ejemplo n.º 5
0
def test_timing_add_attribute():
    timer = Timing()
    timer.takeTime('test')
    # Additional Attributes now possible:
    timer.addAttribute('franzi', 'fritzi', 'test')
    timer.takeTime('test')

    lResult = timer.returnTime()
    print(lResult)
    assert "franzi" in lResult
Ejemplo n.º 6
0
    def __init__(self, timing=None, screenshotPath=None, statistics=None):
        self.iFrame = None
        self.element = None
        self.browserData = BrowserDriverData(
            locatorType=None,
            locator=None,
            driver=webDrv.BROWSER_DRIVERS[GC.BROWSER_FIREFOX])
        self.slowExecution = False
        self.slowExecutionTimeoutInSeconds = 1
        self.downloadFolder = None
        self.downloadFolderMonitoring = None
        self.randomProxy = None
        self.zoomFactorDesired = None  # Desired zoom factor for this page
        self.browserName = None
        # Reference to Selenium "HTML" in order to track page changes. It is set on every interaction with the page
        self.html = None
        self.managedPaths = ManagedPaths()
        self.statistics = Statistic()

        if timing:
            self.timing = timing
            self.takeTime = timing.takeTime
        else:
            self.timing = Timing()
            self.takeTime = self.timing.takeTime

        if not screenshotPath or screenshotPath == "":
            self.screenshotPath = self.managedPaths.getOrSetScreenshotsPath()
        else:
            self.screenshotPath = screenshotPath
Ejemplo n.º 7
0
def test_timing_reset_time():
    timer = Timing()
    names = ['test', 'hello', 'world']
    for name in names:
        timer.takeTime(name)

    timer.resetTime('test')
    assert timer.returnTime() == ''
Ejemplo n.º 8
0
def test_timing___format_time():
    # naming due to private method name hiding
    assert Timing._Timing__format_time(1) == '00:00:01'
    assert Timing._Timing__format_time(59) == '00:00:59'
    assert Timing._Timing__format_time(60) == '00:01:00'
    assert Timing._Timing__format_time(60 * 59) == '00:59:00'
    assert Timing._Timing__format_time(60 * 60) == '01:00:00'
    assert Timing._Timing__format_time(60 * 60 * 23) == '23:00:00'
    assert Timing._Timing__format_time(60 * 60 * 24) == '00:00:00'
Ejemplo n.º 9
0
def testStepMaster():
    return TestStepMaster(TimingClassInstance=Timing(),
                          TESTRUNINSTANCE=FakeTestRun(),
                          data={})
Ejemplo n.º 10
0
def test_timing_name():
    timer = Timing()
    names = ['test', 'hello', 'world']
    for name in names:
        assert timer.takeTime(name) == name
Ejemplo n.º 11
0
def test_timing_force_new():
    timer = Timing()
    names = ['test', 'hello', 'world']
    for k in range(101):
        for name in names:
            assert timer.takeTime(name, forceNew=True) == f'{name}_{k}'
Ejemplo n.º 12
0
class TestCaseMaster:
    def __init__(self, executeDirect=True, **kwargs):
        self.name = None
        self.description = None
        self.testSteps = {}
        self.apiInstance = None
        self.numberOfParallelRuns = None
        self.statistic = Statistic()
        self.kwargs = kwargs

        self.timing = Timing()  # Use own instance of the timing class, so that we can record timing also in
        # parallel runs.

        self.testRunInstance = kwargs.get(GC.KWARGS_TESTRUNINSTANCE)
        self.testRunUtils = self.testRunInstance.testRunUtils
        self.testSequence = self.testRunUtils.getSequenceByNumber(testRunName=self.testRunInstance.testRunName,
                                                                  sequence=kwargs.get(GC.STRUCTURE_TESTCASESEQUENCE))
        self.testCaseSettings = self.testRunUtils.getTestCaseByNumber(self.testSequence,
                                                                      kwargs.get(GC.STRUCTURE_TESTCASE))
        self.testSteps = self.testCaseSettings[2][GC.STRUCTURE_TESTSTEP]
        self.testCaseType = self.testCaseSettings[1][GC.KWARGS_TESTCASETYPE]

        self.sequenceNumber = self.kwargs.get(GC.KWARGS_SEQUENCENUMBER)

        # In Unit-Tests this is a problem. When we run within the main loop of TestRun we are expected to directly
        # execute on __init__.
        if executeDirect:
            try:
                self.executeTestCase()
            except Exception as e:
                logger.warning(f"Uncought exception {e}")
                utils.traceback(exception_in=e)
                self.kwargs[GC.KWARGS_DATA][GC.TESTCASESTATUS_STOPERROR] = True
                self.kwargs[GC.KWARGS_DATA][GC.TESTCASESTATUS] = GC.TESTCASESTATUS_ERROR

    def executeTestCase(self):
        self.timingName = self.timing.takeTime(self.__class__.__name__, forceNew=True)
        if self.testCaseType == GC.KWARGS_BROWSER:
            self.kwargs[GC.KWARGS_DATA][GC.TESTCASESTATUS] = GC.TESTCASESTATUS_SUCCESS  # We believe in a good outcome
            self.__getBrowserForTestCase()

        elif self.testCaseType == GC.KWARGS_API_SESSION:
            # FIXME: For now we're using session_number always = 1. We need to be able to run e.g. 10 sessions with
            # FIXME: Parallel API-Test.
            self.apiInstance = self.testRunInstance.getAPI()
            self.kwargs[GC.KWARGS_API_SESSION] = self.apiInstance

            # For API-Tests we assume status = Passed and actively set it to error if not.
            self.kwargs[GC.KWARGS_DATA][GC.TESTCASESTATUS] = GC.TESTCASESTATUS_SUCCESS
        self.execute()
        self.tearDown()

    def __getBrowserForTestCase(self):
        logger.info(f"Settings for this TestCase: {str(self.testCaseSettings)[0:100]}")
        self.browserType = self.testCaseSettings[1][GC.KWARGS_BROWSER].upper()
        self.browserSettings = self.testCaseSettings[1][GC.BROWSER_ATTRIBUTES]
        self.mobileType = self.testCaseSettings[1].get(GC.KWARGS_MOBILE)
        self.mobileApp = self.testCaseSettings[1].get(GC.KWARGS_MOBILE_APP)
        browserWindowSize = self.testCaseSettings[1].get(GC.BROWSER_WINDOW_SIZE)
        self.mobile_desired_app = {}
        self.mobile_app_setting = {}
        if self.mobileType:
            self.mobile_desired_app[GC.MOBILE_PLATFORM_NAME] = self.testCaseSettings[1][GC.MOBILE_PLATFORM_NAME]
            self.mobile_desired_app[GC.MOBILE_DEVICE_NAME] = self.testCaseSettings[1][GC.MOBILE_DEVICE_NAME]
            self.mobile_desired_app[GC.MOBILE_PLATFORM_VERSION] = self.testCaseSettings[1][GC.MOBILE_PLATFORM_VERSION]
            self.mobile_app_setting[GC.MOBILE_APP_URL] = self.testCaseSettings[1][GC.MOBILE_APP_URL]
            self.mobile_app_setting[GC.MOBILE_APP_PACKAGE] = self.testCaseSettings[1][GC.MOBILE_APP_PACKAGE]
            self.mobile_app_setting[GC.MOBILE_APP_ACTIVITY] = self.testCaseSettings[1][GC.MOBILE_APP_ACTIVITY]
        self.browser = self.testRunInstance.getBrowser(browserInstance=self.sequenceNumber,
                                                       browserName=self.browserType,
                                                       browserAttributes=self.browserSettings,
                                                       mobileType=self.mobileType,
                                                       mobileApp=self.mobileApp,
                                                       desired_app=self.mobile_desired_app,
                                                       mobile_app_setting=self.mobile_app_setting,
                                                       browserWindowSize=browserWindowSize)
        self.kwargs[GC.KWARGS_BROWSER] = self.browser

    def execute(self):
        # Save timing Class from Testrun for later:
        lTestRunTiming = self.kwargs[GC.KWARGS_TIMING]
        # Replace Timing class with current, local timing class:
        self.kwargs[GC.KWARGS_TIMING] = self.timing

        # Get all the TestSteps for the global loop, that are kept within this TestCase:
        lTestStepClasses = {}
        for testStepSequenceNumer, testStep in enumerate(self.testSteps.keys(), start=1):
            if self.testSteps[testStep][0]["TestStepClass"]:
                lTestStepClasses[testStepSequenceNumer] = self.testSteps[testStep][0]["TestStepClass"]

        try:
            self.testRunInstance.executeDictSequenceOfClasses(lTestStepClasses, GC.STRUCTURE_TESTSTEP, **self.kwargs)
        except baangtTestStepException as e:
            self.kwargs[GC.KWARGS_DATA][GC.TESTCASEERRORLOG] += '\n' + "Exception-Text: " + str(e)
            self.kwargs[GC.KWARGS_DATA][GC.TESTCASESTATUS] = GC.TESTCASESTATUS_ERROR
        finally:
            self._finalizeTestCase()
            # Switch back to global Timing class:
            self.kwargs[GC.KWARGS_TIMING] = lTestRunTiming

    def _finalizeTestCase(self):
        tcData = self.kwargs[GC.KWARGS_DATA]
        tcData[GC.TIMING_DURATION] = self.timing.takeTime(self.timingName)  # Write the End-Record for this Testcase

        tcData[GC.TIMELOG] = self.timing.returnTime()
        self.timing.resetTime(self.timingName)

    def _checkAndSetTestcaseStatusIfFailExpected(self):
        """
        If this Testcase is supposed to fail and failed, he's actually successful.
        If this Testcase is supposed to fail and doesn't, he's actually failed.
        @return: Directly sets the Testcasestatus accordingly.
        """
        tcData = self.kwargs[GC.KWARGS_DATA]

        if tcData.get(GC.TESTCASE_EXPECTED_ERROR_FIELD) == 'X':
            if tcData[GC.TESTCASESTATUS] == GC.TESTCASESTATUS_ERROR:
                tcData[GC.TESTCASESTATUS] = GC.TESTCASESTATUS_SUCCESS
            elif tcData[GC.TESTCASESTATUS] == GC.TESTCASESTATUS_SUCCESS:
                tcData[GC.TESTCASESTATUS] = GC.TESTCASESTATUS_ERROR

    def tearDown(self):

        data = self.kwargs[GC.KWARGS_DATA]

        # If TestcaseErrorlog is not empty, the testcase status should be error.
        if data[GC.TESTCASEERRORLOG]:
            data[GC.TESTCASESTATUS] = GC.TESTCASESTATUS_ERROR

        if self.kwargs[GC.KWARGS_DATA][GC.TESTCASESTATUS] == GC.TESTCASESTATUS_ERROR:
            # Try taking a Screenshot
            if self.testCaseType == GC.KWARGS_BROWSER:
                lShot = self.browser.takeScreenshot()
                if lShot:    # Otherwise browser was already closed. Nothing we can do...
                    lShot = lShot.strip()
                    if data[GC.SCREENSHOTS]:
                        if isinstance(data[GC.SCREENSHOTS], str):
                            # From where does this come, damn it?!
                            data[GC.SCREENSHOTS] = [lShot, data[GC.SCREENSHOTS]]
                            pass
                        else:
                            data[GC.SCREENSHOTS].extend([lShot])
                    else:
                        data[GC.SCREENSHOTS] = [lShot]

        # If Testcase-Status was not set, we'll set error. Shouldn't happen anyways.
        if not self.kwargs[GC.KWARGS_DATA][GC.TESTCASESTATUS]:
            data[GC.TESTCASESTATUS] = GC.TESTCASESTATUS_ERROR
            data[GC.TESTCASEERRORLOG] += "\nTestcase had not status - setting error"
            logger.critical("Testcase had no status - setting error")

        self._checkAndSetTestcaseStatusIfFailExpected()

        if data[GC.TESTCASESTATUS] == GC.TESTCASESTATUS_SUCCESS:
            self.statistic.update_success()
        elif data[GC.TESTCASESTATUS] == GC.TESTCASESTATUS_ERROR:
            self.statistic.update_error()
        elif data[GC.TESTCASESTATUS] == GC.TESTCASESTATUS_WAITING:
            self.statistic.update_waiting()

        logger.info(
            f"Testcase {self.kwargs.get(GC.STRUCTURE_TESTSTEP, '')} finished with status: {data[GC.TESTCASESTATUS]}")
Ejemplo n.º 13
0
class TestRun:
    """
    This is the main Class of Testexecution in the baangt Framework. It is usually started
    from baangtIA.py
    """
    def __init__(self,
                 testRunName,
                 globalSettingsFileNameAndPath=None,
                 testRunDict=None,
                 uuid=uuid4(),
                 executeDirect=True,
                 noCloneXls=False):  # -- API support: testRunDict --
        """
        @param testRunName: The name of the TestRun to be executed.
        @param globalSettingsFileNameAndPath: from where to read the <globals>.json
        """

        # Take over importing parameters:
        self.uuid = uuid
        logger.info(f'Init Testrun, uuid is {self.uuid}')
        self.testRunDict = testRunDict
        self.globalSettingsFileNameAndPath = globalSettingsFileNameAndPath
        self.testRunName, self.testRunFileName = \
            self._sanitizeTestRunNameAndFileName(testRunName, executeDirect)

        # Initialize everything else
        self.apiInstance = None
        self.testType = None
        self.networkInfo = None
        self.results = None
        self.browserFactory = None
        self.kwargs = {}
        self.dataRecords = {}
        self.globalSettings = {}
        self.json_dict = {
        }  # Used to maintain records of RLP_ data which will be used will exporting results
        self.managedPaths = ManagedPaths()
        self.classesForObjects = ClassesForObjects(
        )  # Dynamically loaded classes
        self.timing = Timing()
        self.testRunUtils = TestRunUtils()
        self.testCasesEndDateTimes_1D = []  # refer to single execution
        self.testCasesEndDateTimes_2D = [[]]  # refer to parallel execution
        # New way to export additional Tabs to Excel
        # If you want to export additional data, place a Dict with Tabname + Datafields in additionalExportTabs
        # from anywhere within your custom code base.
        self.additionalExportTabs = {}
        self.statistics = Statistic()
        self.noCloneXls = noCloneXls
        signal.signal(signal.SIGINT, self.exit_signal_handler)
        signal.signal(signal.SIGTERM, self.exit_signal_handler)

        # Initialize other values
        self.timing.takeTime(GC.TIMING_TESTRUN)  # Initialize Testrun Duration

        # Usually the Testrun is called without the parameter executeDirect, meaning it default to "Execute"
        # during Unit-Tests we don't want this behaviour:
        if executeDirect:
            self.executeTestRun()

    def exit_signal_handler(self, signal, frame):
        self.browserFactory.teardown()

    def executeTestRun(self):
        self._initTestRunSettingsFromFile()  # Loads the globals*.json file

        self._loadJSONTestRunDefinitions()
        self._loadExcelTestRunDefinitions()

        self.browserFactory = BrowserFactory(self)
        self.executeTestSequence()
        self.tearDown()

        try:
            Sender.send_all(self.results, self.globalSettings)
        except Exception as ex:
            logger.error(f"Error from SendAll: {ex}")

    def append1DTestCaseEndDateTimes(self, dt):
        self.testCasesEndDateTimes_1D.append(dt)

    def append2DTestCaseEndDateTimes(self, index, tcAndDt):
        tc = tcAndDt[0]
        dt = tcAndDt[1]
        [
            self.testCasesEndDateTimes_2D.append([])
            for i in range(index + 1 - len(self.testCasesEndDateTimes_2D))
        ] if index + 1 > len(self.testCasesEndDateTimes_2D) else None
        self.testCasesEndDateTimes_2D[index].append([tc, dt])

    def tearDown(self):
        """
        Close browser (unless stated in the Globals to not do so) and API-Instances
        Take overall Time spent for the complete TestRun
        Write results of TestRun to output channel(s)
        """

        self.timing.takeTime(GC.TIMING_TESTRUN)
        self.timing.takeTimeSumOutput()

        if self.apiInstance:
            self.apiInstance.tearDown()

        network_info = self.browserFactory.teardown()
        self.kwargs['networkInfo'] = network_info

        if self.testCasesEndDateTimes_1D:
            self.kwargs[
                'testCasesEndDateTimes_1D'] = self.testCasesEndDateTimes_1D

        if self.testCasesEndDateTimes_2D and self.testCasesEndDateTimes_2D[0]:
            self.kwargs[
                'testCasesEndDateTimes_2D'] = self.testCasesEndDateTimes_2D

        if len(self.additionalExportTabs) > 0:
            self.kwargs[GC.EXPORT_ADDITIONAL_DATA] = self.additionalExportTabs

        self.results = ExportResults(
            **self.kwargs)  # -- API support: self.results --
        successful, error = self.getSuccessAndError()
        waiting = self.getWaiting()
        self.statistics.update_all(successful, error, waiting)
        logger.info(
            f"Finished execution of Testrun {self.testRunName}. "
            f"{successful} Testcases successfully executed, {error} errors")
        print(f"Finished execution of Testrun {self.testRunName}. "
              f"{successful} Testcases successfully executed, {error} errors")

    def getSuccessAndError(self):
        """
        Returns number of successful and number of error test cases of the current test run
        @rtype: object
        """
        lError = 0
        lSuccess = 0
        for value in self.dataRecords.values():
            if value[GC.TESTCASESTATUS] == GC.TESTCASESTATUS_ERROR:
                lError += 1
            elif value[GC.TESTCASESTATUS] == GC.TESTCASESTATUS_SUCCESS:
                lSuccess += 1
        return lSuccess, lError

    def getWaiting(self):
        lWaiting = 0
        for value in self.dataRecords.values():
            if value[GC.TESTCASESTATUS] == GC.TESTCASESTATUS_WAITING:
                lWaiting += 1
        return lWaiting

    def getAllTestRunAttributes(self):
        return self.testRunUtils.getCompleteTestRunAttributes(self.testRunName)

    def getBrowser(self,
                   browserInstance=0,
                   browserName=None,
                   browserAttributes=None,
                   mobileType=None,
                   mobileApp=None,
                   desired_app=None,
                   mobile_app_setting=None,
                   browserWindowSize=None):

        return self.browserFactory.getBrowser(
            browserInstance=browserInstance,
            browserName=browserName,
            browserAttributes=browserAttributes,
            mobileType=mobileType,
            mobileApp=mobileApp,
            desired_app=desired_app,
            mobile_app_setting=mobile_app_setting,
            browserWindowSize=browserWindowSize)

    def getAPI(self):
        if not self.apiInstance:
            self.apiInstance = ApiHandling()
        return self.apiInstance

    def setResult(self, recordNumber, dataRecordResult):
        logger.debug(f"Received new result for Testrecord {recordNumber}")
        self.dataRecords[recordNumber] = dataRecordResult

    def executeTestSequence(self):
        """
        Start TestcaseSequence

        TestCaseSequence is a sequence of Testcases. In the TestcaseSequence there's a sequential List of
        Testcases to be executed.

        Before the loop (executeDictSequenceOfClasses) variables inside the the testrun-definition are replaced
        by values from the globals-file (e.g. if you want to generally run with FF, but in a certain case you want to
        run with Chrome, you'd have FF in the Testrundefinition, but set parameter in globals_chrome.json accordingly
        (in this case {"TC.Browser": "CHROME"}. TC.-Prefix signals the logic to look for this variable ("Browser")
        inside the testcase definitions and replace it with value "CHROME".

        """
        self.testRunUtils.replaceGlobals(self.globalSettings)
        self.testRunUtils.replaceClasses(self.testRunName,
                                         self.classesForObjects)

        kwargs = {
            GC.KWARGS_TESTRUNATTRIBUTES: self.getAllTestRunAttributes(),
            GC.KWARGS_TESTRUNINSTANCE: self,
            GC.KWARGS_TIMING: self.timing
        }

        self.executeDictSequenceOfClasses(
            kwargs[GC.KWARGS_TESTRUNATTRIBUTES][GC.STRUCTURE_TESTCASESEQUENCE],
            counterName=GC.STRUCTURE_TESTCASESEQUENCE,
            **kwargs)

    def executeDictSequenceOfClasses(self, dictSequenceOfClasses, counterName,
                                     **kwargs):
        """
        This is the main loop of the TestCaseSequence, TestCases, TestStepSequences and TestSteps.
        The Sequence of which class instance to create is defined by the TestRunAttributes.

        Before instancgetBrowsering the class it is checked, whether the class was loaded already and if not, will be loaded
        (only if the classname is fully qualified (e.g baangt<projectname>.TestSteps.myTestStep).
        If the testcase-Status is already "error" (GC.TESTCASESTATUS_ERROR) we'll stop the loop.

        @param dictSequenceOfClasses: The list of classes to be instanced. Must be a dict of {Enum, Classname},
        can be also {enum: [classname, <whatEverElse>]}
        @param counterName: Which Structure element we're currently looping, e.g. "TestStep" (GC.STRUCTURE_TESTSTEP)
        @param kwargs: TestrunAttributes, this TestRun, the Timings-Instance, the datarecord

        """
        if not kwargs.get(GC.KWARGS_TESTRUNATTRIBUTES):
            kwargs[
                GC.KWARGS_TESTRUNATTRIBUTES] = self.getAllTestRunAttributes()
        if not kwargs.get(GC.KWARGS_TESTRUNINSTANCE):
            kwargs[GC.KWARGS_TESTRUNINSTANCE] = self
            logger.info(
                'get into not kwargs.getGC.KWARGS_TESTRUNINSTANCE, id is {}'.
                format(id(self)))
        if not kwargs.get(GC.KWARGS_TIMING):
            kwargs[GC.KWARGS_TIMING] = self.timing
        for key, value in dictSequenceOfClasses.items():
            # If any of the previous steps set the testcase to "Error" - exit here.
            if kwargs.get(GC.KWARGS_DATA):
                if kwargs[GC.KWARGS_DATA][
                        GC.TESTCASESTATUS] == GC.TESTCASESTATUS_ERROR:
                    logger.info(
                        f"TC is already in status Error - not processing steps {counterName}: {key}, {value}"
                        f"and everything behind this step")
                    return
                if kwargs[GC.KWARGS_DATA].get(GC.TESTCASESTATUS_STOP):
                    logger.info(
                        f"TC wanted to stop. Not processing steps {counterName}: {key}, {value}"
                        f"and everything behind this step. TC-Status is "
                        f"{kwargs[GC.KWARGS_DATA][GC.TESTCASESTATUS]}")
                    return
                if kwargs[GC.KWARGS_DATA].get(GC.TESTCASESTATUS_STOPERROR):
                    kwargs[GC.KWARGS_DATA][
                        GC.TESTCASESTATUS] = GC.TESTCASESTATUS_ERROR
                    if not kwargs[GC.KWARGS_DATA].get(GC.TESTCASEERRORLOG):
                        kwargs[GC.KWARGS_DATA][
                            GC.
                            TESTCASEERRORLOG] = "Aborted by command 'TCStopTestCaseError'"
                    else:
                        kwargs[GC.KWARGS_DATA][GC.TESTCASEERRORLOG] = kwargs[GC.KWARGS_DATA][GC.TESTCASEERRORLOG] \
                                                                      + "\nAborted by command 'TCStopTestCaseError'"
                    return

            logger.info(f"Starting {counterName}: {key}")
            kwargs[counterName] = key

            # Get the class reference:
            if isinstance(value, list):
                lFullQualified = value[
                    0]  # First List-Entry must hold the ClassName
            else:
                lFullQualified = value

            l_class = TestRun.__dynamicImportClasses(lFullQualified)

            try:
                l_class(**kwargs)  # Executes the class´es  __init__ method
            except TypeError as e:
                # Damn! The class is wrong.
                l_class = TestRun.__dynamicImportClasses(lFullQualified)
                l_class(**kwargs)

        self.kwargs = kwargs

    def _initTestRunSettingsFromFile(self):
        self.__loadJSONGlobals()
        self.__setPathsIfNotPredefined()
        self.__sanitizeGlobalsValues()

    def __setPathsIfNotPredefined(self):
        if not self.globalSettings.get(GC.PATH_SCREENSHOTS, None):
            self.globalSettings[GC.PATH_SCREENSHOTS] = str(
                Path(self.managedPaths.getOrSetScreenshotsPath()).expanduser())
        else:
            self.managedPaths.getOrSetScreenshotsPath(
                path=self.globalSettings.get(GC.PATH_SCREENSHOTS))
        if not self.globalSettings.get(GC.PATH_EXPORT, None):
            self.globalSettings[GC.PATH_EXPORT] = str(
                Path(self.managedPaths.getOrSetExportPath()).expanduser())
        else:
            self.managedPaths.getOrSetExportPath(
                path=self.globalSettings.get(GC.PATH_EXPORT))
        if not self.globalSettings.get(GC.PATH_IMPORT, None):
            self.globalSettings[GC.PATH_IMPORT] = str(
                Path(self.managedPaths.getOrSetImportPath()).expanduser())
        else:
            self.managedPaths.getOrSetImportPath(
                path=self.globalSettings.get(GC.PATH_IMPORT))
        if not self.globalSettings.get(GC.PATH_ROOT, None):
            self.globalSettings[GC.PATH_ROOT] = str(
                Path(self.managedPaths.getOrSetRootPath()).parent.expanduser())
        else:
            self.managedPaths.getOrSetRootPath(
                path=self.globalSettings.get(GC.PATH_ROOT))

    def __loadJSONGlobals(self):
        if self.globalSettingsFileNameAndPath:
            self.globalSettings = utils.openJson(
                self.globalSettingsFileNameAndPath)

        # Set default execution STAGE
        if not self.globalSettings.get(GC.EXECUTION_STAGE, None):
            logger.debug(
                f"Execution Stage was not set. Setting to default value {GC.EXECUTION_STAGE_TEST}"
            )
            self.globalSettings[GC.EXECUTION_STAGE] = GC.EXECUTION_STAGE_TEST

    def __sanitizeGlobalsValues(self):
        # Support for new dataClass to load different Classes
        for key, value in self.globalSettings.items():
            if "CL." in key:
                self.classesForObjects.__setattr__(key.strip("CL."), value)

            # Change boolean strings into boolean values.
            if isinstance(value, str):
                if value.lower() in ("false", "true", "no", "x"):
                    self.globalSettings[key] = utils.anything2Boolean(value)
                elif "renv_" in value.lower():
                    self.globalSettings[
                        key] = TestDataGenerator.get_env_variable(value[5:])
            if isinstance(value, dict):
                if "default" in value:
                    # This happens in the new UI, if a value was added manually,
                    # but is not part of the globalSetting.json. In this case there's the whole shebang in a dict. We
                    # are only interested in the actual value, which is stored in "default":
                    self.globalSettings[key] = value["default"]
                    if isinstance(self.globalSettings[key], str):
                        if "renv_" in self.globalSettings[key].lower():
                            self.globalSettings[
                                key] = TestDataGenerator.get_env_variable(
                                    self.globalSettings[key][5:])
                    continue
                else:
                    # This could be the "old" way of the globals-file (with {"HEADLESS":"True"})
                    self.globalSettings[key] = value
                    continue

            if isinstance(value, str) and len(value) > 0:
                if value[0] == "{" and value[-1] == "}":
                    # Dict, that is not seen as dict
                    value = value.replace("\'", '"')
                    self.globalSettings[key] = json.loads(value)

        if self.globalSettings.get("TC." + GC.EXECUTION_LOGLEVEL):
            utils.setLogLevel(
                self.globalSettings.get("TC." + GC.EXECUTION_LOGLEVEL))

    def _loadJSONTestRunDefinitions(self):
        if not self.testRunFileName and not self.testRunDict:  # -- API support: testRunDict --
            return

        if self.testRunFileName and ".JSON" in self.testRunFileName.upper(
        ):  # -- API support: self.testRunFileName --
            data = utils.replaceAllGlobalConstantsInDict(
                utils.openJson(self.testRunFileName))
            self.testRunUtils.setCompleteTestRunAttributes(
                testRunName=self.testRunName, testRunAttributes=data)

        # -- API support --
        # load TestRun from dict
        if self.testRunDict:
            data = utils.replaceAllGlobalConstantsInDict(self.testRunDict)
            self.testRunUtils.setCompleteTestRunAttributes(
                testRunName=self.testRunName, testRunAttributes=data)
        # -- END of API support --

    def _loadExcelTestRunDefinitions(self):
        if not self.testRunFileName:
            return

        if ".XLSX" in self.testRunFileName.upper():
            logger.info(f"Reading Definition from {self.testRunFileName}")
            lExcelImport = TestRunExcelImporter(
                FileNameAndPath=self.testRunFileName,
                testRunUtils=self.testRunUtils)
            lExcelImport.importConfig(global_settings=self.globalSettings)

    @staticmethod
    def __dynamicImportClasses(fullQualifiedImportName):
        return utils.dynamicImportOfClasses(
            fullQualifiedImportName=fullQualifiedImportName)

    @staticmethod
    def _sanitizeTestRunNameAndFileName(TestRunNameInput, direct):
        """
        @param TestRunNameInput: The complete File and Path of the TestRun definition (JSON or XLSX).
        @return: TestRunName and FileName (if definition of testrun comes from a file (JSON or XLSX)
        """
        if ".XLSX" in TestRunNameInput.upper():
            cloneXls = CloneXls(TestRunNameInput)
            lFileName = cloneXls.update_or_make_clone(
                ignore_headers=["TestResult", "UseCount"], clone=direct)
            lRunName = utils.extractFileNameFromFullPath(lFileName)
        elif ".JSON" in TestRunNameInput.upper():
            lRunName = utils.extractFileNameFromFullPath(TestRunNameInput)
            lFileName = TestRunNameInput
        else:
            lRunName = TestRunNameInput
            lFileName = None

        return lRunName, lFileName
Ejemplo n.º 14
0
 def timing_init(self):
     return Timing()