Java自动生成testcase

package com.citi.sl.tlc.common.extract;

import java.io.BufferedWriter;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

import org.apache.commons.lang3.RandomStringUtils;

import com.gemstone.bp.edu.emory.mathcs.backport.java.util.Arrays;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

public class TestCaseGenerator {

    private static final String FILE_SUFFIX_LOWERCASE = ".java";
    private static final String FILE_SUFFIX_UPPERCASE = ".JAVA";

    public static void main(String[] args) {
        generateTestCaseFiles(
                "C:\\Users\\pz\\git\\dev\\xx\\xx\\xx\\src\\main\\java");
    }

    /**
     * Example1 :
     * C:\\Users\\pz\\git\\trade\\

     * 
     * @param projectAbsolutePath
     */
    public static void generateTestCaseFiles(String projectAbsolutePath) {
        List folderList = getAllSubFolders(Paths.get(projectAbsolutePath));
        if (folderList.isEmpty()) {
            System.out.println("folder not exist or no files.");
        }

        folderList.forEach(sourceDir -> {

            Path sourcePath = Paths.get(sourceDir);
            String testFolderStr = sourceDir.replace("\\src\\main", "\\src\\test");
            Path createdTestFolderPath = createTestCaseFolder(Paths.get(testFolderStr));
            createTestCaseFile(sourcePath, createdTestFolderPath);
        });
    }

    public static List getAllSubFolders(Path path) {
        List folders = new ArrayList<>();
        try {
            if (path.toFile().isDirectory()) {
                folders.add(path.toFile().getAbsolutePath());
                Files.list(path).forEach(f -> {
                    List subFolders = getAllSubFolders(f);
                    folders.addAll(subFolders);
                });
            }
        } catch (IOException e) {
            exitProcess(e);
        }
        return folders;
    }

    private static Path createTestCaseFolder(Path createTargetPath) {
        try {
            if (notExists(createTargetPath)) {
                return Files.createDirectories(createTargetPath);
            }
        } catch (IOException e) {
            exitProcess(e);
        }
        return createTargetPath;

    }

    private static void createTestCaseFile(Path sourcePath, Path testFolderPath) {
        try {
            Files.list(sourcePath).forEach(sourceFilePath -> {
                if (sourceFilePath.toFile().isFile() && (sourceFilePath.toString().endsWith(FILE_SUFFIX_UPPERCASE)
                        || sourceFilePath.toString().endsWith(FILE_SUFFIX_LOWERCASE))) {
                    buildTestClass(sourceFilePath, testFolderPath);
                }
            });
        } catch (IOException e) {
            exitProcess(e);
        }
    }

    private static void buildTestClass(Path sourceFilePath, Path targetFolder) {
        String className = sourceFilePath.getFileName().toString().replace(FILE_SUFFIX_LOWERCASE, "");
        try {
            Path newTestFilePath = targetFolder.resolve(className + "Test" + FILE_SUFFIX_LOWERCASE);
            if (notExists(newTestFilePath)) {

                String javaPath = convertPathToPackageClass(sourceFilePath);
                Class sourceClass = getSourceClass(javaPath);

                if (isJavaBean(sourceClass)) {
                    newTestFilePath = Files.createFile(newTestFilePath);
                    writeJavaBeanTestClass(sourceClass, newTestFilePath);
                    System.out.println("JavaBean :" + newTestFilePath.toString() + " created.");

                } else if (isNotAbstract(sourceClass) && isNotInterface(sourceClass)) {
                    newTestFilePath = Files.createFile(newTestFilePath);
                    writeTestClass(sourceClass, newTestFilePath);
                    System.out.println(newTestFilePath.toString() + " created.");
                }

            }
        } catch (IOException e) {
            exitProcess(e);
        }

    }

    private static void writeTestClass(Class sourceClass, Path newTestFilePath) {

        String className = sourceClass.getSimpleName();
        Set methodNames = getClassPublicMethods(sourceClass);
        Map methodMap = getMethodMap(sourceClass);
        String packageLine = sourceClass.getPackage().toString();

        BufferedWriter writer = null;
        try {
            writer = Files.newBufferedWriter(newTestFilePath);
            StringBuilder fileBuilder = new StringBuilder();

            fileBuilder.append(packageLine + ";\n");
            fileBuilder.append("\n");
            String importPackage = "import org.mockito.InjectMocks;\r\n" + "import org.mockito.MockitoAnnotations;\r\n"
                    + "import org.junit.Before;\r\n" + "import org.junit.Test;";
            fileBuilder.append(importPackage);
            fileBuilder.append("\n");
            fileBuilder.append("public class " + className + "Test{\n");
            fileBuilder.append("\n");
            fileBuilder.append("\t");
            fileBuilder.append("@InjectMocks\n");
            fileBuilder.append("\t");
            fileBuilder.append("private " + className + " "
                    + firstCharLowerCase(className) + ";\n");

            fileBuilder.append(getInitMethodString());

            for (String methodName : methodNames) {
                fileBuilder.append(generateTestMethod(methodName, methodMap));
            }
            fileBuilder.append("\n\n}");
            writer.write(fileBuilder.toString());

        } catch (IOException e) {
            exitProcess(e);
        } finally {
            if (null != writer) {
                try {
                    writer.close();
                } catch (IOException e) {
                    exitProcess(e);
                }
            }
        }

    }

    private static void writeJavaBeanTestClass(Class sourceClass, Path newTestFilePath) {

        String className = sourceClass.getSimpleName();
        String packageLine = sourceClass.getPackage().toString();

        BufferedWriter writer = null;
        try {
            writer = Files.newBufferedWriter(newTestFilePath);
            StringBuilder fileBuilder = new StringBuilder();
            fileBuilder.append(packageLine + ";\n");
            fileBuilder.append("\n");
            fileBuilder.append(generateJavaBeanTestClass(sourceClass.getPackage().getName(), className));
            writer.write(fileBuilder.toString());

        } catch (IOException e) {
            exitProcess(e);
        } finally {
            if (null != writer) {
                try {
                    writer.close();
                } catch (IOException e) {
                    exitProcess(e);
                }
            }
        }

    }

    private static String generateJavaBeanTestClass(String packageName, String className) {

        String packageImport = "import java.beans.PropertyDescriptor;\r\n" + "import java.lang.reflect.Field;\r\n"
                + "import java.lang.reflect.Method;\r\n" + "\r\n" + "import org.junit.Before;\r\n"
                + "import org.junit.Test;\r\n" + "import org.mockito.InjectMocks;\r\n"
                + "import org.mockito.MockitoAnnotations;\n";

        String classBodyStart = "public class " + className + "Test{\n";

        String method = "    \r\n" + "    @InjectMocks\r\n" + "    private " + className + " "
                + firstCharLowerCase(className) + ";\r\n"
                + "\r\n" + "    @Before\r\n" + "    public void initMocks(){\r\n"
                + "        MockitoAnnotations.initMocks(this);\r\n" + "    }\r\n" + "    @Test\r\n"
                + "    public void testSetGetMethod() {\r\n" + "        try {\r\n"
                + "            Class clazz = Class.forName(\"" + packageName + "." + className + "\");\r\n"
                + "            Object obj = clazz.newInstance();\r\n"
                + "            Field[] fields = clazz.getDeclaredFields();\r\n"
                + "            for (Field f : fields) {\r\n" + "                try {\r\n"
                + "                    PropertyDescriptor pd = new PropertyDescriptor(f.getName(), clazz);\r\n"
                + "                    Method writeMethod = pd.getWriteMethod();\r\n"
                + "                    writeMethod.invoke(obj, new Object[] { null });\r\n"
                + "                    Method readMethod = pd.getReadMethod();\r\n"
                + "                    readMethod.invoke(obj);\r\n" + "                } catch (Exception e) {\r\n"
                + "                    System.out.println(e);\r\n" + "                }\r\n" + "            }\r\n"
                + "        } catch (Exception e) {\r\n" + "            System.out.println(e);\r\n" + "        }\r\n" + "\r\n"
                + "    }";

        String classBodyEnd = "}";

        StringBuilder builder = new StringBuilder();
        builder.append(packageImport);
        builder.append("\n\n");
        builder.append(classBodyStart);
        builder.append(method);
        builder.append(classBodyEnd);
        return builder.toString();
    }

    private static boolean isJavaBean(Class sourceClass) {
        String fullPackage = sourceClass.getPackage().getName().toLowerCase();
        return (fullPackage.endsWith(".bean") || fullPackage.endsWith(".entity") || fullPackage.endsWith(".beans")
                || fullPackage.endsWith(".entities"));
    }

    private static String generateTestMethod(String methodName, Map methodMap) {
        StringBuilder methodBuilder = new StringBuilder();
        String className = (String) methodMap.get("className");
        Object[] methodObj = (Object[]) methodMap.get(methodName);

        Class returnType = (Class) methodObj[0];
        Class[] paramTypes = (Class[]) methodObj[1];

        List> paramTypeList = Arrays.asList(paramTypes);
        List paramTypeParam = Lists.newArrayList();
        
        Map basicTypeMap = Maps.newHashMap();
        basicTypeMap.put("STRING", "\""+RandomStringUtils.randomAlphabetic(3)+"\"");
        basicTypeMap.put("INT", "0");
        basicTypeMap.put("INTEGER", "0");
        basicTypeMap.put("LONG", "1L");
        basicTypeMap.put("DOUBLE", "1D");
        basicTypeMap.put("SHORT", "1");
        basicTypeMap.put("FLOAT", "1F");
        basicTypeMap.put("BOOLEAN", "true");
        basicTypeMap.put("BYTE", "0");

        for (Class paramClass : paramTypeList) {
            
            String paramClsStr = paramClass.getSimpleName().toUpperCase();
            
            String paramValue = basicTypeMap.get(paramClsStr);
            if(paramValue != null) {
                paramTypeParam.add(paramValue);
            }
            else {
                paramTypeParam.add("null");
            }
        }
        
        String paramStr = String.join(",", paramTypeParam);

        String returnCode = "";
        String returnClassName = returnType.getSimpleName();
        if (!returnClassName.equals("void")) {
            if(returnType.isArray()) {
                returnCode = returnType.getComponentType().getName() + "[]" + " result = ";
            }
            else {
                returnCode = returnType.getName() + " result = ";
            }
        }

        String methodBody = "\t@Test\r\n" + "    public void test"
                + firstCharUpperCase(methodName) + "(){\r\n"
                + "\t\ttry{\r\n"
                + "\t\t\t" + returnCode
                + firstCharLowerCase(className) + "."
                + methodName + "(" + paramStr + ");\r\n" + "\t\t}catch (Exception e) {\n\t\t}\n"
                + "\n\t}\n\n";

        methodBuilder.append(methodBody);
        return methodBuilder.toString();
    }

    public static String getInitMethodString() {
        StringBuilder methodBuilder = new StringBuilder();
        methodBuilder.append("\n");
        methodBuilder.append("\t@Before\n");
        methodBuilder.append("\t");
        methodBuilder.append("public void initMocks(){\n");
        methodBuilder.append("\t\tMockitoAnnotations.initMocks(this);\n");
        methodBuilder.append("\t}");
        methodBuilder.append("\n");
        return methodBuilder.toString();
    }
    
    
    private static String firstCharUpperCase(String input) {
        return input.substring(0, 1).toUpperCase().concat(input.substring(1));
        
    }

    private static String firstCharLowerCase(String input) {
        return input.substring(0, 1).toLowerCase().concat(input.substring(1));
        
    }
    
    private static String convertPathToPackageClass(Path sourcePath) {
        String fileName = "";
        fileName = sourcePath.getFileName().toString().replace(".java", "");
        String packageName = getPackageName(sourcePath);
        return packageName + "." + fileName;
    }

    private static String getPackageName(Path sourcePath) {
        try {
            Optional optional = Files.lines(sourcePath).findFirst();
            if (optional.isPresent()) {
                return optional.get().replace("package ", "").replace(";", "");
            }
        } catch (IOException e) {
            exitProcess(e);
        }
        return "";
    }

    private static boolean isNotAbstract(Class cls) {
        return !Modifier.isAbstract(cls.getModifiers());
    }

    private static boolean isNotInterface(Class cls) {
        return !Modifier.isInterface(cls.getModifiers());
    }

    private static Set getClassPublicMethods(Class cls) {
        Set methodSet = new HashSet<>();
        Method[] publicMethods = cls.getDeclaredMethods();
        for (Method m : publicMethods) {
            if (Modifier.isPublic(m.getModifiers()) || Modifier.isProtected(m.getModifiers())) {
                methodSet.add(m.getName());
            }
        }

        return methodSet;
    }

    private static Map getMethodMap(Class cls) {
        Map methodMap = new HashMap<>();
        Method[] publicMethods = cls.getDeclaredMethods();
        for (Method m : publicMethods) {
            if (Modifier.isPublic(m.getModifiers()) || Modifier.isProtected(m.getModifiers())) {
                // Return type
                Class returnType = m.getReturnType();
                // Method parameter
                Class[] paramTypes = m.getParameterTypes();
                Object[] methodObj = new Object[] { returnType, paramTypes };
                methodMap.put(m.getName(), methodObj);
            }
        }

        methodMap.put("className", cls.getSimpleName());

        return methodMap;
    }

    private static Class getSourceClass(String className) {
        Class cls = null;
        try {
            cls = Class.forName(className);
        } catch (ClassNotFoundException e) {
            exitProcess(e);
        }
        return cls;
    }

    private static void exitProcess(Exception e) {
        e.printStackTrace();
        System.exit(-1);
    }

    private static boolean notExists(Path path) {
        return !exists(path);
    }

    private static boolean exists(Path path) {
        return path.toFile().exists();
    }

}

 

转载于:https://www.cnblogs.com/changfangxing/p/11126829.html

你可能感兴趣的:(Java自动生成testcase)