TestRunner.java revision 58a8b0aba2dec5695628a2bf25a3fae42c2c3533
1package junit.swingui; 2 3import java.awt.BorderLayout; 4import java.awt.Component; 5import java.awt.GridBagConstraints; 6import java.awt.GridBagLayout; 7import java.awt.GridLayout; 8import java.awt.Image; 9import java.awt.Insets; 10import java.awt.event.ActionEvent; 11import java.awt.event.ActionListener; 12import java.awt.event.ItemEvent; 13import java.awt.event.ItemListener; 14import java.awt.event.KeyAdapter; 15import java.awt.event.KeyEvent; 16import java.awt.event.WindowAdapter; 17import java.awt.event.WindowEvent; 18import java.io.BufferedReader; 19import java.io.BufferedWriter; 20import java.io.File; 21import java.io.FileReader; 22import java.io.FileWriter; 23import java.io.IOException; 24import java.lang.reflect.Constructor; 25import java.net.URL; 26import java.util.Enumeration; 27import java.util.Vector; 28 29import javax.swing.DefaultListModel; 30import javax.swing.Icon; 31import javax.swing.ImageIcon; 32import javax.swing.JButton; 33import javax.swing.JCheckBox; 34import javax.swing.JComboBox; 35import javax.swing.JFrame; 36import javax.swing.JLabel; 37import javax.swing.JMenu; 38import javax.swing.JMenuBar; 39import javax.swing.JMenuItem; 40import javax.swing.JOptionPane; 41import javax.swing.JPanel; 42import javax.swing.JScrollPane; 43import javax.swing.JSeparator; 44import javax.swing.JSplitPane; 45import javax.swing.JTabbedPane; 46import javax.swing.ListModel; 47import javax.swing.ScrollPaneConstants; 48import javax.swing.SwingConstants; 49import javax.swing.SwingUtilities; 50import javax.swing.event.ChangeEvent; 51import javax.swing.event.ChangeListener; 52import javax.swing.event.DocumentEvent; 53 54import junit.framework.Test; 55import junit.framework.TestCase; 56import junit.framework.TestFailure; 57import junit.framework.TestResult; 58import junit.framework.TestSuite; 59import junit.runner.BaseTestRunner; 60import junit.runner.FailureDetailView; 61import junit.runner.SimpleTestCollector; 62import junit.runner.TestCollector; 63import junit.runner.TestRunListener; 64import junit.runner.Version; 65 66/** 67 * A Swing based user interface to run tests. 68 * Enter the name of a class which either provides a static 69 * suite method or is a subclass of TestCase. 70 * <pre> 71 * Synopsis: java junit.swingui.TestRunner [-noloading] [TestCase] 72 * </pre> 73 * TestRunner takes as an optional argument the name of the testcase class to be run. 74 */ 75public class TestRunner extends BaseTestRunner implements TestRunContext { 76 private static final int GAP= 4; 77 private static final int HISTORY_LENGTH= 5; 78 79 protected JFrame fFrame; 80 private Thread fRunner; 81 private TestResult fTestResult; 82 83 private JComboBox fSuiteCombo; 84 private ProgressBar fProgressIndicator; 85 private DefaultListModel fFailures; 86 private JLabel fLogo; 87 private CounterPanel fCounterPanel; 88 private JButton fRun; 89 private JButton fQuitButton; 90 private JButton fRerunButton; 91 private StatusLine fStatusLine; 92 private FailureDetailView fFailureView; 93 private JTabbedPane fTestViewTab; 94 private JCheckBox fUseLoadingRunner; 95 private Vector fTestRunViews= new Vector(); // view associated with tab in tabbed pane 96 97 private static final String TESTCOLLECTOR_KEY= "TestCollectorClass"; 98 private static final String FAILUREDETAILVIEW_KEY= "FailureViewClass"; 99 100 public TestRunner() { 101 } 102 103 public static void main(String[] args) { 104 new TestRunner().start(args); 105 } 106 107 public static void run(Class test) { 108 String args[]= { test.getName() }; 109 main(args); 110 } 111 112 public void testFailed(final int status, final Test test, final Throwable t) { 113 SwingUtilities.invokeLater( 114 new Runnable() { 115 public void run() { 116 switch (status) { 117 case TestRunListener.STATUS_ERROR: 118 fCounterPanel.setErrorValue(fTestResult.errorCount()); 119 appendFailure(test, t); 120 break; 121 case TestRunListener.STATUS_FAILURE: 122 fCounterPanel.setFailureValue(fTestResult.failureCount()); 123 appendFailure(test, t); 124 break; 125 } 126 } 127 } 128 ); 129 } 130 131 public void testStarted(String testName) { 132 postInfo("Running: "+testName); 133 } 134 135 public void testEnded(String stringName) { 136 synchUI(); 137 SwingUtilities.invokeLater( 138 new Runnable() { 139 public void run() { 140 if (fTestResult != null) { 141 fCounterPanel.setRunValue(fTestResult.runCount()); 142 fProgressIndicator.step(fTestResult.runCount(), fTestResult.wasSuccessful()); 143 } 144 } 145 } 146 ); 147 } 148 149 public void setSuite(String suiteName) { 150 fSuiteCombo.getEditor().setItem(suiteName); 151 } 152 153 private void addToHistory(final String suite) { 154 for (int i= 0; i < fSuiteCombo.getItemCount(); i++) { 155 if (suite.equals(fSuiteCombo.getItemAt(i))) { 156 fSuiteCombo.removeItemAt(i); 157 fSuiteCombo.insertItemAt(suite, 0); 158 fSuiteCombo.setSelectedIndex(0); 159 return; 160 } 161 } 162 fSuiteCombo.insertItemAt(suite, 0); 163 fSuiteCombo.setSelectedIndex(0); 164 pruneHistory(); 165 } 166 167 private void pruneHistory() { 168 int historyLength= getPreference("maxhistory", HISTORY_LENGTH); 169 if (historyLength < 1) 170 historyLength= 1; 171 for (int i= fSuiteCombo.getItemCount()-1; i > historyLength-1; i--) 172 fSuiteCombo.removeItemAt(i); 173 } 174 175 private void appendFailure(Test test, Throwable t) { 176 fFailures.addElement(new TestFailure(test, t)); 177 if (fFailures.size() == 1) 178 revealFailure(test); 179 } 180 181 private void revealFailure(Test test) { 182 for (Enumeration e= fTestRunViews.elements(); e.hasMoreElements(); ) { 183 TestRunView v= (TestRunView) e.nextElement(); 184 v.revealFailure(test); 185 } 186 } 187 188 protected void aboutToStart(final Test testSuite) { 189 for (Enumeration e= fTestRunViews.elements(); e.hasMoreElements(); ) { 190 TestRunView v= (TestRunView) e.nextElement(); 191 v.aboutToStart(testSuite, fTestResult); 192 } 193 } 194 195 protected void runFinished(final Test testSuite) { 196 SwingUtilities.invokeLater( 197 new Runnable() { 198 public void run() { 199 for (Enumeration e= fTestRunViews.elements(); e.hasMoreElements(); ) { 200 TestRunView v= (TestRunView) e.nextElement(); 201 v.runFinished(testSuite, fTestResult); 202 } 203 } 204 } 205 ); 206 } 207 208 protected CounterPanel createCounterPanel() { 209 return new CounterPanel(); 210 } 211 212 protected JPanel createFailedPanel() { 213 JPanel failedPanel= new JPanel(new GridLayout(0, 1, 0, 2)); 214 fRerunButton= new JButton("Run"); 215 fRerunButton.setEnabled(false); 216 fRerunButton.addActionListener( 217 new ActionListener() { 218 public void actionPerformed(ActionEvent e) { 219 rerun(); 220 } 221 } 222 ); 223 failedPanel.add(fRerunButton); 224 return failedPanel; 225 } 226 227 protected FailureDetailView createFailureDetailView() { 228 String className= BaseTestRunner.getPreference(FAILUREDETAILVIEW_KEY); 229 if (className != null) { 230 Class viewClass= null; 231 try { 232 viewClass= Class.forName(className); 233 return (FailureDetailView)viewClass.newInstance(); 234 } catch(Exception e) { 235 JOptionPane.showMessageDialog(fFrame, "Could not create Failure DetailView - using default view"); 236 } 237 } 238 return new DefaultFailureDetailView(); 239 } 240 241 /** 242 * Creates the JUnit menu. Clients override this 243 * method to add additional menu items. 244 */ 245 protected JMenu createJUnitMenu() { 246 JMenu menu= new JMenu("JUnit"); 247 menu.setMnemonic('J'); 248 JMenuItem mi1= new JMenuItem("About..."); 249 mi1.addActionListener( 250 new ActionListener() { 251 public void actionPerformed(ActionEvent event) { 252 about(); 253 } 254 } 255 ); 256 mi1.setMnemonic('A'); 257 menu.add(mi1); 258 259 menu.addSeparator(); 260 JMenuItem mi2= new JMenuItem(" Exit "); 261 mi2.addActionListener( 262 new ActionListener() { 263 public void actionPerformed(ActionEvent event) { 264 terminate(); 265 } 266 } 267 ); 268 mi2.setMnemonic('x'); 269 menu.add(mi2); 270 271 return menu; 272 } 273 274 protected JFrame createFrame() { 275 JFrame frame= new JFrame("JUnit"); 276 Image icon= loadFrameIcon(); 277 if (icon != null) 278 frame.setIconImage(icon); 279 frame.getContentPane().setLayout(new BorderLayout(0, 0)); 280 281 frame.addWindowListener( 282 new WindowAdapter() { 283 public void windowClosing(WindowEvent e) { 284 terminate(); 285 } 286 } 287 ); 288 return frame; 289 } 290 291 protected JLabel createLogo() { 292 JLabel label; 293 Icon icon= getIconResource(BaseTestRunner.class, "logo.gif"); 294 if (icon != null) 295 label= new JLabel(icon); 296 else 297 label= new JLabel("JV"); 298 label.setToolTipText("JUnit Version "+Version.id()); 299 return label; 300 } 301 302 protected void createMenus(JMenuBar mb) { 303 mb.add(createJUnitMenu()); 304 } 305 306 protected JCheckBox createUseLoaderCheckBox() { 307 boolean useLoader= useReloadingTestSuiteLoader(); 308 JCheckBox box= new JCheckBox("Reload classes every run", useLoader); 309 box.setToolTipText("Use a custom class loader to reload the classes for every run"); 310 if (inVAJava()) 311 box.setVisible(false); 312 return box; 313 } 314 315 protected JButton createQuitButton() { 316 // spaces required to avoid layout flicker 317 // Exit is shorter than Stop that shows in the same column 318 JButton quit= new JButton(" Exit "); 319 quit.addActionListener( 320 new ActionListener() { 321 public void actionPerformed(ActionEvent e) { 322 terminate(); 323 } 324 } 325 ); 326 return quit; 327 } 328 329 protected JButton createRunButton() { 330 JButton run= new JButton("Run"); 331 run.setEnabled(true); 332 run.addActionListener( 333 new ActionListener() { 334 public void actionPerformed(ActionEvent e) { 335 runSuite(); 336 } 337 } 338 ); 339 return run; 340 } 341 342 protected Component createBrowseButton() { 343 JButton browse= new JButton("..."); 344 browse.setToolTipText("Select a Test class"); 345 browse.addActionListener( 346 new ActionListener() { 347 public void actionPerformed(ActionEvent e) { 348 browseTestClasses(); 349 } 350 } 351 ); 352 return browse; 353 } 354 355 protected StatusLine createStatusLine() { 356 return new StatusLine(380); 357 } 358 359 protected JComboBox createSuiteCombo() { 360 JComboBox combo= new JComboBox(); 361 combo.setEditable(true); 362 combo.setLightWeightPopupEnabled(false); 363 364 combo.getEditor().getEditorComponent().addKeyListener( 365 new KeyAdapter() { 366 public void keyTyped(KeyEvent e) { 367 textChanged(); 368 if (e.getKeyChar() == KeyEvent.VK_ENTER) 369 runSuite(); 370 } 371 } 372 ); 373 try { 374 loadHistory(combo); 375 } catch (IOException e) { 376 // fails the first time 377 } 378 combo.addItemListener( 379 new ItemListener() { 380 public void itemStateChanged(ItemEvent event) { 381 if (event.getStateChange() == ItemEvent.SELECTED) { 382 textChanged(); 383 } 384 } 385 } 386 ); 387 return combo; 388 } 389 390 protected JTabbedPane createTestRunViews() { 391 JTabbedPane pane= new JTabbedPane(SwingConstants.BOTTOM); 392 393 FailureRunView lv= new FailureRunView(this); 394 fTestRunViews.addElement(lv); 395 lv.addTab(pane); 396 397 TestHierarchyRunView tv= new TestHierarchyRunView(this); 398 fTestRunViews.addElement(tv); 399 tv.addTab(pane); 400 401 pane.addChangeListener( 402 new ChangeListener() { 403 public void stateChanged(ChangeEvent e) { 404 testViewChanged(); 405 } 406 } 407 ); 408 return pane; 409 } 410 411 public void testViewChanged() { 412 TestRunView view= (TestRunView)fTestRunViews.elementAt(fTestViewTab.getSelectedIndex()); 413 view.activate(); 414 } 415 416 protected TestResult createTestResult() { 417 return new TestResult(); 418 } 419 420 protected JFrame createUI(String suiteName) { 421 JFrame frame= createFrame(); 422 JMenuBar mb= new JMenuBar(); 423 createMenus(mb); 424 frame.setJMenuBar(mb); 425 426 JLabel suiteLabel= new JLabel("Test class name:"); 427 fSuiteCombo= createSuiteCombo(); 428 fRun= createRunButton(); 429 frame.getRootPane().setDefaultButton(fRun); 430 Component browseButton= createBrowseButton(); 431 432 fUseLoadingRunner= createUseLoaderCheckBox(); 433 434 fStatusLine= createStatusLine(); 435 if (inMac()) 436 fProgressIndicator= new MacProgressBar(fStatusLine); 437 else 438 fProgressIndicator= new ProgressBar(); 439 fCounterPanel= createCounterPanel(); 440 441 fFailures= new DefaultListModel(); 442 443 fTestViewTab= createTestRunViews(); 444 JPanel failedPanel= createFailedPanel(); 445 446 fFailureView= createFailureDetailView(); 447 JScrollPane tracePane= new JScrollPane(fFailureView.getComponent(), ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS); 448 449 450 451 fQuitButton= createQuitButton(); 452 fLogo= createLogo(); 453 454 JPanel panel= new JPanel(new GridBagLayout()); 455 456 addGrid(panel, suiteLabel, 0, 0, 2, GridBagConstraints.HORIZONTAL, 1.0, GridBagConstraints.WEST); 457 addGrid(panel, fSuiteCombo, 0, 1, 1, GridBagConstraints.HORIZONTAL, 1.0, GridBagConstraints.WEST); 458 addGrid(panel, browseButton, 1, 1, 1, GridBagConstraints.NONE, 0.0, GridBagConstraints.WEST); 459 addGrid(panel, fRun, 2, 1, 1, GridBagConstraints.HORIZONTAL, 0.0, GridBagConstraints.CENTER); 460 461 addGrid(panel, fUseLoadingRunner, 0, 2, 3, GridBagConstraints.NONE, 1.0, GridBagConstraints.WEST); 462 //addGrid(panel, new JSeparator(), 0, 3, 3, GridBagConstraints.HORIZONTAL, 1.0, GridBagConstraints.WEST); 463 464 465 addGrid(panel, fProgressIndicator, 0, 3, 2, GridBagConstraints.HORIZONTAL, 1.0, GridBagConstraints.WEST); 466 addGrid(panel, fLogo, 2, 3, 1, GridBagConstraints.NONE, 0.0, GridBagConstraints.NORTH); 467 468 addGrid(panel, fCounterPanel, 0, 4, 2, GridBagConstraints.NONE, 0.0, GridBagConstraints.WEST); 469 addGrid(panel, new JSeparator(), 0, 5, 2, GridBagConstraints.HORIZONTAL, 1.0, GridBagConstraints.WEST); 470 addGrid(panel, new JLabel("Results:"), 0, 6, 2, GridBagConstraints.HORIZONTAL, 1.0, GridBagConstraints.WEST); 471 472 JSplitPane splitter= new JSplitPane(JSplitPane.VERTICAL_SPLIT, fTestViewTab, tracePane); 473 addGrid(panel, splitter, 0, 7, 2, GridBagConstraints.BOTH, 1.0, GridBagConstraints.WEST); 474 475 addGrid(panel, failedPanel, 2, 7, 1, GridBagConstraints.HORIZONTAL, 0.0, GridBagConstraints.NORTH/*CENTER*/); 476 477 addGrid(panel, fStatusLine, 0, 9, 2, GridBagConstraints.HORIZONTAL, 1.0, GridBagConstraints.CENTER); 478 addGrid(panel, fQuitButton, 2, 9, 1, GridBagConstraints.HORIZONTAL, 0.0, GridBagConstraints.CENTER); 479 480 frame.setContentPane(panel); 481 frame.pack(); 482 frame.setLocation(200, 200); 483 return frame; 484 } 485 486 private void addGrid(JPanel p, Component co, int x, int y, int w, int fill, double wx, int anchor) { 487 GridBagConstraints c= new GridBagConstraints(); 488 c.gridx= x; c.gridy= y; 489 c.gridwidth= w; 490 c.anchor= anchor; 491 c.weightx= wx; 492 c.fill= fill; 493 if (fill == GridBagConstraints.BOTH || fill == GridBagConstraints.VERTICAL) 494 c.weighty= 1.0; 495 c.insets= new Insets(y == 0 ? 10 : 0, x == 0 ? 10 : GAP, GAP, GAP); 496 p.add(co, c); 497 } 498 499 protected String getSuiteText() { 500 if (fSuiteCombo == null) 501 return ""; 502 return (String)fSuiteCombo.getEditor().getItem(); 503 } 504 505 public ListModel getFailures() { 506 return fFailures; 507 } 508 509 public void insertUpdate(DocumentEvent event) { 510 textChanged(); 511 } 512 513 protected Object instanciateClass(String fullClassName, Object param) { 514 try { 515 Class clazz= Class.forName(fullClassName); 516 if (param == null) { 517 return clazz.newInstance(); 518 } else { 519 Class[] clazzParam= {param.getClass()}; 520 Constructor clazzConstructor= clazz.getConstructor(clazzParam); 521 Object[] objectParam= {param}; 522 return clazzConstructor.newInstance(objectParam); 523 } 524 } catch (Exception e) { 525 e.printStackTrace(); 526 } 527 return null; 528 } 529 530 public void browseTestClasses() { 531 TestCollector collector= createTestCollector(); 532 TestSelector selector= new TestSelector(fFrame, collector); 533 if (selector.isEmpty()) { 534 JOptionPane.showMessageDialog(fFrame, "No Test Cases found.\nCheck that the configured \'TestCollector\' is supported on this platform."); 535 return; 536 } 537 selector.show(); 538 String className= selector.getSelectedItem(); 539 if (className != null) 540 setSuite(className); 541 } 542 543 TestCollector createTestCollector() { 544 String className= BaseTestRunner.getPreference(TESTCOLLECTOR_KEY); 545 if (className != null) { 546 Class collectorClass= null; 547 try { 548 collectorClass= Class.forName(className); 549 return (TestCollector)collectorClass.newInstance(); 550 } catch(Exception e) { 551 JOptionPane.showMessageDialog(fFrame, "Could not create TestCollector - using default collector"); 552 } 553 } 554 return new SimpleTestCollector(); 555 } 556 557 private Image loadFrameIcon() { 558 ImageIcon icon= (ImageIcon)getIconResource(BaseTestRunner.class, "smalllogo.gif"); 559 if (icon != null) 560 return icon.getImage(); 561 return null; 562 } 563 564 private void loadHistory(JComboBox combo) throws IOException { 565 BufferedReader br= new BufferedReader(new FileReader(getSettingsFile())); 566 int itemCount= 0; 567 try { 568 String line; 569 while ((line= br.readLine()) != null) { 570 combo.addItem(line); 571 itemCount++; 572 } 573 if (itemCount > 0) 574 combo.setSelectedIndex(0); 575 576 } finally { 577 br.close(); 578 } 579 } 580 581 private File getSettingsFile() { 582 String home= System.getProperty("user.home"); 583 return new File(home,".junitsession"); 584 } 585 586 private void postInfo(final String message) { 587 SwingUtilities.invokeLater( 588 new Runnable() { 589 public void run() { 590 showInfo(message); 591 } 592 } 593 ); 594 } 595 596 private void postStatus(final String status) { 597 SwingUtilities.invokeLater( 598 new Runnable() { 599 public void run() { 600 showStatus(status); 601 } 602 } 603 ); 604 } 605 606 public void removeUpdate(DocumentEvent event) { 607 textChanged(); 608 } 609 610 private void rerun() { 611 TestRunView view= (TestRunView)fTestRunViews.elementAt(fTestViewTab.getSelectedIndex()); 612 Test rerunTest= view.getSelectedTest(); 613 if (rerunTest != null) 614 rerunTest(rerunTest); 615 } 616 617 private void rerunTest(Test test) { 618 if (!(test instanceof TestCase)) { 619 showInfo("Could not reload "+ test.toString()); 620 return; 621 } 622 Test reloadedTest= null; 623 TestCase rerunTest= (TestCase)test; 624 625 try { 626 Class reloadedTestClass= getLoader().reload(test.getClass()); 627 reloadedTest= TestSuite.createTest(reloadedTestClass, rerunTest.getName()); 628 } catch(Exception e) { 629 showInfo("Could not reload "+ test.toString()); 630 return; 631 } 632 TestResult result= new TestResult(); 633 reloadedTest.run(result); 634 635 String message= reloadedTest.toString(); 636 if(result.wasSuccessful()) 637 showInfo(message+" was successful"); 638 else if (result.errorCount() == 1) 639 showStatus(message+" had an error"); 640 else 641 showStatus(message+" had a failure"); 642 } 643 644 protected void reset() { 645 fCounterPanel.reset(); 646 fProgressIndicator.reset(); 647 fRerunButton.setEnabled(false); 648 fFailureView.clear(); 649 fFailures.clear(); 650 } 651 652 protected void runFailed(String message) { 653 showStatus(message); 654 fRun.setText("Run"); 655 fRunner= null; 656 } 657 658 synchronized public void runSuite() { 659 if (fRunner != null) { 660 fTestResult.stop(); 661 } else { 662 setLoading(shouldReload()); 663 reset(); 664 showInfo("Load Test Case..."); 665 final String suiteName= getSuiteText(); 666 final Test testSuite= getTest(suiteName); 667 if (testSuite != null) { 668 addToHistory(suiteName); 669 doRunTest(testSuite); 670 } 671 } 672 } 673 674 private boolean shouldReload() { 675 return !inVAJava() && fUseLoadingRunner.isSelected(); 676 } 677 678 679 synchronized protected void runTest(final Test testSuite) { 680 if (fRunner != null) { 681 fTestResult.stop(); 682 } else { 683 reset(); 684 if (testSuite != null) { 685 doRunTest(testSuite); 686 } 687 } 688 } 689 690 private void doRunTest(final Test testSuite) { 691 setButtonLabel(fRun, "Stop"); 692 fRunner= new Thread("TestRunner-Thread") { 693 public void run() { 694 TestRunner.this.start(testSuite); 695 postInfo("Running..."); 696 697 long startTime= System.currentTimeMillis(); 698 testSuite.run(fTestResult); 699 700 if (fTestResult.shouldStop()) { 701 postStatus("Stopped"); 702 } else { 703 long endTime= System.currentTimeMillis(); 704 long runTime= endTime-startTime; 705 postInfo("Finished: " + elapsedTimeAsString(runTime) + " seconds"); 706 } 707 runFinished(testSuite); 708 setButtonLabel(fRun, "Run"); 709 fRunner= null; 710 System.gc(); 711 } 712 }; 713 // make sure that the test result is created before we start the 714 // test runner thread so that listeners can register for it. 715 fTestResult= createTestResult(); 716 fTestResult.addListener(TestRunner.this); 717 aboutToStart(testSuite); 718 719 fRunner.start(); 720 } 721 722 private void saveHistory() throws IOException { 723 BufferedWriter bw= new BufferedWriter(new FileWriter(getSettingsFile())); 724 try { 725 for (int i= 0; i < fSuiteCombo.getItemCount(); i++) { 726 String testsuite= fSuiteCombo.getItemAt(i).toString(); 727 bw.write(testsuite, 0, testsuite.length()); 728 bw.newLine(); 729 } 730 } finally { 731 bw.close(); 732 } 733 } 734 735 private void setButtonLabel(final JButton button, final String label) { 736 SwingUtilities.invokeLater( 737 new Runnable() { 738 public void run() { 739 button.setText(label); 740 } 741 } 742 ); 743 } 744 745 public void handleTestSelected(Test test) { 746 fRerunButton.setEnabled(test != null && (test instanceof TestCase)); 747 showFailureDetail(test); 748 } 749 750 private void showFailureDetail(Test test) { 751 if (test != null) { 752 ListModel failures= getFailures(); 753 for (int i= 0; i < failures.getSize(); i++) { 754 TestFailure failure= (TestFailure)failures.getElementAt(i); 755 if (failure.failedTest() == test) { 756 fFailureView.showFailure(failure); 757 return; 758 } 759 } 760 } 761 fFailureView.clear(); 762 } 763 764 private void showInfo(String message) { 765 fStatusLine.showInfo(message); 766 } 767 768 private void showStatus(String status) { 769 fStatusLine.showError(status); 770 } 771 772 /** 773 * Starts the TestRunner 774 */ 775 public void start(String[] args) { 776 String suiteName= processArguments(args); 777 fFrame= createUI(suiteName); 778 fFrame.pack(); 779 fFrame.setVisible(true); 780 781 if (suiteName != null) { 782 setSuite(suiteName); 783 runSuite(); 784 } 785 } 786 787 private void start(final Test test) { 788 SwingUtilities.invokeLater( 789 new Runnable() { 790 public void run() { 791 int total= test.countTestCases(); 792 fProgressIndicator.start(total); 793 fCounterPanel.setTotal(total); 794 } 795 } 796 ); 797 } 798 799 /** 800 * Wait until all the events are processed in the event thread 801 */ 802 private void synchUI() { 803 try { 804 SwingUtilities.invokeAndWait( 805 new Runnable() { 806 public void run() {} 807 } 808 ); 809 } 810 catch (Exception e) { 811 } 812 } 813 814 /** 815 * Terminates the TestRunner 816 */ 817 public void terminate() { 818 fFrame.dispose(); 819 try { 820 saveHistory(); 821 } catch (IOException e) { 822 System.out.println("Couldn't save test run history"); 823 } 824 System.exit(0); 825 } 826 827 public void textChanged() { 828 fRun.setEnabled(getSuiteText().length() > 0); 829 clearStatus(); 830 } 831 832 protected void clearStatus() { 833 fStatusLine.clear(); 834 } 835 836 public static Icon getIconResource(Class clazz, String name) { 837 URL url= clazz.getResource(name); 838 if (url == null) { 839 System.err.println("Warning: could not load \""+name+"\" icon"); 840 return null; 841 } 842 return new ImageIcon(url); 843 } 844 845 private void about() { 846 AboutDialog about= new AboutDialog(fFrame); 847 about.show(); 848 } 849} 850