multitest.java.svn-base

来自「cqME :java framework for TCK test.」· SVN-BASE 代码 · 共 478 行

SVN-BASE
478
字号
/* * $Id$ * * Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. * */package com.sun.tck.cldc.lib;import java.io.PrintStream;import java.util.Vector;/** * Base class for tests with multiple sub test cases. * This base class implements the standard com.sun.tck.cldc.lib.Test  * features so that you can provide the additional test cases with only * a little concern about the boilerplate needed to execute individual   * test case methods, namely, you need to update the runTestCases() method * to add check and invocation statement. * MultiTest is designed as a base class used during development  * of new test classes.   * * <P>You must add individual test case methods to your derived test class * to create a useful test class. Each test case method must take no  * arguments.  If you need to pass an argument into a test method, you should  * design a wrapper test case to calculate the argument values and then call  * the test method with the correct arguments.  The test case methods must  * implement this interface:  * <BLOCKQUOTE> * <STRONG><CODE>public Status methodName( )</CODE></STRONG> * </BLOCKQUOTE> * * <P>Possible future additions may include * <UL> * <LI>Method to assert a boolean expression and return a Status  * <LI>Method to assert string equality and return a Status * <LI>Method to parse argv for known and specified arrays from JavaTest * <LI>Methods to be called just before the test and just after the test  *     is executed. *</UL> * * @see com.sun.tck.cldc.lib.Test */public abstract class MultiTest implements Test {    public static class SetupException extends Exception {	/**	 * Construct a new SetupException object that signals failure	 * with a corresponding message.	 * 	 * @param s the string containing a comment	 */	public SetupException(String s) {	    super(s);	}		/**	 * Creates SetupException object which indicates that 	 * this test is not applicable. The cases when it is needed 	 * are rare, so please think twice whether you really need it.	 * 	 * @param msg the string containing a comment         * @return SetupException object with <CODE>msg</CODE> comment.         *         <CODE>isPassed()</CODE> method for this object should         *         return true.	 */	public static SetupException notApplicable(String msg) {	    SetupException e = new SetupException("Test not applicable: " + msg);	    e.passed = true;	    return e;	}		/**	 * Determines whether this SetupException signals failure or not.	 *          * @return true if this exception was created by         *         <CODE>notApplicable()</CODE> method, false otherwise.	 */	public boolean isPassed() {	    return passed;	    	}	/**	 * Indicate whether this exception was the result of calling         * <CODE>notApplicable</CODE> method.	 * @serial	 */	private boolean passed = false;    }    /**      * Run the test contained in this object.     *     * <P>This method calls the decodeAllArgs method  with the value of argv to     * decode command line arguments, and then calls the init method to perform     * any other initialization.     * Then it calls runTestCases to run actual tests.     * <P>To add parsing for new arguments you need to override the decodeArg     * method.     * The init method may also be overridden in case you need additional       * initialization.     *     *     * @see #decodeAllArgs     * @see #init     * @see #runTestCases     *     * @param argv Execute arguments passed in from either the      *             command line or the execution harness.     * @param log Output stream for general messages from the tests.     *            Is assigned to this.log.     * @param ref Output stream for reference output from the tests.     *            Is assigned to this.ref.     * @return Overall status of running all of the test cases.     */    public Status run(String[] argv, PrintStream log, PrintStream ref) {        // assign log and reference output streams        this.ref = ref;        this.log = log;	// perform initialization	Status initStatus = init(argv);	if (testNotApplicable 		|| (initStatus != null && initStatus.getType() != Status.PASSED)) {	    return initStatus;	}	// main work	try {	    runTestCases();            return getStatus(); 	}	catch (Throwable t) {	    return Status.failed("Unexpected Throwable (in " 		    + lastTestCase + "): " + t); // since we don't have printStackTrace..	}    }    /**      * Run the tests contained in this object after initialization.     *     */    protected abstract void runTestCases();    /**      * Checks whether the particular test case should be executed.     * Should be called for each test case from runTestCases().     *     * @param testCase test case name, which should be checked if it is     *                 selected or not.     * @return true if all test cases are selected, or test case list contains     *         <CODE>testCase</CODE> and exclude list is empty or does not     *         contains <CODE>testCase</CODE> false otherwise.     */    protected boolean isSelected(String testCase) {	if ((testAll || testCases.contains(testCase)) &&                (excludeTestCases == null ||                ! excludeTestCases.contains(testCase))) {	    lastTestCase = testCase;	    return true;	} else {	    return false;	}    }    /**      * Add another test into the set for consideration.     *     * @param status The outcome of this test case     */    protected void addStatus(Status status) {	log.println(lastTestCase + ": " + status);	++iTests;		if (status != null) {	    switch (status.getType()) {	    case Status.PASSED:		++iPassed;		return;			    case Status.FAILED:		if (iFail == 0 && iBad == 0) {		    firstTest = lastTestCase;		}		++iFail;		return;			    default:	    }	}	if (iBad == 0) {	    firstTest = lastTestCase;	}	++iBad;    }    /**     * Get the aggregate outcome of all the outcomes passed to "add".     *     * @return Status object with passed or failed status depending on test     *         run results. If there were bad or failed tests     *         <CODE>Status.failed()</CODE> is returned, if all tests passed     *         <CODE>Status.passed()</CODE> is returned.     */    public Status getStatus() {	log.flush();	String summary = "tests: " + iTests;	if (iPassed > 0)	    summary += "; passed: " + iPassed;	if (iFail > 0)	    summary += "; failed: " + iFail;	if (iBad > 0)	    summary += "; bad status: " + iBad;	/* Return a status object that reflects the aggregate of the various test cases. */        /* At least one test case was bad */	if (iBad > 0) {	    return Status.failed(summary + "; first bad test case found: " + firstTest);	}        /* At least one test case failed */	else if (iFail > 0) {	    return Status.failed(summary + "; first test case failure: " + firstTest);	}	/* All test cases passed */	else {	    return Status.passed(summary);	}    }    /**      * Parses the arguments passed to the test.     *     * This method embodies the main for loop for all of the      * execute arguments. It calls <CODE>decodeArg</CODE>      * for successive arguments in the argv array.     *     * @param argv execute arguments from the test harness or from the     *             command line.     *     * @exception SetupException raised when an invalid parameter is passed,      * or another error occurred.     *     * @see #decodeArg      */    protected final void decodeAllArgs( String argv[] ) throws SetupException {	/* Please note, we do not increment i	 * that happens when decodeArg returns the 	 * number of array elements consumed	 */	for (int i = 0 ; i < argv.length; ) {	    int elementsConsumed = decodeArg(argv, i);	    if (elementsConsumed == 0 ) {		// The argument was not recognized.		throw new SetupException("Could not recognize argument: " + argv[i]);	    }	    i += elementsConsumed;	}    }    /**      * Decode the next argument in the argument array.     * May be overridden to parse additional execute arguments.       *     * The default behavior of decodeArg( String argv[], int index )     * is to parse test case IDs starting from <CODE>index</CODE>      * from execute arguments <CODE>argv</CODE>.     * <P>The derived class may override this method to provide      * parsing of additional arguments. However, it is recommended     * for this method to return super.decodeArg() if it      * does not recognize the argument. So it has to parse     * specific for derived class arguments only.     *     * <P>The required syntax for using this method is the execute     * argument <EM>-TestCaseID</EM> followed by a space and then a     * space delimited list of one or more test case method names.     * Using the test case method name <STRONG>ALL</STRONG> specifies     * that all of the individual test case methods that match the     * required test method signature should be executed.  The method     * getAllTestCases() is called to gather the list of all methods     * that match the test method signature.     *     * <P>Once the execute argument <EM>-TestCaseID</EM> is found, all      * subsequent execute arguments will be treated as test case method      * names until either the execute argument array is exhausted or      * an execute argument that begins with <EM>-</EM> is found.     *     * @param argv execute arguments from the test harness or from the      *             command line     * @param index current index into argv.     *     * @exception SetupException raised when an invalid argument is passed,      * or another error occurred.     *     * @return number of arguments that were processed.     *     * @see #decodeAllArgs      */    protected int decodeArg( String argv[], int index ) throws SetupException {	if (argv[index].equals("-exclude")) {            excludeTestCases = new Vector(1,1);	    split(argv[index + 1], excludeTestCases);	    return 2;	}	    	if (!argv[index].equals("-TestCaseID")) 	    return 0;	/* consume elements until it is done	 * creating the array of test case id's	 * return the number of elements consumed	 */	int i = index + 1;	if (i < argv.length && argv[i].equals("ALL")) {	    testAll = true;	    return 2;	}        testCases = new Vector(1,1);	while (i < argv.length && ! argv[i].startsWith("-")) {	    testCases.addElement(argv[i++]);	}	if (testCases.isEmpty())	    throw new SetupException("No test case(s) specified");	return i - index;    }    private void split(String s, Vector v) {	int start = 0;	for (int i = s.indexOf(','); i != -1; i = s.indexOf(',', start)) {	    v.addElement(s.substring(start, i));	    start = i + 1;	}	if (start != s.length())	    v.addElement(s.substring(start));    }    /**      * A setup method called after argument decoding is complete,     * and before the test cases are executed. By default, it does     * nothing; it may be overridden to provide additional behavior.      *     * @throws SetupException if processing should not continue.     * This may be due to some inconsistency in the arguments,     * or if it is determined the test should not execute for     * some reason.     */    protected void init() throws SetupException { }    /**      *      * Initialize the test from the given arguments.     *     * @param argv a string array of test arguments, that should be processed by     *        <CODE>decodeAllArgs()</CODE>     *     * @return null if no SetupExceptions were thrown during initialization,      *         Status.passed if SetupException was thrown because test case is     *         not applicable, Status.failed if some problem occurred during     *         initialization.     */    private Status init(String[] argv) {      	/* Decode test arguments and delegate all other	 * test setup to the init method provided by	 * derived classes	 */	try {	    decodeAllArgs(argv);	    if (testCases == null) {		/* Assuming that all test cases should be run 		 * if no "-TestCaseID" argument is specified.		 */		testAll = true;	    }	    init();	    return null;	}	catch (SetupException e) {	    testNotApplicable = true;	    return (e.isPassed() 			? Status.passed(e.getMessage()) 		    	: Status.failed(e.getMessage()) );	}    }    /**      * Output to be logged to result file.       *     * Output to this PrintStream is not used during golden file comparison.     * Also used to output the Status from each individual test case.     */    protected PrintStream log;    /**      * Output that can be used as reference.     *     * Output to this PrintStream is used during golden file comparison.     */    protected PrintStream ref;    /**      * The list of test case methods to be executed.     */    private Vector testCases = null;    /**      * Determines whether we should run all tests     */    private boolean testAll = false;    /**     * The set of test cases to be excluded.     */    private Vector excludeTestCases = null;    /**     * may be set if SetupException is thrown during decodeArgs() or init     */    private boolean testNotApplicable = false;    private String lastTestCase;    // These values accumulate the aggregate outcome, without requiring    // the individual outcomes be stored    private int iTests = 0;    private int iPassed = 0;    private int iFail = 0;    private int iBad = 0;    private String firstTest = "";}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?