fork
Fork of cpputest by
Embed:
(wiki syntax)
Show/hide line numbers
JUnitTestOutput.cpp
00001 /* 00002 * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions are met: 00007 * * Redistributions of source code must retain the above copyright 00008 * notice, this list of conditions and the following disclaimer. 00009 * * Redistributions in binary form must reproduce the above copyright 00010 * notice, this list of conditions and the following disclaimer in the 00011 * documentation and/or other materials provided with the distribution. 00012 * * Neither the name of the <organization> nor the 00013 * names of its contributors may be used to endorse or promote products 00014 * derived from this software without specific prior written permission. 00015 * 00016 * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY 00017 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00018 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00019 * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY 00020 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00021 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00022 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00023 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00024 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00025 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00026 */ 00027 00028 #include "CppUTest/TestHarness.h" 00029 #include "CppUTest/JUnitTestOutput.h" 00030 #include "CppUTest/TestResult.h" 00031 #include "CppUTest/TestFailure.h" 00032 #include "CppUTest/PlatformSpecificFunctions.h" 00033 00034 struct JUnitTestCaseResultNode 00035 { 00036 JUnitTestCaseResultNode() : 00037 execTime_(0), failure_(0), next_(0) 00038 { 00039 } 00040 00041 SimpleString name_; 00042 long execTime_; 00043 TestFailure* failure_; 00044 JUnitTestCaseResultNode* next_; 00045 }; 00046 00047 struct JUnitTestGroupResult 00048 { 00049 JUnitTestGroupResult() : 00050 testCount_(0), failureCount_(0), startTime_(0), groupExecTime_(0), head_(0), tail_(0) 00051 { 00052 } 00053 00054 int testCount_; 00055 int failureCount_; 00056 long startTime_; 00057 long groupExecTime_; 00058 SimpleString group_; 00059 JUnitTestCaseResultNode* head_; 00060 JUnitTestCaseResultNode* tail_; 00061 }; 00062 00063 struct JUnitTestOutputImpl 00064 { 00065 JUnitTestGroupResult results_; 00066 PlatformSpecificFile file_; 00067 SimpleString package_; 00068 }; 00069 00070 JUnitTestOutput::JUnitTestOutput() : 00071 impl_(new JUnitTestOutputImpl) 00072 { 00073 } 00074 00075 JUnitTestOutput::~JUnitTestOutput() 00076 { 00077 resetTestGroupResult(); 00078 delete impl_; 00079 } 00080 00081 void JUnitTestOutput::resetTestGroupResult() 00082 { 00083 impl_->results_.testCount_ = 0; 00084 impl_->results_.failureCount_ = 0; 00085 impl_->results_.group_ = ""; 00086 JUnitTestCaseResultNode* cur = impl_->results_.head_; 00087 while (cur) { 00088 JUnitTestCaseResultNode* tmp = cur->next_; 00089 ; 00090 delete cur->failure_; 00091 delete cur; 00092 cur = tmp; 00093 } 00094 impl_->results_.head_ = 0; 00095 impl_->results_.tail_ = 0; 00096 } 00097 00098 void JUnitTestOutput::printTestsStarted() 00099 { 00100 } 00101 00102 void JUnitTestOutput::printCurrentGroupStarted(const UtestShell& /*test*/) 00103 { 00104 } 00105 00106 void JUnitTestOutput::printCurrentTestEnded(const TestResult& result) 00107 { 00108 impl_->results_.tail_->execTime_ 00109 = result.getCurrentTestTotalExecutionTime(); 00110 } 00111 00112 void JUnitTestOutput::printTestsEnded(const TestResult& /*result*/) 00113 { 00114 } 00115 00116 void JUnitTestOutput::printCurrentGroupEnded(const TestResult& result) 00117 { 00118 impl_->results_.groupExecTime_ = result.getCurrentGroupTotalExecutionTime(); 00119 writeTestGroupToFile(); 00120 resetTestGroupResult(); 00121 } 00122 00123 void JUnitTestOutput::printCurrentTestStarted(const UtestShell& test) 00124 { 00125 impl_->results_.testCount_++; 00126 impl_->results_.group_ = test.getGroup(); 00127 impl_->results_.startTime_ = GetPlatformSpecificTimeInMillis(); 00128 00129 if (impl_->results_.tail_ == 0) { 00130 impl_->results_.head_ = impl_->results_.tail_ 00131 = new JUnitTestCaseResultNode; 00132 } 00133 else { 00134 impl_->results_.tail_->next_ = new JUnitTestCaseResultNode; 00135 impl_->results_.tail_ = impl_->results_.tail_->next_; 00136 } 00137 impl_->results_.tail_->name_ = test.getName(); 00138 } 00139 00140 SimpleString JUnitTestOutput::createFileName(const SimpleString& group) 00141 { 00142 SimpleString fileName = "cpputest_"; 00143 fileName += group; 00144 fileName.replace('/', '_'); 00145 fileName += ".xml"; 00146 return fileName; 00147 } 00148 00149 void JUnitTestOutput::setPackageName(const SimpleString& package) 00150 { 00151 if (impl_ != NULL) { 00152 impl_->package_ = package; 00153 } 00154 } 00155 00156 void JUnitTestOutput::writeXmlHeader() 00157 { 00158 writeToFile("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"); 00159 } 00160 00161 void JUnitTestOutput::writeTestSuiteSummery() 00162 { 00163 SimpleString 00164 buf = 00165 StringFromFormat( 00166 "<testsuite errors=\"0\" failures=\"%d\" hostname=\"localhost\" name=\"%s\" tests=\"%d\" time=\"%d.%03d\" timestamp=\"%s\">\n", 00167 impl_->results_.failureCount_, 00168 impl_->results_.group_.asCharString(), 00169 impl_->results_.testCount_, 00170 (int) (impl_->results_.groupExecTime_ / 1000), (int) (impl_->results_.groupExecTime_ % 1000), 00171 GetPlatformSpecificTimeString()); 00172 writeToFile(buf.asCharString()); 00173 } 00174 00175 void JUnitTestOutput::writeProperties() 00176 { 00177 writeToFile("<properties>\n"); 00178 writeToFile("</properties>\n"); 00179 } 00180 00181 void JUnitTestOutput::writeTestCases() 00182 { 00183 JUnitTestCaseResultNode* cur = impl_->results_.head_; 00184 while (cur) { 00185 SimpleString buf = StringFromFormat( 00186 "<testcase classname=\"%s%s%s\" name=\"%s\" time=\"%d.%03d\">\n", 00187 impl_->package_.asCharString(), 00188 impl_->package_.isEmpty() == true ? "" : ".", 00189 impl_->results_.group_.asCharString(), 00190 cur->name_.asCharString(), (int) (cur->execTime_ / 1000), (int)(cur->execTime_ % 1000)); 00191 writeToFile(buf.asCharString()); 00192 00193 if (cur->failure_) { 00194 writeFailure(cur); 00195 } 00196 writeToFile("</testcase>\n"); 00197 cur = cur->next_; 00198 } 00199 } 00200 00201 void JUnitTestOutput::writeFailure(JUnitTestCaseResultNode* node) 00202 { 00203 SimpleString message = node->failure_->getMessage().asCharString(); 00204 message.replace('"', '\''); 00205 message.replace('<', '['); 00206 message.replace('>', ']'); 00207 message.replace("&", "&"); 00208 message.replace("\n", "{newline}"); 00209 SimpleString buf = StringFromFormat( 00210 "<failure message=\"%s:%d: %s\" type=\"AssertionFailedError\">\n", 00211 node->failure_->getFileName().asCharString(), 00212 node->failure_->getFailureLineNumber(), message.asCharString()); 00213 writeToFile(buf.asCharString()); 00214 writeToFile("</failure>\n"); 00215 } 00216 00217 void JUnitTestOutput::writeFileEnding() 00218 { 00219 writeToFile("<system-out></system-out>\n"); 00220 writeToFile("<system-err></system-err>\n"); 00221 writeToFile("</testsuite>"); 00222 } 00223 00224 void JUnitTestOutput::writeTestGroupToFile() 00225 { 00226 openFileForWrite(createFileName(impl_->results_.group_)); 00227 writeXmlHeader(); 00228 writeTestSuiteSummery(); 00229 writeProperties(); 00230 writeTestCases(); 00231 writeFileEnding(); 00232 closeFile(); 00233 } 00234 00235 void JUnitTestOutput::verbose() 00236 { 00237 } 00238 00239 void JUnitTestOutput::printBuffer(const char*) 00240 { 00241 } 00242 00243 void JUnitTestOutput::print(const char*) 00244 { 00245 } 00246 00247 void JUnitTestOutput::print(long) 00248 { 00249 } 00250 00251 void JUnitTestOutput::print(const TestFailure& failure) 00252 { 00253 if (impl_->results_.tail_->failure_ == 0) { 00254 impl_->results_.failureCount_++; 00255 impl_->results_.tail_->failure_ = new TestFailure(failure); 00256 } 00257 } 00258 00259 void JUnitTestOutput::printTestRun(int /*number*/, int /*total*/) 00260 { 00261 } 00262 00263 void JUnitTestOutput::flush() 00264 { 00265 } 00266 00267 void JUnitTestOutput::openFileForWrite(const SimpleString& fileName) 00268 { 00269 impl_->file_ = PlatformSpecificFOpen(fileName.asCharString(), "w"); 00270 } 00271 00272 void JUnitTestOutput::writeToFile(const SimpleString& buffer) 00273 { 00274 PlatformSpecificFPuts(buffer.asCharString(), impl_->file_); 00275 } 00276 00277 void JUnitTestOutput::closeFile() 00278 { 00279 PlatformSpecificFClose(impl_->file_); 00280 }
Generated on Tue Jul 12 2022 21:37:56 by 1.7.2