FB_AdsTestResultLogger  Function Block

Implements I_TestResultLogger

This function block reports the results from the tests using the built-in ADSLOGSTR functionality provided by the Tc2_System library. This sends the result using ADS, which is consumed by the "Error List" of Visual Studio (which can print Errors, Warnings and Messages).


Variables

Name Type Description
TestResults I_TestResults
PrintingTestSuiteResultNumber UINT(1..GVL_Param_TcUnit.MaxNumberOfTestSuites)
PrintingTestSuiteTrigger R_TRIG
PrintedFinalTestResults BOOL
PrintedTestSuitesResults BOOL

Methods

FB_init : BOOL

Parameters

Name Type Description
bInitRetains BOOL if TRUE, the retain variables are initialized (warm start / cold start)
bInCopyCode BOOL if TRUE, the instance afterwards gets moved into the copy code (online change)
iTestResults I_TestResults
Implementation
TestResults := iTestResults;
LogTestSuiteResults PUBLIC
Implementation
TcUnitTestResults REF= TestResults.GetTestSuiteResults();

IF PrintingTestSuiteResultNumber <= GVL_TcUnit.NumberOfInitializedTestSuites AND NOT PrintedTestSuitesResults THEN
    PrintingTestSuiteTrigger(CLK := GVL_TcUnit.TestSuiteAddresses[PrintingTestSuiteResultNumber]^.AreAllTestsFinished());
    IF PrintingTestSuiteTrigger.Q THEN
        StringToPrint := CONCAT(STR1 := '| Test suite ID=',
                                STR2 := UINT_TO_STRING(TcUnitTestResults.TestSuiteResults[PrintingTestSuiteResultNumber].Identity));
        StringToPrint := CONCAT(STR1 := StringToPrint,
                                STR2 :=  ' $'%s$'');

        // Print test suite name and ID
        GVL_TcUnit.AdsMessageQueue.WriteLog(MsgCtrlMask := ADSLOG_MSGTYPE_HINT,
                                            MsgFmtStr := StringToPrint,
                                            StrArg := TcUnitTestResults.TestSuiteResults[PrintingTestSuiteResultNumber].Name);

        // Print number of tests/number of failed tests in test suite
        StringToPrint := CONCAT(STR1 := '| ID=',
                                             STR2 := UINT_TO_STRING(TcUnitTestResults.TestSuiteResults[PrintingTestSuiteResultNumber].Identity));
        StringToPrint := CONCAT(STR1 := StringToPrint,
                                             STR2 := ' number of tests=');
        StringToPrint := CONCAT(STR1 := StringToPrint,
                                             STR2 := UINT_TO_STRING(TcUnitTestResults.TestSuiteResults[PrintingTestSuiteResultNumber].NumberOfTests));
        StringToPrint := CONCAT(STR1 := StringToPrint,
                                             STR2 := ', number of failed tests=');
        StringToPrint := CONCAT(STR1 := StringToPrint,
                                             STR2 := UINT_TO_STRING(TcUnitTestResults.TestSuiteResults[PrintingTestSuiteResultNumber].NumberOfFailedTests));
        StringToPrint := CONCAT(STR1 := StringToPrint,
                                             STR2 := ', duration=');
        StringToPrint := CONCAT(STR1 := StringToPrint,
                                             STR2 := LREAL_TO_STRING(TcUnitTestResults.TestSuiteResults[PrintingTestSuiteResultNumber].Duration));
											 
        GVL_TcUnit.AdsMessageQueue.WriteLog(MsgCtrlMask := ADSLOG_MSGTYPE_HINT,
                                            MsgFmtStr := StringToPrint,
                                            StrArg := '');

        // Print error if there are too many tests in the test suite
        IF (TcUnitTestResults.TestSuiteResults[PrintingTestSuiteResultNumber].NumberOfTests > GVL_Param_TcUnit.MaxNumberOfTestsForEachTestSuite) THEN
            MaxNumberOfTestsToPrint := GVL_Param_TcUnit.MaxNumberOfTestsForEachTestSuite;
        ELSE
            MaxNumberOfTestsToPrint := TcUnitTestResults.TestSuiteResults[PrintingTestSuiteResultNumber].NumberOfTests;
        END_IF

        // Iterate and print all tests in test suite
        FOR TestsInTestSuiteCounter := 1 TO MaxNumberOfTestsToPrint BY 1 DO
            // Print test name
            GVL_TcUnit.AdsMessageQueue.WriteLog(MsgCtrlMask := ADSLOG_MSGTYPE_HINT,
                                                MsgFmtStr := '| Test name=%s',
                                                StrArg := TcUnitTestResults.TestSuiteResults[PrintingTestSuiteResultNumber].TestCaseResults[TestsInTestSuiteCounter].TestName);
            // Print test class name
            GVL_TcUnit.AdsMessageQueue.WriteLog(MsgCtrlMask := ADSLOG_MSGTYPE_HINT,
                                                MsgFmtStr := '| Test class name=%s',
                                                StrArg := TcUnitTestResults.TestSuiteResults[PrintingTestSuiteResultNumber].TestCaseResults[TestsInTestSuiteCounter].TestClassName);

            // Print test result/status (SUCCESS, FAILED, SKIPPED) + number of assertions made
            IF TcUnitTestResults.TestSuiteResults[PrintingTestSuiteResultNumber].TestCaseResults[TestsInTestSuiteCounter].TestIsFailed THEN
                StringToPrint := CONCAT(STR1 := '| Test status=', STR2 := TEST_STATUS_FAIL);
            ELSIF TcUnitTestResults.TestSuiteResults[PrintingTestSuiteResultNumber].TestCaseResults[TestsInTestSuiteCounter].TestIsSkipped THEN
                StringToPrint := CONCAT(STR1 := '| Test status=', STR2 := TEST_STATUS_SKIP);
            ELSE
                StringToPrint := CONCAT(STR1 := '| Test status=', STR2 := TEST_STATUS_PASS);
            END_IF

            StringToPrint := CONCAT(STR1 := StringToPrint, STR2 := ', number of asserts=');
            StringToPrint := CONCAT(STR1 := StringToPrint, STR2 :=
                                                 UINT_TO_STRING(TcUnitTestResults.TestSuiteResults[PrintingTestSuiteResultNumber].TestCaseResults[TestsInTestSuiteCounter].NumberOfAsserts));
            StringToPrint := CONCAT(STR1 := StringToPrint, STR2 := ', duration=');
            StringToPrint := CONCAT(STR1 := StringToPrint, STR2 :=
                                                 LREAL_TO_STRING(TcUnitTestResults.TestSuiteResults[PrintingTestSuiteResultNumber].TestCaseResults[TestsInTestSuiteCounter].Duration));												 
            GVL_TcUnit.AdsMessageQueue.WriteLog(MsgCtrlMask := ADSLOG_MSGTYPE_HINT,
                                                MsgFmtStr := StringToPrint,
                                                StrArg := '');

            // Print assertion/failure message (if existing)
            IF (LEN(STR := TcUnitTestResults.TestSuiteResults[PrintingTestSuiteResultNumber].TestCaseResults[TestsInTestSuiteCounter].FailureMessage) > 0) THEN
                GVL_TcUnit.AdsMessageQueue.WriteLog(MsgCtrlMask := ADSLOG_MSGTYPE_HINT,
                                                    MsgFmtStr := '| Test assert message=%s',
                                                    StrArg := TcUnitTestResults.TestSuiteResults[PrintingTestSuiteResultNumber].TestCaseResults[TestsInTestSuiteCounter].FailureMessage);
            END_IF

            // Print assertion/failure type (if existing)
            IF TcUnitTestResults.TestSuiteResults[PrintingTestSuiteResultNumber].TestCaseResults[TestsInTestSuiteCounter].FailureType <> E_AssertionType.Type_UNDEFINED THEN
                GVL_TcUnit.AdsMessageQueue.WriteLog(MsgCtrlMask := ADSLOG_MSGTYPE_HINT,
                                                    MsgFmtStr := '| Test assert type=%s',
                                                    StrArg := F_AssertionTypeToString(AssertionType :=
                                                        TcUnitTestResults.TestSuiteResults[PrintingTestSuiteResultNumber].TestCaseResults[TestsInTestSuiteCounter].FailureType));
            END_IF
        END_FOR

        // Print error message if there are too many tests in the test suite
        IF (TcUnitTestResults.TestSuiteResults[PrintingTestSuiteResultNumber].NumberOfTests > GVL_Param_TcUnit.MaxNumberOfTestsForEachTestSuite) THEN
            GVL_TcUnit.AdsMessageQueue.WriteLog(MsgCtrlMask := ADSLOG_MSGTYPE_ERROR,
                                                MsgFmtStr := 'Tests failed because the number of tests (%s',
                                                StrArg := CONCAT(STR1 := TO_STRING(TcUnitTestResults.TestSuiteResults[PrintingTestSuiteResultNumber].NumberOfTests),
                                                                              STR2 := CONCAT(STR1 := ') in the test suite $'',
                                                                                                          STR2 := CONCAT(STR1 := TcUnitTestResults.TestSuiteResults[PrintingTestSuiteResultNumber].Name,
                                                                                                                                      STR2 := CONCAT(STR1 := '$' are more than is defined in parameter $'GVL_Param_TcUnit.MaxNumberOfTestsForEachTestSuite$' (',
                                                                                                                                                                  STR2 := CONCAT(STR1 := UINT_TO_STRING(GVL_Param_TcUnit.MaxNumberOfTestsForEachTestSuite),
                                                                                                                                                                                              STR2 := '). Please increase this parameter.'))))));
        END_IF

        IF PrintingTestSuiteResultNumber = GVL_TcUnit.NumberOfInitializedTestSuites THEN
            PrintedTestSuitesResults := TRUE;
        ELSE
            PrintingTestSuiteResultNumber := PrintingTestSuiteResultNumber + 1;
        END_IF
        PrintingTestSuiteTrigger(CLK := FALSE); // Reset trigger
    END_IF
END_IF

// Log end results once all test suites have finished running
IF (GVL_TcUnit.NumberOfInitializedTestSuites = 0 OR PrintingTestSuiteResultNumber = GVL_TcUnit.NumberOfInitializedTestSuites)
    AND NOT PrintedFinalTestResults AND TestResults.GetAreTestResultsAvailable() THEN
    GVL_TcUnit.AdsMessageQueue.WriteLog(MsgCtrlMask := ADSLOG_MSGTYPE_ERROR,
                                        MsgFmtStr := '%s',
                                        StrArg := '| ==========TESTS FINISHED RUNNING==========');
    GVL_TcUnit.AdsMessageQueue.WriteLog(MsgCtrlMask := ADSLOG_MSGTYPE_ERROR,
                                        MsgFmtStr := '| Test suites: %s',
                                        StrArg := UINT_TO_STRING(TcUnitTestResults.NumberOfTestSuites));
    GVL_TcUnit.AdsMessageQueue.WriteLog(MsgCtrlMask := ADSLOG_MSGTYPE_ERROR,
                                        MsgFmtStr := '| Tests: %s',
                                        StrArg := UINT_TO_STRING(TcUnitTestResults.NumberOfTestCases));
    GVL_TcUnit.AdsMessageQueue.WriteLog(MsgCtrlMask := ADSLOG_MSGTYPE_ERROR,
                                        MsgFmtStr := '| Successful tests: %s',
                                        StrArg := UINT_TO_STRING(TcUnitTestResults.NumberOfSuccessfulTestCases));
    GVL_TcUnit.AdsMessageQueue.WriteLog(MsgCtrlMask := ADSLOG_MSGTYPE_ERROR,
                                        MsgFmtStr := '| Failed tests: %s',
                                        StrArg := UINT_TO_STRING(TcUnitTestResults.NumberOfFailedTestCases));
    GVL_TcUnit.AdsMessageQueue.WriteLog(MsgCtrlMask := ADSLOG_MSGTYPE_ERROR,
                                        MsgFmtStr := '| Duration: %s',
                                        StrArg := LREAL_TO_STRING(TcUnitTestResults.Duration));                                        
    GVL_TcUnit.AdsMessageQueue.WriteLog(MsgCtrlMask := ADSLOG_MSGTYPE_ERROR,
                                        MsgFmtStr := '%s',
                                        StrArg := '| ======================================');
    PrintedFinalTestResults := TRUE;
END_IF

Used by

Declaration source
(*
    This function block reports the results from the tests using the built-in ADSLOGSTR functionality
    provided by the Tc2_System library. This sends the result using ADS, which is consumed by the "Error List"
    of Visual Studio (which can print Errors, Warnings and Messages).
*)
FUNCTION_BLOCK FB_AdsTestResultLogger IMPLEMENTS I_TestResultLogger
VAR
    TestResults : I_TestResults;

    PrintingTestSuiteResultNumber : UINT(1..GVL_Param_TcUnit.MaxNumberOfTestSuites);
    PrintingTestSuiteTrigger : R_TRIG;

    // This flag is set once the final end result has printed
    PrintedFinalTestResults : BOOL;

    // This flag is set once the test suites result have been printed
    PrintedTestSuitesResults : BOOL;
END_VAR