TestRunner.java revision 3573:c4a18ee691c4
11541Srgrimes/* 21541Srgrimes * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 31541Srgrimes * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 41541Srgrimes * 51541Srgrimes * This code is free software; you can redistribute it and/or modify it 61541Srgrimes * under the terms of the GNU General Public License version 2 only, as 71541Srgrimes * published by the Free Software Foundation. 81541Srgrimes * 91541Srgrimes * This code is distributed in the hope that it will be useful, but WITHOUT 101541Srgrimes * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 111541Srgrimes * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 121541Srgrimes * version 2 for more details (a copy is included in the LICENSE file that 131541Srgrimes * accompanied this code). 141541Srgrimes * 151541Srgrimes * You should have received a copy of the GNU General Public License version 161541Srgrimes * 2 along with this work; if not, write to the Free Software Foundation, 171541Srgrimes * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 181541Srgrimes * 191541Srgrimes * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 201541Srgrimes * or visit www.oracle.com if you need additional information or have any 211541Srgrimes * questions. 221541Srgrimes */ 231541Srgrimes 241541Srgrimespackage toolbox; 251541Srgrimes 261541Srgrimesimport java.io.PrintStream; 271541Srgrimesimport java.lang.annotation.Annotation; 281541Srgrimesimport java.lang.annotation.Retention; 291541Srgrimesimport java.lang.annotation.RetentionPolicy; 301541Srgrimesimport java.lang.reflect.InvocationTargetException; 311541Srgrimesimport java.lang.reflect.Method; 321541Srgrimesimport java.util.function.Function; 331541Srgrimes 341541Srgrimes/** 351541Srgrimes * Utility class to manage and execute sub-tests within a test. 361541Srgrimes * 371541Srgrimes * This class does the following: 3814476Shsu * <ul> 3950477Speter * <li> invokes those test methods annotated with @Test 401541Srgrimes * <li> keeps track of successful and failed tests 411541Srgrimes * <li> throws an Exception if any test fails. 4260041Sphk * <li> provides a test summary at the end of the run. 4360041Sphk * </ul> 4415493Sbde 451541Srgrimes * Tests must extend this class, annotate the test methods 461541Srgrimes * with @Test and call one of the runTests method. 4759840Sphk */ 486549Sbdepublic abstract class TestRunner { 496549Sbde /** Marker annotation for test cases. */ 506549Sbde @Retention(RetentionPolicy.RUNTIME) 516549Sbde public @interface Test { } 5259840Sphk 536549Sbde int testCount = 0; 546549Sbde int errorCount = 0; 556549Sbde 566549Sbde public String testName = null; 576549Sbde 586549Sbde protected PrintStream out; 596549Sbde 601541Srgrimes /** 6158934Sphk * Constructs the Object. 6258926Sphk * @param out the PrintStream to print output to. 6358926Sphk */ 6458934Sphk public TestRunner(PrintStream out) { 6558934Sphk this.out = out; 6658926Sphk } 6758942Sphk 6858942Sphk /** 6958942Sphk * Invoke all methods annotated with @Test. 7058934Sphk * @throws java.lang.Exception if any errors occur 7158934Sphk */ 7258934Sphk protected void runTests() throws Exception { 7358934Sphk runTests(f -> new Object[0]); 7459840Sphk } 7558934Sphk 7658934Sphk /** 7758934Sphk * Invoke all methods annotated with @Test. 7858934Sphk * @param f a lambda expression to specify arguments for the test method 7960938Sjake * @throws java.lang.Exception if any errors occur 8058934Sphk */ 8158934Sphk protected void runTests(Function<Method, Object[]> f) throws Exception { 8258934Sphk for (Method m : getClass().getDeclaredMethods()) { 8358934Sphk Annotation a = m.getAnnotation(Test.class); 8458926Sphk if (a != null) { 8558926Sphk testName = m.getName(); 8658345Sphk try { 8758345Sphk testCount++; 8858345Sphk out.println("test: " + testName); 8958942Sphk m.invoke(this, f.apply(m)); 9058345Sphk } catch (InvocationTargetException e) { 9160041Sphk errorCount++; 9260041Sphk Throwable cause = e.getCause(); 9360041Sphk out.println("Exception: " + e.getCause()); 9459915Sphk cause.printStackTrace(out); 9559915Sphk } 9658934Sphk out.println(); 9755205Speter } 9848225Smckusick } 9960041Sphk 10060041Sphk if (testCount == 0) { 10148225Smckusick throw new Error("no tests found"); 10260041Sphk } 10360041Sphk 10448225Smckusick StringBuilder summary = new StringBuilder(); 10548273Speter if (testCount != 1) { 10658942Sphk summary.append(testCount).append(" tests"); 10760938Sjake } 10858942Sphk if (errorCount > 0) { 10958942Sphk if (summary.length() > 0) { 11058942Sphk summary.append(", "); 11158942Sphk } 11258942Sphk summary.append(errorCount).append(" errors"); 11358942Sphk } 11458942Sphk out.println(summary); 11558942Sphk if (errorCount > 0) { 11658942Sphk throw new Exception(errorCount + " errors found"); 11758942Sphk } 11858942Sphk } 11939238Sgibbs 12029683Sgibbs protected void error(String message) { 12158942Sphk out.println("Error: " + message); 12258942Sphk errorCount++; 12358942Sphk } 12458942Sphk} 12558942Sphk