• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package junit.awtui;
2 
3 import java.awt.BorderLayout;
4 import java.awt.Button;
5 import java.awt.Checkbox;
6 import java.awt.Color;
7 import java.awt.Component;
8 import java.awt.Font;
9 import java.awt.Frame;
10 import java.awt.GridBagConstraints;
11 import java.awt.GridBagLayout;
12 import java.awt.GridLayout;
13 import java.awt.Image;
14 import java.awt.Insets;
15 import java.awt.Label;
16 import java.awt.List;
17 import java.awt.Menu;
18 import java.awt.MenuBar;
19 import java.awt.MenuItem;
20 import java.awt.Panel;
21 import java.awt.SystemColor;
22 import java.awt.TextArea;
23 import java.awt.TextField;
24 import java.awt.Toolkit;
25 import java.awt.event.ActionEvent;
26 import java.awt.event.ActionListener;
27 import java.awt.event.ItemEvent;
28 import java.awt.event.ItemListener;
29 import java.awt.event.TextEvent;
30 import java.awt.event.TextListener;
31 import java.awt.event.WindowAdapter;
32 import java.awt.event.WindowEvent;
33 import java.awt.image.ImageProducer;
34 import java.util.Vector;
35 
36 import junit.framework.Test;
37 import junit.framework.TestCase;
38 import junit.framework.TestResult;
39 import junit.framework.TestSuite;
40 import junit.runner.BaseTestRunner;
41 import junit.runner.TestRunListener;
42 
43 /**
44  * An AWT based user interface to run tests.
45  * Enter the name of a class which either provides a static
46  * suite method or is a subclass of TestCase.
47  * <pre>
48  * Synopsis: java junit.awtui.TestRunner [-noloading] [TestCase]
49  * </pre>
50  * TestRunner takes as an optional argument the name of the testcase class to be run.
51  */
52  public class TestRunner extends BaseTestRunner {
53 	protected Frame fFrame;
54 	protected Vector fExceptions;
55 	protected Vector fFailedTests;
56 	protected Thread fRunner;
57 	protected TestResult fTestResult;
58 
59 	protected TextArea fTraceArea;
60 	protected TextField fSuiteField;
61 	protected Button fRun;
62 	protected ProgressBar fProgressIndicator;
63 	protected List fFailureList;
64 	protected Logo fLogo;
65 	protected Label fNumberOfErrors;
66 	protected Label fNumberOfFailures;
67 	protected Label fNumberOfRuns;
68 	protected Button fQuitButton;
69 	protected Button fRerunButton;
70 	protected TextField fStatusLine;
71 	protected Checkbox fUseLoadingRunner;
72 
73 	protected static final Font PLAIN_FONT= new Font("dialog", Font.PLAIN, 12);
74 	private static final int GAP= 4;
75 
TestRunner()76 	public TestRunner() {
77 	}
78 
about()79 	private void about() {
80 		AboutDialog about= new AboutDialog(fFrame);
81 		about.setModal(true);
82 		about.setLocation(300, 300);
83 		about.setVisible(true);
84 	}
85 
testStarted(String testName)86 	public void testStarted(String testName) {
87 		showInfo("Running: "+testName);
88 	}
89 
testEnded(String testName)90 	public void testEnded(String testName) {
91 		setLabelValue(fNumberOfRuns, fTestResult.runCount());
92 		synchronized(this) {
93 			fProgressIndicator.step(fTestResult.wasSuccessful());
94 		}
95 	}
96 
testFailed(int status, Test test, Throwable t)97 	public void testFailed(int status, Test test, Throwable t) {
98 		switch (status) {
99 			case TestRunListener.STATUS_ERROR:
100 				fNumberOfErrors.setText(Integer.toString(fTestResult.errorCount()));
101 				appendFailure("Error", test, t);
102 				break;
103 			case TestRunListener.STATUS_FAILURE:
104 				fNumberOfFailures.setText(Integer.toString(fTestResult.failureCount()));
105 				appendFailure("Failure", test, t);
106 				break;
107 		}
108 	}
109 
addGrid(Panel p, Component co, int x, int y, int w, int fill, double wx, int anchor)110 	protected void addGrid(Panel p, Component co, int x, int y, int w, int fill, double wx, int anchor) {
111 		GridBagConstraints c= new GridBagConstraints();
112 		c.gridx= x; c.gridy= y;
113 		c.gridwidth= w;
114 		c.anchor= anchor;
115 		c.weightx= wx;
116 		c.fill= fill;
117 		if (fill == GridBagConstraints.BOTH || fill == GridBagConstraints.VERTICAL)
118 			c.weighty= 1.0;
119 		c.insets= new Insets(y == 0 ? GAP : 0, x == 0 ? GAP : 0, GAP, GAP);
120 		p.add(co, c);
121 	}
122 
appendFailure(String kind, Test test, Throwable t)123 	private void appendFailure(String kind, Test test, Throwable t) {
124 		kind+= ": " + test;
125 		String msg= t.getMessage();
126 		if (msg != null) {
127 			kind+= ":" + truncate(msg);
128 		}
129 		fFailureList.add(kind);
130 		fExceptions.addElement(t);
131 		fFailedTests.addElement(test);
132 		if (fFailureList.getItemCount() == 1) {
133 			fFailureList.select(0);
134 			failureSelected();
135 		}
136 	}
137 	/**
138 	 * Creates the JUnit menu. Clients override this
139 	 * method to add additional menu items.
140 	 */
createJUnitMenu()141 	protected Menu createJUnitMenu() {
142 		Menu menu= new Menu("JUnit");
143 		MenuItem mi= new MenuItem("About...");
144 		mi.addActionListener(
145 		    new ActionListener() {
146 		        public void actionPerformed(ActionEvent event) {
147 		            about();
148 		        }
149 		    }
150 		);
151 		menu.add(mi);
152 
153 		menu.addSeparator();
154 		mi= new MenuItem("Exit");
155 		mi.addActionListener(
156 		    new ActionListener() {
157 		        public void actionPerformed(ActionEvent event) {
158 		            System.exit(0);
159 		        }
160 		    }
161 		);
162 		menu.add(mi);
163 		return menu;
164 	}
165 
createMenus(MenuBar mb)166 	protected void createMenus(MenuBar mb) {
167 		mb.add(createJUnitMenu());
168 	}
createTestResult()169 	protected TestResult createTestResult() {
170 		return new TestResult();
171 	}
172 
createUI(String suiteName)173 	protected Frame createUI(String suiteName) {
174 		Frame frame= new Frame("JUnit");
175 		Image icon= loadFrameIcon();
176 		if (icon != null)
177 			frame.setIconImage(icon);
178 
179 		frame.setLayout(new BorderLayout(0, 0));
180 		frame.setBackground(SystemColor.control);
181 		final Frame finalFrame= frame;
182 
183 		frame.addWindowListener(
184 			new WindowAdapter() {
185 				public void windowClosing(WindowEvent e) {
186 					finalFrame.dispose();
187 					System.exit(0);
188 				}
189 			}
190 		);
191 
192 		MenuBar mb = new MenuBar();
193 		createMenus(mb);
194 		frame.setMenuBar(mb);
195 
196 		//---- first section
197 		Label suiteLabel= new Label("Test class name:");
198 
199 		fSuiteField= new TextField(suiteName != null ? suiteName : "");
200 		fSuiteField.selectAll();
201 		fSuiteField.requestFocus();
202 		fSuiteField.setFont(PLAIN_FONT);
203 		fSuiteField.setColumns(40);
204 		fSuiteField.addActionListener(
205 			new ActionListener() {
206 				public void actionPerformed(ActionEvent e) {
207 					runSuite();
208 				}
209 			}
210 		);
211 		fSuiteField.addTextListener(
212 			new TextListener() {
213 				public void textValueChanged(TextEvent e) {
214 					fRun.setEnabled(fSuiteField.getText().length() > 0);
215 					fStatusLine.setText("");
216 				}
217 			}
218 		);
219 		fRun= new Button("Run");
220 		fRun.setEnabled(false);
221 		fRun.addActionListener(
222 			new ActionListener() {
223 				public void actionPerformed(ActionEvent e) {
224 					runSuite();
225 				}
226 			}
227 		);
228 		boolean useLoader= useReloadingTestSuiteLoader();
229 		fUseLoadingRunner= new Checkbox("Reload classes every run", useLoader);
230 		if (inVAJava())
231 			fUseLoadingRunner.setVisible(false);
232 
233 		//---- second section
234 		fProgressIndicator= new ProgressBar();
235 
236 		//---- third section
237 		fNumberOfErrors= new Label("0000", Label.RIGHT);
238 		fNumberOfErrors.setText("0");
239 		fNumberOfErrors.setFont(PLAIN_FONT);
240 
241 		fNumberOfFailures= new Label("0000", Label.RIGHT);
242 		fNumberOfFailures.setText("0");
243 		fNumberOfFailures.setFont(PLAIN_FONT);
244 
245 		fNumberOfRuns= new Label("0000", Label.RIGHT);
246 		fNumberOfRuns.setText("0");
247 		fNumberOfRuns.setFont(PLAIN_FONT);
248 
249 		Panel numbersPanel= createCounterPanel();
250 
251 		//---- fourth section
252 		Label failureLabel= new Label("Errors and Failures:");
253 
254 		fFailureList= new List(5);
255 		fFailureList.addItemListener(
256 			new ItemListener() {
257 				public void itemStateChanged(ItemEvent e) {
258 					failureSelected();
259 				}
260 			}
261 		);
262 		fRerunButton= new Button("Run");
263 		fRerunButton.setEnabled(false);
264 		fRerunButton.addActionListener(
265 			new ActionListener() {
266 				public void actionPerformed(ActionEvent e) {
267 					rerun();
268 				}
269 			}
270 		);
271 
272 		Panel failedPanel= new Panel(new GridLayout(0, 1, 0, 2));
273 		failedPanel.add(fRerunButton);
274 
275 		fTraceArea= new TextArea();
276 		fTraceArea.setRows(5);
277 		fTraceArea.setColumns(60);
278 
279 		//---- fifth section
280 		fStatusLine= new TextField();
281 		fStatusLine.setFont(PLAIN_FONT);
282 		fStatusLine.setEditable(false);
283 		fStatusLine.setForeground(Color.red);
284 
285 		fQuitButton= new Button("Exit");
286 		fQuitButton.addActionListener(
287 			new ActionListener() {
288 				public void actionPerformed(ActionEvent e) {
289 					System.exit(0);
290 				}
291 			}
292 		);
293 
294 		// ---------
295 		fLogo= new Logo();
296 
297 		//---- overall layout
298 		Panel panel= new Panel(new GridBagLayout());
299 
300 		addGrid(panel, suiteLabel,		 0, 0, 2, GridBagConstraints.HORIZONTAL, 	1.0, GridBagConstraints.WEST);
301 
302 		addGrid(panel, fSuiteField, 	 0, 1, 2, GridBagConstraints.HORIZONTAL, 	1.0, GridBagConstraints.WEST);
303 		addGrid(panel, fRun, 			 2, 1, 1, GridBagConstraints.HORIZONTAL, 	0.0, GridBagConstraints.CENTER);
304 		addGrid(panel, fUseLoadingRunner, 0, 2, 2, GridBagConstraints.NONE, 	1.0, GridBagConstraints.WEST);
305 		addGrid(panel, fProgressIndicator, 0, 3, 2, GridBagConstraints.HORIZONTAL, 	1.0, GridBagConstraints.WEST);
306 		addGrid(panel, fLogo, 			 2, 3, 1, GridBagConstraints.NONE, 			0.0, GridBagConstraints.NORTH);
307 
308 		addGrid(panel, numbersPanel,	 0, 4, 2, GridBagConstraints.NONE, 			0.0, GridBagConstraints.WEST);
309 
310 		addGrid(panel, failureLabel, 	 0, 5, 2, GridBagConstraints.HORIZONTAL, 	1.0, GridBagConstraints.WEST);
311 		addGrid(panel, fFailureList, 	 0, 6, 2, GridBagConstraints.BOTH, 			1.0, GridBagConstraints.WEST);
312 		addGrid(panel, failedPanel, 	 2, 6, 1, GridBagConstraints.HORIZONTAL, 	0.0, GridBagConstraints.CENTER);
313 		addGrid(panel, fTraceArea, 	     0, 7, 2, GridBagConstraints.BOTH, 			1.0, GridBagConstraints.WEST);
314 
315 		addGrid(panel, fStatusLine, 	 0, 8, 2, GridBagConstraints.HORIZONTAL, 	1.0, GridBagConstraints.CENTER);
316 		addGrid(panel, fQuitButton, 	 2, 8, 1, GridBagConstraints.HORIZONTAL, 	0.0, GridBagConstraints.CENTER);
317 
318 		frame.add(panel, BorderLayout.CENTER);
319 		frame.pack();
320 		return frame;
321 	}
322 
createCounterPanel()323 	protected Panel createCounterPanel() {
324 		Panel numbersPanel= new Panel(new GridBagLayout());
325 		addToCounterPanel(
326 			numbersPanel,
327 			new Label("Runs:"),
328 			0, 0, 1, 1, 0.0, 0.0,
329           	GridBagConstraints.CENTER, GridBagConstraints.NONE,
330           	new Insets(0, 0, 0, 0)
331 		);
332 		addToCounterPanel(
333 			numbersPanel,
334 			fNumberOfRuns,
335           	1, 0, 1, 1, 0.33, 0.0,
336           	GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL,
337           	new Insets(0, 8, 0, 40)
338 		);
339 		addToCounterPanel(
340 			numbersPanel,
341 			new Label("Errors:"),
342           	2, 0, 1, 1, 0.0, 0.0,
343           	GridBagConstraints.CENTER, GridBagConstraints.NONE,
344           	new Insets(0, 8, 0, 0)
345 		);
346 		addToCounterPanel(
347 			numbersPanel,
348 			fNumberOfErrors,
349           	3, 0, 1, 1, 0.33, 0.0,
350           	GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL,
351           	new Insets(0, 8, 0, 40)
352 		);
353 		addToCounterPanel(
354 			numbersPanel,
355 			new Label("Failures:"),
356           	4, 0, 1, 1, 0.0, 0.0,
357           	GridBagConstraints.CENTER, GridBagConstraints.NONE,
358           	new Insets(0, 8, 0, 0)
359 		);
360 		addToCounterPanel(
361 			numbersPanel,
362 			fNumberOfFailures,
363           	5, 0, 1, 1, 0.33, 0.0,
364           	GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL,
365           	new Insets(0, 8, 0, 0)
366 		);
367 		return numbersPanel;
368 	}
369 
addToCounterPanel(Panel counter, Component comp, int gridx, int gridy, int gridwidth, int gridheight, double weightx, double weighty, int anchor, int fill, Insets insets)370 	private void addToCounterPanel(Panel counter, Component comp,
371 	    	int gridx, int gridy, int gridwidth, int gridheight,
372 			double weightx, double weighty,
373 			int anchor, int fill,
374 			Insets insets) {
375 
376 		GridBagConstraints constraints= new GridBagConstraints();
377 		constraints.gridx= gridx;
378 		constraints.gridy= gridy;
379 		constraints.gridwidth= gridwidth;
380 		constraints.gridheight= gridheight;
381 		constraints.weightx= weightx;
382 		constraints.weighty= weighty;
383 		constraints.anchor= anchor;
384 		constraints.fill= fill;
385 		constraints.insets= insets;
386 		counter.add(comp, constraints);
387 	}
388 
389 
failureSelected()390 	public void failureSelected() {
391 		fRerunButton.setEnabled(isErrorSelected());
392 		showErrorTrace();
393 	}
394 
isErrorSelected()395 	private boolean isErrorSelected() {
396 		return fFailureList.getSelectedIndex() != -1;
397 	}
398 
loadFrameIcon()399 	private Image loadFrameIcon() {
400 		Toolkit toolkit= Toolkit.getDefaultToolkit();
401 		try {
402 			java.net.URL url= BaseTestRunner.class.getResource("smalllogo.gif");
403 			return toolkit.createImage((ImageProducer) url.getContent());
404 		} catch (Exception ex) {
405 		}
406 		return null;
407 	}
408 
getRunner()409 	public Thread getRunner() {
410 		return fRunner;
411 	}
412 
main(String[] args)413 	public static void main(String[] args) {
414 		new TestRunner().start(args);
415 	}
416 
run(Class test)417 	public static void run(Class test) {
418 		String args[]= { test.getName() };
419 		main(args);
420 	}
421 
rerun()422 	public void rerun() {
423 		int index= fFailureList.getSelectedIndex();
424 		if (index == -1)
425 			return;
426 
427 		Test test= (Test)fFailedTests.elementAt(index);
428 		rerunTest(test);
429 	}
430 
rerunTest(Test test)431 	private void rerunTest(Test test) {
432 		if (!(test instanceof TestCase)) {
433 			showInfo("Could not reload "+ test.toString());
434 			return;
435 		}
436 		Test reloadedTest= null;
437 		TestCase rerunTest= (TestCase)test;
438 		try {
439 			Class reloadedTestClass= getLoader().reload(test.getClass());
440 			reloadedTest= TestSuite.createTest(reloadedTestClass, rerunTest.getName());
441 		} catch(Exception e) {
442 			showInfo("Could not reload "+ test.toString());
443 			return;
444 		}
445 		TestResult result= new TestResult();
446 		reloadedTest.run(result);
447 
448 		String message= reloadedTest.toString();
449 		if(result.wasSuccessful())
450 			showInfo(message+" was successful");
451 		else if (result.errorCount() == 1)
452 			showStatus(message+" had an error");
453 		else
454 			showStatus(message+" had a failure");
455 	}
456 
reset()457 	protected void reset() {
458 		setLabelValue(fNumberOfErrors, 0);
459 		setLabelValue(fNumberOfFailures, 0);
460 		setLabelValue(fNumberOfRuns, 0);
461 		fProgressIndicator.reset();
462 		fRerunButton.setEnabled(false);
463 		fFailureList.removeAll();
464 		fExceptions= new Vector(10);
465 		fFailedTests= new Vector(10);
466 		fTraceArea.setText("");
467 
468 	}
469 
runFailed(String message)470 	protected void runFailed(String message) {
471 		showStatus(message);
472 		fRun.setLabel("Run");
473 		fRunner= null;
474 	}
475 
runSuite()476 	synchronized public void runSuite() {
477 		if (fRunner != null && fTestResult != null) {
478 			fTestResult.stop();
479 		} else {
480 			setLoading(shouldReload());
481 			fRun.setLabel("Stop");
482 			showInfo("Initializing...");
483 			reset();
484 
485 			showInfo("Load Test Case...");
486 
487 			final Test testSuite= getTest(fSuiteField.getText());
488 			if (testSuite != null) {
489 				fRunner= new Thread() {
490 					public void run() {
491 						fTestResult= createTestResult();
492 						fTestResult.addListener(TestRunner.this);
493 						fProgressIndicator.start(testSuite.countTestCases());
494 						showInfo("Running...");
495 
496 						long startTime= System.currentTimeMillis();
497 						testSuite.run(fTestResult);
498 
499 						if (fTestResult.shouldStop()) {
500 							showStatus("Stopped");
501 						} else {
502 							long endTime= System.currentTimeMillis();
503 							long runTime= endTime-startTime;
504 							showInfo("Finished: " + elapsedTimeAsString(runTime) + " seconds");
505 						}
506 						fTestResult= null;
507 						fRun.setLabel("Run");
508 						fRunner= null;
509 						System.gc();
510 					}
511 				};
512 				fRunner.start();
513 			}
514 		}
515 	}
516 
shouldReload()517 	private boolean shouldReload() {
518 		return !inVAJava() && fUseLoadingRunner.getState();
519 	}
520 
setLabelValue(Label label, int value)521 	private void setLabelValue(Label label, int value) {
522 		label.setText(Integer.toString(value));
523 		label.invalidate();
524 		label.getParent().validate();
525 
526 	}
527 
setSuiteName(String suite)528 	public void setSuiteName(String suite) {
529 		fSuiteField.setText(suite);
530 	}
531 
showErrorTrace()532 	private void showErrorTrace() {
533 		int index= fFailureList.getSelectedIndex();
534 		if (index == -1)
535 			return;
536 
537 		Throwable t= (Throwable) fExceptions.elementAt(index);
538 		fTraceArea.setText(getFilteredTrace(t));
539 	}
540 
541 
showInfo(String message)542 	private void showInfo(String message) {
543 		fStatusLine.setFont(PLAIN_FONT);
544 		fStatusLine.setForeground(Color.black);
545 		fStatusLine.setText(message);
546 	}
547 
clearStatus()548 	protected void clearStatus() {
549 		showStatus("");
550 	}
551 
showStatus(String status)552 	private void showStatus(String status) {
553 		fStatusLine.setFont(PLAIN_FONT);
554 		fStatusLine.setForeground(Color.red);
555 		fStatusLine.setText(status);
556 	}
557 	/**
558 	 * Starts the TestRunner
559 	 */
start(String[] args)560 	public void start(String[] args) {
561 		String suiteName= processArguments(args);
562 		fFrame= createUI(suiteName);
563 		fFrame.setLocation(200, 200);
564 		fFrame.setVisible(true);
565 
566 		if (suiteName != null) {
567 			setSuiteName(suiteName);
568 			runSuite();
569 		}
570 	}
571 }