📄 anttestrunner.java
字号:
package momeunit.runner;import java.io.PrintStream;import java.util.Timer;import java.util.TimerTask;import java.util.Vector;import javax.microedition.lcdui.Command;import javax.microedition.midlet.MIDletStateChangeException;import mome.MoXMIDlet;import mome.ext.Utils;import momeunit.framework.AssertionFailedError;import momeunit.framework.Test;import momeunit.framework.TestCase;import momeunit.framework.TestListener;import momeunit.framework.TestResult;import momeunit.framework.TestSuite;/** * Test runner that generates test events to be processed by formatters of * MoMEUnit Ant Integration package. It creates test events of tests run, sends * them to recipient via {@link System#err} output stream and exits. * <p> * <strong>Note:</strong> It is built upon <strong><a * href="http://momelib.sourceforge.net" target="_blank" >MoMELib</a></strong> * library. This is a J2ME library that offers possibilities to execute commands * in separate from AMS (Application Management Software) callback thread, issue * commands programmatically, associate key (game action) or sequence of keys * and/or game actions with command, use any complimentary argument with command * and much more. If you are interested, visit <a * href="http://momelib.sourceforge.net" target="_blank" >MoMELib Home Page</a> * </p> * * @author Sergio Morozov * @version 1.1.2 */public class AntTestRunner extends MoXMIDlet implements TestListener{ /** * Item separator string. * * @since 1.1 */ public static final String ITEM_SEPARATOR = ","; /** * Test suite description property prefix. * * @since 1.1 */ public static final String TEST_PROPERTY_PREFIX = "MoMEUnit-Test-"; /** * Global test suite description property name. * * @since 1.1 */ public static final String TESTS_PROPERTY = "MoMEUnit-Tests"; /** * Global test suite name property name. * * @since 1.1.1 */ public static final String TESTSNAME_PROPERTY = "MoMEUnit-TestsName"; /** * Global test suite default name. * * @since 1.1 */ public static final String DEFAULT_SUITE_NAME = "Tests"; /** * Timeout property name. * * @since 1.1.1 */ public static final String TIMEOUT_PROPERTY = "MoMEUnit-TimeOut"; /** * HaltOnError property name. * * @since 1.1.2 */ public static final String HALTONERROR_PROPERTY = "MoMEUnit-HaltOnError"; /** * HaltOnFailure property name. * * @since 1.1.2 */ public static final String HALTONFAILURE_PROPERTY = "MoMEUnit-HaltOnFailure"; /** * Exit command. */ private static final Command EXIT = new Command("Exit", "Exit Runner", Command.EXIT, 1); /** * Test command. */ private static final Command TEST = new Command("Run", "Run Tests", Command.SCREEN, 32); /** * Start test event keyword. */ private static final String TEST_START_KEY = "TEST_START:"; /** * End test event keyword. */ private static final String TEST_END_KEY = "TEST_END:"; /** * Fail test event keyword. */ private static final String TEST_FAIL_KEY = "TEST_FAIL:"; /** * Stack trace indicator. */ private static final String STACK_TRACE_INDICATOR = "<<!!STACK_TRACE!!>>"; /** * Error test event keyword. */ private static final String TEST_ERROR_KEY = "TEST_ERROR:"; /** * Test event indicator. */ private static final String TESTEVENT_INDICATOR = "<<!!MOMEUNIT_TESTEVENT!!>>"; /** * Test event here-document indicator. * * @since 1.1 */ public static final String HEREDOCUMENT_TESTEVENT_INDICATOR = "<<<-" + TESTEVENT_INDICATOR; private PrintStream out = System.err; /** * Global test suite. */ private TestSuite suite = null; private TestResult result = null; private Timer timer = null; private TimerTask timeoutTask = null; private String timeoutProp = null; private long timeout = -1; private Test lastTest = null; private boolean haltOnError = false; private boolean haltOnFailure = false; /** * Creates {@link TestResult} instance with AntTestRunner as * {@link TestListener}. * * @return the created {@link TestResult} instance. */ private TestResult createTestResult() { this.result = new TestResult(); this.result.setListener(this); return this.result; } /** * Generates {@link TestSuite} of given name that contains tests specified as * string. Tests in the list can be afully specified class name as argument to * {@link Class#forName(String)} or name of test suite as specified by * respective configuration property. See * {@link momeunit.runner#config package description} for more details. * * @param name * name of test suite to generate. * @param tests * list of tests that constitute test suite. * @param usedTests * test already added an this branch. Used to detect cycles. * @return TestSuite generated. */ private TestSuite generateTestSuite(String name, String tests, Vector usedTests) { TestSuite res = new TestSuite(name); if (tests != null) { char[] cTests = tests.toCharArray(); int end = cTests.length; while (--end >= 0 && Utils.isTestSeparator(cTests[end])); for (int start = end; start > 0; end = start) { for (; start >= 0 && !Utils.isTestSeparator(cTests[start]); start--); String test = String.valueOf(cTests, start + 1, end - start); String testTests = this.getAppProperty(TEST_PROPERTY_PREFIX + test); if (testTests == null) res.addTest(test); else { if (usedTests == null) usedTests = new Vector(); if (usedTests.contains(test)) throw new IllegalStateException( "Test cycle detected: \"" + test + "\""); usedTests.addElement(test); res.addTest(this.generateTestSuite(test, testTests, usedTests)); usedTests.removeElement(test); } while (--start >= 0 && Utils.isTestSeparator(cTests[start])); } } return res; } /** * Generates global test suite. * * @see mome.MoXMIDlet#initApp() */ protected void initApp() throws MIDletStateChangeException { super.initApp(); String prop = this.getAppProperty(TESTSNAME_PROPERTY); if (prop == null) prop = DEFAULT_SUITE_NAME; this.suite = this.generateTestSuite(prop, this .getAppProperty(TESTS_PROPERTY), null); setTimeOut(); this.haltOnError = Utils.parseBoolean(getAppProperty(HALTONERROR_PROPERTY)); this.haltOnFailure = Utils.parseBoolean(getAppProperty(HALTONFAILURE_PROPERTY)); } protected void setTimeOut() { this.timeoutProp = getAppProperty(TIMEOUT_PROPERTY); if (this.timeoutProp != null) { this.timeout = Utils.parseTimeInterval(this.timeoutProp); if (this.timeout > 0) { this.timer = new Timer(); this.timeoutTask = null; } else System.err.println("Invalid value of property \"" + TIMEOUT_PROPERTY + "\" specified " + this.timeoutProp + "\nExecuting without any timeout checking."); } } /** * Starts tests run, creates and sends test events and then exits. * * @see mome.MoXMIDlet#startApp() */ protected void startApp() throws MIDletStateChangeException { super.startApp(); this.pushCommand(TEST, null); this.pushCommand(EXIT, null); } /* * (non-Javadoc) * * @see mome.MoXMIDlet#xCommandAction(java.lang.Object, java.lang.Object) */ public void xCommandAction(Object cmd, Object src) { if (cmd == TEST) { if (this.timer != null) this.timer.schedule( this.timeoutTask = new TimerTask() { public void run() { if (Character.isDigit(timeoutProp .charAt(timeoutProp.length() - 1))) timeoutProp = timeoutProp + "ms"; pushError(TEST_ERROR_KEY, lastTest, new Exception( "Tests execution timeouts after " + timeoutProp)); pushStartEnd(TEST_END_KEY, lastTest); timeoutTask = null; exit(); } }, this.timeout); this.suite.run(this.createTestResult()); if (this.timeoutTask != null) { this.timeoutTask.cancel(); this.timeoutTask = null; } } else if (cmd == EXIT) this.exit(); } /** * Sends error/failure event. * * @param key * error or failure test event keyword. * @param test * test that generates test event. * @param t * exception thrown by test. */ private void pushError(String key, Test test, Throwable t) { TestCase testCase = (TestCase) test; this.out.println(HEREDOCUMENT_TESTEVENT_INDICATOR + key + System.currentTimeMillis() + ITEM_SEPARATOR + testCase.getName() + ITEM_SEPARATOR + testCase.getClass().getName() + ITEM_SEPARATOR + t.getClass().getName() + ITEM_SEPARATOR + t.getMessage()); this.out.println(STACK_TRACE_INDICATOR); t.printStackTrace(); this.out.println(TESTEVENT_INDICATOR); } /** * Sends start/end test event. * * @param key * start or end test event keyword. * @param test * test that generates test event. */ private void pushStartEnd(String key, Test test) { TestCase testCase = (TestCase) test; this.out.println(HEREDOCUMENT_TESTEVENT_INDICATOR + key + System.currentTimeMillis() + ITEM_SEPARATOR + testCase.getName() + ITEM_SEPARATOR + testCase.getClass().getName() + TESTEVENT_INDICATOR); } /** * Sends error test event. * * @param test * test that threw the error. * @param t * exception thrown by test. * * @see momeunit.framework.TestListener#addError(momeunit.framework.Test, * java.lang.Throwable) */ public void addError(Test test, Throwable t) { this.pushError(TEST_ERROR_KEY, test, t); if (this.haltOnError || this.haltOnFailure) { pushStartEnd(TEST_END_KEY, test); exit(); } } /** * Sends failure test event. * * @param test * the failed test. * @param t * exception thrown by test. * * @see momeunit.framework.TestListener#addFailure(momeunit.framework.Test, * momeunit.framework.AssertionFailedError) */ public void addFailure(Test test, AssertionFailedError t) { this.pushError(TEST_FAIL_KEY, test, t); if (this.haltOnFailure) { pushStartEnd(TEST_END_KEY, test); exit(); } } /** * Sends end test event. * * @param test * test that ends. * * @see momeunit.framework.TestListener#endTest(momeunit.framework.Test) */ public void endTest(Test test) { this.pushStartEnd(TEST_END_KEY, test); } /** * Sends start test event. * * @param test * test that starts. * * @see momeunit.framework.TestListener#startTest(momeunit.framework.Test) */ public void startTest(Test test) { this.lastTest = test; this.pushStartEnd(TEST_START_KEY, test); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -