Java tutorial
/* * Copyright 2006-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.consol.citrus.util; import com.consol.citrus.CitrusConstants; import com.consol.citrus.exceptions.CitrusRuntimeException; import org.apache.commons.cli.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.*; import java.text.SimpleDateFormat; import java.util.GregorianCalendar; import java.util.Properties; /** * CLI creating a new test case from a template. * * @author Christoph Deppisch * @since 2009 */ public class TestCaseCreator { /** Test name */ private String name; /** Test author */ private String author; /** Test description */ private String description; /** Target package of test case */ private String targetPackage; /** Sample XML-Request */ private String xmlRequest; /** Sample XML-Request */ private String xmlResponse; /** Target unit testing framework */ private UnitFramework framework; /** * Logger */ private static Logger log = LoggerFactory.getLogger(TestCaseCreator.class); /** * Unit testing framework can be either JUnit or TestNG. Test case creator * will create different Java classes according to the unit test framework. */ public static enum UnitFramework { TESTNG, JUNIT; public static UnitFramework fromString(String value) { if (value.equalsIgnoreCase("testng")) { return TESTNG; } else if (value.equalsIgnoreCase("junit")) { return JUNIT; } else { throw new IllegalArgumentException("Found unsupported unit test framework '" + value + "'"); } } }; /** * Main CLI method. * @param args */ public static void main(String[] args) { Options options = new TestCaseCreatorCliOptions(); CommandLineParser cliParser = new GnuParser(); CommandLine cmd = null; try { cmd = cliParser.parse(options, args); if (cmd.hasOption("help")) { HelpFormatter formatter = new HelpFormatter(); formatter.printHelp("CITRUS test creation", options); return; } TestCaseCreator creator = TestCaseCreator.build().withName(cmd.getOptionValue("name")) .withAuthor(cmd.getOptionValue("author", "Unknown")) .withDescription(cmd.getOptionValue("description", "TODO: Description")) .usePackage(cmd.getOptionValue("package", "com.consol.citrus")) .withFramework(UnitFramework.fromString(cmd.getOptionValue("framework", "testng"))); creator.createTestCase(); } catch (ParseException e) { HelpFormatter formatter = new HelpFormatter(); formatter.printHelp("\n **** CITRUS TESTCREATOR ****", "\n CLI options:", options, ""); } } /** * Create the test case. */ public void createTestCase() { if (Character.isLowerCase(name.charAt(0))) { throw new CitrusRuntimeException("Test name must start with an uppercase letter"); } Properties properties = prepareTestCaseProperties(); targetPackage = targetPackage.replace('.', '/'); createFileFromTemplate(properties, CitrusConstants.DEFAULT_TEST_DIRECTORY + targetPackage + File.separator + name + ".xml", getTemplateFileForXMLTest(xmlRequest != null && xmlResponse != null)); createFileFromTemplate(properties, CitrusConstants.DEFAULT_JAVA_DIRECTORY + targetPackage + File.separator + name + ".java", getTemplateFileForJavaClass()); } /** * Prepares the test case properties for dynamic property replacement in * test case templates. * * @return the prepared property set. */ private Properties prepareTestCaseProperties() { Properties properties = new Properties(); properties.put("test.name", name); properties.put("test.author", author); properties.put("test.description", description); properties.put("test.updatedon.datetime", new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(GregorianCalendar.getInstance().getTime())); properties.put("test.creation.date", new SimpleDateFormat("yyyy-MM-dd").format(GregorianCalendar.getInstance().getTime())); properties.put("test.method.name", name.substring(0, 1).toLowerCase() + name.substring(1)); properties.put("test.package", targetPackage); if (xmlRequest != null && xmlResponse != null) { properties.put("test.request", xmlRequest); properties.put("test.response", xmlResponse); } return properties; } /** * Builds the Java file content based on a template file. * * @return the Java test file content. */ public String buildJavaFileContent() { return buildFileContentFromTemplate(prepareTestCaseProperties(), getTemplateFileForJavaClass()); } /** * Builds ther XML file content based on a template file. * * @return the XML test file content. */ public String buildXmlFileContent() { return buildFileContentFromTemplate(prepareTestCaseProperties(), getTemplateFileForXMLTest(xmlRequest != null && xmlResponse != null)); } /** * Read the given template file and replace all test case properties. * * @param properties the dynamic test case properties. * @param templateFilePath the template file to use as base. * @return the final rest file content. */ private String buildFileContentFromTemplate(Properties properties, String templateFilePath) { BufferedReader reader = null; StringBuilder contentBuilder = new StringBuilder(); try { reader = new BufferedReader( new InputStreamReader(TestCaseCreator.class.getResourceAsStream(templateFilePath))); String line; while ((line = reader.readLine()) != null) { contentBuilder.append(PropertyUtils.replacePropertiesInString(line, properties)); contentBuilder.append("\n"); } } catch (FileNotFoundException e) { throw new CitrusRuntimeException("Failed to create test case, unable to find test case template", e); } catch (IOException e) { throw new CitrusRuntimeException( "Failed to create test case, error while accessing test case template file", e); } finally { try { if (reader != null) { reader.close(); } } catch (IOException e) { log.error("Error while closing test case template file", e); } } return contentBuilder.toString(); } /** * Creates test case files from template files replacing * properties in template file. * @param properties to replace placeholders in template file * @param filePath target file path * @param templateFilePath template file path */ private void createFileFromTemplate(Properties properties, String filePath, String templateFilePath) { OutputStream buffered = null; try { File file = new File(filePath); if (!file.getParentFile().exists()) { boolean success = file.getParentFile().mkdirs(); if (!success) { throw new CitrusRuntimeException("Unable to create folder structure for test case"); } } buffered = new BufferedOutputStream(new FileOutputStream(file)); buffered.write(buildFileContentFromTemplate(properties, templateFilePath).getBytes()); buffered.flush(); } catch (FileNotFoundException e) { throw new CitrusRuntimeException("Failed to create test case", e); } catch (IOException e) { throw new CitrusRuntimeException("Failed to create test case, unable to access test file", e); } finally { try { if (buffered != null) { buffered.close(); } } catch (IOException e) { log.error("Error while closing test case file", e); } } } /** * Get the Java class template file according to the * used unit testing framework. * @return file path of template file. */ private String getTemplateFileForJavaClass() { return "java-" + framework.toString().toLowerCase() + "-template.txt"; } /** * Get the XML test case file template. * @return file path of template file. */ private String getTemplateFileForXMLTest(boolean isWithRequestAndResponse) { return isWithRequestAndResponse ? "test-req-res-template.xml" : "test-template.xml"; } /** * Builder method for this creator. * @return */ public static TestCaseCreator build() { return new TestCaseCreator(); } /** * Set name via builder method. * @param name * @return */ public TestCaseCreator withName(String name) { this.name = name; return this; } /** * Set author via builder method. * @param author * @return */ public TestCaseCreator withAuthor(String author) { this.author = author; return this; } /** * Set description via builder method. * @param description * @return */ public TestCaseCreator withDescription(String description) { this.description = description; return this; } /** * Set package via builder method. * @param targetPackage * @return */ public TestCaseCreator usePackage(String targetPackage) { this.targetPackage = targetPackage; return this; } /** * Set the unit testing framework to use. * @param framework * @return */ public TestCaseCreator withFramework(UnitFramework framework) { this.framework = framework; return this; } /** * Set the request to use. * @param xmlRequest * @return */ public TestCaseCreator withXmlRequest(String xmlRequest) { this.xmlRequest = xmlRequest; return this; } /** * Set the response to use. * @param xmlResponse * @return */ public TestCaseCreator withXmlResponse(String xmlResponse) { this.xmlResponse = xmlResponse; return this; } /** * CLI options for test creation */ private static class TestCaseCreatorCliOptions extends Options { private static final long serialVersionUID = 1L; @SuppressWarnings("static-access") public TestCaseCreatorCliOptions() { this.addOption(new Option("help", "print usage help")); this.addOption(OptionBuilder.withArgName("name").hasArg().withDescription("the test name (required)") .isRequired(true).create("name")); this.addOption(OptionBuilder.withArgName("author").hasArg() .withDescription("the author of the test (optional)").isRequired(false).create("author")); this.addOption(OptionBuilder.withArgName("description").hasArg() .withDescription("describes the test (optional)").isRequired(false).create("description")); this.addOption(OptionBuilder.withArgName("package").hasArg() .withDescription("the package to use (optional)").isRequired(false).create("package")); this.addOption(OptionBuilder.withArgName("framework").hasArg() .withDescription("the framework to use (optional) [testng, junit4, junit3]").isRequired(false) .create("framework")); } } /** * Set the test name. * @param name the name to set */ public void setName(String name) { this.name = name; } /** * Get the test name. * @return the name */ public String getName() { return name; } /** * Set the test author. * @param author the author to set */ public void setAuthor(String author) { this.author = author; } /** * Get the test author. * @return the author */ public String getAuthor() { return author; } /** * Set the test description. * @param description the description to set */ public void setDescription(String description) { this.description = description; } /** * Get the test description. * @return the description */ public String getDescription() { return description; } /** * Set the test package. * @param targetPackage the targetPackage to set */ public void setPackage(String targetPackage) { this.targetPackage = targetPackage; } /** * Get the test package. * @return the targetPackage */ public String getPackage() { return targetPackage; } /** * Get the target package. * @return the targetPackage */ public String getTargetPackage() { return targetPackage; } /** * Set the target package. * @param targetPackage the targetPackage to set */ public void setTargetPackage(String targetPackage) { this.targetPackage = targetPackage; } /** * Get the unit test framework (usually TestNG or JUnit). * @return the framework */ public UnitFramework getFramework() { return framework; } /** * Set the unit test framework. * @param framework the framework to set */ public void setFramework(UnitFramework framework) { this.framework = framework; } }