Menu

#45 Generate JUnit format

open
Core Issue (23)
5
2014-08-22
2010-11-04
No

The JUnit format is not possible to generate in a direct forward way as implemented now and the way the \"old\" CUnit XML is. It is because the <testsuite>-starttag have attributes with values that are not known until the suite is complete.

Discussion

  • Anonymous

    Anonymous - 2013-05-06

    I really need this. There are XSLT around to transform but it is far from ideal.

     
  • mensfort

    mensfort - 2014-08-22

    Here a possible solution, maybe a little late, just add some code and call the new handlers. Be aware that the time per test is always 0.

    void JUNIT_test_start(const CU_pTest pTest, const CU_pSuite pSuite)
    {
        (void)pTest;
        (void)pSuite;
    }
    
    void JUNIT_test_end(const CU_pTest pTest,
                                  const CU_pSuite pSuite,
                                  const CU_pFailureRecord pFailure)
    {
        char suite[4096], test[4096];
        const char *package =CU_automated_package_name_get();
        CU_translate_special_characters(pSuite->pName, suite, 4096);
        CU_translate_special_characters(pTest->pName ? pTest->pName:"noname", test, 4096);
    
        if ( pFailure ==NULL)
        {
            fprintf( f_pTestResultFile,  "    <testcase name=\"%s\" classname=\"%s.%s\" time=\"%f\"/>\n",
                    package, suite, test, 0);
        }
        else
        {
            fprintf( f_pTestResultFile,  "    <testcase name=\"%s\" classname=\"%s.%s\" time=\"%f\">\n",
                    package, suite, test, 0);
            CU_pFailureRecord fail =pFailure;
            while ( fail !=NULL)
            {
                char *type;
                *test =0;
                switch ( fail->type)
                {
                case CUF_SuiteInactive:
                    type ="INACTIVE";
                    break;
                case CUF_SuiteInitFailed:
                    type ="INIT FAILED";
                    break;
                case CUF_SuiteCleanupFailed:
                    type ="CLEAN FAILED";
                    break;
                case CUF_TestInactive:
                    type ="INACTIVE";
                    break;
                case CUF_AssertFailed:
                    type ="ASSERT";
                    sprintf( test, "CONDITION=%s, FILE=%s, LINE=%d", pFailure->strCondition, pFailure->strFileName, pFailure->uiLineNumber);
                    break;
                default:
                    type ="INVALID";
                    break;
                }
                fprintf( f_pTestResultFile, "        <failure type=\"%s\">%s</failure>\n", type, test);
    
                fail =fail->pNext;
            }
            fprintf( f_pTestResultFile, "    </testcase>\n");
        }
    }
    
    void JUNIT_suite_start(const CU_pSuite pSuite)
    {
        int n=0;
        CU_pTest test=pSuite->pTest;
        while (test)
        {
            n++;
            test=test->pNext;
        }
        fprintf( f_pTestResultFile, "<testsuite tests=\"%d\">\n", n);
    }
    
    void JUNIT_suite_end( const CU_pSuite pSuite, const CU_pFailureRecord pFailure)
    {
        (void)pFailure;
        fprintf( f_pTestResultFile, "</testsuite>\n");
    }
    
    ### in CU_automated_run_tests(void) you have to adjust a few lines:
        CU_set_test_start_handler( JUNIT_test_start);
        CU_set_test_complete_handler( JUNIT_test_end);
        CU_set_suite_start_handler( JUNIT_suite_start);
        CU_set_suite_complete_handler( JUNIT_suite_end);
    
    ### This should work for Junit testing. Call following to do all tests:
        CU_automated_enable_junit_xml( CU_TRUE);
            CU_automated_run_tests(void);
    
     

Anonymous
Anonymous

Add attachments
Cancel