tk.elevenk.restfulrobot.testcase.TestCase.java Source code

Java tutorial

Introduction

Here is the source code for tk.elevenk.restfulrobot.testcase.TestCase.java

Source

/* 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;
    }

}