View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2010 eviware.com 
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of version 2.1 of the GNU Lesser General Public License as published by 
6    *  the Free Software Foundation.
7    *
8    *  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
9    *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
10   *  See the GNU Lesser General Public License for more details at gnu.org.
11   */
12  
13  package com.eviware.soapui.report;
14  
15  import java.io.File;
16  import java.io.PrintWriter;
17  import java.io.StringWriter;
18  import java.util.ArrayList;
19  import java.util.HashMap;
20  import java.util.Iterator;
21  import java.util.List;
22  import java.util.Set;
23  
24  import com.eviware.soapui.model.testsuite.ProjectRunContext;
25  import com.eviware.soapui.model.testsuite.ProjectRunListener;
26  import com.eviware.soapui.model.testsuite.ProjectRunner;
27  import com.eviware.soapui.model.testsuite.TestCase;
28  import com.eviware.soapui.model.testsuite.TestCaseRunContext;
29  import com.eviware.soapui.model.testsuite.TestCaseRunner;
30  import com.eviware.soapui.model.testsuite.TestRunListener;
31  import com.eviware.soapui.model.testsuite.TestStep;
32  import com.eviware.soapui.model.testsuite.TestStepResult;
33  import com.eviware.soapui.model.testsuite.TestSuite;
34  import com.eviware.soapui.model.testsuite.TestSuiteRunContext;
35  import com.eviware.soapui.model.testsuite.TestSuiteRunListener;
36  import com.eviware.soapui.model.testsuite.TestSuiteRunner;
37  import com.eviware.soapui.model.testsuite.TestRunner.Status;
38  import com.eviware.soapui.model.testsuite.TestStepResult.TestStepStatus;
39  import com.eviware.soapui.support.StringUtils;
40  import com.eviware.soapui.support.xml.XmlUtils;
41  
42  /***
43   * Collects TestRun results and creates JUnitReports
44   * 
45   * @author ole.matzura
46   */
47  
48  public class JUnitReportCollector implements TestRunListener, TestSuiteRunListener, ProjectRunListener
49  {
50  	HashMap<String, JUnitReport> reports;
51  	HashMap<TestCase, String> failures;
52  	HashMap<TestCase, Integer> errorCount;
53  	private int maxErrors = 0;
54  
55  	public JUnitReportCollector()
56  	{
57  		this( 0 );
58  	}
59  
60  	public JUnitReportCollector( int maxErrors )
61  	{
62  		this.maxErrors = maxErrors;
63  		reports = new HashMap<String, JUnitReport>();
64  		errorCount = new HashMap<TestCase, Integer>();
65  		failures = new HashMap<TestCase, String>();
66  	}
67  
68  	public List<String> saveReports( String path ) throws Exception
69  	{
70  
71  		File file = new File( path );
72  		if( !file.exists() || !file.isDirectory() )
73  			file.mkdirs();
74  
75  		List<String> result = new ArrayList<String>();
76  
77  		Iterator<String> keyset = reports.keySet().iterator();
78  		while( keyset.hasNext() )
79  		{
80  			String name = keyset.next();
81  			JUnitReport report = reports.get( name );
82  			String fileName = path + File.separatorChar + "TEST-" + StringUtils.createFileName( name, '_' ) + ".xml";
83  			saveReport( report, fileName );
84  			result.add( fileName );
85  		}
86  
87  		return result;
88  	}
89  
90  	public HashMap<String, JUnitReport> getReports()
91  	{
92  		return reports;
93  	}
94  
95  	private void saveReport( JUnitReport report, String filename ) throws Exception
96  	{
97  		report.save( new File( filename ) );
98  	}
99  
100 	public String getReport()
101 	{
102 		Set<String> keys = reports.keySet();
103 		if( keys.size() > 0 )
104 		{
105 			String key = ( String )keys.toArray()[0];
106 			return reports.get( key ).toString();
107 		}
108 		return "No reports..:";
109 	}
110 
111 	public void afterRun( TestCaseRunner testRunner, TestCaseRunContext runContext )
112 	{
113 		TestCase testCase = testRunner.getTestCase();
114 		JUnitReport report = reports.get( testCase.getTestSuite().getName() );
115 
116 		if( Status.INITIALIZED != testRunner.getStatus() && Status.RUNNING != testRunner.getStatus() )
117 		{
118 			if( Status.CANCELED == testRunner.getStatus() )
119 			{
120 				report.addTestCaseWithFailure( testCase.getName(), testRunner.getTimeTaken(), testRunner.getReason(), "" );
121 			}
122 			if( Status.FAILED == testRunner.getStatus() )
123 			{
124 				String msg = "";
125 				if( failures.containsKey( testCase ) )
126 				{
127 					msg = failures.get( testCase ).toString();
128 				}
129 				report.addTestCaseWithFailure( testCase.getName(), testRunner.getTimeTaken(), testRunner.getReason(), msg );
130 			}
131 			if( Status.FINISHED == testRunner.getStatus() )
132 			{
133 				report.addTestCase( testCase.getName(), testRunner.getTimeTaken() );
134 			}
135 
136 		}
137 	}
138 
139 	public void afterStep( TestCaseRunner testRunner, TestCaseRunContext runContext, TestStepResult result )
140 	{
141 		TestStep currentStep = result.getTestStep();
142 		TestCase testCase = currentStep.getTestCase();
143 
144 		if( result.getStatus() == TestStepStatus.FAILED )
145 		{
146 			if( maxErrors > 0 )
147 			{
148 				Integer errors = errorCount.get( testCase );
149 				if( errors == null )
150 					errors = 0;
151 
152 				if( errors >= maxErrors )
153 					return;
154 
155 				errorCount.put( testCase, errors + 1 );
156 			}
157 
158 			StringBuffer buf = new StringBuffer();
159 			if( failures.containsKey( testCase ) )
160 			{
161 				buf.append( failures.get( testCase ) );
162 			}
163 
164 			buf.append( "<h3><b>" ).append( XmlUtils.entitize( result.getTestStep().getName() ) ).append(
165 					" Failed</b></h3><pre>" );
166 			for( String message : result.getMessages() )
167 			{
168 				if( message.toLowerCase().startsWith( "url:" ) )
169 				{
170 					String url = XmlUtils.entitize( message.substring( 4 ).trim() );
171 					buf.append( "URL: <a target=\"new\" href=\"" ).append( url ).append( "\">" ).append( url ).append(
172 							"</a>" );
173 				}
174 				else
175 				{
176 					buf.append( message );
177 				}
178 
179 				buf.append( "\r\n" );
180 			}
181 
182 			// use string value since constant is defined in pro.. duh..
183 			if( testRunner.getTestCase().getSettings().getBoolean( "Complete Error Logs" ) )
184 			{
185 				StringWriter stringWriter = new StringWriter();
186 				PrintWriter writer = new PrintWriter( stringWriter );
187 				result.writeTo( writer );
188 
189 				buf.append( XmlUtils.entitize( stringWriter.toString() ) );
190 			}
191 
192 			buf.append( "</pre><hr/>" );
193 
194 			failures.put( testCase, buf.toString() );
195 		}
196 	}
197 
198 	public void beforeRun( TestCaseRunner testRunner, TestCaseRunContext runContext )
199 	{
200 		TestCase testCase = testRunner.getTestCase();
201 		TestSuite testSuite = testCase.getTestSuite();
202 		if( !reports.containsKey( testSuite.getName() ) )
203 		{
204 			JUnitReport report = new JUnitReport();
205 			report.setTestSuiteName( testSuite.getProject().getName() + "." + testSuite.getName() );
206 			reports.put( testSuite.getName(), report );
207 		}
208 	}
209 
210 	public void beforeStep( TestCaseRunner testRunner, TestCaseRunContext runContext )
211 	{
212 	}
213 
214 	public void beforeStep( TestCaseRunner testRunner, TestCaseRunContext runContext, TestStep testStep )
215 	{
216 	}
217 
218 	public void reset()
219 	{
220 		reports.clear();
221 		failures.clear();
222 		errorCount.clear();
223 	}
224 
225 	public void afterRun( TestSuiteRunner testRunner, TestSuiteRunContext runContext )
226 	{
227 	}
228 
229 	public void afterTestCase( TestSuiteRunner testRunner, TestSuiteRunContext runContext, TestCaseRunner testCaseRunner )
230 	{
231 		testCaseRunner.getTestCase().removeTestRunListener( this );
232 	}
233 
234 	public void beforeRun( TestSuiteRunner testRunner, TestSuiteRunContext runContext )
235 	{
236 	}
237 
238 	public void beforeTestCase( TestSuiteRunner testRunner, TestSuiteRunContext runContext, TestCase testCase )
239 	{
240 		testCase.addTestRunListener( this );
241 	}
242 
243 	public void afterRun( ProjectRunner testScenarioRunner, ProjectRunContext runContext )
244 	{
245 	}
246 
247 	public void afterTestSuite( ProjectRunner testScenarioRunner, ProjectRunContext runContext,
248 			TestSuiteRunner testRunner )
249 	{
250 		testRunner.getTestSuite().removeTestSuiteRunListener( this );
251 	}
252 
253 	public void beforeRun( ProjectRunner testScenarioRunner, ProjectRunContext runContext )
254 	{
255 	}
256 
257 	public void beforeTestSuite( ProjectRunner testScenarioRunner, ProjectRunContext runContext, TestSuite testSuite )
258 	{
259 		testSuite.addTestSuiteRunListener( this );
260 	}
261 }