|
1 /* |
|
2 * Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 package com.nokia.testfw.core.model.result; |
|
18 |
|
19 import java.util.ArrayList; |
|
20 import java.util.Collection; |
|
21 import java.util.HashSet; |
|
22 import java.util.LinkedHashMap; |
|
23 import java.util.Set; |
|
24 |
|
25 import org.eclipse.core.runtime.IStatus; |
|
26 |
|
27 import com.nokia.testfw.core.StfPlugin; |
|
28 import com.nokia.testfw.core.model.result.TestResult.TestStatus; |
|
29 |
|
30 /** |
|
31 * Result for one test run. It has summary counters and detail result for each |
|
32 * test case. |
|
33 * <P> |
|
34 * |
|
35 * This result will be updated during test execution. |
|
36 * |
|
37 * <P> |
|
38 * |
|
39 */ |
|
40 public class TestRunResult { |
|
41 int testCount = 0; |
|
42 int passedTestCount = 0; |
|
43 int failedTestCount = 0; |
|
44 int skippedTestCount = 0; |
|
45 |
|
46 LinkedHashMap<String, TestResult> root; |
|
47 ArrayList<TestResultListener> listeners; |
|
48 |
|
49 public TestRunResult() { |
|
50 root = new LinkedHashMap<String, TestResult>(); |
|
51 listeners = new ArrayList<TestResultListener>(); |
|
52 } |
|
53 |
|
54 public int getTestCount() { |
|
55 return testCount; |
|
56 } |
|
57 |
|
58 public int getPassedTestCount() { |
|
59 return passedTestCount; |
|
60 } |
|
61 |
|
62 public int getfailedTestCount() { |
|
63 return failedTestCount; |
|
64 } |
|
65 |
|
66 public int getSkippedTestCount() { |
|
67 return skippedTestCount; |
|
68 } |
|
69 |
|
70 /** |
|
71 * add a suite to the result. |
|
72 * |
|
73 * @param suiteName |
|
74 * @return |
|
75 */ |
|
76 public synchronized TestSuiteResult addTestSuite(String suiteName) { |
|
77 String[] suites = suiteName.split("\\."); |
|
78 |
|
79 TestResult testResult; |
|
80 TestSuiteResult parentSuite = null; |
|
81 for (String suite : suites) { |
|
82 if (parentSuite == null) { |
|
83 testResult = root.get(new TestSuiteResult(suite) |
|
84 .getUniqueName()); |
|
85 } else { |
|
86 testResult = parentSuite.getChild(suite); |
|
87 } |
|
88 if ((testResult == null) |
|
89 || !(testResult instanceof TestSuiteResult)) { |
|
90 testResult = new TestSuiteResult(suite); |
|
91 if (parentSuite == null) { |
|
92 root.put(testResult.getUniqueName(), testResult); |
|
93 } else { |
|
94 parentSuite.addTestResult(testResult); |
|
95 } |
|
96 } |
|
97 parentSuite = (TestSuiteResult) testResult; |
|
98 } |
|
99 |
|
100 return parentSuite; |
|
101 } |
|
102 |
|
103 /** |
|
104 * add a test case to the result |
|
105 * |
|
106 * @param suiteName |
|
107 * , maybe null if no associated suite |
|
108 * @param caseName |
|
109 * , test case name |
|
110 * @return |
|
111 */ |
|
112 public synchronized TestCaseResult addTestCase(String suiteName, |
|
113 String caseName) { |
|
114 TestCaseResult result = new TestCaseResult(caseName); |
|
115 if (suiteName == null) { |
|
116 // top level result |
|
117 root.put(result.getUniqueName(), result); |
|
118 } else { |
|
119 TestSuiteResult suite = addTestSuite(suiteName); |
|
120 suite.addTestResult(result); |
|
121 } |
|
122 testCount++; |
|
123 for (TestResultListener listener : listeners) { |
|
124 listener.addTestCase(result); |
|
125 } |
|
126 return result; |
|
127 } |
|
128 |
|
129 /** |
|
130 * add a suite to the result. |
|
131 * |
|
132 * @param suiteName |
|
133 * @return |
|
134 */ |
|
135 public TestSuiteResult getTestSuite(String suiteName) { |
|
136 String[] suites = suiteName.split("\\."); |
|
137 |
|
138 TestResult testResult; |
|
139 TestSuiteResult parentSuite = null; |
|
140 for (String suite : suites) { |
|
141 if (parentSuite == null) { |
|
142 testResult = root.get(new TestSuiteResult(suite) |
|
143 .getUniqueName()); |
|
144 } else { |
|
145 testResult = parentSuite.getChild(suite); |
|
146 } |
|
147 if ((testResult != null) && (testResult instanceof TestSuiteResult)) { |
|
148 parentSuite = (TestSuiteResult) testResult; |
|
149 } else { |
|
150 return null; |
|
151 } |
|
152 } |
|
153 |
|
154 return parentSuite; |
|
155 } |
|
156 |
|
157 private TestCaseResult getTestCaseResult(String suiteName, String caseName) { |
|
158 if (suiteName == null) { |
|
159 return (TestCaseResult) root.get((new TestCaseResult(caseName)) |
|
160 .getUniqueName()); |
|
161 } else { |
|
162 TestSuiteResult suite = getTestSuite(suiteName); |
|
163 if (suite != null) { |
|
164 TestResult result = suite.getChild(caseName); |
|
165 if (result instanceof TestCaseResult) { |
|
166 return (TestCaseResult) result; |
|
167 } |
|
168 } |
|
169 return null; |
|
170 } |
|
171 } |
|
172 |
|
173 /** |
|
174 * update test case status and execution time. notify all listener about the |
|
175 * test case state change |
|
176 * |
|
177 * @param suiteName |
|
178 * , test suite name |
|
179 * @param caseName |
|
180 * , test case name |
|
181 * @param status |
|
182 * , the test case status |
|
183 * @param time |
|
184 * , will be ignored if set to -1 |
|
185 * @see TestStatus |
|
186 * @see TestResultListener |
|
187 */ |
|
188 public synchronized TestCaseResult updateCaseStatus(String suiteName, |
|
189 String caseName, TestStatus status, double time) { |
|
190 TestCaseResult result = getTestCaseResult(suiteName, caseName); |
|
191 if (result != null) { |
|
192 updateCaseStatus(result, status, time); |
|
193 } else { |
|
194 StringBuilder sb = new StringBuilder("unknown test case: "); |
|
195 if (suiteName != null) { |
|
196 sb.append(suiteName).append("."); |
|
197 } |
|
198 sb.append(caseName); |
|
199 StfPlugin.log(IStatus.ERROR, sb.toString()); |
|
200 } |
|
201 return result; |
|
202 } |
|
203 |
|
204 /** |
|
205 * update test case status and execution time. notify all listener about the |
|
206 * test case state change |
|
207 * |
|
208 * @param result |
|
209 * , test case result |
|
210 * @param status |
|
211 * , the test case status |
|
212 * @param time |
|
213 * , will be ignored if set to -1 |
|
214 * @see TestStatus |
|
215 * @see TestResultListener |
|
216 */ |
|
217 public synchronized TestCaseResult updateCaseStatus(TestCaseResult result, |
|
218 TestStatus status, double time) { |
|
219 result.setStatus(status); |
|
220 if (time >= 0) { |
|
221 result.setTime(time); |
|
222 } |
|
223 switch (status) { |
|
224 case SUCCESS: |
|
225 passedTestCount++; |
|
226 break; |
|
227 case FAILURE: |
|
228 failedTestCount++; |
|
229 break; |
|
230 case SKIP: |
|
231 skippedTestCount++; |
|
232 break; |
|
233 case STARTED: |
|
234 break; |
|
235 default: |
|
236 StfPlugin.log(IStatus.ERROR, "unknown teststatus:" + status); |
|
237 } |
|
238 updateSuiteResult(result, status); |
|
239 for (TestResultListener listener : listeners) { |
|
240 listener.testCaseStateChange(result, status); |
|
241 } |
|
242 return result; |
|
243 } |
|
244 |
|
245 private void updateSuiteResult(TestResult result, TestStatus status) { |
|
246 TestSuiteResult suite = result.iParent; |
|
247 if (suite == null) { |
|
248 return; |
|
249 } |
|
250 if (status == TestStatus.STARTED) { |
|
251 if (suite.getStatus() == TestStatus.NOTSTART) { |
|
252 suite.setStatus(TestStatus.STARTED); |
|
253 } |
|
254 } else if (status == TestStatus.FAILURE) { |
|
255 suite.setStatus(status); |
|
256 } else if (status == TestStatus.SKIP) { |
|
257 if (suite.getStatus() != TestStatus.FAILURE) { |
|
258 suite.setStatus(status); |
|
259 } |
|
260 } else if (status == TestStatus.SUCCESS) { |
|
261 // set the suite to pass only all cases passed |
|
262 boolean suitePassed = true; |
|
263 for (TestResult test : suite.getChildren()) { |
|
264 if (test.getStatus() != TestStatus.SUCCESS) { |
|
265 suitePassed = false; |
|
266 break; |
|
267 } |
|
268 }// end of for |
|
269 if (suitePassed) { |
|
270 suite.setStatus(TestStatus.SUCCESS); |
|
271 } |
|
272 } |
|
273 updateSuiteResult(suite, suite.getStatus()); |
|
274 } |
|
275 |
|
276 /** |
|
277 * add a new test result listener |
|
278 * |
|
279 * @param listener |
|
280 * , the listener |
|
281 */ |
|
282 public void addResultListener(TestResultListener listener) { |
|
283 listeners.add(listener); |
|
284 } |
|
285 |
|
286 /** |
|
287 * remove a test listener from the result |
|
288 * |
|
289 * @param listener |
|
290 * , the listener to remove |
|
291 */ |
|
292 public void removeResultListener(TestResultListener listener) { |
|
293 listeners.remove(listener); |
|
294 } |
|
295 |
|
296 /** |
|
297 * notify all listeners that test has started |
|
298 * |
|
299 * @see TestResultListener |
|
300 */ |
|
301 public void testStarted() { |
|
302 for (TestResultListener listener : listeners) { |
|
303 listener.testStarted(); |
|
304 } |
|
305 } |
|
306 |
|
307 /** |
|
308 * notify all listeners the test has finished. |
|
309 * |
|
310 * @see TestResultListener |
|
311 */ |
|
312 public void testFinished() { |
|
313 for (TestResultListener listener : listeners) { |
|
314 listener.testFinished(); |
|
315 } |
|
316 } |
|
317 |
|
318 public TestResult[] getResults() { |
|
319 return root.values().toArray(new TestResult[0]); |
|
320 } |
|
321 |
|
322 public Set<TestCaseResult> getFailedResults() { |
|
323 return gatherFailedTestCaseResult(root.values()); |
|
324 } |
|
325 |
|
326 private Set<TestCaseResult> gatherFailedTestCaseResult( |
|
327 Collection<TestResult> results) { |
|
328 Set<TestCaseResult> failedCaseSet = new HashSet<TestCaseResult>(); |
|
329 for (TestResult result : results) { |
|
330 if (result instanceof TestCaseResult) { |
|
331 if (result.getStatus() == TestStatus.FAILURE) { |
|
332 failedCaseSet.add((TestCaseResult) result); |
|
333 } |
|
334 } else { |
|
335 failedCaseSet |
|
336 .addAll(gatherFailedTestCaseResult(((TestSuiteResult) result) |
|
337 .getChildren())); |
|
338 } |
|
339 } |
|
340 return failedCaseSet; |
|
341 } |
|
342 } |