All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.arpitos.framework.ScanTestSuite Maven / Gradle / Ivy

// Copyright <2018> 

// Permission is hereby granted, free of charge, to any person obtaining a copy of this software
// and associated documentation files (the "Software"), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package com.arpitos.framework;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.reflections.Reflections;
import org.reflections.scanners.MethodAnnotationsScanner;
import org.reflections.scanners.SubTypesScanner;
import org.reflections.scanners.TypeAnnotationsScanner;

import com.arpitos.annotation.AfterTest;
import com.arpitos.annotation.AfterTestsuite;
import com.arpitos.annotation.BeforeTest;
import com.arpitos.annotation.BeforeTestsuite;
import com.arpitos.annotation.KnownToFail;
import com.arpitos.annotation.TestCase;
import com.arpitos.annotation.TestPlan;
import com.arpitos.framework.infra.TestContext;
import com.arpitos.interfaces.TestExecutable;

/**
 * This class provides all utilities for reflection
 * 
 * 
 *
 */
public class ScanTestSuite {
	Reflections reflection;
	List testLabels = new ArrayList<>();
	List testObjWrapperList_All = new ArrayList<>();
	List testObjWrapperList_WithoutSkipped = new ArrayList<>();

	/**
	 * Default constructor. Scans all packages within provided package
	 * 
	 * @param packageName
	 *            Base package name
	 */
	public ScanTestSuite(String packageName) {
		scan(packageName);
	}

	/**
	 * Scans for Test cases within provided packageName
	 * 
	 * @param packageName
	 *            Base package name
	 */
	private void scan(String packageName) {

		List testLabels_withDuplicates = new ArrayList<>();
		reflection = new Reflections(packageName, new MethodAnnotationsScanner(), new TypeAnnotationsScanner(), new SubTypesScanner(false));

		for (Class cl : reflection.getTypesAnnotatedWith(TestCase.class)) {
			TestCase testcase = cl.getAnnotation(TestCase.class);
			TestPlan testplan = cl.getAnnotation(TestPlan.class);
			KnownToFail ktf = cl.getAnnotation(KnownToFail.class);

			// @formatter:off
			//			System.out.println("@Testcase = " + cl.getName()
			//			+ "\nskip : " + testcase.skip()
			//			+ "\nscenario : " + testcase.sequence()
			//			+ "\ndecription : " + testcase.label()
			//			);
			//			System.out.println("@Testcase = " + cl.getName()
			//			+ "\ndecription : " + testplan.decription()
			//			+ "\npreparedBy : " + testplan.preparedBy()
			//			+ "\npreparationDate : " + testplan.preparationDate()
			//			+ "\nreviewedBy : " + testplan.reviewedBy()
			//			+ "\nreviewDate : " + testplan.reviewDate()
			//			);
			// @formatter:on

			TestObjectWrapper testobj = new TestObjectWrapper(cl, testcase.skip(), testcase.sequence(), testcase.label());

			// Test Plan is optional attribute so it can be null
			if (null != testplan) {
				testobj.setTestPlanDescription(testplan.decription());
				testobj.setTestPlanPreparedBy(testplan.preparedBy());
				testobj.setTestPlanPreparationDate(testplan.preparationDate());
				testobj.setTestreviewedBy(testplan.reviewedBy());
				testobj.setTestReviewDate(testplan.reviewDate());
			}

			// collect all labels
			String[] labelArray = testcase.label().toLowerCase().trim().split(":");
			for (String s : labelArray) {
				if (null != s && !"".equals(s)) {
					testLabels_withDuplicates.add(s.trim());
				}
			}

			// KTF is optional attribute so it can be null
			if (null != ktf) {
				testobj.setKTF(ktf.ktf());
				testobj.setBugTrackingNumber(ktf.bugref());
			}

			testObjWrapperList_All.add(testobj);
			if (!testcase.skip()) {
				testObjWrapperList_WithoutSkipped.add(testobj);
			}
		}

		// Remove duplicates from the test Label list for later use
		testLabels = testLabels_withDuplicates.stream().distinct().collect(Collectors.toList());

		for (Method method : reflection.getMethodsAnnotatedWith(BeforeTest.class)) {
			// System.out.println("@BeforeTest = " + method.getName() + " : " +
			// method.getDeclaringClass().getName());
		}
		for (Method method : reflection.getMethodsAnnotatedWith(BeforeTestsuite.class)) {
			// System.out.println("@BeforeTestsuite = " + method.getName() + " :
			// " + method.getDeclaringClass().getName());
		}
		for (Method method : reflection.getMethodsAnnotatedWith(AfterTest.class)) {
			// System.out.println("@AfterTest = " + method.getName() + " : " +
			// method.getDeclaringClass().getName());
		}
		for (Method method : reflection.getMethodsAnnotatedWith(AfterTestsuite.class)) {
			// System.out.println("@AfterTestsuite = " + method.getName() + " :
			// "
			// + method.getDeclaringClass().getName());
		}
	}

	/**
	 * logic to bubble sort the elements
	 * 
	 * @param array
	 *            Array of all scanned test objects
	 * @return
	 */
	private TestObjectWrapper[] bubble_srt(TestObjectWrapper[] array) {
		int n = array.length;
		int k;
		for (int m = n; m >= 0; m--) {
			for (int i = 0; i < n - 1; i++) {
				k = i + 1;
				if (array[i].getTestsequence() > array[k].getTestsequence()) {
					swapNumbers(i, k, array);
				}
			}
		}
		return array;
	}

	/**
	 * Swap object in the array
	 * 
	 * @param i
	 *            To
	 * @param j
	 *            From
	 * @param array
	 *            Array of all scanned test objects
	 */
	private void swapNumbers(int i, int j, TestObjectWrapper[] array) {
		TestObjectWrapper temp;
		temp = array[i];
		array[i] = array[j];
		array[j] = temp;
	}

	/**
	 * Generates test plan using annotation provided in the test case classes
	 * 
	 * @param context
	 *            Test Context
	 * @return String Test Plan
	 */
	public String getTestPlan(TestContext context) {
		StringBuilder sb = new StringBuilder();

		for (TestObjectWrapper testObject : testObjWrapperList_All) {
			sb.append("\nTestCaseName : " + testObject.getTestClassObject().getName());
			sb.append("\nSkipTest : " + Boolean.toString(testObject.isSkipTest()));
			sb.append("\nTestSequence : " + testObject.getTestsequence());
			sb.append("\nTestLabel : " + testObject.getTestCaseLabel());
			sb.append("\nDescription : " + testObject.getTestPlanDescription());
			sb.append("\nPreparedBy : " + testObject.getTestPlanPreparedBy());
			sb.append("\nPreparationDate : " + testObject.getTestPlanPreparationDate());
			sb.append("\nReviewedBy : " + testObject.getTestreviewedBy());
			sb.append("\nReviewedDate : " + testObject.getTestReviewDate());
		}

		return sb.toString();
	}

	public String getTestLabelsToPrint(TestContext context) {
		StringBuilder sb = new StringBuilder();

		for (String label : testLabels) {
			sb.append("\n" + label);
		}

		return sb.toString();
	}

	/**
	 * Returns all scanned test cases wrapped with TestObjWrapper components
	 * 
	 * @param sortBySeqNum
	 *            Enables sorting of the test cases
	 * @param removeSkippedTests
	 *            Enables removal of test cases which are marked 'Skip'
	 * @return List of {@code TestObjectWrapper}
	 */
	public List getTestObjWrapperList(boolean sortBySeqNum, boolean removeSkippedTests) {
		// Convert list to array and then do bubble sort based on sequence
		// number
		TestObjectWrapper[] sortedArray = null;

		if (!sortBySeqNum) {
			if (removeSkippedTests) {
				return testObjWrapperList_WithoutSkipped;
			} else {
				return testObjWrapperList_All;
			}
		}

		if (removeSkippedTests) {
			sortedArray = bubble_srt(testObjWrapperList_WithoutSkipped.parallelStream().toArray(TestObjectWrapper[]::new));
		} else {
			sortedArray = bubble_srt(testObjWrapperList_All.parallelStream().toArray(TestObjectWrapper[]::new));
		}
		return Arrays.asList(sortedArray);
	}

	/**
	 * Returns all scanned test cases
	 * 
	 * @param sortBySeqNum
	 *            Enables sorting of the test cases
	 * @param removeSkippedTests
	 *            Enables removal of test cases which are marked 'Skip'
	 * @return List of {@code TestExecutable}
	 * @throws IllegalAccessException
	 *             if the class or its nullary constructor is not accessible.
	 * @throws InstantiationException
	 *             if this Class represents an abstract class, an interface, an
	 *             array class, a primitive type, or void; or if the class has
	 *             no nullary constructor; or if the instantiation fails for
	 *             some other reason.
	 */
	public List getTestList(boolean sortBySeqNum, boolean removeSkippedTests) throws InstantiationException, IllegalAccessException {
		List testList = new ArrayList();

		List testObjWrapperList = getTestObjWrapperList(sortBySeqNum, removeSkippedTests);
		for (TestObjectWrapper t : testObjWrapperList) {
			// create new Instance of test object so user can execute the test
			testList.add((TestExecutable) t.getTestClassObject().newInstance());
		}
		return testList;
	}

	/**
	 * Returns scanned test cases HashMap so user can search test case by
	 * TestCase FQCN
	 * 
	 * @param removeSkippedTests
	 *            removes test cases marked with skipped
	 * @return HashMap of all test objects
	 */
	public Map getTestObjWrapperMap(boolean removeSkippedTests) {
		Map testObjWrapperMap = new HashMap<>();

		List testObjWrapperList = getTestObjWrapperList(false, removeSkippedTests);
		for (TestObjectWrapper t : testObjWrapperList) {
			// create new Instance of test object so user can execute the test
			testObjWrapperMap.put(t.getTestClassObject().getName(), t);
		}
		return testObjWrapperMap;
	}

	public List getTestLabels() {
		return testLabels;
	}

	public void setTestLabels(List testLabels) {
		this.testLabels = testLabels;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy