Java tutorial
/* This source code file is part of RESTfulRobot Copyright (C) 2014 John Krause (Eleven-K Software) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package tk.elevenk.restfulrobot.testcase; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.util.ArrayList; import javax.script.Bindings; import javax.script.ScriptContext; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; import org.apache.commons.lang3.exception.ExceptionUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import tk.elevenk.restfulrobot.RestfulRobot; import tk.elevenk.restfulrobot.request.Request; import tk.elevenk.restfulrobot.request.RequestData; import tk.elevenk.restfulrobot.response.IResponse; import tk.elevenk.restfulrobot.testresult.TestResult; import tk.elevenk.restfulrobot.testsuite.TestSuite; import tk.elevenk.restfulrobot.utility.NetworkUtility; public class TestCase { // ************************************************** // * STATIC CLASS VARIABLES // ************************************************** private static Logger logger = LogManager.getLogger(TestCase.class.getName()); // ************************************************** // * FIELDS // ************************************************** // Test Case Meta Data public String scriptFileName = null; public String testCategory = null; public String testType = null; public TestSuite testSuite; public String testProject = null; public String testPlan = null; public String testCaseID = null; public String testName = null; // Request/Response Data public Request request; public IResponse response; // private data private float runtime; private TestResult result; private ArrayList<Request> requests; private ArrayList<IResponse> responses; private boolean running; private Bindings bindings; private NetworkUtility connectionUtility; // ************************************************** // * CONSTRUCTOR // ************************************************** public TestCase(String file) { this.scriptFileName = file; if (!this.scriptFileName.endsWith(".js")) { this.scriptFileName += ".js"; } this.result = new TestResult(); this.requests = new ArrayList<Request>(); this.responses = new ArrayList<IResponse>(); this.running = false; this.connectionUtility = new NetworkUtility(); } // ************************************************** // * METHODS // **************************************************/ /** * Runs all actions in the test case * * @return * @throws Exception */ public void runTest(ScriptEngine _engine) { // check that the test is not already running if (!running) { // prepare bindings before running test this.bindings = _engine.getBindings(ScriptContext.ENGINE_SCOPE); // create empty response and request for bindings this.buildRequest(null); this.bindings.put("Response", this.response); // run the script runtime = System.nanoTime(); this.runScript(scriptFileName); runtime = System.nanoTime() - runtime; } } /** * Builds the request to be sent from the data currently in the test case. * This data should be set by the user in the test script */ private void buildRequest(RequestData data) { // use data in this test case to build request // the data is exposed to the scripter to allow // the scripter to set the data Request request = new Request(data); this.requests.add(request); this.request = request; this.responses.add(null); this.bindings.remove("Request"); this.bindings.put("Request", this.request); } public TestCase newRequest() { return newRequest(true); } public TestCase newRequest(boolean reusePreviousData) { if (reusePreviousData) { buildRequest(this.request.requestData); } else { buildRequest(null); } return this; } /** * Sends the request that was built by the user test script. If there are no * requests, one is built. */ public void sendRequest(int numRequests, boolean validateResponse) { for (int i = 0; i < numRequests; i++) { IResponse response = this.connectionUtility.makeRequest(testSuite.baseURL, requests.get(requests.size() - 1)); responses.set(requests.size() - 1, response); this.response = response; this.bindings.remove("Response"); this.bindings.put("Response", this.response); if (validateResponse) this.validateResponse(); this.newRequest(); } } public void sendRequest() { this.sendRequest(1, true); } public void sendRequest(boolean validateResponse) { this.sendRequest(1, validateResponse); } /** * Validates the last response using the validations given in the test * script * * @return Boolean of whether the validations passed or failed */ public boolean validateResponse() { boolean passed = false; // check all validations and catch any assertion errors try { this.responses.get(responses.size() - 1) .validate(this.requests.get(requests.size() - 1).requestData.validations); this.result.setDetails(TestResult.MESSAGE_PASSED); this.result.setResultType(TestResult.TYPE_PASS); passed = true; } catch (AssertionError e) { logger.error(e.getMessage()); this.result.setDetails(e.getMessage()); this.result.setResultType(TestResult.TYPE_FAILURE); } catch (Exception e) { logger.error(ExceptionUtils.getStackTrace(e)); this.result.setDetails(e.getMessage()); this.result.setResultType(TestResult.TYPE_ERROR); } return passed; } /** * Runs the given test script file * * @param fileName */ public void runScript(String fileName) { ScriptEngine engine = new ScriptEngineManager().getEngineByName("javascript"); engine.setBindings(bindings, ScriptContext.ENGINE_SCOPE); if (!fileName.endsWith(".js")) { fileName = fileName.concat(".js"); } FileReader scriptFile = null; // attempt to open the script file try { scriptFile = new FileReader(new File(RestfulRobot.SCRIPTS_PATH + fileName)); } catch (FileNotFoundException e) { logger.error(ExceptionUtils.getStackTrace(e)); result.setDetails(e.getMessage()); result.setResultType(TestResult.TYPE_ERROR); } // run the script try { logger.info("Running script " + fileName); engine.eval(scriptFile); } catch (ScriptException e) { logger.error(ExceptionUtils.getStackTrace(e)); result.setDetails(e.getMessage()); result.setResultType(TestResult.TYPE_ERROR); } // pull data from script try { this.testCaseID = (String) engine.get("testCaseID"); this.testCategory = (String) engine.get("testCategory"); this.testPlan = (String) engine.get("testPlan"); this.testProject = (String) engine.get("testProject"); this.testType = (String) engine.get("testType"); this.testName = (String) engine.get("testName"); } catch (Exception e) { // TODO make this try each parameter } logger.info("Finished running script"); } /** * Runs the given script file * * @param fileName */ public void include(String fileName) { this.runScript(fileName); } // ************************************************************** // GETTERS/SETTERS // ************************************************************** /** * * @return The type of this test case */ public String getTestType() { return this.testType; } /** * * @param _testType */ public void setTestType(String _testType) { this.testType = _testType; } /** * * @return The test suite associated with this test case */ public TestSuite getTestSuite() { return this.testSuite; } /** * * @param _testSuite */ public void setTestSuite(TestSuite _testSuite) { this.testSuite = _testSuite; } /** * * @return The TestLink test project associated with this test case */ public String getTestProject() { return testProject; } /** * * @param testProject */ public void setTestProject(String testProject) { this.testProject = testProject; } /** * * @return The TestLink test plan associated with this test case */ public String getTestPlan() { return testPlan; } /** * * @param testPlan */ public void setTestPlan(String testPlan) { this.testPlan = testPlan; } /** * * @return The category of this test case */ public String getTestCategory() { return testCategory; } /** * * @param testCategory */ public void setTestCategory(String testCategory) { this.testCategory = testCategory; } /** * * @return The TestLink test case ID associated with this test case */ public String getTestCaseID() { return testCaseID; } /** * * @param testCaseID */ public void setTestCaseID(String testCaseID) { this.testCaseID = testCaseID; } /** * * @return The runtime of this test case */ public float getRuntime() { return runtime; } /** * * @param runtime */ public void setRuntime(float runtime) { this.runtime = runtime; } public String getTestName() { return testName; } public void setTestName(String testName) { this.testName = testName; } public TestResult getResult() { return result; } public void setResult(TestResult result) { this.result = result; } }