/** * Write the data back to the file that is represented by the Resource instance * * @param resource the resource instance to which teh data needs to be written * @param actualData the actual data that needs to be written * @param methodNames OPTIONAL names of methods for which the data needs to be written. If the * method names are not provided, then the data is written for all the test methods ofr which * teh data is present in the actualData parameter */ public void writeData( Resource resource, Map<String, List<Map<String, Object>>> actualData, String... methodNames) { try { if (methodNames == null || methodNames.length == 0) { writeFullDataToSpreadsheet(resource.getOutputStream(), actualData); } else { for (String methodName : methodNames) { writeDataToSpreadsheet(resource, methodName, actualData); } } } catch (IOException e) { LOG.warn( "Unable to write data to file {} . An I/O Exception occured.", resource.getResourceName(), e); } }
/** * Main entry point for the Loader * * @param resource The resource to load the data from * @return a Map representing the loaded data */ public Map<String, List<Map<String, Object>>> loadData(Resource resource) { LOG.debug("Trying to load the data for resource :" + resource.getResourceName()); Map<String, List<Map<String, Object>>> result = null; try { result = loadFromSpreadsheet(resource.getInputStream()); } catch (IOException e) { LOG.error( "IOException occured while trying to Load the resource {} . Moving to the next resource.", resource.getResourceName(), e); } if (result != null) { LOG.debug( "Loading data from resource {} succedded and the data loaded is {}", resource.getResourceName(), result); } return result; }
/** * Write the data for the given method to the excel sheet * * @param resource * @param methodNameForDataLoad * @param data * @throws IOException */ private void writeDataToSpreadsheet( Resource resource, String methodNameForDataLoad, Map<String, List<Map<String, Object>>> data) throws IOException { LOG.debug("writeDataToSpreadsheet started" + resource.toString() + data); Workbook workbook; try { workbook = WorkbookFactory.create(new POIFSFileSystem(resource.getInputStream())); } catch (Exception e) { LOG.error("Error creating WorkbookFactory for resource " + resource.toString(), e); throw new IOException(); } Sheet sheet = workbook.getSheetAt(0); Integer recordNum = getMethodRowNumFromExcel(sheet, methodNameForDataLoad); // if record doesn't exist then return without writing any thing if (recordNum == null) { LOG.error("Method doesn't exist in the excel:" + methodNameForDataLoad); return; } int columnNum = sheet.getRow(recordNum).getLastCellNum(); int rowNum = 0; boolean isActualResultHeaderWritten = false; boolean isTestDurationHeaderWritten = false; boolean isHeaderRowNumIncremented = false; for (Map<String, Object> methodData : data.get(methodNameForDataLoad)) { // rowNum increment by one to proceed with next record of the method. rowNum++; Object testDuration = methodData.get(DURATION); if (testDuration != null) { if (!isTestDurationHeaderWritten && recordNum != null) { // Write the test duration header. writeDataToCell(sheet, recordNum, columnNum, DURATION); // increment the rowNum rowNum = rowNum + recordNum; isTestDurationHeaderWritten = true; } // Write the actual result and test status values. if (isTestDurationHeaderWritten) { LOG.debug("testDuration:" + testDuration.toString()); writeDataToCell(sheet, rowNum, columnNum, testDuration.toString()); } } if (!isHeaderRowNumIncremented && (isTestDurationHeaderWritten || isActualResultHeaderWritten)) { isHeaderRowNumIncremented = true; } Object actualResult = methodData.get(ACTUAL_RESULT); Object testStatus = methodData.get(TEST_STATUS); if (actualResult != null) { if (!isActualResultHeaderWritten && recordNum != null) { // Write the actual result and test status headers. writeDataToCell(sheet, recordNum, columnNum + 1, ACTUAL_RESULT); if (testStatus != null) writeDataToCell(sheet, recordNum, columnNum + 2, TEST_STATUS); // rowNum = rowNum + recordNum; isActualResultHeaderWritten = true; } LOG.debug("rowNum:" + rowNum); // Write the actual result and test status values. if (isActualResultHeaderWritten) { LOG.debug("actualResult:" + actualResult.toString()); // trim actual result to 30KB if it is more than that actualResult = trimActualResult(actualResult.toString()); writeDataToCell(sheet, rowNum, columnNum + 1, actualResult.toString()); if (testStatus != null) { // Check against trimmed actual result Object expectedResult = methodData.get(EXPECTED_RESULT); testStatus = expectedResult.toString().equals(actualResult.toString()) ? Loader.TEST_PASSED : Loader.TEST_FAILED; LOG.debug("testStatus:" + testStatus.toString()); writeDataToCell(sheet, rowNum, columnNum + 2, testStatus.toString()); } } } } // Write the output to a file workbook.write(resource.getOutputStream()); LOG.debug("writeDataToSpreadsheet finished"); }
/** * Load the Data for the given class or method. This method will try to find {@link DataLoader} on * either the class level or the method level. In case the annotation is found, this method will * load the data using the specified loader class and then save it in the DataContext for further * use by the system. We also create another copy of the input test data that we store in the * {@link DataDrivenTestRunner#writableData} field. This is done in order to facilitate the * writing of the data that might be returned by the test method. * * @param testClass the class object, if any. * @param method current executing method, if any. * @param currentTestClass the currently executing test class. this is used to append in front of * the method name to get unique method names as there could be methods in different classes * with the same name and thus we want to avoid conflicts. * @param writableData The writable data that is used internally for reporting purposes */ public static void loadData( Class<?> testClass, FrameworkMethod method, TestClass currentTestClass, Map<String, List<Map<String, Object>>> writableData) { if (testClass == null && method == null) { Assert.fail( "The framework should provide either the testClass parameter or the method parameter in order to load the test data."); } // We give priority to Class Loading and then to method loading DataLoader testData = null; if (testClass != null) { testData = testClass.getAnnotation(DataLoader.class); } else { testData = method.getAnnotation(DataLoader.class); } if (testData != null) { TestInfo testInfo = DataLoaderUtil.determineLoader(testData, currentTestClass); Loader dataLoader = testInfo.getDataLoader(); if (testInfo.getDataLoader() == null) { Assert.fail( "The framework currently does not support the specified Loader type. " + "You can provide the custom Loader by choosing LoaderType.CUSTOM in TestData " + "annotation and providing your custom loader using DataLoader annotation."); } else { if (testInfo.getFilePaths() == null || testInfo.getFilePaths().length == 0) { // implies that there exists a CUSTOM loader that loads the data using Java classes Map<String, List<Map<String, Object>>> data = dataLoader.loadData(new EmptyResource()); // We also maintain the copy of the actual data for our write functionality. writableData.putAll(data); DataContext.setData(DataConverter.appendClassName(data, currentTestClass.getJavaClass())); DataContext.setConvertedData( DataConverter.convert(data, currentTestClass.getJavaClass())); } else { ResourceLoader resourceLoader = new ResourceLoaderStrategy(currentTestClass.getJavaClass()); for (String filePath : testInfo.getFilePaths()) { Resource resource = resourceLoader.getResource(filePath); try { if (resource.exists()) { Map<String, List<Map<String, Object>>> data = dataLoader.loadData(resource); // We also maintain the copy of the actual data for our write functionality. writableData.putAll(data); DataContext.setData( DataConverter.appendClassName(data, currentTestClass.getJavaClass())); DataContext.setConvertedData( DataConverter.convert(data, currentTestClass.getJavaClass())); } else { LOG.warn( "Resource {} does not exists in the specified path. If it is a classpath resource, use 'classpath:' " + "before the path name, else check the path.", resource); } } catch (Exception e) { LOG.error( "Exception occured while trying to load the data for resource {}", resource, e); throw new RuntimeException(e); } } } } } }