
org.glassfish.pfl.test.TestBase Maven / Gradle / Ivy
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2011-2011 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package org.glassfish.pfl.test;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set ;
import java.util.HashSet ;
import java.lang.reflect.Method ;
import java.util.Arrays;
import java.util.Collection;
import org.glassfish.pfl.basic.tools.argparser.DefaultValue;
import org.glassfish.pfl.basic.tools.argparser.Help;
import org.glassfish.pfl.basic.tools.argparser.Separator;
import org.glassfish.pfl.basic.tools.argparser.ArgParser;
/** A VERY quick-and-dirty test framework.
*
* @author ken
*/
public class TestBase {
private final List testMethods ;
private final List currentResults ;
// private final List currentNotes ;
private final Arguments argvals ;
private final Set includes ;
private final Set excludes ;
private final List preMethods ;
private final List postMethods ;
private String current ;
private Set pass = new HashSet() ;
private Set fail = new HashSet() ;
private Set skip = new HashSet() ;
private final Object testObject ;
JUnitReportHelper reportHelper ;
private interface Arguments {
@DefaultValue( "false" )
@Help( "Control debugging mode")
boolean debug() ;
@DefaultValue( "false" )
@Help( "Displays the valid test case identifiers" )
boolean cases() ;
@DefaultValue( "" )
@Help( "A list of test cases to include: includes everything if empty" )
@Separator( "," )
List include() ;
@DefaultValue( "" )
@Help( "A list of test cases to excelude: include everything if empty" )
@Separator( "," )
List exclude() ;
@DefaultValue( "true" )
@Help( "If true, generate a JUnit report for the tests")
boolean generateJunitReport() ;
}
private void execute( Collection methods )
throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException {
for (Method m : methods) {
m.invoke( this ) ;
}
}
public TestBase( String[] args ) {
this( args, null ) ;
}
public TestBase(String[] args, Class> parserInterface) {
this( args, parserInterface, null ) ;
}
public TestBase(String[] args, Class> parserInterface, Object testObject ) {
reportHelper = new JUnitReportHelper( this.getClass().getName() );
testMethods = new ArrayList() ;
preMethods = new ArrayList() ;
postMethods = new ArrayList() ;
this.testObject = (testObject == null)
? this
: testObject ;
final Class> cls = (testObject == null)
? this.getClass()
: testObject.getClass() ;
for (Method m : cls.getMethods()) {
if (m.getDeclaringClass().equals( TestBase.class )
&& !this.getClass().equals( TestBase.class )) {
// Skip test methods defined on this class for self test
// unless we are actually running the self test.
continue ;
}
TestCase anno = m.getAnnotation( TestCase.class ) ;
if (anno != null) {
if (m.getParameterTypes().length == 0) {
if (m.getReturnType().equals( void.class )) {
testMethods.add( m ) ;
} else {
msg( "Method " + m + " is annotated @Test, "
+ "but has a non-void return type").nl() ;
}
} else {
msg( "Method " + m + " is annotated @Test, "
+ "but has parameters").nl() ;
}
}
Pre pre = m.getAnnotation( Pre.class ) ;
if (pre != null) {
preMethods.add( m ) ;
}
Post post = m.getAnnotation( Post.class ) ;
if (post != null) {
postMethods.add( m ) ;
}
}
Class>[] interfaces = (parserInterface == null)
? new Class>[]{ Arguments.class }
: new Class>[]{ Arguments.class, parserInterface } ;
ArgParser parser = new ArgParser( Arrays.asList(interfaces)) ;
argvals = (Arguments)parser.parse( args ) ;
if (argvals.debug()) {
msg( "Arguments are:\n" + argvals ).nl() ;
}
if (argvals.include().isEmpty()) {
includes = new HashSet() ;
for (Method m : testMethods) {
includes.add( getTestId( m ) ) ;
}
} else {
List incs = argvals.include() ;
includes = new HashSet( incs ) ;
}
excludes = new HashSet( argvals.exclude() ) ;
if (argvals.cases()) {
msg( "Valid test case identifiers are:" ).nl() ;
for (Method m : testMethods) {
msg( " " + getTestId( m ) ).nl() ;
}
}
currentResults = new ArrayList() ;
// currentNotes = new ArrayList() ;
}
public T getArguments( Class cls ) {
return cls.cast( argvals ) ;
}
private TestBase msg( String str ) {
System.out.print( str ) ;
return this ;
}
private TestBase nl() {
System.out.println() ;
return this ;
}
private String getTestId( Method m ) {
TestCase anno = m.getAnnotation( TestCase.class ) ;
if (!anno.value().equals("")) {
return anno.value() ;
}
String mname = m.getName() ;
if (mname.startsWith( "test" )) {
return mname.substring( 4 ) ;
} else {
return mname ;
}
}
private void display( String title, List strs ) {
if (!strs.isEmpty()) {
msg( title + ":" ).nl() ;
for (String str : strs ) {
msg( "\t" + str ).nl() ;
}
}
}
private String getMessage( List strs ) {
StringBuilder sb = new StringBuilder() ;
for (String str : strs ) {
if (sb.length() != 0) {
sb.append( '\n' ) ;
}
sb.append(str) ;
}
return sb.toString() ;
}
public int run() {
for (Method m : testMethods) {
currentResults.clear() ;
// currentNotes.clear() ;
current = getTestId( m ) ;
if (includes.contains(current) && !excludes.contains(current)) {
reportHelper.start( current ) ;
msg( "Test " + current + ": " ).nl() ;
msg( " Notes:" ).nl() ;
long start = System.currentTimeMillis() ;
long duration = 0 ;
try {
execute( preMethods ) ;
m.invoke( testObject ) ;
} catch (Exception exc) {
fail( "Caught exception : " + exc ) ;
exc.printStackTrace();
} finally {
try {
execute(postMethods);
} catch (Exception exc) {
fail( "Exception in post methods : " + exc ) ;
exc.printStackTrace();
}
duration = System.currentTimeMillis() - start ;
}
if (currentResults.isEmpty()) {
reportHelper.pass( duration ) ;
pass.add( current ) ;
msg( "Test " + current + " PASSED." ).nl() ;
} else {
reportHelper.fail( getMessage( currentResults ),
duration ) ;
fail.add( current ) ;
msg( "Test " + current + " FAILED." ).nl() ;
}
reportHelper.done() ;
// display( " Notes", currentNotes ) ;
display( " Results", currentResults ) ;
} else {
msg( "Test " + current + " SKIPPED" ).nl() ;
skip.add( current ) ;
}
}
msg( "-------------------------------------------------").nl() ;
msg( "Results:" ).nl() ;
msg( "-------------------------------------------------").nl() ;
msg( "\tFAILED:").nl() ; displaySet( fail ) ;
msg( "\tSKIPPED:").nl() ; displaySet( skip ) ;
msg( "\tPASSED:").nl() ; displaySet( pass ) ;
nl() ;
msg( pass.size() + " test(s) passed; "
+ fail.size() + " test(s) failed; "
+ skip.size() + " test(s) skipped." ).nl() ;
msg( "-------------------------------------------------").nl() ;
return fail.size() ;
}
private void displaySet( Set set ) {
for (String str : set ) {
msg( "\t\t" ).msg( str ).nl() ;
}
}
public void fail( String failMessage ) {
check( false, failMessage ) ;
}
public void check( boolean result, String failMessage ) {
if (!result) {
currentResults.add( failMessage ) ;
}
}
public void note( String msg ) {
// currentNotes.add( msg ) ;
msg( "\t" + msg ).nl() ;
}
@TestCase
public void testSimple() {}
@TestCase
public void testGood( ) {
note( "this is a good test" ) ;
note( "A second note") ;
}
@TestCase( "Bad" )
public void badTest() {
note( "this is a bad test" ) ;
fail( "this test failed once" ) ;
fail( "this test failed twice" ) ;
}
@TestCase
public void exception() {
throw new RuntimeException( "This test throws an exception") ;
}
@TestCase
public boolean badReturnType() {
return true ;
}
@TestCase
public void hasParameters( String name ) {
}
public static void main( String[] args ) {
TestBase base = new TestBase( args ) ;
base.run() ;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy