001    package org.junit.runner;
002    
003    import org.junit.runner.notification.Failure;
004    import org.junit.runner.notification.RunListener;
005    
006    import java.io.Serializable;
007    import java.util.List;
008    import java.util.concurrent.CopyOnWriteArrayList;
009    import java.util.concurrent.atomic.AtomicInteger;
010    import java.util.concurrent.atomic.AtomicLong;
011    
012    /**
013     * A <code>Result</code> collects and summarizes information from running multiple tests.
014     * All tests are counted -- additional information is collected from tests that fail.
015     *
016     * @since 4.0
017     */
018    public class Result implements Serializable {
019        private static final long serialVersionUID = 2L;
020        private final AtomicInteger count = new AtomicInteger();
021        private final AtomicInteger ignoreCount = new AtomicInteger();
022        private final CopyOnWriteArrayList<Failure> failures = new CopyOnWriteArrayList<Failure>();
023        private final AtomicLong runTime = new AtomicLong();
024        private final AtomicLong startTime = new AtomicLong();
025    
026        /**
027         * @return the number of tests run
028         */
029        public int getRunCount() {
030            return count.get();
031        }
032    
033        /**
034         * @return the number of tests that failed during the run
035         */
036        public int getFailureCount() {
037            return failures.size();
038        }
039    
040        /**
041         * @return the number of milliseconds it took to run the entire suite to run
042         */
043        public long getRunTime() {
044            return runTime.get();
045        }
046    
047        /**
048         * @return the {@link Failure}s describing tests that failed and the problems they encountered
049         */
050        public List<Failure> getFailures() {
051            return failures;
052        }
053    
054        /**
055         * @return the number of tests ignored during the run
056         */
057        public int getIgnoreCount() {
058            return ignoreCount.get();
059        }
060    
061        /**
062         * @return <code>true</code> if all tests succeeded
063         */
064        public boolean wasSuccessful() {
065            return getFailureCount() == 0;
066        }
067    
068        @RunListener.ThreadSafe
069        private class Listener extends RunListener {
070            @Override
071            public void testRunStarted(Description description) throws Exception {
072                startTime.set(System.currentTimeMillis());
073            }
074    
075            @Override
076            public void testRunFinished(Result result) throws Exception {
077                long endTime = System.currentTimeMillis();
078                runTime.addAndGet(endTime - startTime.get());
079            }
080    
081            @Override
082            public void testFinished(Description description) throws Exception {
083                count.getAndIncrement();
084            }
085    
086            @Override
087            public void testFailure(Failure failure) throws Exception {
088                failures.add(failure);
089            }
090    
091            @Override
092            public void testIgnored(Description description) throws Exception {
093                ignoreCount.getAndIncrement();
094            }
095    
096            @Override
097            public void testAssumptionFailure(Failure failure) {
098                // do nothing: same as passing (for 4.5; may change in 4.6)
099            }
100        }
101    
102        /**
103         * Internal use only.
104         */
105        public RunListener createListener() {
106            return new Listener();
107        }
108    }