📄 automated.c
字号:
/* * CUnit - A Unit testing framework library for C. * Copyright (C) 2001 Anil Kumar * Copyright (C) 2004 Anil Kumar, Jerry St.Clair * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//* * Contains the Automated Test Interface implementation. * * Created By : Anil Kumar on ...(in month of Feb 2002) * Last Modified : 13/Feb/2002 * Comment : Added initial automated interface functions to generate * HTML based Run report. * Email : aksaharan@yahoo.com * * Modified : 23/Jul/2002 (Anil Kumar) * Comment : Changed HTML to XML Format file generation for Automated Tests. * Email : aksaharan@yahoo.com * * Modified : 27/Jul/2003 (Anil Kumar) * Comment : Fixed a bug which hinders the listing of all failures. * Email : aksaharan@yahoo.com * * Modified : 17-Jul-2004 (JDS) * Comment : New interface, doxygen comments, eliminate compiler warnings, * automated_run_tests now assigns a generic file name if * none has been supplied. * Email : jds2@users.sourceforge.net *//** @file * Automated test interface with xml result output (implementation). *//** @addtogroup Automated @{*/#include <stdio.h>#include <stdlib.h>#include <ctype.h>#include <assert.h>#include <string.h>#include <limits.h>#include <time.h>#include "CUnit.h"#include "TestDB.h"#include "Util.h"#include "TestRun.h"#include "Automated.h"static CU_pSuite f_pRunningSuite = NULL; /**< The running test suite. */static char f_szDefaultFileRoot[] = "CUnitAutomated"; /**< Default filename root for automated output files. */static char f_szTestListFileName[FILENAME_MAX] = ""; /**< Current output file name for the test listing file. */static char f_szTestResultFileName[FILENAME_MAX] = ""; /**< Current output file name for the test results file. */static FILE* f_pTestResultFile = NULL; /**< FILE pointer the test results file. */static BOOL f_bWriting_CUNIT_RUN_SUITE = FALSE; /**< Flag for keeping track of when a closing xml tag is required. */static CU_ErrorCode automated_list_all_tests(CU_pTestRegistry pRegistry, const char* szFilename);static CU_ErrorCode initialize_result_file(const char* szFilename);static CU_ErrorCode uninitialize_result_file(void);static void automated_run_all_tests(CU_pTestRegistry pRegistry);static void automated_test_start_message_handler(const CU_pTest pTest, const CU_pSuite pSuite);static void automated_test_complete_message_handler(const CU_pTest pTest, const CU_pSuite pSuite, const CU_pFailureRecord pFailure);static void automated_all_tests_complete_message_handler(const CU_pFailureRecord pFailure);static void automated_suite_init_failure_message_handler(const CU_pSuite pSuite);/*------------------------------------------------------------------------*//** Run CUnit tests using the automated interface. * This functions sets appropriate callback functions, * initializes the test output files, and calls the * appropriate functions to list the tests and run them. * If an output file name root has not been specified using * CU_set_output_filename(), a generic root will be applied. */void CU_automated_run_tests(void){ CU_pTestRegistry pRegistry = CU_get_registry(); /* Ensure output makes it to screen at the moment of a SIGSEGV. */ setvbuf(stdout, NULL, _IONBF, 0); setvbuf(stderr, NULL, _IONBF, 0); /* if a filename root hasn't been set, use the default one */ if (0 == strlen(f_szTestResultFileName)) CU_set_output_filename(f_szDefaultFileRoot); if (initialize_result_file(f_szTestResultFileName)) { fprintf(stderr, "\nERROR - Failed to create/initialize the result file."); } else { if (pRegistry) { /* set up the message handlers for writing xml output */ CU_set_test_start_handler(automated_test_start_message_handler); CU_set_test_complete_handler(automated_test_complete_message_handler); CU_set_all_test_complete_handler(automated_all_tests_complete_message_handler); CU_set_suite_init_failure_handler(automated_suite_init_failure_message_handler); f_bWriting_CUNIT_RUN_SUITE = FALSE; automated_run_all_tests(pRegistry); } if (uninitialize_result_file()) { fprintf(stderr, "\nERROR - Failed to close/uninitialize the result files."); } }}/*------------------------------------------------------------------------*//** Set the root file name for automated test output files. * The strings "-Listing.xml" and "-Results.xml" are appended to * the specified root to generate the filenames. If szFilename * is empty, the function has no effect. * @param szFileRoot String containing root to use for file names. */void CU_set_output_filename(const char* szFileRoot){ const char* szListEnding = "-Listing.xml"; const char* szResultEnding = "-Results.xml"; if (NULL != szFileRoot) { strncpy(f_szTestListFileName, szFileRoot, FILENAME_MAX - strlen(szListEnding) - 1); f_szTestListFileName[FILENAME_MAX - strlen(szListEnding) - 1] = 0; strcat(f_szTestListFileName, szListEnding); strncpy(f_szTestResultFileName, szFileRoot, FILENAME_MAX - strlen(szResultEnding) - 1); f_szTestResultFileName[FILENAME_MAX - strlen(szResultEnding) - 1] = 0; strcat(f_szTestResultFileName, szResultEnding); }}/*------------------------------------------------------------------------*//** Generate an xml file containing a list of all tests in all * suites in the active registry. * The output file will be named according to the most recent * call to CU_set_output_filename(), or a default if not * previously set. * @return An error code indicating the error status. */CU_ErrorCode CU_list_tests_to_file(){ /* if a filename root hasn't been set, use the default one */ if (0 == strlen(f_szTestListFileName)) CU_set_output_filename(f_szDefaultFileRoot); return automated_list_all_tests(CU_get_registry(), f_szTestListFileName);}/*------------------------------------------------------------------------*//** Run the registered tests using the automated interface. * The specified registry is set as the active registry if it * is not already. The actual test running is performed by * CU_run_all_tests(). * @param pRegistry The test registry to run. */static void automated_run_all_tests(CU_pTestRegistry pRegistry){ CU_pTestRegistry pOldRegistry = NULL; assert(pRegistry); assert(f_pTestResultFile); f_pRunningSuite = NULL; pOldRegistry = CU_set_registry(pRegistry); fprintf(f_pTestResultFile," <CUNIT_RESULT_LISTING> \n"); CU_run_all_tests(); CU_set_registry(pOldRegistry);}/*------------------------------------------------------------------------*//** Initialize the test results file generated by the automated interface. * A file stream is opened and header information is written. */static CU_ErrorCode initialize_result_file(const char* szFilename){ CU_set_error(CUE_SUCCESS); if ((NULL == szFilename) || (strlen(szFilename) == 0)) { CU_set_error(CUE_BAD_FILENAME); } else if (NULL == (f_pTestResultFile = fopen(szFilename, "w"))) { CU_set_error(CUE_FOPEN_FAILED); } else { setvbuf(f_pTestResultFile, NULL, _IONBF, 0); fprintf(f_pTestResultFile, "<?xml version=\"1.0\" ?> \n" "<?xml-stylesheet type=\"text/xsl\" href=\"CUnit-Run.xsl\" ?> \n" "<!DOCTYPE CUNIT_TEST_RUN_REPORT SYSTEM \"CUnit-Run.dtd\"> \n" "<CUNIT_TEST_RUN_REPORT> \n" " <CUNIT_HEADER/> \n"); } return CU_get_error();}/*------------------------------------------------------------------------*//** Handler function called at start of each test. * @param pTest The test being run. * @param pSuite The suite containing the test. */static void automated_test_start_message_handler(const CU_pTest pTest, const CU_pSuite pSuite){ (void)pTest; /* not currently used - stop compiler warning */ assert(f_pTestResultFile); /* write suite close/open tags if this is the 1st test for this szSuite */ if (!f_pRunningSuite || (f_pRunningSuite != pSuite)) { if (f_bWriting_CUNIT_RUN_SUITE) { fprintf(f_pTestResultFile, " </CUNIT_RUN_SUITE_SUCCESS> \n" " </CUNIT_RUN_SUITE> \n"); } fprintf(f_pTestResultFile, " <CUNIT_RUN_SUITE> \n" " <CUNIT_RUN_SUITE_SUCCESS> \n" " <SUITE_NAME> %s </SUITE_NAME> \n", pSuite->pName); f_bWriting_CUNIT_RUN_SUITE = TRUE; f_pRunningSuite = pSuite; }}/*------------------------------------------------------------------------*//** Handler function called at completion of each test. * @param pTest The test being run. * @param pSuite The suite containing the test. * @param pFailure Pointer to the 1st failure record for this test. */static void automated_test_complete_message_handler(const CU_pTest pTest, const CU_pSuite pSuite, const CU_pFailureRecord pFailure){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -