Mercurial > hg > MauveTestCoverage
changeset 6:5849d5bfbee0
2012-01-18 Pavel Tisnovsky <ptisnovs@redhat.com>
* templates/class_template.html:
* templates/summary.html:
New templates used for a summary and a report
generated for each tested class.
* src/ReportGenerator.java:
Support for templates updated, added the functionality
to generate summary.
author | Pavel Tisnovsky <ptisnovs@redhat.com> |
---|---|
date | Wed, 18 Jan 2012 16:52:43 +0100 |
parents | 5ef74c026b81 |
children | 342d366654ce |
files | ChangeLog src/ReportGenerator.java templates/class_template.html templates/summary.html |
diffstat | 4 files changed, 242 insertions(+), 41 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Tue Jan 17 14:02:07 2012 +0100 +++ b/ChangeLog Wed Jan 18 16:52:43 2012 +0100 @@ -1,3 +1,13 @@ +2012-01-18 Pavel Tisnovsky <ptisnovs@redhat.com> + + * templates/class_template.html: + * templates/summary.html: + New templates used for a summary and a report + generated for each tested class. + * src/ReportGenerator.java: + Support for templates updated, added the functionality + to generate summary. + 2012-01-17 Pavel Tisnovsky <ptisnovs@redhat.com> * src/FileUtils.java:
--- a/src/ReportGenerator.java Tue Jan 17 14:02:07 2012 +0100 +++ b/src/ReportGenerator.java Wed Jan 18 16:52:43 2012 +0100 @@ -37,11 +37,9 @@ */ import java.io.BufferedReader; -import java.io.BufferedWriter; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; -import java.io.FileWriter; import java.io.IOException; import java.util.LinkedList; import java.util.List; @@ -70,6 +68,7 @@ List<String> fileContent = FileUtils.readTextFile(allClassListFileName); // set of classes should be sorted Set<String> allClasses = new TreeSet<String>(); + // add all lines read from a file to a set (and sort them) allClasses.addAll(fileContent); return allClasses; } @@ -90,6 +89,7 @@ { List<String> template = FileUtils.readTextFile("templates/all_packages_template.html"); List<String> out = new LinkedList<String>(); + // iterate through whole template for (String templateLine : template) { // replace text in template where needed @@ -97,11 +97,13 @@ { addPackageList(packageNames, out); } + // normal line else { out.add(templateLine); } } + // write list of string to a file with given name FileUtils.writeTextFile(reportDirectory, "all_packages.html", out); } @@ -121,6 +123,7 @@ { List<String> template = FileUtils.readTextFile("templates/package_template.html"); List<String> out = new LinkedList<String>(); + // iterate through whole template for (String templateLine : template) { // replace text in template where needed @@ -128,11 +131,13 @@ { addClassList(packageName, testedClasses, out); } + // normal line else { out.add(templateLine); } } + // write list of string to a file with given name FileUtils.writeTextFile(reportDirectory, packageName + ".html", out); } @@ -153,6 +158,7 @@ { List<String> template = FileUtils.readTextFile("templates/all_classes_template.html"); List<String> out = new LinkedList<String>(); + // iterate through whole template for (String templateLine : template) { // replace text in template where needed @@ -160,11 +166,13 @@ { addPackageAndClassList(usedPackageNames, testedClasses, out); } + // normal line else { out.add(templateLine); } } + // write list of string to a file with given name FileUtils.writeTextFile(reportDirectory, "all_classes.html", out); } @@ -198,6 +206,7 @@ */ private static void addClassList(String packageName, Set<String> testedClasses, List<String> out) { + // iterate through all class names for (String className : testedClasses) { // list only classes from given package @@ -221,6 +230,7 @@ */ private static void addPackageAndClassList(Set<String> usedPackageNames, Set<String> testedClasses, List<String> out) { + // iterate through all class names for (String packageName : usedPackageNames) { out.add("<h2>Package " + packageName + "</h2>"); @@ -235,56 +245,87 @@ } } + /** + * Create new HTML file containing report for one tested class. + * + * @param reportDirectory + * directory where report is generated + * @param testClass + * name of tested class + * @param allMethods + * superset of apiMethods and testedMethods + * @param apiMethods + * methods presented in API + * @param testedMethods + * methods called from tests + */ private static void createFileForClass(String reportDirectory, String testClass, Set<String> allMethods, Set<String> apiMethods, Set<String> testedMethods) { - BufferedWriter fout = null; - try + List<String> template = FileUtils.readTextFile("templates/class_template.html"); + List<String> out = new LinkedList<String>(); + // iterate through whole template + for (String templateLine : template) { - fout = new BufferedWriter(new FileWriter(new File(reportDirectory, testClass + ".html"))); - fout.write("<html>\n"); - fout.write("<head>\n"); - fout.write("<title>" + testClass + "</title>\n"); - fout.write("</head>\n"); - fout.write("<body>\n"); - fout.write("<h1>Class " + testClass + "</h1>\n"); - fout.write("<table>\n"); - fout.write("<tr><th>Method</th><th><a href='"+testClass+"_api.txt'>API</a></th><th><a href='"+testClass+"_test.txt'>Tested</a></th></tr>\n"); - for (String methodName : allMethods) + // replace text in template where needed + if (templateLine.contains("${CLASS_NAME}")) { - fout.write("<tr><td>" + constructPrintedMethodName(methodName) + "</td>"); - fout.write(printMethodCoverage(methodName, apiMethods)); - fout.write(printMethodCoverage(methodName, testedMethods)); - fout.write("</tr>\n"); + out.add(templateLine.replace("${CLASS_NAME}", testClass)); + } + // replace text in template where needed + else if (templateLine.contains("${METHOD_LIST}")) + { + printReportForAllMethods(allMethods, apiMethods, testedMethods, out); + } + // normal line + else + { + out.add(templateLine); } - fout.write("</table>\n"); - fout.write("</body>\n"); - fout.write("</html>\n"); } - catch (IOException e) - { - e.printStackTrace(); - } - finally + // write list of string to a file with given name + FileUtils.writeTextFile(reportDirectory, testClass + ".html", out); + } + + /** + * Print report for all methods in given class. + * + * @param allMethods + * superset of apiMethods and testedMethods + * @param apiMethods + * methods presented in API + * @param testedMethods + * methods called from tests + * @param out + * list of string which represents generated report + */ + private static void printReportForAllMethods(Set<String> allMethods, Set<String> apiMethods, + Set<String> testedMethods, List<String> out) + { + // iterate through all methods + for (String methodName : allMethods) { - try - { - if (fout != null) - { - fout.close(); - } - } - catch (IOException e) - { - e.printStackTrace(); - } + out.add("<tr><td>" + constructPrintedMethodName(methodName) + "</td>"); + out.add(printMethodCoverage(methodName, apiMethods)); + out.add(printMethodCoverage(methodName, testedMethods)); + out.add("</tr>\n"); } } + /** + * Construct set filled with public API classes. + * + * @param allClasses + * set of all API classes (including classes from proprietary + * packages) + * @return set filled with public API classes + */ private static Set<String> preparePackageNames(Set<String> allClasses) { Set<String> packages = new TreeSet<String>(); + // iterate through all class names for (String className : allClasses) { + // filter only public API classes String packageName = className.substring(0, className.lastIndexOf('.')); if (!packageName.startsWith("com.") && !packageName.startsWith("sun")) { @@ -407,6 +448,76 @@ return allMethods; } + private static void printSummaryPage(String reportDirectory, Set<String> allPackageNames, Set<String> allClasses, + Set<String> testedClasses, Set<String> usedPackageNames) + { + final int numberOfAllPackages = allPackageNames.size(); + final int numberOfAllClasses = allClasses.size(); + final int numberOfUsedPackages = usedPackageNames.size(); + final int numberOfTestedClasses = testedClasses.size(); + + List<String> template = FileUtils.readTextFile("templates/summary.html"); + List<String> out = new LinkedList<String>(); + for (String templateLine : template) + { + // replace text in template where needed + if (templateLine.contains("${API_PACKAGES}")) + { + out.add(templateLine.replace("${API_PACKAGES}", "" + numberOfAllPackages)); + } + // replace text in template where needed + else if (templateLine.contains("${API_CLASSES}")) + { + out.add(templateLine.replace("${API_CLASSES}", "" + numberOfAllClasses)); + } + else + { + if (templateLine.contains("${TESTED_PACKAGES}")) + { + out.add(templateLine.replace("${TESTED_PACKAGES}", "" + numberOfUsedPackages)); + } + // replace text in template where needed + else if (templateLine.contains("${TESTED_CLASSES}")) + { + out.add(templateLine.replace("${TESTED_CLASSES}", "" + numberOfTestedClasses)); + } + // replace text in template where needed + else if (templateLine.contains("${TESTED_PACKAGES_RATIO}")) + { + out.add(templateLine.replace("${TESTED_PACKAGES_RATIO}", "" + calcRatio(numberOfUsedPackages, numberOfAllPackages))); + } + // replace text in template where needed + else if (templateLine.contains("${TESTED_CLASSES_RATIO}")) + { + out.add(templateLine.replace("${TESTED_CLASSES_RATIO}", "" + calcRatio(numberOfTestedClasses, numberOfAllClasses))); + } + // normal output + else + { + out.add(templateLine); + } + } + } + FileUtils.writeTextFile(reportDirectory, "all_results.html", out); + } + + /** + * Calculate ratio of two items (usually tested classes vs. all classes) and + * return textual representation of the calculated ratio (percentage) + * + * @param numberOfTestedItems + * number of tested items + * @param numberOfAllItems + * number of all items + * @return textual representation of the calculated ratio (percentage) + */ + @SuppressWarnings("boxing") + private static String calcRatio(int numberOfTestedItems, int numberOfAllItems) + { + float ratio = 100.0f * numberOfTestedItems / numberOfAllItems; + return String.format("%.2f%%", ratio); + } + private static void prepareReport(String allClassListFileName, String testedClassListFileName, String reportDirectory) { @@ -416,13 +527,13 @@ Set<String> usedPackageNames = prepareUsedPackageNames(allPackageNames, testedClasses); System.out.println("All class list: " + allClassListFileName); - System.out.println("Read " + allClasses.size() + " class names"); + System.out.println("Read " + (allClasses.size()) + " class names"); System.out.println("Tested class list: " + testedClassListFileName); - System.out.println("Read " + testedClasses.size() + " class names"); + System.out.println("Read " + (testedClasses.size()) + " class names"); - System.out.println("Setting list of " + allPackageNames.size() + " all package names"); - System.out.println("Setting list of " + usedPackageNames.size() + " used package names"); + System.out.println("Setting list of " + (allPackageNames.size()) + " all package names"); + System.out.println("Setting list of " + (usedPackageNames.size()) + " used package names"); System.out.println("Report directory: " + reportDirectory); @@ -430,18 +541,29 @@ printReportForAllClassesInOneFile(reportDirectory, usedPackageNames, testedClasses); printReportForAllPackages(reportDirectory, usedPackageNames, testedClasses); printReportForAllClasses(reportDirectory, testedClasses); + printSummaryPage(reportDirectory, allPackageNames, allClasses, testedClasses, usedPackageNames); } + /** + * Entry point to the report generator. + * + * @param args + * should contain name of file containing all class list, name of + * file containing tested class list and the report directory + */ public static void main(String[] args) { + // check if all parameters are specified on command line if (args.length != 3) { System.err.println("Usage allClassListFileName classListFileName reportDirectory"); System.exit(1); } + // resolve all three parameters String allClassListFileName = args[0]; String testedClassListFileName = args[1]; String reportDirectory = args[2]; + // and do the report prepareReport(allClassListFileName, testedClassListFileName, reportDirectory); } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/class_template.html Wed Jan 18 16:52:43 2012 +0100 @@ -0,0 +1,24 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> + <head> + <title>Report for class: ${CLASS_NAME}</title> + <meta name="Generator" content="MauveTestCoverage" /> + <meta http-equiv="content-type" content="text/html; charset=utf-8" /> + <link type="text/css" rel="StyleSheet" href="style.css" /> + </head> + <body> + <h1>Report for class: ${CLASS_NAME} <a href='all_results.html'>summary</a></h1> + + <table> + <tr> + <th>Method</th> + <th><a href="${CLASS_NAME}_api.txt">API</a></th> + <th><a href="${CLASS_NAME}_test.txt">Tested</a></th> + </tr> +${METHOD_LIST} + </table> + + </body> +</html> +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/summary.html Wed Jan 18 16:52:43 2012 +0100 @@ -0,0 +1,45 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> + <head> + <title>Summary</title> + <meta name="Generator" content="MauveTestCoverage" /> + <meta http-equiv="content-type" content="text/html; charset=utf-8" /> + <link type="text/css" rel="StyleSheet" href="style.css" /> + </head> + <body> + <h1>Summary</h1> + <table> + <tr> + <td>Public API packages:</td> + <td>${API_PACKAGES}</td> + <td> </td> + </tr> + <tr> + <td>Public API classes:</td> + <td>${API_CLASSES}</td> + <td> </td> + </tr> + <tr> + <td colspan='3'> </td> + </tr> + <tr> + <td>Checked packages:</td> + <td>${TESTED_PACKAGES}</td> + <td>${TESTED_PACKAGES_RATIO}</td> + </tr> + <tr> + <td>Checked classes:</td> + <td>${TESTED_CLASSES}</td> + <td>${TESTED_CLASSES_RATIO}</td> + </tr> + <tr> + <td colspan='2'> </td> + </tr> + <tr> + <td><a target='ClassesListFrame' href='all_classes.html'>All classes</a></td><td> </td> + </tr> + </table> + </body> +</html> +