
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