001    package org.junit.runner;
002    
003    import junit.runner.Version;
004    import org.junit.internal.JUnitSystem;
005    import org.junit.internal.RealSystem;
006    import org.junit.internal.TextListener;
007    import org.junit.internal.runners.JUnit38ClassRunner;
008    import org.junit.runner.notification.RunListener;
009    import org.junit.runner.notification.RunNotifier;
010    
011    /**
012     * <code>JUnitCore</code> is a facade for running tests. It supports running JUnit 4 tests,
013     * JUnit 3.8.x tests, and mixtures. To run tests from the command line, run
014     * <code>java org.junit.runner.JUnitCore TestClass1 TestClass2 ...</code>.
015     * For one-shot test runs, use the static method {@link #runClasses(Class[])}.
016     * If you want to add special listeners,
017     * create an instance of {@link org.junit.runner.JUnitCore} first and use it to run the tests.
018     *
019     * @see org.junit.runner.Result
020     * @see org.junit.runner.notification.RunListener
021     * @see org.junit.runner.Request
022     * @since 4.0
023     */
024    public class JUnitCore {
025        private final RunNotifier notifier = new RunNotifier();
026    
027        /**
028         * Run the tests contained in the classes named in the <code>args</code>.
029         * If all tests run successfully, exit with a status of 0. Otherwise exit with a status of 1.
030         * Write feedback while tests are running and write
031         * stack traces for all failed tests after the tests all complete.
032         *
033         * @param args names of classes in which to find tests to run
034         */
035        public static void main(String... args) {
036            Result result = new JUnitCore().runMain(new RealSystem(), args);
037            System.exit(result.wasSuccessful() ? 0 : 1);
038        }
039    
040        /**
041         * Run the tests contained in <code>classes</code>. Write feedback while the tests
042         * are running and write stack traces for all failed tests after all tests complete. This is
043         * similar to {@link #main(String[])}, but intended to be used programmatically.
044         *
045         * @param classes Classes in which to find tests
046         * @return a {@link Result} describing the details of the test run and the failed tests.
047         */
048        public static Result runClasses(Class<?>... classes) {
049            return runClasses(defaultComputer(), classes);
050        }
051    
052        /**
053         * Run the tests contained in <code>classes</code>. Write feedback while the tests
054         * are running and write stack traces for all failed tests after all tests complete. This is
055         * similar to {@link #main(String[])}, but intended to be used programmatically.
056         *
057         * @param computer Helps construct Runners from classes
058         * @param classes  Classes in which to find tests
059         * @return a {@link Result} describing the details of the test run and the failed tests.
060         */
061        public static Result runClasses(Computer computer, Class<?>... classes) {
062            return new JUnitCore().run(computer, classes);
063        }
064    
065        /**
066         * @param system
067         * @param args from main()
068         */
069        Result runMain(JUnitSystem system, String... args) {
070            system.out().println("JUnit version " + Version.id());
071    
072            JUnitCommandLineParseResult jUnitCommandLineParseResult = JUnitCommandLineParseResult.parse(args);
073    
074            RunListener listener = new TextListener(system);
075            addListener(listener);
076    
077            return run(jUnitCommandLineParseResult.createRequest(defaultComputer()));
078        }
079    
080        /**
081         * @return the version number of this release
082         */
083        public String getVersion() {
084            return Version.id();
085        }
086    
087        /**
088         * Run all the tests in <code>classes</code>.
089         *
090         * @param classes the classes containing tests
091         * @return a {@link Result} describing the details of the test run and the failed tests.
092         */
093        public Result run(Class<?>... classes) {
094            return run(defaultComputer(), classes);
095        }
096    
097        /**
098         * Run all the tests in <code>classes</code>.
099         *
100         * @param computer Helps construct Runners from classes
101         * @param classes the classes containing tests
102         * @return a {@link Result} describing the details of the test run and the failed tests.
103         */
104        public Result run(Computer computer, Class<?>... classes) {
105            return run(Request.classes(computer, classes));
106        }
107    
108        /**
109         * Run all the tests contained in <code>request</code>.
110         *
111         * @param request the request describing tests
112         * @return a {@link Result} describing the details of the test run and the failed tests.
113         */
114        public Result run(Request request) {
115            return run(request.getRunner());
116        }
117    
118        /**
119         * Run all the tests contained in JUnit 3.8.x <code>test</code>. Here for backward compatibility.
120         *
121         * @param test the old-style test
122         * @return a {@link Result} describing the details of the test run and the failed tests.
123         */
124        public Result run(junit.framework.Test test) {
125            return run(new JUnit38ClassRunner(test));
126        }
127    
128        /**
129         * Do not use. Testing purposes only.
130         */
131        public Result run(Runner runner) {
132            Result result = new Result();
133            RunListener listener = result.createListener();
134            notifier.addFirstListener(listener);
135            try {
136                notifier.fireTestRunStarted(runner.getDescription());
137                runner.run(notifier);
138                notifier.fireTestRunFinished(result);
139            } finally {
140                removeListener(listener);
141            }
142            return result;
143        }
144    
145        /**
146         * Add a listener to be notified as the tests run.
147         *
148         * @param listener the listener to add
149         * @see org.junit.runner.notification.RunListener
150         */
151        public void addListener(RunListener listener) {
152            notifier.addListener(listener);
153        }
154    
155        /**
156         * Remove a listener.
157         *
158         * @param listener the listener to remove
159         */
160        public void removeListener(RunListener listener) {
161            notifier.removeListener(listener);
162        }
163    
164        static Computer defaultComputer() {
165            return new Computer();
166        }
167    }