| package junit.awtui; |
| |
| import junit.framework.*; |
| import junit.runner.*; |
| |
| import java.util.Vector; |
| import java.lang.reflect.*; |
| import java.awt.*; |
| import java.awt.event.*; |
| import java.awt.image.*; |
| import java.io.*; |
| |
| /** |
| * An AWT based user interface to run tests. |
| * Enter the name of a class which either provides a static |
| * suite method or is a subclass of TestCase. |
| * <pre> |
| * Synopsis: java junit.awtui.TestRunner [-noloading] [TestCase] |
| * </pre> |
| * TestRunner takes as an optional argument the name of the testcase class to be run. |
| */ |
| public class TestRunner extends BaseTestRunner { |
| protected Frame fFrame; |
| protected Vector fExceptions; |
| protected Vector fFailedTests; |
| protected Thread fRunner; |
| protected TestResult fTestResult; |
| |
| protected TextArea fTraceArea; |
| protected TextField fSuiteField; |
| protected Button fRun; |
| protected ProgressBar fProgressIndicator; |
| protected List fFailureList; |
| protected Logo fLogo; |
| protected Label fNumberOfErrors; |
| protected Label fNumberOfFailures; |
| protected Label fNumberOfRuns; |
| protected Button fQuitButton; |
| protected Button fRerunButton; |
| protected TextField fStatusLine; |
| protected Checkbox fUseLoadingRunner; |
| |
| protected static Font PLAIN_FONT= new Font("dialog", Font.PLAIN, 12); |
| private static final int GAP= 4; |
| private static final String SUITE_METHODNAME= "suite"; |
| |
| public TestRunner() { |
| } |
| |
| private void about() { |
| AboutDialog about= new AboutDialog(fFrame); |
| about.setModal(true); |
| about.setLocation(300, 300); |
| about.setVisible(true); |
| } |
| |
| public void addError(Test test, Throwable t) { |
| fNumberOfErrors.setText(Integer.toString(fTestResult.errorCount())); |
| appendFailure("Error", test, t); |
| } |
| |
| public void addFailure(Test test, AssertionFailedError t) { |
| fNumberOfFailures.setText(Integer.toString(fTestResult.failureCount())); |
| appendFailure("Failure", test, t); |
| } |
| |
| protected void addGrid(Panel p, Component co, int x, int y, int w, int fill, double wx, int anchor) { |
| GridBagConstraints c= new GridBagConstraints(); |
| c.gridx= x; c.gridy= y; |
| c.gridwidth= w; |
| c.anchor= anchor; |
| c.weightx= wx; |
| c.fill= fill; |
| if (fill == GridBagConstraints.BOTH || fill == GridBagConstraints.VERTICAL) |
| c.weighty= 1.0; |
| c.insets= new Insets(y == 0 ? GAP : 0, x == 0 ? GAP : 0, GAP, GAP); |
| p.add(co, c); |
| } |
| |
| private void appendFailure(String kind, Test test, Throwable t) { |
| kind+= ": " + test; |
| String msg= t.getMessage(); |
| if (msg != null) { |
| kind+= ":" + truncate(msg); |
| } |
| fFailureList.add(kind); |
| fExceptions.addElement(t); |
| fFailedTests.addElement(test); |
| if (fFailureList.getItemCount() == 1) { |
| fFailureList.select(0); |
| failureSelected(); |
| } |
| } |
| /** |
| * Creates the JUnit menu. Clients override this |
| * method to add additional menu items. |
| */ |
| protected Menu createJUnitMenu() { |
| Menu menu= new Menu("JUnit"); |
| MenuItem mi= new MenuItem("About..."); |
| mi.addActionListener( |
| new ActionListener() { |
| public void actionPerformed(ActionEvent event) { |
| about(); |
| } |
| } |
| ); |
| menu.add(mi); |
| |
| menu.addSeparator(); |
| mi= new MenuItem("Exit"); |
| mi.addActionListener( |
| new ActionListener() { |
| public void actionPerformed(ActionEvent event) { |
| System.exit(0); |
| } |
| } |
| ); |
| menu.add(mi); |
| return menu; |
| } |
| |
| protected void createMenus(MenuBar mb) { |
| mb.add(createJUnitMenu()); |
| } |
| protected TestResult createTestResult() { |
| return new TestResult(); |
| } |
| |
| protected Frame createUI(String suiteName) { |
| Frame frame= new Frame("JUnit"); |
| Image icon= loadFrameIcon(); |
| if (icon != null) |
| frame.setIconImage(icon); |
| |
| frame.setLayout(new BorderLayout(0, 0)); |
| frame.setBackground(SystemColor.control); |
| final Frame finalFrame= frame; |
| |
| frame.addWindowListener( |
| new WindowAdapter() { |
| public void windowClosing(WindowEvent e) { |
| finalFrame.dispose(); |
| System.exit(0); |
| } |
| } |
| ); |
| |
| MenuBar mb = new MenuBar(); |
| createMenus(mb); |
| frame.setMenuBar(mb); |
| |
| //---- first section |
| Label suiteLabel= new Label("Test class name:"); |
| |
| fSuiteField= new TextField(suiteName != null ? suiteName : ""); |
| fSuiteField.selectAll(); |
| fSuiteField.requestFocus(); |
| fSuiteField.setFont(PLAIN_FONT); |
| fSuiteField.setColumns(40); |
| fSuiteField.addActionListener( |
| new ActionListener() { |
| public void actionPerformed(ActionEvent e) { |
| runSuite(); |
| } |
| } |
| ); |
| fSuiteField.addTextListener( |
| new TextListener() { |
| public void textValueChanged(TextEvent e) { |
| fRun.setEnabled(fSuiteField.getText().length() > 0); |
| fStatusLine.setText(""); |
| } |
| } |
| ); |
| fRun= new Button("Run"); |
| fRun.setEnabled(false); |
| fRun.addActionListener( |
| new ActionListener() { |
| public void actionPerformed(ActionEvent e) { |
| runSuite(); |
| } |
| } |
| ); |
| boolean useLoader= useReloadingTestSuiteLoader(); |
| fUseLoadingRunner= new Checkbox("Reload classes every run", useLoader); |
| if (inVAJava()) |
| fUseLoadingRunner.setVisible(false); |
| |
| //---- second section |
| fProgressIndicator= new ProgressBar(); |
| |
| //---- third section |
| fNumberOfErrors= new Label("0000", Label.RIGHT); |
| fNumberOfErrors.setText("0"); |
| fNumberOfErrors.setFont(PLAIN_FONT); |
| |
| fNumberOfFailures= new Label("0000", Label.RIGHT); |
| fNumberOfFailures.setText("0"); |
| fNumberOfFailures.setFont(PLAIN_FONT); |
| |
| fNumberOfRuns= new Label("0000", Label.RIGHT); |
| fNumberOfRuns.setText("0"); |
| fNumberOfRuns.setFont(PLAIN_FONT); |
| |
| Panel numbersPanel= new Panel(new FlowLayout()); |
| numbersPanel.add(new Label("Runs:")); numbersPanel.add(fNumberOfRuns); |
| numbersPanel.add(new Label(" Errors:")); numbersPanel.add(fNumberOfErrors); |
| numbersPanel.add(new Label(" Failures:")); numbersPanel.add(fNumberOfFailures); |
| |
| |
| //---- fourth section |
| Label failureLabel= new Label("Errors and Failures:"); |
| |
| fFailureList= new List(5); |
| fFailureList.addItemListener( |
| new ItemListener() { |
| public void itemStateChanged(ItemEvent e) { |
| failureSelected(); |
| } |
| } |
| ); |
| fRerunButton= new Button("Run"); |
| fRerunButton.setEnabled(false); |
| fRerunButton.addActionListener( |
| new ActionListener() { |
| public void actionPerformed(ActionEvent e) { |
| rerun(); |
| } |
| } |
| ); |
| |
| Panel failedPanel= new Panel(new GridLayout(0, 1, 0, 2)); |
| failedPanel.add(fRerunButton); |
| |
| fTraceArea= new TextArea(); |
| fTraceArea.setRows(5); |
| fTraceArea.setColumns(60); |
| |
| //---- fifth section |
| fStatusLine= new TextField(); |
| fStatusLine.setFont(PLAIN_FONT); |
| fStatusLine.setEditable(false); |
| fStatusLine.setForeground(Color.red); |
| |
| fQuitButton= new Button("Exit"); |
| fQuitButton.addActionListener( |
| new ActionListener() { |
| public void actionPerformed(ActionEvent e) { |
| System.exit(0); |
| } |
| } |
| ); |
| |
| // --------- |
| fLogo= new Logo(); |
| |
| //---- overall layout |
| Panel panel= new Panel(new GridBagLayout()); |
| |
| addGrid(panel, suiteLabel, 0, 0, 2, GridBagConstraints.HORIZONTAL, 1.0, GridBagConstraints.WEST); |
| |
| addGrid(panel, fSuiteField, 0, 1, 2, GridBagConstraints.HORIZONTAL, 1.0, GridBagConstraints.WEST); |
| addGrid(panel, fRun, 2, 1, 1, GridBagConstraints.HORIZONTAL, 0.0, GridBagConstraints.CENTER); |
| addGrid(panel, fUseLoadingRunner, 0, 2, 2, GridBagConstraints.HORIZONTAL, 1.0, GridBagConstraints.WEST); |
| addGrid(panel, fProgressIndicator, 0, 3, 2, GridBagConstraints.HORIZONTAL, 1.0, GridBagConstraints.WEST); |
| addGrid(panel, fLogo, 2, 3, 1, GridBagConstraints.NONE, 0.0, GridBagConstraints.NORTH); |
| |
| addGrid(panel, numbersPanel, 0, 4, 2, GridBagConstraints.NONE, 0.0, GridBagConstraints.CENTER); |
| |
| addGrid(panel, failureLabel, 0, 5, 2, GridBagConstraints.HORIZONTAL, 1.0, GridBagConstraints.WEST); |
| addGrid(panel, fFailureList, 0, 6, 2, GridBagConstraints.BOTH, 1.0, GridBagConstraints.WEST); |
| addGrid(panel, failedPanel, 2, 6, 1, GridBagConstraints.HORIZONTAL, 0.0, GridBagConstraints.CENTER); |
| addGrid(panel, fTraceArea, 0, 7, 2, GridBagConstraints.BOTH, 1.0, GridBagConstraints.WEST); |
| |
| addGrid(panel, fStatusLine, 0, 8, 2, GridBagConstraints.HORIZONTAL, 1.0, GridBagConstraints.CENTER); |
| addGrid(panel, fQuitButton, 2, 8, 1, GridBagConstraints.HORIZONTAL, 0.0, GridBagConstraints.CENTER); |
| |
| frame.add(panel, BorderLayout.CENTER); |
| frame.pack(); |
| return frame; |
| } |
| |
| public void failureSelected() { |
| fRerunButton.setEnabled(isErrorSelected()); |
| showErrorTrace(); |
| } |
| |
| public void endTest(Test test) { |
| setLabelValue(fNumberOfRuns, fTestResult.runCount()); |
| synchronized(this) { |
| fProgressIndicator.step(fTestResult.wasSuccessful()); |
| } |
| } |
| |
| private boolean isErrorSelected() { |
| return fFailureList.getSelectedIndex() != -1; |
| } |
| |
| private Image loadFrameIcon() { |
| Toolkit toolkit= Toolkit.getDefaultToolkit(); |
| try { |
| java.net.URL url= BaseTestRunner.class.getResource("smalllogo.gif"); |
| return toolkit.createImage((ImageProducer) url.getContent()); |
| } catch (Exception ex) { |
| } |
| return null; |
| } |
| |
| public Thread getRunner() { |
| return fRunner; |
| } |
| |
| public static void main(String[] args) { |
| new TestRunner().start(args); |
| } |
| |
| public static void run(Class test) { |
| String args[]= { test.getName() }; |
| main(args); |
| } |
| |
| public void rerun() { |
| int index= fFailureList.getSelectedIndex(); |
| if (index == -1) |
| return; |
| |
| Test test= (Test)fFailedTests.elementAt(index); |
| if (!(test instanceof TestCase)) { |
| showInfo("Could not reload "+ test.toString()); |
| return; |
| } |
| Test reloadedTest= null; |
| try { |
| Class reloadedTestClass= getLoader().reload(test.getClass()); |
| Class[] classArgs= { String.class }; |
| Constructor constructor= reloadedTestClass.getConstructor(classArgs); |
| Object[] args= new Object[]{((TestCase)test).getName()}; |
| reloadedTest=(Test)constructor.newInstance(args); |
| } catch(Exception e) { |
| showInfo("Could not reload "+ test.toString()); |
| return; |
| } |
| TestResult result= new TestResult(); |
| reloadedTest.run(result); |
| |
| String message= reloadedTest.toString(); |
| if(result.wasSuccessful()) |
| showInfo(message+" was successful"); |
| else if (result.errorCount() == 1) |
| showStatus(message+" had an error"); |
| else |
| showStatus(message+" had a failure"); |
| } |
| |
| protected void reset() { |
| setLabelValue(fNumberOfErrors, 0); |
| setLabelValue(fNumberOfFailures, 0); |
| setLabelValue(fNumberOfRuns, 0); |
| fProgressIndicator.reset(); |
| fRerunButton.setEnabled(false); |
| fFailureList.removeAll(); |
| fExceptions= new Vector(10); |
| fFailedTests= new Vector(10); |
| fTraceArea.setText(""); |
| |
| } |
| /** |
| * runs a suite. |
| * @deprecated use runSuite() instead |
| */ |
| public void run() { |
| runSuite(); |
| } |
| |
| protected void runFailed(String message) { |
| showStatus(message); |
| fRun.setLabel("Run"); |
| fRunner= null; |
| } |
| |
| synchronized public void runSuite() { |
| if (fRunner != null) { |
| fTestResult.stop(); |
| } else { |
| setLoading(shouldReload()); |
| fRun.setLabel("Stop"); |
| showInfo("Initializing..."); |
| reset(); |
| |
| showInfo("Load Test Case..."); |
| |
| final Test testSuite= getTest(fSuiteField.getText()); |
| if (testSuite != null) { |
| fRunner= new Thread() { |
| public void run() { |
| fTestResult= createTestResult(); |
| fTestResult.addListener(TestRunner.this); |
| fProgressIndicator.start(testSuite.countTestCases()); |
| showInfo("Running..."); |
| |
| long startTime= System.currentTimeMillis(); |
| testSuite.run(fTestResult); |
| |
| if (fTestResult.shouldStop()) { |
| showStatus("Stopped"); |
| } else { |
| long endTime= System.currentTimeMillis(); |
| long runTime= endTime-startTime; |
| showInfo("Finished: " + elapsedTimeAsString(runTime) + " seconds"); |
| } |
| fTestResult= null; |
| fRun.setLabel("Run"); |
| fRunner= null; |
| System.gc(); |
| } |
| }; |
| fRunner.start(); |
| } |
| } |
| } |
| |
| private boolean shouldReload() { |
| return !inVAJava() && fUseLoadingRunner.getState(); |
| } |
| |
| private void setLabelValue(Label label, int value) { |
| label.setText(Integer.toString(value)); |
| label.invalidate(); |
| label.getParent().validate(); |
| |
| } |
| |
| public void setSuiteName(String suite) { |
| fSuiteField.setText(suite); |
| } |
| |
| private void showErrorTrace() { |
| int index= fFailureList.getSelectedIndex(); |
| if (index == -1) |
| return; |
| |
| Throwable t= (Throwable) fExceptions.elementAt(index); |
| fTraceArea.setText(getFilteredTrace(t)); |
| } |
| |
| |
| private void showInfo(String message) { |
| fStatusLine.setFont(PLAIN_FONT); |
| fStatusLine.setForeground(Color.black); |
| fStatusLine.setText(message); |
| } |
| |
| protected void clearStatus() { |
| showStatus(""); |
| } |
| |
| private void showStatus(String status) { |
| fStatusLine.setFont(PLAIN_FONT); |
| fStatusLine.setForeground(Color.red); |
| fStatusLine.setText(status); |
| } |
| /** |
| * Starts the TestRunner |
| */ |
| public void start(String[] args) { |
| String suiteName= processArguments(args); |
| fFrame= createUI(suiteName); |
| fFrame.setLocation(200, 200); |
| fFrame.setVisible(true); |
| |
| if (suiteName != null) { |
| setSuiteName(suiteName); |
| runSuite(); |
| } |
| } |
| |
| public void startTest(Test test) { |
| showInfo("Running: "+test); |
| } |
| } |