├── README.md ├── _config.yml ├── libs ├── guice-3.0.jar └── reportng-1.1.5.jar ├── pom.xml └── src ├── .DS_Store ├── main ├── .DS_Store └── java │ ├── .DS_Store │ ├── org │ ├── reportng │ │ ├── AbstractReporter.java │ │ ├── HTMLReporter.java │ │ ├── JUnitXMLReporter.java │ │ ├── ReportMetadata.java │ │ ├── ReportNGException.java │ │ ├── ReportNGUtils.java │ │ ├── TestClassComparator.java │ │ ├── TestMethodComparator.java │ │ ├── TestResultComparator.java │ │ ├── messages │ │ │ ├── reportng.properties │ │ │ ├── reportng_fr.properties │ │ │ └── reportng_pt.properties │ │ └── templates │ │ │ ├── html │ │ │ ├── class-results.html.vm │ │ │ ├── groups.html.vm │ │ │ ├── index.html.vm │ │ │ ├── output.html.vm │ │ │ ├── overview.html.vm │ │ │ ├── reportng.css │ │ │ ├── reportng.js │ │ │ ├── results.html.vm │ │ │ └── suites.html.vm │ │ │ └── xml │ │ │ └── results.xml.vm │ └── resultMail │ │ ├── DataBean.java │ │ ├── MailContext.java │ │ ├── ReportUnits.java │ │ ├── ReporterData.java │ │ └── TestResultSort.java │ └── tools │ ├── correlation │ ├── CorrelationFunction.java │ └── getMatchers.java │ ├── excelread │ ├── GetHostIp.java │ ├── GetHostIpExcel.java │ └── GetTestCaseExcel.java │ ├── filetozip │ └── FileToZip.java │ ├── httprequest │ ├── HttpGetTest.java │ ├── HttpJmeterExcelData.java │ └── HttpPostTest.java │ ├── mail │ ├── MailConfig.java │ ├── MailListener.java │ ├── MailUtil.java │ └── TestAddressList.java │ └── sqlRequest │ └── DBHelper.java └── test ├── TestCaseExcelData ├── HostIP │ └── HostIP.xls ├── dubbo │ └── com.xxxx.order.promise.api.xls ├── emailList │ └── emailList.xls └── http │ ├── testcase.xls │ └── tradeservice.xls ├── java └── com │ └── testcase │ ├── dubbo │ ├── TestIPromiseForOrderService.java │ └── TestOrderStatusService.java │ ├── http │ ├── testExampleForGet.java │ ├── testExampleForJmeterData.java │ └── testExampleForPost.java │ └── sql │ └── SqlTest.java └── resources ├── dubbo-config.xml ├── environmentConfig.properties ├── log4j2.xml ├── mailConfig.properties └── testngReportRecord.xml /README.md: -------------------------------------------------------------------------------- 1 | ### 已停止维护 2 | 接口自动化测试框架,用于完成接口自动化测试,适用于dubbo、http/https、mysql的测试,输出html报告 3 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /libs/guice-3.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OnTheWay111/Avatar/9c26e2630aaf46b6d0e4641e3555465b78383a5e/libs/guice-3.0.jar -------------------------------------------------------------------------------- /libs/reportng-1.1.5.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OnTheWay111/Avatar/9c26e2630aaf46b6d0e4641e3555465b78383a5e/libs/reportng-1.1.5.jar -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.dafy 6 | test 7 | 0.0.1-SNAPSHOT 8 | jar 9 | 10 | test 11 | http://maven.apache.org 12 | 13 | 14 | 15 | 16 | letv-mall-snapshot 17 | letv mall Snapshot 18 | http://maven.xxxx.cn/nexus/content/repositories/xxxx-Snapshot/ 19 | 20 | 21 | letv-mall-release 22 | letv mall Release 23 | http://maven.xxxx.cn/nexus/content/repositories/xxxx-Release/ 24 | 25 | 26 | 27 | 28 | 29 | xxxx-public 30 | xxxx-public 31 | 32 | 33 | 34 | 35 | http://maven.xxxx.cn/nexus/content 36 | 37 | 38 | 39 | 40 | UTF-8 41 | 42 | 43 | 44 | 45 | junit 46 | junit 47 | 4.13.1 48 | test 49 | 50 | 51 | 52 | org.testng 53 | testng 54 | 6.11 55 | test 56 | 57 | 58 | 59 | org.seleniumhq.selenium 60 | selenium-java 61 | 3.7.1 62 | 63 | 64 | 65 | 66 | com.hynnet 67 | jxl 68 | 2.6.12.1 69 | 70 | 71 | org.springframework 72 | spring-framework-bom 73 | 3.2.9.RELEASE 74 | pom 75 | import 76 | 77 | 78 | 79 | org.springframework 80 | spring-core 81 | 5.0.11.RELEASE 82 | 83 | 84 | 85 | org.springframework 86 | spring-beans 87 | 5.0.1.RELEASE 88 | 89 | 90 | 91 | org.springframework 92 | spring-expression 93 | 5.0.1.RELEASE 94 | 95 | 96 | 97 | org.springframework 98 | spring-context-support 99 | 5.0.1.RELEASE 100 | 101 | 102 | 103 | org.springframework 104 | spring-context 105 | 5.0.1.RELEASE 106 | 107 | 108 | 109 | org.springframework 110 | spring-aop 111 | 5.0.1.RELEASE 112 | 113 | 114 | 115 | com.101tec 116 | zkclient 117 | 0.10 118 | 119 | 120 | 121 | io.appium 122 | java-client 123 | 5.0.4 124 | 125 | 126 | 127 | 128 | javax.mail 129 | mail 130 | 1.5.0-b01 131 | 132 | 133 | org.apache.jmeter 134 | ApacheJMeter_java 135 | 3.2 136 | test 137 | 138 | 139 | 140 | com.alibaba 141 | dubbo 142 | 2.8.4.2 143 | 144 | 145 | 146 | 147 | org.apache.maven 148 | maven-plugin-api 149 | 3.5.2 150 | 151 | 152 | 153 | libs 154 | guice 155 | 3.0 156 | system 157 | ${project.basedir}/libs/guice-3.0.jar 158 | 159 | 160 | 161 | libs 162 | reportng 163 | 1.1.5 164 | system 165 | ${project.basedir}/libs/reportng-1.1.5.jar 166 | 167 | 168 | 169 | 170 | velocity 171 | velocity-dep 172 | 1.4 173 | 174 | 175 | 176 | 177 | org.apache.httpcomponents 178 | httpclient 179 | 4.5.4 180 | 181 | 182 | 183 | 184 | mysql 185 | mysql-connector-java 186 | 8.0.16 187 | 188 | 189 | 190 | org.mybatis 191 | mybatis 192 | 3.4.5 193 | 194 | 195 | commons-httpclient 196 | commons-httpclient 197 | 3.1 198 | test 199 | 200 | 201 | org.testng 202 | testng 203 | 6.11 204 | 205 | 206 | commons-httpclient 207 | commons-httpclient 208 | 3.1 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | org.apache.maven.plugins 219 | maven-compiler-plugin 220 | 221 | 1.8 222 | 1.8 223 | UTF-8 224 | 225 | 226 | 227 | 228 | org.apache.maven.plugins 229 | maven-surefire-plugin 230 | 231 | 232 | 233 | test 234 | 235 | 236 | 237 | 2.20.1 238 | 239 | 240 | ./src/test/resources/testngReportRecord.xml 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | -------------------------------------------------------------------------------- /src/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OnTheWay111/Avatar/9c26e2630aaf46b6d0e4641e3555465b78383a5e/src/.DS_Store -------------------------------------------------------------------------------- /src/main/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OnTheWay111/Avatar/9c26e2630aaf46b6d0e4641e3555465b78383a5e/src/main/.DS_Store -------------------------------------------------------------------------------- /src/main/java/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OnTheWay111/Avatar/9c26e2630aaf46b6d0e4641e3555465b78383a5e/src/main/java/.DS_Store -------------------------------------------------------------------------------- /src/main/java/org/reportng/AbstractReporter.java: -------------------------------------------------------------------------------- 1 | package org.reportng; 2 | 3 | import org.apache.velocity.VelocityContext; 4 | import org.apache.velocity.app.Velocity; 5 | import org.testng.IReporter; 6 | import org.uncommons.reportng.ReportMetadata; 7 | import org.uncommons.reportng.ReportNGException; 8 | import org.uncommons.reportng.ReportNGUtils; 9 | 10 | import java.io.*; 11 | import java.util.ResourceBundle; 12 | 13 | /** 14 | * @author 李振7 15 | * Created Time: 2017/11/24 下午4:45 16 | */ 17 | public abstract class AbstractReporter implements IReporter { 18 | private static final String ENCODING = "UTF-8"; 19 | protected static final String TEMPLATE_EXTENSION = ".vm"; 20 | private static final String META_KEY = "meta"; 21 | protected static final ReportMetadata META = new ReportMetadata(); 22 | private static final String UTILS_KEY = "utils"; 23 | private static final ReportNGUtils UTILS = new ReportNGUtils(); 24 | private static final String MESSAGES_KEY = "messages"; 25 | private static final ResourceBundle MESSAGES; 26 | private final String classpathPrefix; 27 | 28 | protected AbstractReporter(String classpathPrefix) { 29 | this.classpathPrefix = classpathPrefix; 30 | Velocity.setProperty("resource.loader", "classpath"); 31 | Velocity.setProperty("classpath.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); 32 | if (!META.shouldGenerateVelocityLog()) { 33 | Velocity.setProperty("runtime.log.logsystem.class", "org.apache.velocity.runtime.log.NullLogSystem"); 34 | } 35 | 36 | try { 37 | Velocity.init(); 38 | } catch (Exception var3) { 39 | throw new ReportNGException("Failed to initialise Velocity.", var3); 40 | } 41 | } 42 | 43 | protected VelocityContext createContext() { 44 | VelocityContext context = new VelocityContext(); 45 | context.put("meta", META); 46 | context.put("utils", UTILS); 47 | context.put("messages", MESSAGES); 48 | return context; 49 | } 50 | 51 | protected void generateFile(File file, String templateName, VelocityContext context) throws Exception { 52 | OutputStream out = new FileOutputStream(file); 53 | BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, "utf-8")); 54 | 55 | try { 56 | Velocity.mergeTemplate(this.classpathPrefix + templateName, "UTF-8", context, writer); 57 | writer.flush(); 58 | } finally { 59 | writer.close(); 60 | } 61 | 62 | } 63 | 64 | protected void copyClasspathResource(File outputDirectory, String resourceName, String targetFileName) throws IOException { 65 | String resourcePath = this.classpathPrefix + resourceName; 66 | InputStream resourceStream = this.getClass().getClassLoader().getResourceAsStream(resourcePath); 67 | this.copyStream(outputDirectory, resourceStream, targetFileName); 68 | } 69 | 70 | protected void copyFile(File outputDirectory, File sourceFile, String targetFileName) throws IOException { 71 | FileInputStream fileStream = new FileInputStream(sourceFile); 72 | 73 | try { 74 | this.copyStream(outputDirectory, fileStream, targetFileName); 75 | } finally { 76 | fileStream.close(); 77 | } 78 | 79 | } 80 | 81 | protected void copyStream(File outputDirectory, InputStream stream, String targetFileName) throws IOException { 82 | File resourceFile = new File(outputDirectory, targetFileName); 83 | BufferedReader reader = null; 84 | BufferedWriter writer = null; 85 | 86 | try { 87 | reader = new BufferedReader(new InputStreamReader(stream, "UTF-8")); 88 | writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(resourceFile), "UTF-8")); 89 | 90 | for(String line = reader.readLine(); line != null; line = reader.readLine()) { 91 | writer.write(line); 92 | writer.write(10); 93 | } 94 | 95 | writer.flush(); 96 | } finally { 97 | if (reader != null) { 98 | reader.close(); 99 | } 100 | 101 | if (writer != null) { 102 | writer.close(); 103 | } 104 | 105 | } 106 | } 107 | 108 | protected void removeEmptyDirectories(File outputDirectory) { 109 | if (outputDirectory.exists()) { 110 | File[] var2 = outputDirectory.listFiles(new EmptyDirectoryFilter()); 111 | int var3 = var2.length; 112 | 113 | for(int var4 = 0; var4 < var3; ++var4) { 114 | File file = var2[var4]; 115 | file.delete(); 116 | } 117 | } 118 | 119 | } 120 | 121 | static { 122 | MESSAGES = ResourceBundle.getBundle("org.uncommons.reportng.messages.reportng", META.getLocale()); 123 | } 124 | 125 | private static final class EmptyDirectoryFilter implements FileFilter { 126 | private EmptyDirectoryFilter() { 127 | } 128 | 129 | @Override 130 | public boolean accept(File file) { 131 | return file.isDirectory() && file.listFiles().length == 0; 132 | } 133 | } 134 | } 135 | 136 | -------------------------------------------------------------------------------- /src/main/java/org/reportng/HTMLReporter.java: -------------------------------------------------------------------------------- 1 | package org.reportng; 2 | 3 | import tools.correlation.CorrelationFunction; 4 | import tools.correlation.getMatchers; 5 | import tools.mail.MailListener; 6 | import org.apache.velocity.VelocityContext; 7 | import org.resultMail.*; 8 | import org.testng.*; 9 | import org.testng.xml.XmlSuite; 10 | 11 | import java.io.File; 12 | import java.io.IOException; 13 | import java.io.InputStream; 14 | import java.text.NumberFormat; 15 | import java.util.*; 16 | 17 | /** 18 | * @author 李振7 19 | * Created Time: 2017/11/24 下午4:46 20 | */ 21 | public class HTMLReporter extends AbstractReporter { 22 | private static final String FRAMES_PROPERTY = "org.uncommons.reportng.frames"; 23 | private static final String ONLY_FAILURES_PROPERTY = "org.uncommons.reportng.failures-only"; 24 | private static final String TEMPLATES_PATH = "org/uncommons/reportng/templates/html/"; 25 | private static final String INDEX_FILE = "TestReportSummary.html"; 26 | private static final String SUITES_FILE = "suites.html"; 27 | private static final String OVERVIEW_FILE = "overview.html"; 28 | private static final String GROUPS_FILE = "groups.html"; 29 | private static final String RESULTS_FILE = "results.html"; 30 | private static final String OUTPUT_FILE = "output.html"; 31 | private static final String CUSTOM_STYLE_FILE = "custom.css"; 32 | private static final String SUITE_KEY = "suite"; 33 | private static final String SUITES_KEY = "suites"; 34 | private static final String GROUPS_KEY = "groups"; 35 | private static final String RESULT_KEY = "result"; 36 | private static final String FAILED_CONFIG_KEY = "failedConfigurations"; 37 | private static final String SKIPPED_CONFIG_KEY = "skippedConfigurations"; 38 | private static final String FAILED_TESTS_KEY = "failedTests"; 39 | private static final String SKIPPED_TESTS_KEY = "skippedTests"; 40 | private static final String PASSED_TESTS_KEY = "passedTests"; 41 | private static final String ONLY_FAILURES_KEY = "onlyReportFailures"; 42 | private static final String REPORT_DIRECTORY = "html"; 43 | private static final Comparator METHOD_COMPARATOR = new TestMethodComparator(); 44 | private static final Comparator RESULT_COMPARATOR = new TestResultComparator(); 45 | private static final Comparator CLASS_COMPARATOR = new TestClassComparator(); 46 | private String caseName = ""; 47 | private String methodName = ""; 48 | private String failReason = ""; 49 | private String failMethodName = ""; 50 | public String mailhtml; 51 | int allPassedTestCases = 0; 52 | int allfailedTestCases = 0; 53 | int allSkippedTestCases = 0; 54 | 55 | public HTMLReporter() { 56 | super("org/uncommons/reportng/templates/html/"); 57 | } 58 | 59 | @Override 60 | public void generateReport(List xmlSuites, List suites, String outputDirectoryName) { 61 | this.removeEmptyDirectories(new File(outputDirectoryName)); 62 | boolean useFrames = "true".equals(System.getProperty("org.uncommons.reportng.frames", "true")); 63 | boolean onlyFailures = "true".equals(System.getProperty("org.uncommons.reportng.failures-only", "false")); 64 | File outputDirectory = new File(outputDirectoryName, "html"); 65 | outputDirectory.mkdirs(); 66 | 67 | try { 68 | if (useFrames) { 69 | this.createFrameset(outputDirectory); 70 | } 71 | 72 | this.createOverview(suites, outputDirectory, !useFrames, onlyFailures); 73 | this.createSuiteList(suites, outputDirectory, onlyFailures); 74 | this.createGroups(suites, outputDirectory); 75 | this.createResults(suites, outputDirectory, onlyFailures); 76 | this.createLog(outputDirectory, onlyFailures); 77 | this.copyResources(outputDirectory); 78 | 79 | //测试MailContext 80 | VelocityContext context = new VelocityContext(); 81 | StringBuilder tableContent = new StringBuilder(); 82 | String sulteName = ""; 83 | for (ISuite suite : suites) { 84 | Map suiteResults = suite.getResults(); 85 | int suitePassedCount = 0; 86 | int suiteFailedCount = 0; 87 | int suiteSkippedCount = 0; 88 | for (ISuiteResult suiteResult : suiteResults.values()) { 89 | ReporterData data = new ReporterData(); 90 | ITestContext testContext = suiteResult.getTestContext(); 91 | // 把数据填入上下文 92 | //测试结果汇总信息 93 | context.put("overView", data.testContext(testContext)); 94 | //所有的测试方法 95 | //ITestNGMethod[] allTests = testContext.getAllTestMethods(); 96 | //未执行的测试方法 97 | //Collection excludeTests = testContext.getExcludedMethods(); 98 | //测试通过的测试方法 99 | IResultMap passedTests = testContext.getPassedTests(); 100 | //测试失败的测试方法 101 | IResultMap failedTests = testContext.getFailedTests(); 102 | //测试跳过的测试方法 103 | IResultMap skippedTests = testContext.getSkippedTests(); 104 | 105 | context.put("pass", data.testResults(passedTests, ITestResult.SUCCESS)); 106 | context.put("fail", data.testResults(failedTests, ITestResult.FAILURE)); 107 | context.put("skip", data.testResults(skippedTests, ITestResult.FAILURE)); 108 | 109 | suitePassedCount = suitePassedCount + data.testContext(testContext).getPassedTestsSize(); 110 | suiteFailedCount = suiteFailedCount + data.testContext(testContext).getFailedTestsSize(); 111 | suiteSkippedCount = suiteSkippedCount + data.testContext(testContext).getSkippedTestsSize(); 112 | if (suiteFailedCount>0) { 113 | String AllFileResult = testContext.getFailedTests().getAllResults().toString(); 114 | if (AllFileResult != null && AllFileResult.length() > 0) { 115 | // String methodNameRegex = "[\\s\\S]?method=([\\s\\S]+?)\\[pri[\\s\\S]+?[,\\s]+"; 116 | String methodNameRegex1 = "[\\s\\S]?instance:([\\s\\S]+?)@[\\s\\S]+?[,\\s]+"; 117 | getMatchers getMatchers = new getMatchers(); 118 | List s = getMatchers.getMatchers(methodNameRegex1, AllFileResult); 119 | for (int i = 0; i < s.size(); i++) { 120 | // System.out.println(s.get(i)); 121 | if (!(failMethodName.contains(s.get(i)))) { 122 | failMethodName = failMethodName + s.get(i) + " / "; 123 | } 124 | // System.out.println("===========AllFileResult_before==================" + AllFileResult); 125 | } 126 | System.out.println("===========failMethodName==============\n" + failMethodName + "\n==========================="); 127 | 128 | tableContent = tableContent.append(" \n" + 129 | " " + testContext.getName() + "\n" + 130 | " " + data.testContext(testContext).getPassedTestsSize() + "\n" + 131 | " " + data.testContext(testContext).getSkippedTestsSize() + "\n" + 132 | " " + data.testContext(testContext).getFailedTestsSize() + "\n" + 133 | " " + data.testContext(testContext).getPassPercent() + "\n" + 134 | // 输出失败的用例信息 135 | " " + failMethodName + "\n" + 136 | " \n"); 137 | } else { 138 | 139 | tableContent = tableContent.append(" \n" + 140 | " " + testContext.getName() + "\n" + 141 | " " + data.testContext(testContext).getPassedTestsSize() + "\n" + 142 | " " + data.testContext(testContext).getSkippedTestsSize() + "\n" + 143 | " " + data.testContext(testContext).getFailedTestsSize() + "\n" + 144 | " " + data.testContext(testContext).getPassPercent() + "\n" + 145 | " \n"); 146 | } 147 | failMethodName = ""; 148 | } 149 | 150 | } 151 | 152 | //获取suiteName 153 | sulteName = suite.getName(); 154 | allPassedTestCases = allPassedTestCases + suitePassedCount; 155 | allfailedTestCases = allfailedTestCases + suiteFailedCount; 156 | allSkippedTestCases = allSkippedTestCases + suiteSkippedCount; 157 | } 158 | String allPassRate = NumberFormat.getInstance().format((float) allPassedTestCases /(float)(allPassedTestCases + allfailedTestCases + allSkippedTestCases)*100) + "%"; 159 | String tableSuiteName = "\n" + 160 | sulteName +"\n" + 161 | " \n"; 162 | 163 | String tabletitle = " \n" + 164 | " testname\n" + 165 | " Passed\n" + 166 | " Skipped\n" + 167 | " Failed\n" + 168 | " Pass Rate\n" + 169 | " Failed Case\n" + 170 | " \n"; 171 | 172 | 173 | String lastrow = " \n" + 174 | " Total\n" + 175 | " "+ allPassedTestCases +"\n" + 176 | " "+ allSkippedTestCases +"\n" + 177 | " "+ allfailedTestCases +"\n" + 178 | " "+ allPassRate +"\n" + 179 | // " \n" + 180 | " \n" + 181 | "\n"; 182 | 183 | mailhtml = "\n" + 184 | "\n" + 185 | "\n" + 186 | ""+sulteName + "\n" + 187 | "\n" + "\n" + 188 | "\n" + 189 | "\n" + 190 | tableSuiteName + 191 | tabletitle + 192 | tableContent + 193 | lastrow + 194 | "
\n" + 195 | "

备注:详细内容见附件

\n" + 196 | "\n" + 197 | ""; 198 | //打包,并发送邮件 199 | MailListener maillistener = new MailListener(); 200 | maillistener.subject = sulteName; 201 | maillistener.mailHtml = mailhtml; 202 | if(allPassedTestCases <(allPassedTestCases + allfailedTestCases + allSkippedTestCases)) { 203 | maillistener.failMailTest(); 204 | } 205 | 206 | } catch (Exception var8) { 207 | throw new ReportNGException("Failed generating HTML report.", var8); 208 | } 209 | } 210 | 211 | private void createFrameset(File outputDirectory) throws Exception { 212 | VelocityContext context = this.createContext(); 213 | this.generateFile(new File(outputDirectory, "TestReportSummary.html"), "index.html.vm", context); 214 | } 215 | 216 | private void createOverview(List suites, File outputDirectory, boolean isIndex, boolean onlyFailures) throws Exception { 217 | VelocityContext context = this.createContext(); 218 | context.put("suites", suites); 219 | context.put("onlyReportFailures", onlyFailures); 220 | this.generateFile(new File(outputDirectory, isIndex ? "TestReportSummary.html" : "overview.html"), "overview.html.vm", context); 221 | } 222 | 223 | private void createSuiteList(List suites, File outputDirectory, boolean onlyFailures) throws Exception { 224 | VelocityContext context = this.createContext(); 225 | context.put("suites", suites); 226 | context.put("onlyReportFailures", onlyFailures); 227 | this.generateFile(new File(outputDirectory, "suites.html"), "suites.html.vm", context); 228 | } 229 | 230 | private void createResults(List suites, File outputDirectory, boolean onlyShowFailures) throws Exception { 231 | int index = 1; 232 | 233 | for(Iterator var5 = suites.iterator(); var5.hasNext(); ++index) { 234 | ISuite suite = (ISuite)var5.next(); 235 | int index2 = 1; 236 | 237 | for(Iterator var8 = suite.getResults().values().iterator(); var8.hasNext(); ++index2) { 238 | ISuiteResult result = (ISuiteResult)var8.next(); 239 | boolean failuresExist = result.getTestContext().getFailedTests().size() > 0 || result.getTestContext().getFailedConfigurations().size() > 0; 240 | if (!onlyShowFailures || failuresExist) { 241 | VelocityContext context = this.createContext(); 242 | context.put("result", result); 243 | context.put("failedConfigurations", this.sortByTestClass(result.getTestContext().getFailedConfigurations())); 244 | context.put("skippedConfigurations", this.sortByTestClass(result.getTestContext().getSkippedConfigurations())); 245 | context.put("failedTests", this.sortByTestClass(result.getTestContext().getFailedTests())); 246 | context.put("skippedTests", this.sortByTestClass(result.getTestContext().getSkippedTests())); 247 | context.put("passedTests", this.sortByTestClass(result.getTestContext().getPassedTests())); 248 | String fileName = String.format("suite%d_test%d_%s", index, index2, "results.html"); 249 | this.generateFile(new File(outputDirectory, fileName), "results.html.vm", context); 250 | } 251 | } 252 | } 253 | 254 | } 255 | 256 | private SortedMap> sortByTestClass(IResultMap results) { 257 | SortedMap> sortedResults = new TreeMap(CLASS_COMPARATOR); 258 | 259 | ITestResult result; 260 | Object resultsForClass; 261 | int index; 262 | for(Iterator var3 = results.getAllResults().iterator(); var3.hasNext(); ((List)resultsForClass).add(index, result)) { 263 | result = (ITestResult)var3.next(); 264 | resultsForClass = (List)sortedResults.get(result.getTestClass()); 265 | if (resultsForClass == null) { 266 | resultsForClass = new ArrayList(); 267 | sortedResults.put(result.getTestClass(), (List) resultsForClass); 268 | } 269 | 270 | index = Collections.binarySearch((List)resultsForClass, result, RESULT_COMPARATOR); 271 | if (index < 0) { 272 | index = Math.abs(index + 1); 273 | } 274 | } 275 | 276 | return sortedResults; 277 | } 278 | 279 | private void createGroups(List suites, File outputDirectory) throws Exception { 280 | int index = 1; 281 | 282 | for(Iterator var4 = suites.iterator(); var4.hasNext(); ++index) { 283 | ISuite suite = (ISuite)var4.next(); 284 | SortedMap> groups = this.sortGroups(suite.getMethodsByGroups()); 285 | if (!groups.isEmpty()) { 286 | VelocityContext context = this.createContext(); 287 | context.put("suite", suite); 288 | context.put("groups", groups); 289 | String fileName = String.format("suite%d_%s", index, "groups.html"); 290 | this.generateFile(new File(outputDirectory, fileName), "groups.html.vm", context); 291 | } 292 | } 293 | 294 | } 295 | 296 | private void createLog(File outputDirectory, boolean onlyFailures) throws Exception { 297 | if (!Reporter.getOutput().isEmpty()) { 298 | VelocityContext context = this.createContext(); 299 | context.put("onlyReportFailures", onlyFailures); 300 | this.generateFile(new File(outputDirectory, "output.html"), "output.html.vm", context); 301 | } 302 | 303 | } 304 | 305 | private SortedMap> sortGroups(Map> groups) { 306 | SortedMap> sortedGroups = new TreeMap(); 307 | Iterator var3 = groups.entrySet().iterator(); 308 | 309 | while(var3.hasNext()) { 310 | Map.Entry> entry = (Map.Entry)var3.next(); 311 | SortedSet methods = new TreeSet(METHOD_COMPARATOR); 312 | methods.addAll((Collection)entry.getValue()); 313 | sortedGroups.put(entry.getKey(), methods); 314 | } 315 | 316 | return sortedGroups; 317 | } 318 | 319 | private void copyResources(File outputDirectory) throws IOException { 320 | this.copyClasspathResource(outputDirectory, "reportng.css", "reportng.css"); 321 | this.copyClasspathResource(outputDirectory, "reportng.js", "reportng.js"); 322 | File customStylesheet = META.getStylesheetPath(); 323 | if (customStylesheet != null) { 324 | if (customStylesheet.exists()) { 325 | this.copyFile(outputDirectory, customStylesheet, "custom.css"); 326 | } else { 327 | InputStream stream = ClassLoader.getSystemClassLoader().getResourceAsStream(customStylesheet.getPath()); 328 | if (stream != null) { 329 | this.copyStream(outputDirectory, stream, "custom.css"); 330 | } 331 | } 332 | } 333 | } 334 | } 335 | -------------------------------------------------------------------------------- /src/main/java/org/reportng/JUnitXMLReporter.java: -------------------------------------------------------------------------------- 1 | package org.reportng; 2 | 3 | import org.apache.velocity.VelocityContext; 4 | import org.testng.IClass; 5 | import org.testng.ISuite; 6 | import org.testng.ISuiteResult; 7 | import org.testng.ITestResult; 8 | import org.testng.xml.XmlSuite; 9 | import org.uncommons.reportng.AbstractReporter; 10 | import org.uncommons.reportng.ReportNGException; 11 | 12 | import java.io.File; 13 | import java.util.*; 14 | 15 | /** 16 | * @author 李振7 17 | * Created Time: 2017/11/24 下午4:48 18 | */ 19 | public class JUnitXMLReporter extends AbstractReporter { 20 | private static final String RESULTS_KEY = "results"; 21 | private static final String TEMPLATES_PATH = "org/uncommons/reportng/templates/xml/"; 22 | private static final String RESULTS_FILE = "results.xml"; 23 | private static final String REPORT_DIRECTORY = "xml"; 24 | 25 | public JUnitXMLReporter() { 26 | super("org/uncommons/reportng/templates/xml/"); 27 | } 28 | 29 | @Override 30 | public void generateReport(List xmlSuites, List suites, String outputDirectoryName) { 31 | this.removeEmptyDirectories(new File(outputDirectoryName)); 32 | File outputDirectory = new File(outputDirectoryName, "xml"); 33 | outputDirectory.mkdirs(); 34 | Collection flattenedResults = this.flattenResults(suites); 35 | Iterator var6 = flattenedResults.iterator(); 36 | 37 | while(var6.hasNext()) { 38 | TestClassResults results = (TestClassResults)var6.next(); 39 | VelocityContext context = this.createContext(); 40 | context.put("results", results); 41 | 42 | try { 43 | this.generateFile(new File(outputDirectory, results.getTestClass().getName() + '_' + "results.xml"), "results.xml.vm", context); 44 | } catch (Exception var10) { 45 | throw new ReportNGException("Failed generating JUnit XML report.", var10); 46 | } 47 | } 48 | 49 | } 50 | 51 | private Collection flattenResults(List suites) { 52 | Map flattenedResults = new HashMap(100); 53 | Iterator var3 = suites.iterator(); 54 | 55 | while(var3.hasNext()) { 56 | ISuite suite = (ISuite)var3.next(); 57 | Iterator var5 = suite.getResults().values().iterator(); 58 | 59 | while(var5.hasNext()) { 60 | ISuiteResult suiteResult = (ISuiteResult)var5.next(); 61 | this.organiseByClass(suiteResult.getTestContext().getFailedConfigurations().getAllResults(), flattenedResults); 62 | this.organiseByClass(suiteResult.getTestContext().getSkippedConfigurations().getAllResults(), flattenedResults); 63 | this.organiseByClass(suiteResult.getTestContext().getFailedTests().getAllResults(), flattenedResults); 64 | this.organiseByClass(suiteResult.getTestContext().getSkippedTests().getAllResults(), flattenedResults); 65 | this.organiseByClass(suiteResult.getTestContext().getPassedTests().getAllResults(), flattenedResults); 66 | } 67 | } 68 | 69 | return flattenedResults.values(); 70 | } 71 | 72 | private void organiseByClass(Set testResults, Map flattenedResults) { 73 | Iterator var3 = testResults.iterator(); 74 | 75 | while(var3.hasNext()) { 76 | ITestResult testResult = (ITestResult)var3.next(); 77 | this.getResultsForClass(flattenedResults, testResult).addResult(testResult); 78 | } 79 | 80 | } 81 | 82 | private TestClassResults getResultsForClass(Map flattenedResults, ITestResult testResult) { 83 | TestClassResults resultsForClass = (TestClassResults)flattenedResults.get(testResult.getTestClass()); 84 | if (resultsForClass == null) { 85 | resultsForClass = new TestClassResults(testResult.getTestClass()); 86 | flattenedResults.put(testResult.getTestClass(), resultsForClass); 87 | } 88 | 89 | return resultsForClass; 90 | } 91 | 92 | public static final class TestClassResults { 93 | private final IClass testClass; 94 | private final Collection failedTests; 95 | private final Collection skippedTests; 96 | private final Collection passedTests; 97 | private long duration; 98 | 99 | private TestClassResults(IClass testClass) { 100 | this.failedTests = new LinkedList(); 101 | this.skippedTests = new LinkedList(); 102 | this.passedTests = new LinkedList(); 103 | this.duration = 0L; 104 | this.testClass = testClass; 105 | } 106 | 107 | public IClass getTestClass() { 108 | return this.testClass; 109 | } 110 | 111 | void addResult(ITestResult result) { 112 | switch(result.getStatus()) { 113 | case 1: 114 | this.passedTests.add(result); 115 | break; 116 | case 3: 117 | if (AbstractReporter.META.allowSkippedTestsInXML()) { 118 | this.skippedTests.add(result); 119 | break; 120 | } 121 | case 2: 122 | case 4: 123 | this.failedTests.add(result); 124 | } 125 | 126 | this.duration += result.getEndMillis() - result.getStartMillis(); 127 | } 128 | 129 | public Collection getFailedTests() { 130 | return this.failedTests; 131 | } 132 | 133 | public Collection getSkippedTests() { 134 | return this.skippedTests; 135 | } 136 | 137 | public Collection getPassedTests() { 138 | return this.passedTests; 139 | } 140 | 141 | public long getDuration() { 142 | return this.duration; 143 | } 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /src/main/java/org/reportng/ReportMetadata.java: -------------------------------------------------------------------------------- 1 | package org.reportng; 2 | 3 | import java.io.File; 4 | import java.net.InetAddress; 5 | import java.net.UnknownHostException; 6 | import java.text.DateFormat; 7 | import java.text.SimpleDateFormat; 8 | import java.util.Date; 9 | import java.util.Locale; 10 | 11 | /** 12 | * @author 李振7 13 | * Created Time: 2017/11/24 下午4:48 14 | */ 15 | public final class ReportMetadata { 16 | static final String PROPERTY_KEY_PREFIX = "org.uncommons.reportng."; 17 | static final String TITLE_KEY = "org.uncommons.reportng.title"; 18 | static final String DEFAULT_TITLE = "Test Results Report"; 19 | static final String COVERAGE_KEY = "org.uncommons.reportng.coverage-report"; 20 | static final String EXCEPTIONS_KEY = "org.uncommons.reportng.show-expected-exceptions"; 21 | static final String OUTPUT_KEY = "org.uncommons.reportng.escape-output"; 22 | static final String XML_DIALECT_KEY = "org.uncommons.reportng.xml-dialect"; 23 | static final String STYLESHEET_KEY = "org.uncommons.reportng.stylesheet"; 24 | static final String LOCALE_KEY = "org.uncommons.reportng.locale"; 25 | static final String VELOCITY_LOG_KEY = "org.uncommons.reportng.velocity-log"; 26 | final DateFormat DATE_FORMAT = new SimpleDateFormat("EEEE dd MMMM yyyy"); 27 | final DateFormat TIME_FORMAT = new SimpleDateFormat("HH:mm z"); 28 | final Date reportTime = new Date(); 29 | 30 | public ReportMetadata() { 31 | } 32 | 33 | public String getReportDate() { 34 | return DATE_FORMAT.format(this.reportTime); 35 | } 36 | 37 | public String getReportTime() { 38 | return TIME_FORMAT.format(this.reportTime); 39 | } 40 | 41 | public String getReportTitle() { 42 | return System.getProperty("org.uncommons.reportng.title", "Test Results Report"); 43 | } 44 | 45 | public String getCoverageLink() { 46 | return System.getProperty("org.uncommons.reportng.coverage-report"); 47 | } 48 | 49 | public File getStylesheetPath() { 50 | String path = System.getProperty("org.uncommons.reportng.stylesheet"); 51 | return path == null ? null : new File(path); 52 | } 53 | 54 | public boolean shouldShowExpectedExceptions() { 55 | return "true".equalsIgnoreCase(System.getProperty("org.uncommons.reportng.show-expected-exceptions", "false")); 56 | } 57 | 58 | public boolean shouldEscapeOutput() { 59 | return "true".equalsIgnoreCase(System.getProperty("org.uncommons.reportng.escape-output", "true")); 60 | } 61 | 62 | public boolean allowSkippedTestsInXML() { 63 | return !"junit".equalsIgnoreCase(System.getProperty("org.uncommons.reportng.xml-dialect", "testng")); 64 | } 65 | 66 | public boolean shouldGenerateVelocityLog() { 67 | return "true".equalsIgnoreCase(System.getProperty("org.uncommons.reportng.velocity-log", "false")); 68 | } 69 | 70 | public String getUser() throws UnknownHostException { 71 | String user = System.getProperty("user.name"); 72 | String host = InetAddress.getLocalHost().getHostName(); 73 | return user + '@' + host; 74 | } 75 | 76 | public String getJavaInfo() { 77 | return String.format("Java %s (%s)", System.getProperty("java.version"), System.getProperty("java.vendor")); 78 | } 79 | 80 | public String getPlatform() { 81 | return String.format("%s %s (%s)", System.getProperty("os.name"), System.getProperty("os.version"), System.getProperty("os.arch")); 82 | } 83 | 84 | public Locale getLocale() { 85 | String str = "org.uncommons.reportng.locale"; 86 | if (System.getProperties().containsKey(str)) { 87 | String locale = System.getProperty(str); 88 | String[] components = locale.split("_", 3); 89 | switch(components.length) { 90 | case 1: 91 | return new Locale(locale); 92 | case 2: 93 | return new Locale(components[0], components[1]); 94 | case 3: 95 | return new Locale(components[0], components[1], components[2]); 96 | default: 97 | System.err.println("Invalid locale specified: " + locale); 98 | } 99 | } 100 | 101 | return Locale.getDefault(); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/main/java/org/reportng/ReportNGException.java: -------------------------------------------------------------------------------- 1 | package org.reportng; 2 | 3 | /** 4 | * @author 李振7 5 | * Created Time: 2017/11/24 下午4:49 6 | */ 7 | public class ReportNGException extends RuntimeException { 8 | public ReportNGException(String string) { 9 | super(string); 10 | } 11 | 12 | public ReportNGException(String string, Throwable throwable) { 13 | super(string, throwable); 14 | } 15 | } -------------------------------------------------------------------------------- /src/main/java/org/reportng/ReportNGUtils.java: -------------------------------------------------------------------------------- 1 | package org.reportng; 2 | 3 | import org.testng.*; 4 | 5 | import java.text.DecimalFormat; 6 | import java.text.NumberFormat; 7 | import java.util.*; 8 | 9 | /** 10 | * @author 李振7 11 | * Created Time: 2017/11/24 下午4:49 12 | */ 13 | public class ReportNGUtils { 14 | private static final NumberFormat DURATION_FORMAT = new DecimalFormat("#0.000"); 15 | private static final NumberFormat PERCENTAGE_FORMAT = new DecimalFormat("#0.00%"); 16 | 17 | public ReportNGUtils() { 18 | } 19 | 20 | /** 21 | 获取响应时间 22 | */ 23 | public long getDuration(ITestContext context) { 24 | long duration = this.getDuration(context.getPassedConfigurations().getAllResults()); 25 | duration += this.getDuration(context.getPassedTests().getAllResults()); 26 | duration += this.getDuration(context.getSkippedConfigurations().getAllResults()); 27 | duration += this.getDuration(context.getSkippedTests().getAllResults()); 28 | duration += this.getDuration(context.getFailedConfigurations().getAllResults()); 29 | duration += this.getDuration(context.getFailedTests().getAllResults()); 30 | return duration; 31 | } 32 | 33 | private long getDuration(Set results) { 34 | long duration = 0L; 35 | 36 | ITestResult result; 37 | for(Iterator var4 = results.iterator(); var4.hasNext(); duration += result.getEndMillis() - result.getStartMillis()) { 38 | result = (ITestResult)var4.next(); 39 | } 40 | 41 | return duration; 42 | } 43 | 44 | public String formatDuration(long startMillis, long endMillis) { 45 | long elapsed = endMillis - startMillis; 46 | return this.formatDuration(elapsed); 47 | } 48 | 49 | public String formatDuration(long elapsed) { 50 | double seconds = (double)elapsed / 1000.0D; 51 | return DURATION_FORMAT.format(seconds); 52 | } 53 | 54 | public List getCauses(Throwable t) { 55 | List causes = new LinkedList(); 56 | Throwable next = t; 57 | 58 | while(next.getCause() != null) { 59 | next = next.getCause(); 60 | causes.add(next); 61 | } 62 | 63 | return causes; 64 | } 65 | 66 | public List getTestOutput(ITestResult result) { 67 | return Reporter.getOutput(result); 68 | } 69 | 70 | public List getAllOutput() { 71 | return Reporter.getOutput(); 72 | } 73 | 74 | public boolean hasArguments(ITestResult result) { 75 | return result.getParameters().length > 0; 76 | } 77 | 78 | public String getArguments(ITestResult result) { 79 | Object[] arguments = result.getParameters(); 80 | List argumentStrings = new ArrayList(arguments.length); 81 | Object[] var4 = arguments; 82 | int var5 = arguments.length; 83 | 84 | for(int var6 = 0; var6 < var5; ++var6) { 85 | Object argument = var4[var6]; 86 | argumentStrings.add(this.renderArgument(argument)); 87 | } 88 | 89 | return this.commaSeparate(argumentStrings); 90 | } 91 | 92 | private String renderArgument(Object argument) { 93 | if (argument == null) { 94 | return "null"; 95 | } else if (argument instanceof String) { 96 | return "\"" + argument + "\""; 97 | } else { 98 | return argument instanceof Character ? "'" + argument + "'" : argument.toString(); 99 | } 100 | } 101 | 102 | public boolean hasDependentGroups(ITestResult result) { 103 | return result.getMethod().getGroupsDependedUpon().length > 0; 104 | } 105 | 106 | public String getDependentGroups(ITestResult result) { 107 | String[] groups = result.getMethod().getGroupsDependedUpon(); 108 | return this.commaSeparate(Arrays.asList(groups)); 109 | } 110 | 111 | public boolean hasDependentMethods(ITestResult result) { 112 | return result.getMethod().getMethodsDependedUpon().length > 0; 113 | } 114 | 115 | public String getDependentMethods(ITestResult result) { 116 | String[] methods = result.getMethod().getMethodsDependedUpon(); 117 | return this.commaSeparate(Arrays.asList(methods)); 118 | } 119 | 120 | public boolean hasSkipException(ITestResult result) { 121 | return result.getThrowable() instanceof SkipException; 122 | } 123 | 124 | public String getSkipExceptionMessage(ITestResult result) { 125 | return this.hasSkipException(result) ? result.getThrowable().getMessage() : ""; 126 | } 127 | 128 | public boolean hasGroups(ISuite suite) { 129 | return !suite.getMethodsByGroups().isEmpty(); 130 | } 131 | 132 | private String commaSeparate(Collection strings) { 133 | StringBuilder buffer = new StringBuilder(); 134 | Iterator iterator = strings.iterator(); 135 | 136 | while(iterator.hasNext()) { 137 | String string = (String)iterator.next(); 138 | buffer.append(string); 139 | if (iterator.hasNext()) { 140 | buffer.append(", "); 141 | } 142 | } 143 | 144 | return buffer.toString(); 145 | } 146 | 147 | public String escapeString(String s) { 148 | if (s == null) { 149 | return null; 150 | } else { 151 | StringBuilder buffer = new StringBuilder(); 152 | 153 | for(int i = 0; i < s.length(); ++i) { 154 | buffer.append(this.escapeChar(s.charAt(i))); 155 | } 156 | 157 | return buffer.toString(); 158 | } 159 | } 160 | 161 | private String escapeChar(char character) { 162 | switch(character) { 163 | case '"': 164 | return """; 165 | case '&': 166 | return "&"; 167 | case '\'': 168 | return "'"; 169 | case '<': 170 | return "<"; 171 | case '>': 172 | return ">"; 173 | default: 174 | return String.valueOf(character); 175 | } 176 | } 177 | 178 | public String escapeHTMLString(String s) { 179 | if (s == null) { 180 | return null; 181 | } else { 182 | StringBuilder buffer = new StringBuilder(); 183 | 184 | for(int i = 0; i < s.length(); ++i) { 185 | char ch = s.charAt(i); 186 | switch(ch) { 187 | case '\n': 188 | buffer.append("
\n"); 189 | break; 190 | case ' ': 191 | char nextCh = i + 1 < s.length() ? s.charAt(i + 1) : 0; 192 | buffer.append(nextCh == ' ' ? " " : " "); 193 | break; 194 | default: 195 | buffer.append(this.escapeChar(ch)); 196 | } 197 | } 198 | 199 | return buffer.toString(); 200 | } 201 | } 202 | 203 | public String stripThreadName(String threadId) { 204 | if (threadId == null) { 205 | return null; 206 | } else { 207 | int index = threadId.lastIndexOf(64); 208 | return index >= 0 ? threadId.substring(0, index) : threadId; 209 | } 210 | } 211 | 212 | public long getStartTime(List methods) { 213 | long startTime = System.currentTimeMillis(); 214 | 215 | IInvokedMethod method; 216 | for(Iterator var4 = methods.iterator(); var4.hasNext(); startTime = Math.min(startTime, method.getDate())) { 217 | method = (IInvokedMethod)var4.next(); 218 | } 219 | 220 | return startTime; 221 | } 222 | 223 | public long getEndTime(ISuite suite, IInvokedMethod method, List methods) { 224 | boolean found = false; 225 | Iterator var5 = methods.iterator(); 226 | 227 | while(var5.hasNext()) { 228 | IInvokedMethod m = (IInvokedMethod)var5.next(); 229 | if (m == method) { 230 | found = true; 231 | } else if (found && m.getTestMethod().getId().equals(method.getTestMethod().getId())) { 232 | return m.getDate(); 233 | } 234 | } 235 | 236 | return this.getEndTime(suite, method); 237 | } 238 | 239 | private long getEndTime(ISuite suite, IInvokedMethod method) { 240 | Iterator var3 = suite.getResults().entrySet().iterator(); 241 | 242 | while(var3.hasNext()) { 243 | Map.Entry entry = (Map.Entry)var3.next(); 244 | ITestContext testContext = ((ISuiteResult)entry.getValue()).getTestContext(); 245 | ITestNGMethod[] var6 = testContext.getAllTestMethods(); 246 | int var7 = var6.length; 247 | 248 | for(int var8 = 0; var8 < var7; ++var8) { 249 | ITestNGMethod m = var6[var8]; 250 | if (method == m) { 251 | return testContext.getEndDate().getTime(); 252 | } 253 | } 254 | 255 | Iterator var10 = testContext.getPassedConfigurations().getAllMethods().iterator(); 256 | 257 | ITestNGMethod m; 258 | while(var10.hasNext()) { 259 | m = (ITestNGMethod)var10.next(); 260 | if (method == m) { 261 | return testContext.getEndDate().getTime(); 262 | } 263 | } 264 | 265 | var10 = testContext.getFailedConfigurations().getAllMethods().iterator(); 266 | 267 | while(var10.hasNext()) { 268 | m = (ITestNGMethod)var10.next(); 269 | if (method == m) { 270 | return testContext.getEndDate().getTime(); 271 | } 272 | } 273 | } 274 | 275 | throw new IllegalStateException("Could not find matching end time."); 276 | } 277 | 278 | public String formatPercentage(int numerator, int denominator) { 279 | return PERCENTAGE_FORMAT.format((double)numerator / (double)denominator); 280 | } 281 | } 282 | -------------------------------------------------------------------------------- /src/main/java/org/reportng/TestClassComparator.java: -------------------------------------------------------------------------------- 1 | package org.reportng; 2 | 3 | import org.testng.IClass; 4 | 5 | import java.util.Comparator; 6 | 7 | /** 8 | * @author 李振7 9 | * Created Time: 2017/11/24 下午4:50 10 | */ 11 | class TestClassComparator implements Comparator { 12 | TestClassComparator() { 13 | } 14 | 15 | @Override 16 | public int compare(IClass class1, IClass class2) { 17 | return class1.getName().compareTo(class2.getName()); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/org/reportng/TestMethodComparator.java: -------------------------------------------------------------------------------- 1 | package org.reportng; 2 | 3 | import org.testng.ITestNGMethod; 4 | 5 | import java.util.Comparator; 6 | 7 | /** 8 | * @author 李振7 9 | * Created Time: 2017/11/24 下午4:51 10 | */ 11 | class TestMethodComparator implements Comparator { 12 | TestMethodComparator() { 13 | } 14 | 15 | @Override 16 | public int compare(ITestNGMethod method1, ITestNGMethod method2) { 17 | int compare = method1.getRealClass().getName().compareTo(method2.getRealClass().getName()); 18 | if (compare == 0) { 19 | compare = method1.getMethodName().compareTo(method2.getMethodName()); 20 | } 21 | 22 | return compare; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/org/reportng/TestResultComparator.java: -------------------------------------------------------------------------------- 1 | package org.reportng; 2 | 3 | import org.testng.ITestResult; 4 | 5 | import java.util.Comparator; 6 | 7 | /** 8 | * @author 李振7 9 | * Created Time: 2017/11/24 下午4:51 10 | */ 11 | class TestResultComparator implements Comparator { 12 | TestResultComparator() { 13 | } 14 | 15 | @Override 16 | public int compare(ITestResult result1, ITestResult result2) { 17 | return result1.getName().compareTo(result2.getName()); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/org/reportng/messages/reportng.properties: -------------------------------------------------------------------------------- 1 | atTime=at 2 | causedBy=Caused by 3 | chronology=Chronology 4 | clickToExpandCollapse=Click to expand/collapse 5 | coverageReport=Coverage Report 6 | dependsOnGroups=Depends on group(s) 7 | dependsOnMethods=Depends on method(s) 8 | duration=Duration 9 | failed=Failed 10 | failed.tooltip=Some tests failed. 11 | failedConfiguration=Failed Configuration 12 | failedTests=Failed Tests 13 | generatedBy=Generated by TestNG with ReportNG 14 | groups=Groups 15 | groupsFor=Groups for 16 | logOutput=Log Output 17 | logOutput.description=Combined output from all calls to the log methods of the TestNG Reporter. 18 | method=Method 19 | methodArguments=Method arguments 20 | notApplicable=N/A 21 | onDate=on 22 | overview=Overview 23 | passed=Passed 24 | passed.tooltip=All tests passed. 25 | passedTests=Passed Tests 26 | passRate=Pass Rate 27 | skipped=Skipped 28 | skipped.reason=Reason 29 | skipped.tooltip=All executed tests passed but some tests were skipped. 30 | skippedConfiguration=Skipped Configuration 31 | skippedTests=Skipped Tests 32 | startTime=Start Time 33 | suites=Suites 34 | testDuration=Test duration 35 | thread=Thread 36 | total=Total -------------------------------------------------------------------------------- /src/main/java/org/reportng/messages/reportng_fr.properties: -------------------------------------------------------------------------------- 1 | atTime=à 2 | causedBy=Causés par 3 | chronology=Chronologie 4 | clickToExpandCollapse=Cliquez pour afficher/cacher 5 | coverageReport=Couverture de Test 6 | dependsOnGroups=Dépend des groupes 7 | dependsOnMethods=Dépend des méthodes 8 | duration=Durée 9 | failed=Échoué 10 | failed.tooltip=Quelques tests ont échoué. 11 | failedConfiguration=Configuration Échouée 12 | failedTests=Tests Échoués 13 | generatedBy=Générés par TestNG avec ReportNG 14 | groups=Groupes 15 | groupsFor=Groupes pour 16 | logOutput=Sortie de Journal 17 | logOutput.description=Le sortie combinée de toutes invocations des méthodes de la TestNG Reporter. 18 | method=Méthode 19 | methodArguments=Arguments de la méthode 20 | notApplicable=Néant 21 | onDate=du 22 | overview=Aperçu 23 | passed=Réussi 24 | passed.tooltip=Tous les tests ont réussi. 25 | passedTests=Tests Réussis 26 | passRate=Taux de Réussite 27 | skipped=Ignoré 28 | skipped.reason=Raison 29 | skipped.tooltip=Quelques tests ont été ignorées. 30 | skippedConfiguration=Configuration Ignorée 31 | skippedTests=Tests Ignorés 32 | suites=Suites 33 | testDuration=Durée de test 34 | total=Total 35 | -------------------------------------------------------------------------------- /src/main/java/org/reportng/messages/reportng_pt.properties: -------------------------------------------------------------------------------- 1 | atTime=às 2 | causedBy=Causado por 3 | chronology=Cronologia 4 | clickToExpandCollapse=Clique para expandir/encolher 5 | coverageReport=Relatòrio de cobertura 6 | dependsOnGroups=Depende dos grupo(s) 7 | dependsOnMethods=Depende dos método(s) 8 | duration=Duração 9 | failed=Falha 10 | failed.tooltip=Alguns testes falharam. 11 | failedConfiguration=Configuração dos testes com Falha 12 | failedTests=Testes com Falha 13 | generatedBy=Gerado pelo TestNG com o ReportNG 14 | groups=Grupos 15 | groupsFor=Grupos para 16 | logOutput=Saída do Log 17 | logOutput.description=Saída de todas as chamadas aos métodos de log do TestNG Reporter. 18 | method=Método 19 | methodArguments=Argumentos do método 20 | notApplicable=N/D 21 | onDate=em 22 | overview=Resumo 23 | passed=Sucesso 24 | passed.tooltip=Todos os testes passaram. 25 | passedTests=Testes com Sucesso 26 | passRate=Taxa de sucesso 27 | skipped=Não executado 28 | skipped.reason=Razão 29 | skipped.tooltip=Todos os testes executados passaram, mas alguns não foram executados. 30 | skippedConfiguration=Configuração dos testes Não Executados 31 | skippedTests=Testes não executados 32 | suites=Suítes 33 | testDuration=Duração do teste 34 | total=Total 35 | -------------------------------------------------------------------------------- /src/main/java/org/reportng/templates/html/class-results.html.vm: -------------------------------------------------------------------------------- 1 | ## This macro formats the results (whether passed, skipped or failed) of the test 2 | ## methods in a single class for inclusion in the HTML report. It assumes that the 3 | ## the results for the class are in a variable called $classResults. $id is a page 4 | ## scope variable that is used to assign unique identifiers to divs. 5 | 6 | #foreach ($testResult in $classResults) 7 | 8 | 9 | #set ($testInstanceName = "") 10 | #if ($testResult.testName) 11 | #set ($testInstanceName = " ($testResult.testName)") 12 | #end 13 | #if ($testResult.method.description && $testResult.method.description.length() > 0) 14 | $!testResult.name$!testInstanceName 15 | #else 16 | $!testResult.name$!testInstanceName 17 | #end 18 | 19 | 20 | $!utils.formatDuration($testResult.startMillis, $testResult.endMillis)s 21 | 22 | 23 | ## Display the dependencies for skipped testExampleForJmeterData methods. 24 | #if ($testResult.status == 3) ## 3 means skipped. 25 | #if( $utils.hasDependentGroups($testResult) ) 26 | $!messages.getString("dependsOnGroups"): 27 | $!utils.getDependentGroups($testResult) 28 |
29 | #end 30 | #if ($utils.hasDependentMethods($testResult)) 31 | $!messages.getString("dependsOnMethods"): 32 | $!utils.getDependentMethods($testResult) 33 | #end 34 | #if ($utils.hasSkipException($testResult)) 35 | $!messages.getString("skipped.reason"): 36 | $!utils.getSkipExceptionMessage($testResult) 37 | #end 38 | #end 39 | 40 | #if ($utils.hasArguments($testResult)) 41 | $!messages.getString("methodArguments"): $!utils.getArguments($testResult)
42 | #end 43 | 44 | ## Show logger output for the testExampleForJmeterData. 45 | #set ($output = $utils.getTestOutput($testResult)) 46 | #if ($output.size() > 0) 47 |
48 | #foreach( $line in $output ) 49 | #if ($meta.shouldEscapeOutput()) 50 | $!utils.escapeHTMLString($line)
51 | #else 52 | $!line 53 | #end 54 | #end 55 |
56 | #end 57 | 58 | 59 | #if ($testResult.throwable && ( $testResult.status == 2 || $meta.shouldShowExpectedExceptions())) 60 | $!utils.escapeHTMLString( $testResult.throwable.toString() )
61 |
62 | #foreach ($element in $testResult.throwable.stackTrace) 63 | $!utils.escapeHTMLString( $element.toString() )
64 | #end 65 | #set ($causes = $utils.getCauses($testResult.throwable)) 66 | #foreach ($throwable in $causes) 67 | #set ($id = $id + 1) 68 | $!messages.getString("causedBy"): $!utils.escapeHTMLString( $throwable.toString() )
69 |
70 | #foreach ($element in $throwable.stackTrace) 71 | $!utils.escapeHTMLString($element.toString())
72 | #end 73 |
74 | #end 75 |
76 | #end 77 | #set ($id = $id + 1) 78 | 79 | 80 | #end 81 | -------------------------------------------------------------------------------- /src/main/java/org/reportng/templates/html/groups.html.vm: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | $!meta.reportTitle - $!suite.name - $!messages.getString("groups") 7 | 8 | 9 | 10 | #if ($meta.stylesheetPath) 11 | 12 | #end 13 | 14 | 15 |

$!messages.getString("groupsFor") $!suite.name

16 | 17 | 18 | #foreach ($!group in $!groups.keySet()) 19 | 20 | 21 | 22 | #foreach ($!test in $!groups.get($!group)) 23 | 24 | 25 | 26 | #end 27 | #end 28 |
$!group
$!{test.realClass.name}.$!{test.methodName}
29 | 30 | -------------------------------------------------------------------------------- /src/main/java/org/reportng/templates/html/index.html.vm: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | $!meta.reportTitle 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/main/java/org/reportng/templates/html/output.html.vm: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | $!meta.reportTitle - $!messages.getString("logOutput") 7 | 8 | 9 | 10 | #if ($!meta.stylesheetPath) 11 | 12 | #end 13 | 14 | 15 |

$!messages.getString("logOutput")

16 |

17 | $!messages.getString("logOutput.description") 18 |

19 | 20 |
21 | #foreach ($!line in $!utils.allOutput) 22 | #if ($!meta.shouldEscapeOutput()) 23 | $!utils.escapeHTMLString($!line)
24 | #else 25 | $!line 26 | #end 27 | #end 28 |
29 | 30 | 31 | -------------------------------------------------------------------------------- /src/main/java/org/reportng/templates/html/overview.html.vm: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | $!meta.reportTitle - $!messages.getString("overview") 7 | 8 | 9 | 10 | #if ($meta.stylesheetPath) 11 | 12 | #end 13 | 14 | 15 |
16 | $!messages.getString("generatedBy") 17 | $!messages.getString("atTime") $!meta.reportTime $!messages.getString("onDate") $!meta.reportDate 18 |
$!meta.user / $!meta.javaInfo / $!meta.platform 19 |
20 | 21 |

$!meta.reportTitle

22 | #if (!$utils.allOutput.empty) 23 |

24 | $!messages.getString("logOutput") 25 | #if ($meta.coverageLink) 26 | · $!messages.getString("coverageReport") 27 | #end 28 |

29 | #end 30 | 31 | #foreach ($suite in $suites) 32 | 33 | #set ($suiteId = $velocityCount) 34 | #set ($totalTests = 0) 35 | #set ($totalPassed = 0) 36 | #set ($totalSkipped = 0) 37 | #set ($totalFailed = 0) 38 | 39 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | #foreach ($result in $suite.results) 60 | #set ($notPassedTests = $result.testContext.skippedTests.size() + $result.testContext.failedTests.size()) 61 | #set ($total = $result.testContext.passedTests.size() + $notPassedTests) 62 | #set ($totalTests = $totalTests + $total) 63 | #set ($totalPassed = $totalPassed + $result.testContext.passedTests.size()) 64 | #set ($totalSkipped = $totalSkipped + $result.testContext.skippedTests.size()) 65 | #set ($totalFailed = $totalFailed + $result.testContext.failedTests.size()) 66 | #set ($failuresExist = $result.testContext.failedTests.size()>0 || $result.testContext.failedConfigurations.size()>0) 67 | 68 | #if (($onlyReportFailures && $failuresExist) || (!$onlyReportFailures)) 69 | 70 | 73 | 76 | 77 | #if ($result.testContext.passedTests.size() > 0) 78 | 79 | #else 80 | 81 | #end 82 | 83 | #if ($result.testContext.skippedTests.size() > 0) 84 | 85 | #else 86 | 87 | #end 88 | 89 | #if ($result.testContext.failedTests.size() > 0) 90 | 91 | #else 92 | 93 | #end 94 | 95 | 103 | 104 | #end 105 | #end 106 | 107 | 108 | 109 | 110 | #if ($totalPassed > 0) 111 | 112 | #else 113 | 114 | #end 115 | 116 | #if ($totalSkipped > 0) 117 | 118 | #else 119 | 120 | #end 121 | 122 | #if ($totalFailed > 0) 123 | 124 | #else 125 | 126 | #end 127 | 128 | 136 | 137 | 138 |
40 | 48 | $!{suite.name} 49 |
 $!messages.getString("duration")$!messages.getString("passed")$!messages.getString("skipped")$!messages.getString("failed")$!messages.getString("passRate")
71 | $!{result.testContext.name} 72 | 74 | $!utils.formatDuration($!utils.getDuration($!result.testContext))s 75 | $!result.testContext.passedTests.size()0$!result.testContext.skippedTests.size()0$!result.testContext.failedTests.size()0 96 | #if ($total > 0) 97 | #set ($passes = $total - $notPassedTests) 98 | $!utils.formatPercentage($passes, $total) 99 | #else 100 | $!messages.getString("notApplicable") 101 | #end 102 |
$!messages.getString("total")$!totalPassed0$!totalSkipped0$!totalFailed0 129 | #if ($totalTests > 0) 130 | #set ($totalPasses = $totalTests - $totalSkipped - $totalFailed) 131 | $!utils.formatPercentage($totalPasses, $totalTests) 132 | #else 133 | $!messages.getString("notApplicable") 134 | #end 135 |
139 | #end 140 | 141 | 142 | -------------------------------------------------------------------------------- /src/main/java/org/reportng/templates/html/reportng.css: -------------------------------------------------------------------------------- 1 | * {padding: 0; margin: 0;} 2 | a {color: #006699;} 3 | a:visited {color: #003366;} 4 | body {font-family: Lucida Sans Unicode, Lucida Grande, sans-serif; line-height: 1.8em; font-size: 62.5%; margin: 1.8em 1em;} 5 | h1 {font-family: Arial, Helvetica, sans-serif; font-weight: bold; font-size: 2.7em; margin-bottom: 0.6667em;} 6 | h2 {font-family: Arial, Helvetica, sans-serif; font-weight: bold; font-size: 1.8em; margin-bottom: 0;} 7 | p {font-size: 1.3em;} 8 | td {font-size: 1.3em;} 9 | 10 | .header {font-size: 1.4em; font-weight: bold; text-align: left;} 11 | .passed {background-color: #44aa44;} 12 | .skipped {background-color: #ffaa00;} 13 | .failed {background-color: #ff4444;} 14 | .failedConfig {background-color: #800000; color: #ffffff} 15 | .skippedConfig {background-color: #cc6600; color: #ffffff} 16 | .totalLabel {font-weight: bold; background-color: #ffffff;} 17 | 18 | .suite {background-color: #999999; font-weight: bold;} 19 | .test {background-color: #eeeeee; padding-left: 2em;} 20 | .test .passed {background-color: #88ee88;} 21 | .test .skipped {background-color: #ffff77;} 22 | .test .failed {background-color: #ff8888;} 23 | .group {background-color: #cccccc; color: #000000; font-weight: bold;} 24 | .suiteLinks {float: right; font-weight: normal; vertical-align: middle;} 25 | .suiteLinks a {color: #ffffff; margin-left: .5em;} 26 | .passRate {font-weight: bold; text-align: right;} 27 | .duration {text-align: right;} 28 | .thread {white-space: nowrap;} 29 | 30 | .resultsTable {border: 0; width: 100%; margin-top: 1.8em; line-height: 1.7em; border-spacing: 0.1em;} 31 | .resultsTable .method {width: 18em;} 32 | .resultsTable .duration {width: 6em;} 33 | .resultsTable td {vertical-align: top; padding: 0 1em;} 34 | .resultsTable th {padding: 0 .5em;} 35 | .number {text-align: right;} 36 | .zero {font-weight: normal;} 37 | .columnHeadings {font-size: 1em;} 38 | .columnHeadings th {font-weight: normal;} 39 | 40 | .configTable {border: 1px solid #800000; color: #800000; margin-bottom: 1.5em;} 41 | 42 | #sidebarHeader {padding: 1.8em 1em; margin: 0 -1em 1.8em -1em;} 43 | #suites {line-height: 1.7em; border-spacing: 0.1em; width: 100%;} 44 | .tests {display: table-row-group;} 45 | .header.suite {cursor: pointer; clear: right; height: 1.214em; margin-top: 1px;} 46 | div.test {margin-top: 0.1em; clear: right; font-size: 1.3em;} 47 | 48 | /* The +/- toggle used in the navigation frame. */ 49 | .toggle {font-family: monospace; font-weight: bold; padding-left: 2px; padding-right: 5px; color: #777777;} 50 | .successIndicator {float: right; font-family: monospace; font-weight: bold; padding-right: 2px; color: #44aa44;} 51 | .skipIndicator {float: right; font-family: monospace; font-weight: bold; padding-right: 2px; color: #ffaa00;} 52 | .failureIndicator {float: right; font-family: monospace; font-weight: bold; padding-right: 2px; color: #ff4444;} 53 | 54 | 55 | /* These classes are for information about an individual testExampleForJmeterData result. */ 56 | .result {font-size: 1.1em; vertical-align: middle;} 57 | .dependency {font-family: Lucida Console, Monaco, Courier New, monospace; font-weight: bold;} 58 | .arguments {font-family: Lucida Console, Monaco, Courier New, monospace; font-weight: bold;} 59 | .testOutput {font-family: Lucida Console, Monaco, Courier New, monospace; color: #666666;} 60 | .stackTrace {font-size: 0.9em; line-height: 1.2em; margin-left: 2em; display: none;} 61 | .stackTrace .stackTrace {font-size: inherit;} 62 | 63 | .description {border-bottom: 1px dotted #006699;} 64 | 65 | #meta {font-size: 1em; text-align: right; float: right;} 66 | #systemInfo {color: #666666;} 67 | 68 | /* Reporter log output (individual testExampleForJmeterData ouput is style by "testOutput" above). */ 69 | #log {font-family: Lucida Console, Monaco, Courier New, monospace; font-size: 1.3em; margin-top: 1.8em;} 70 | 71 | .overviewTable {width: 100%; margin-top: 1.8em; line-height: 1.7em; border-spacing: 0.1em;} 72 | .overviewTable td {padding: 0 1em;} 73 | .overviewTable th {padding: 0 .5em;} 74 | .overviewTable .duration {width: 6em;} 75 | .overviewTable .passRate {width: 6em;} 76 | .overviewTable .number {width: 5em;} 77 | .overviewTable tr {height: 1.6em;} 78 | 79 | -------------------------------------------------------------------------------- /src/main/java/org/reportng/templates/html/reportng.js: -------------------------------------------------------------------------------- 1 | function toggleElement(elementId, displayStyle) 2 | { 3 | var element = document.getElementById(elementId); 4 | var current = element.currentStyle 5 | ? element.currentStyle['display'] 6 | : document.defaultView.getComputedStyle(element, null).getPropertyValue('display'); 7 | element.style.display = (current == 'none' ? displayStyle : 'none'); 8 | } 9 | 10 | function toggle(toggleId) 11 | { 12 | var toggle = document.getElementById ? document.getElementById(toggleId) : document.all[toggleId]; 13 | toggle.textContent = toggle.innerHTML == '\u25b6' ? '\u25bc' : '\u25b6'; 14 | } -------------------------------------------------------------------------------- /src/main/java/org/reportng/templates/html/results.html.vm: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | $!meta.reportTitle - $!result.testContext.name 7 | 8 | 9 | 10 | #if ($meta.stylesheetPath) 11 | 12 | #end 13 | 14 | 15 | 16 |

$!result.testContext.name

17 |

18 | $!messages.getString("testDuration"): $!utils.formatDuration($!utils.getDuration($!result.testContext))s 19 |

20 | 21 | #set ($id = 0) 22 | #if ($failedConfigurations.size() > 0) 23 | 24 | 25 | #set ($id = 0) 26 | #foreach ($testClass in $failedConfigurations.keySet()) 27 | 28 | 29 | 30 | #set ($classResults = $failedConfigurations.get($testClass)) 31 | #parse("org/uncommons/reportng/templates/html/class-results.html.vm") 32 | #end 33 | 34 | #if ($skippedConfigurations.size() > 0) 35 | 36 | 37 | #set ($id = 0) 38 | #foreach ($testClass in $skippedConfigurations.keySet()) 39 | 40 | 41 | 42 | #set ($classResults = $skippedConfigurations.get($testClass)) 43 | #parse ("org/uncommons/reportng/templates/html/class-results.html.vm") 44 | #end 45 | #end 46 |
$!messages.getString("failedConfiguration")
$!testClass.name
 
$!messages.getString("skippedConfiguration")
$!testClass.name
47 | #end 48 | 49 | 50 | #if ($failedTests.size() > 0) 51 | 52 | 53 | #foreach ($testClass in $failedTests.keySet()) 54 | 55 | 56 | 57 | #set ($classResults = $failedTests.get($testClass)) 58 | #parse ("org/uncommons/reportng/templates/html/class-results.html.vm") 59 | #end 60 |
$!messages.getString("failedTests")
$!testClass.name
61 | #end 62 | 63 | #if ($skippedTests.size() > 0) 64 | 65 | 66 | #foreach ($testClass in $skippedTests.keySet()) 67 | 68 | 69 | 70 | #set ($classResults = $skippedTests.get($testClass)) 71 | #parse ("org/uncommons/reportng/templates/html/class-results.html.vm") 72 | #end 73 |
$!messages.getString("skippedTests")
$!testClass.name
74 | #end 75 | 76 | #if ($passedTests.size() > 0) 77 | 78 | 79 | #foreach ($testClass in $passedTests.keySet()) 80 | 81 | 82 | 83 | #set ($classResults = $passedTests.get($testClass)) 84 | #parse ("org/uncommons/reportng/templates/html/class-results.html.vm") 85 | #end 86 |
$!messages.getString("passedTests")
$!testClass.name
87 | #end 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /src/main/java/org/reportng/templates/html/suites.html.vm: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | $!meta.reportTitle - $!messages.getString("suites") 7 | 8 | 9 | 10 | #if ($!meta.stylesheetPath) 11 | 12 | #end 13 | 14 | 15 | 16 | 17 |
18 |

$!meta.reportTitle

19 |

20 | $!messages.getString("overview") 21 | #if (!$utils.allOutput.empty) 22 | · $!messages.getString("logOutput") 23 | #end 24 | #if ($meta.coverageLink) 25 | · $!messages.getString("coverageReport") 26 | #end 27 |

28 |
29 | 30 | #foreach ($suite in $suites) 31 | 32 | 33 | 36 | 37 | 38 | 39 | #set ($!suiteId = $!velocityCount) 40 | #foreach ($!result in $!suite.results) 41 | #set ($!failuresExist = $!result.testContext.failedTests.size()>0 || $!result.testContext.failedConfigurations.size()>0) 42 | 43 | #if (($!onlyReportFailures && $!failuresExist) || (!$onlyReportFailures)) 44 | 45 | 57 | 58 | #end 59 | #end 60 | 61 | #end 62 |
34 | $!{suite.name} 35 |
46 | #if ($!result.testContext.failedTests.size() > 0) 47 | 48 | #else 49 | #if ($!result.testContext.skippedTests.size() > 0) 50 | 51 | #else 52 | 53 | #end 54 | #end 55 | $!result.testContext.name 56 |
63 | 64 | 65 | -------------------------------------------------------------------------------- /src/main/java/org/reportng/templates/xml/results.xml.vm: -------------------------------------------------------------------------------- 1 | 2 | #set ($totalTests = $results.passedTests.size() + $results.skippedTests.size() + $results.failedTests.size()) 3 | 9 | 10 | #foreach ($testResult in $results.failedTests) 11 | #if ($testResult.testName) 12 | 13 | #else 14 | 15 | #end 16 | #if ($!testResult.throwable) 17 | 24 | 35 | 36 | 37 | #else 38 | 45 | #end 46 | 47 | #end 48 | 49 | #foreach ($!testResult in $!results.skippedTests) 50 | #if ($!testResult.testName) 51 | 52 | #else 53 | 54 | #end 55 | 56 | 57 | #end 58 | 59 | #foreach ($!testResult in $!results.passedTests) 60 | #if ($!testResult.testName) 61 | 62 | #else 63 | 64 | #end 65 | #end 66 | 67 | 68 | -------------------------------------------------------------------------------- /src/main/java/org/resultMail/DataBean.java: -------------------------------------------------------------------------------- 1 | package org.resultMail; 2 | 3 | import org.testng.ITestNGMethod; 4 | 5 | import java.util.Collection; 6 | import java.util.List; 7 | 8 | /** 9 | * @author 李振7 10 | * Created Time: 2017/11/28 下午2:49 11 | */ 12 | public class DataBean { 13 | private int excludeTestsSize; //未执行的test数量 14 | private int passedTestsSize; //测试通过的数量 15 | private int failedTestsSize; //测试失败的数量 16 | private int skippedTestsSize; //测试跳过的数量 17 | private int allTestsSize; //全部执行的测试的数量 18 | private ITestNGMethod[] allTestsMethod; //全部执行的测试方法 19 | private Collection excludeTestsMethod; //未执行的测试方法 20 | private String testsTime; //测试耗时 21 | private String passPercent; //测试通过率 22 | private String testName; //测试方法名 23 | private String className; //测试类名 24 | private String duration; //单个测试周期 25 | private String params; //测试用参数 26 | private String description; //测试描述 27 | private List output; //Reporter Output 28 | private String dependMethod; //测试依赖方法 29 | private Throwable throwable; //测试异常原因 30 | private StackTraceElement[] stackTrace; // 异常堆栈信息 31 | 32 | public int getExcludeTestsSize() { 33 | return excludeTestsSize; 34 | } 35 | 36 | public void setExcludeTestsSize(int excludeTestsSize) { 37 | this.excludeTestsSize = excludeTestsSize; 38 | } 39 | 40 | public int getPassedTestsSize() { 41 | return passedTestsSize; 42 | } 43 | 44 | public void setPassedTestsSize(int passedTestsSize) { 45 | this.passedTestsSize = passedTestsSize; 46 | } 47 | 48 | public int getFailedTestsSize() { 49 | return failedTestsSize; 50 | } 51 | 52 | public void setFailedTestsSize(int failedTestsSize) { 53 | this.failedTestsSize = failedTestsSize; 54 | } 55 | 56 | public int getSkippedTestsSize() { 57 | return skippedTestsSize; 58 | } 59 | 60 | public void setSkippedTestsSize(int skippedTestsSize) { 61 | this.skippedTestsSize = skippedTestsSize; 62 | } 63 | 64 | public int getAllTestsSize() { 65 | return allTestsSize; 66 | } 67 | 68 | public void setAllTestsSize(int allTestsSize) { 69 | this.allTestsSize = allTestsSize; 70 | } 71 | 72 | public String getPassPercent() { 73 | return passPercent; 74 | } 75 | 76 | public void setPassPercent(String passPercent) { 77 | this.passPercent = passPercent; 78 | } 79 | 80 | public String getTestName() { 81 | return testName; 82 | } 83 | 84 | public void setTestName(String testName) { 85 | this.testName = testName; 86 | } 87 | 88 | public String getClassName() { 89 | return className; 90 | } 91 | 92 | public void setClassName(String className) { 93 | this.className = className; 94 | } 95 | 96 | public String getDuration() { 97 | return duration; 98 | } 99 | 100 | public void setDuration(String duration) { 101 | this.duration = duration; 102 | } 103 | 104 | public String getParams() { 105 | return params; 106 | } 107 | 108 | public void setParams(String params) { 109 | this.params = params; 110 | } 111 | 112 | public String getDescription() { 113 | return description; 114 | } 115 | 116 | public void setDescription(String description) { 117 | this.description = description; 118 | } 119 | 120 | public List getOutput() { 121 | return output; 122 | } 123 | 124 | public void setOutput(List output) { 125 | this.output = output; 126 | } 127 | 128 | public String getDependMethod() { 129 | return dependMethod; 130 | } 131 | 132 | public void setDependMethod(String dependMethod) { 133 | this.dependMethod = dependMethod; 134 | } 135 | 136 | public Throwable getThrowable() { 137 | return throwable; 138 | } 139 | 140 | public void setThrowable(Throwable throwable2) { 141 | this.throwable = throwable2; 142 | } 143 | 144 | public StackTraceElement[] getStackTrace() { 145 | return stackTrace; 146 | } 147 | 148 | public void setStackTrace(StackTraceElement[] stackTrace) { 149 | this.stackTrace = stackTrace; 150 | } 151 | 152 | public void setTestsTime(String testsTime) { 153 | this.testsTime = testsTime; 154 | } 155 | 156 | public String getTestsTime() { 157 | return testsTime; 158 | } 159 | 160 | public void setAllTestsMethod(ITestNGMethod[] allTestsMethod) { 161 | this.allTestsMethod = allTestsMethod; 162 | } 163 | 164 | public ITestNGMethod[] getAllTestsMethod() { 165 | return allTestsMethod; 166 | } 167 | 168 | public void setExcludeTestsMethod(Collection excludeTestsMethod) { 169 | this.excludeTestsMethod = excludeTestsMethod; 170 | } 171 | 172 | public Collection getExcludeTestsMethod() { 173 | return excludeTestsMethod; 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /src/main/java/org/resultMail/MailContext.java: -------------------------------------------------------------------------------- 1 | package org.resultMail; 2 | 3 | import org.apache.velocity.VelocityContext; 4 | import org.apache.velocity.app.VelocityEngine; 5 | import org.testng.*; 6 | import org.testng.xml.XmlSuite; 7 | 8 | import java.io.*; 9 | import java.util.List; 10 | import java.util.Map; 11 | import java.util.Properties; 12 | 13 | /** 14 | * @author 李振7 15 | * Created Time: 2017/11/28 下午3:12 16 | */ 17 | public class MailContext implements IReporter { 18 | @Override 19 | public void generateReport(List xmlSuites, List suites, String outputDirectory) { 20 | // TODO Auto-generated method stub 21 | try { 22 | // 初始化并取得Velocity引擎 23 | VelocityEngine ve = new VelocityEngine(); 24 | Properties p = new Properties(); 25 | //虽然不懂为什么这样设置,但结果是好的.可以用了 26 | p.setProperty("resource.loader", "class"); 27 | p.setProperty("class.resource.loader.class","org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); 28 | ve.init(p); 29 | // Template t = ve.getTemplate("com/reporter/VMmodel/overview.vm"); 30 | VelocityContext context = new VelocityContext(); 31 | 32 | for (ISuite suite : suites) { 33 | Map suiteResults = suite.getResults(); 34 | for (ISuiteResult suiteResult : suiteResults.values()) { 35 | ReporterData data = new ReporterData(); 36 | ITestContext testContext = suiteResult.getTestContext(); 37 | // 把数据填入上下文 38 | context.put("overView", data.testContext(testContext));//测试结果汇总信息 39 | //ITestNGMethod[] allTests = testContext.getAllTestMethods();//所有的测试方法 40 | //Collection excludeTests = testContext.getExcludedMethods();//未执行的测试方法 41 | IResultMap passedTests = testContext.getPassedTests();//测试通过的测试方法 42 | IResultMap failedTests = testContext.getFailedTests();//测试失败的测试方法 43 | IResultMap skippedTests = testContext.getSkippedTests();//测试跳过的测试方法 44 | 45 | context.put("pass", data.testResults(passedTests, ITestResult.SUCCESS)); 46 | context.put("fail", data.testResults(failedTests, ITestResult.FAILURE)); 47 | context.put("skip", data.testResults(skippedTests, ITestResult.FAILURE)); 48 | 49 | System.out.println(context.get("overView")); 50 | 51 | 52 | } 53 | } 54 | // 输出流 55 | OutputStream out=new FileOutputStream("report.html"); 56 | Writer writer = new BufferedWriter(new OutputStreamWriter(out,"utf-8"));//解决乱码问题 57 | // 转换输出 58 | // t.merge(context, writer); 59 | //System.out.println(writer.toString()); 60 | writer.flush(); 61 | } catch (Exception e) { 62 | // TODO Auto-generated catch block 63 | e.printStackTrace(); 64 | } 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/org/resultMail/ReportUnits.java: -------------------------------------------------------------------------------- 1 | package org.resultMail; 2 | 3 | import org.testng.ITestContext; 4 | import org.testng.ITestResult; 5 | import org.testng.Reporter; 6 | 7 | import java.text.DecimalFormat; 8 | import java.text.NumberFormat; 9 | import java.util.*; 10 | 11 | /** 12 | * @author 李振7 13 | * Created Time: 2017/11/28 下午2:50 14 | */ 15 | public class ReportUnits { 16 | private static final NumberFormat DURATION_FORMAT = new DecimalFormat("#0.000"); 17 | private static final NumberFormat PERCENTAGE_FORMAT = new DecimalFormat("#0.00%"); 18 | /** 19 | *测试消耗时长 20 | *return 秒,保留3位小数 21 | */ 22 | public String getTestDuration(ITestContext context){ 23 | long duration; 24 | duration=context.getEndDate().getTime()-context.getStartDate().getTime(); 25 | return formatDuration(duration); 26 | } 27 | 28 | public String formatDuration(long elapsed) 29 | { 30 | double seconds = (double) elapsed / 1000; 31 | return DURATION_FORMAT.format(seconds); 32 | } 33 | /** 34 | *测试通过率 35 | *return 2.22%,保留2位小数 36 | */ 37 | public String formatPercentage(int numerator, int denominator) 38 | { 39 | return PERCENTAGE_FORMAT.format(numerator / (double) denominator); 40 | } 41 | 42 | /** 43 | * 获取方法参数,以逗号分隔 44 | * @param result 45 | * @return 46 | */ 47 | public String getParams(ITestResult result){ 48 | Object[] params = result.getParameters(); 49 | List list = new ArrayList(params.length); 50 | for (Object o:params){ 51 | list.add(renderArgument(o)); 52 | } 53 | return commaSeparate(list); 54 | } 55 | /** 56 | * 获取依赖的方法 57 | * @param result 58 | * @return 59 | */ 60 | public String getDependMethods(ITestResult result){ 61 | String[] methods=result.getMethod().getMethodsDependedUpon(); 62 | return commaSeparate(Arrays.asList(methods)); 63 | } 64 | /** 65 | * 堆栈轨迹,暂不确定怎么做,放着先 66 | * @param throwable 67 | * @return 68 | */ 69 | public String getCause(Throwable throwable){ 70 | StackTraceElement[] stackTrace=throwable.getStackTrace(); //堆栈轨迹 71 | List list = new ArrayList(stackTrace.length); 72 | for (Object o:stackTrace){ 73 | list.add(renderArgument(o)); 74 | } 75 | return commaSeparate(list); 76 | } 77 | /** 78 | * 获取全部日志输出信息 79 | * @return 80 | */ 81 | public List getAllOutput(){ 82 | return Reporter.getOutput(); 83 | } 84 | 85 | /** 86 | * 按testresult获取日志输出信息 87 | * @param result 88 | * @return 89 | */ 90 | public List getTestOutput(ITestResult result){ 91 | return Reporter.getOutput(result); 92 | } 93 | 94 | 95 | /*将object 转换为String*/ 96 | private String renderArgument(Object argument) 97 | { 98 | if (argument == null) 99 | { 100 | return "null"; 101 | } 102 | else if (argument instanceof String) 103 | { 104 | return "\"" + argument + "\""; 105 | } 106 | else if (argument instanceof Character) 107 | { 108 | return "\'" + argument + "\'"; 109 | } 110 | else 111 | { 112 | return argument.toString(); 113 | } 114 | } 115 | /*将集合转换为以逗号分隔的字符串*/ 116 | private String commaSeparate(Collection strings) 117 | { 118 | StringBuilder buffer = new StringBuilder(); 119 | Iterator iterator = strings.iterator(); 120 | while (iterator.hasNext()) 121 | { 122 | String string = iterator.next(); 123 | buffer.append(string); 124 | if (iterator.hasNext()) 125 | { 126 | buffer.append(", "); 127 | } 128 | } 129 | return buffer.toString(); 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /src/main/java/org/resultMail/ReporterData.java: -------------------------------------------------------------------------------- 1 | package org.resultMail; 2 | 3 | import org.testng.*; 4 | 5 | import java.util.*; 6 | 7 | /** 8 | * @author 李振7 9 | * Created Time: 2017/11/28 下午2:52 10 | */ 11 | public class ReporterData { 12 | // 测试结果Set转为list,再按执行时间排序 ,返回list 13 | public List sortByTime(Set str) { 14 | List list = new ArrayList(); 15 | for (ITestResult r : str) { 16 | list.add(r); 17 | } 18 | Collections.sort(list); 19 | return list; 20 | 21 | 22 | } 23 | 24 | public DataBean testContext(ITestContext context) { 25 | // 测试结果汇总数据 26 | DataBean data = new DataBean(); 27 | ReportUnits units = new ReportUnits(); 28 | IResultMap passedTests = context.getPassedTests(); 29 | IResultMap failedTests= context.getFailedTests(); 30 | IResultMap skipedTests = context.getSkippedTests(); 31 | //全部测试周期方法,包括beforetest,beforeclass,beforemethod,aftertest,afterclass,aftermethod 32 | //IResultMap passedConfigurations =context.getPassedConfigurations(); 33 | //IResultMap failedConfigurations =context.getFailedConfigurations(); 34 | //IResultMap skipedConfigurations =context.getSkippedConfigurations(); 35 | Collection excludeTests = context.getExcludedMethods(); 36 | 37 | int passedTestsSize = passedTests.size(); 38 | int failedTestsSize = failedTests.size(); 39 | int skipedTestsSize = skipedTests.size(); 40 | int excludeTestsSize = excludeTests.size(); 41 | //所有测试结果的数量=测试pass+fail+skip的和,因为数据驱动一个测试方法有多次执行的可能,导致方法总数并不等于测试总数 42 | int allTestsSize= passedTestsSize+failedTestsSize+skipedTestsSize; 43 | data.setAllTestsSize(allTestsSize); 44 | data.setPassedTestsSize(passedTestsSize); 45 | data.setFailedTestsSize(failedTestsSize); 46 | data.setSkippedTestsSize(skipedTestsSize); 47 | data.setExcludeTestsSize(excludeTestsSize); 48 | data.setTestsTime(units.getTestDuration(context)); 49 | data.setPassPercent(units.formatPercentage(passedTestsSize, allTestsSize)); 50 | data.setAllTestsMethod(context.getAllTestMethods()); 51 | data.setExcludeTestsMethod(context.getExcludedMethods()); 52 | 53 | return data; 54 | 55 | 56 | } 57 | 58 | 59 | public List testResults(IResultMap map, int status) { 60 | // 测试结果详细数据 61 | List list = new ArrayList(); 62 | ReportUnits units = new ReportUnits(); 63 | map.getAllResults().size(); 64 | for (ITestResult result : sortByTime(map.getAllResults())) { 65 | DataBean data = new DataBean(); 66 | data.setTestName(result.getName()); 67 | data.setClassName(result.getTestClass().getName()); 68 | data.setDuration(units.formatDuration(result.getEndMillis() 69 | - result.getStartMillis())); 70 | data.setParams(units.getParams(result)); 71 | data.setDescription(result.getMethod().getDescription()); 72 | data.setOutput(Reporter.getOutput(result)); 73 | data.setDependMethod(units.getDependMethods(result)); 74 | data.setThrowable(result.getThrowable()); 75 | if (result.getThrowable() != null) { 76 | data.setStackTrace(result.getThrowable().getStackTrace()); 77 | } 78 | list.add(data); 79 | } 80 | return list; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/org/resultMail/TestResultSort.java: -------------------------------------------------------------------------------- 1 | package org.resultMail; 2 | 3 | import org.testng.ITestResult; 4 | 5 | /** 6 | * @author 李振7 7 | * Created Time: 2017/11/28 下午2:51 8 | */ 9 | public class TestResultSort implements Comparable { 10 | private Long order; 11 | @Override 12 | public int compareTo(ITestResult arg0) { 13 | // TODO Auto-generated method stub 14 | return this.order.compareTo( arg0.getStartMillis());//按test开始时间排序 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/tools/correlation/CorrelationFunction.java: -------------------------------------------------------------------------------- 1 | package tools.correlation; 2 | 3 | import java.util.regex.Matcher; 4 | import java.util.regex.Pattern; 5 | 6 | /** 7 | * @author 李振7 8 | * Created Time: 2017/12/22 下午3:43 9 | * 关联函数 10 | */ 11 | public class CorrelationFunction { 12 | String leftBoundary = ""; 13 | String rightBoundary = ""; 14 | 15 | public String getCorrelationStr(String s, String leftBoundary, String rightBoundary) { 16 | // 按指定模式在字符串查找 17 | this.leftBoundary = leftBoundary; 18 | this.rightBoundary = rightBoundary; 19 | String pattern = ".*" + leftBoundary + "(.*)" + rightBoundary +".*"; 20 | String correlationStr = ""; 21 | 22 | // 创建 Pattern 对象 23 | Pattern r = Pattern.compile(pattern); 24 | 25 | // 现在创建 matcher 对象 26 | Matcher m = r.matcher(s); 27 | 28 | 29 | if (m.find()) { 30 | correlationStr = m.group(1); 31 | return correlationStr; 32 | } else { 33 | System.err.println("--------------------Warning: 没有在指定字符串中找到可关联的字符串---------------------"); 34 | return correlationStr; 35 | } 36 | 37 | } 38 | 39 | // public static void main(String[] args) { 40 | // CorrelationFunction correlationFunction = new CorrelationFunction(); 41 | // System.out.println(correlationFunction.GetCorrelationStr("#111%#2222%", "#", "%")); 42 | // 43 | // } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/tools/correlation/getMatchers.java: -------------------------------------------------------------------------------- 1 | package tools.correlation; 2 | 3 | import org.omg.PortableInterceptor.SYSTEM_EXCEPTION; 4 | import org.testng.annotations.Test; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | import java.util.regex.Matcher; 9 | import java.util.regex.Pattern; 10 | 11 | /** 12 | * @author 李振7 13 | * Created Time: 2018/1/31 下午4:15 14 | * 功能描述:获取所有正则匹配内容,并保存在List中 15 | */ 16 | public class getMatchers { 17 | //regex是正则表达式,source为资源字符串 18 | public List getMatchers(String regex, String source){ 19 | Pattern pattern = Pattern.compile(regex); 20 | Matcher matcher = pattern.matcher(source); 21 | List list = new ArrayList<>(); 22 | while (matcher.find()) { 23 | for(int i=1; i<=matcher.groupCount(); i++){ 24 | // System.out.println(i+":-------------"+matcher.group(i)); 25 | list.add(matcher.group(i)); 26 | } 27 | 28 | } 29 | return list; 30 | } 31 | 32 | @Test 33 | public void test() { 34 | String regex = "[\\s\\S]?method=([\\s\\S]+?)\\[pri[\\s\\S]+?[,\\s]+"; 35 | getMatchers getMatchers = new getMatchers(); 36 | List s = getMatchers.getMatchers(regex, "[[TestResult name=cancelOrder status=FAILURE method=pcOrderAllProcess.cancelOrder()[pri:24, instance:com.testcase.http.online.pc.pcOrderAllProcess@38bc8ab5] output=>>>>>>>>>>>>>>>>>>>>断言失败的ResponseData是:status\":\"1<<<<<<<<<<<<<<<<<<<<]][[TestResult name=cancelOrder status=FAILURE method=pcOrderAllProcess.cancelOrder1111()[pri:24, instance:com.testcase.http.online.pc.pcOrderAllProcess@38bc8ab5] output=>>>>>>>>>>>>>>>>>>>>断言失败的ResponseData是:status\":\"1<<<<<<<<<<<<<<<<<<<<]]\n"); 37 | for (int i=0; i hostNameIpMap = new HashMap(); 21 | private static Properties properties; 22 | 23 | 24 | 25 | 26 | public GetHostIp(String hostName) throws IOException, BiffException { 27 | properties = new Properties(); 28 | InputStream inputStream = null; 29 | inputStream = GetHostIp.class.getClassLoader().getResourceAsStream(PROPERTIES_DEFAULT); 30 | properties.load(inputStream); 31 | inputStream.close(); 32 | //确定要测试环境,online,test,yulan 33 | caseName = properties.getProperty("testEnvironment"); 34 | 35 | this.hostName = hostName; 36 | getHostIpExcel = new GetHostIpExcel(caseName); 37 | hostNameIpMap = getHostIpExcel.getHostNameIpMap(); 38 | } 39 | 40 | public String getHostIP() { 41 | String hostIp = ""; 42 | String hostdemo = hostNameIpMap.get(hostName); 43 | if (hostdemo!= null && hostdemo.length()>0 ) { 44 | hostIp = hostdemo; 45 | } else { 46 | hostIp = ""; 47 | } 48 | return hostIp; 49 | } 50 | 51 | /* 测试代码 52 | public static void main (String[] args) throws IOException, BiffException { 53 | String HostName = "m.go.le.com"; 54 | String hostIP = new GetHostIp(HostName).getHostIP(); 55 | System.out.println(hostIP); 56 | } 57 | */ 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/tools/excelread/GetHostIpExcel.java: -------------------------------------------------------------------------------- 1 | package tools.excelread; 2 | 3 | import jxl.read.biff.BiffException; 4 | import org.testng.annotations.DataProvider; 5 | import org.testng.annotations.Test; 6 | 7 | import java.io.IOException; 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | 11 | /** 12 | * @author 李振7 13 | * Created Time: 2018/1/23 下午6:01 14 | */ 15 | 16 | public class GetHostIpExcel { 17 | //文件路径 18 | private String filePath = "/src/test/TestCaseExcelData/HostIP/"; 19 | //文件名,不包含文件后缀.xls 20 | private String fileName = "HostIP"; 21 | //sheet名 22 | private String caseName = "online"; 23 | private GetTestCaseExcel e; 24 | private HashMap[][] hostMap; 25 | private HashMap hostNameIpMap = new HashMap(); 26 | 27 | public GetHostIpExcel(String caseName) throws IOException, BiffException { 28 | this.caseName = caseName; 29 | e=new GetTestCaseExcel(filePath, fileName, caseName); 30 | hostMap = (HashMap[][]) e.getExcelData(); 31 | } 32 | 33 | public HashMap getHostNameIpMap() throws IOException, BiffException { 34 | for (HashMap[] data : hostMap) { 35 | for (HashMap data1 : data) { 36 | String hostip = ""; 37 | String hostname = ""; 38 | for(Map.Entry entry: data1.entrySet()) 39 | { 40 | if("HostIP".equalsIgnoreCase(entry.getKey())) { 41 | hostip = entry.getValue(); 42 | } else if ("HostName".equalsIgnoreCase(entry.getKey())) { 43 | hostname = entry.getValue(); 44 | } 45 | } 46 | System.out.println("HOST配置为:" + hostname + " = " + hostip); 47 | hostNameIpMap.put(hostname, hostip); 48 | } 49 | } 50 | 51 | return hostNameIpMap; 52 | } 53 | 54 | 55 | 56 | // public HashMap GetHostMap() { 57 | // HashMap hostHashMap = (HashMap) hostMap; 58 | // return hostHashMap; 59 | // } 60 | 61 | // public String GetHostIp(String hostNameKey) { 62 | // HashMap hostHashMap1 = (HashMap) hostMap; 63 | // String HostIPValue = ""; 64 | // 65 | // for(Map.Entry entry: hostHashMap1.entrySet()) 66 | // { 67 | // if (entry.getKey().equalsIgnoreCase(hostNameKey)) { 68 | // HostIPValue = entry.getValue(); 69 | // } else { 70 | // HostIPValue = ""; 71 | // } 72 | // } 73 | // return HostIPValue; 74 | // } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/tools/excelread/GetTestCaseExcel.java: -------------------------------------------------------------------------------- 1 | package tools.excelread; 2 | 3 | import jxl.Cell; 4 | import jxl.Sheet; 5 | import jxl.Workbook; 6 | import jxl.read.biff.BiffException; 7 | 8 | import java.io.File; 9 | import java.io.IOException; 10 | import java.util.ArrayList; 11 | import java.util.HashMap; 12 | 13 | /** 14 | * @author 李振7 15 | * Created Time: 2017/11/9 下午4:38 16 | * 根据filePath,fileName,caseName,获取excel中的数据,保存为HashMap[] 17 | */ 18 | @SuppressWarnings("ALL") 19 | public class GetTestCaseExcel { 20 | public Workbook workbook; 21 | public Sheet sheet; 22 | public Cell cell; 23 | int rows; 24 | int columns; 25 | //文件路径 26 | public String filePath; 27 | //文件名,不包含文件后缀.xls 28 | public String fileName; 29 | //sheet名 30 | public String caseName; 31 | public ArrayList arrkey = new ArrayList(); 32 | String sourceFile; 33 | 34 | /** 35 | * @param fileName excel文件名 36 | * @param caseName sheet名 37 | */ 38 | public GetTestCaseExcel(String filePath, String fileName, String caseName) { 39 | super(); 40 | this.fileName = fileName; 41 | this.caseName = caseName; 42 | this.filePath = filePath; 43 | } 44 | 45 | /** 46 | * 获得excel表中的数据 47 | */ 48 | @SuppressWarnings("AlibabaCollectionInitShouldAssignCapacity") 49 | public Object[][] getExcelData() throws BiffException, IOException { 50 | 51 | workbook = Workbook.getWorkbook(new File(this.setPath(filePath,fileName))); 52 | sheet = workbook.getSheet(caseName); 53 | //获取该sheet行数 54 | rows = sheet.getRows(); 55 | //获取该sheet列数 56 | columns = sheet.getColumns(); 57 | // 为了返回值是Object[][],定义一个多行单列的二维数组 58 | HashMap[][] arrmap = new HashMap[rows - 1][1]; 59 | 60 | // 对数组中所有元素hashmap进行初始化 61 | if (rows > 1) { 62 | for (int i = 0; i < rows - 1; i++) { 63 | arrmap[i][0] = new HashMap(100); 64 | } 65 | } else { 66 | System.out.println("excel中没有数据"); 67 | } 68 | 69 | // 获得首行的列名,作为hashmap的key值 70 | for (int c = 0; c < columns; c++) { 71 | String cellvalue = sheet.getCell(c, 0).getContents(); 72 | arrkey.add(cellvalue); 73 | } 74 | // 遍历所有的单元格的值添加到hashmap中 75 | for (int r = 1; r < rows; r++) { 76 | for (int c = 0; c < columns; c++) { 77 | String cellvalue = sheet.getCell(c, r).getContents(); 78 | arrmap[r - 1][0].put(arrkey.get(c), cellvalue); 79 | } 80 | } 81 | return arrmap; 82 | } 83 | 84 | /** 85 | * 获得excel文件的路径 86 | * @return 87 | * @throws IOException 88 | * /Users/leeco/Desktop/letv/workspace/tools/src/resources/testData.xlsx 89 | */ 90 | public String setPath(String path, String fileName) throws IOException { 91 | File directory = new File("."); 92 | sourceFile = directory.getCanonicalPath() + path + fileName + ".xls"; 93 | return sourceFile; 94 | } 95 | 96 | } -------------------------------------------------------------------------------- /src/main/java/tools/filetozip/FileToZip.java: -------------------------------------------------------------------------------- 1 | package tools.filetozip; 2 | 3 | /** 4 | * @author 李振7 5 | * Created Time: 2017/11/24 下午2:38 6 | */ 7 | 8 | import java.io.BufferedInputStream; 9 | import java.io.BufferedOutputStream; 10 | import java.io.File; 11 | import java.io.FileInputStream; 12 | import java.io.FileNotFoundException; 13 | import java.io.FileOutputStream; 14 | import java.io.IOException; 15 | import java.util.zip.ZipEntry; 16 | import java.util.zip.ZipOutputStream; 17 | /** 18 | * 将文件夹下面的文件 19 | * 打包成zip压缩文件 20 | * 21 | * @author admin 22 | * 23 | */ 24 | public final class FileToZip { 25 | 26 | private FileToZip(){} 27 | 28 | /** 29 | * 将存放在sourceFilePath目录下的源文件,打包成fileName名称的zip文件,并存放到zipFilePath路径下 30 | * @param sourceFilePath :待压缩的文件路径 31 | * @param zipFilePath :压缩后存放路径 32 | * @param fileName :压缩后文件的名称 33 | * @return 34 | */ 35 | public static boolean fileToZip(String sourceFilePath,String zipFilePath,String fileName){ 36 | boolean flag = false; 37 | File sourceFile = new File(sourceFilePath); 38 | FileInputStream fis = null; 39 | BufferedInputStream bis = null; 40 | FileOutputStream fos = null; 41 | ZipOutputStream zos = null; 42 | 43 | if(sourceFile.exists() == false){ 44 | System.out.println("待压缩的文件目录:"+sourceFilePath+"不存在."); 45 | }else{ 46 | try { 47 | File zipFile = new File(zipFilePath + "/" + fileName +".zip"); 48 | if(zipFile.exists()){ 49 | System.out.println(zipFilePath + "目录下存在名字为:" + fileName +".zip" +"打包文件."); 50 | }else{ 51 | File[] sourceFiles = sourceFile.listFiles(); 52 | if(null == sourceFiles || sourceFiles.length<1){ 53 | System.out.println("待压缩的文件目录:" + sourceFilePath + "里面不存在文件,无需压缩."); 54 | }else{ 55 | fos = new FileOutputStream(zipFile); 56 | zos = new ZipOutputStream(new BufferedOutputStream(fos)); 57 | byte[] bufs = new byte[1024*10]; 58 | for(int i=0;i headerMap,为header列表 27 | private Map headerMap = new HashMap(); 28 | //String url为post请求的url 29 | private String url = ""; 30 | //断言list,元素为String类型 31 | private List responseDataList = new LinkedList<>(); 32 | private String httpStatus = ""; 33 | private HttpResponse httpresponse = null; 34 | private String responseBody = ""; 35 | private String hostIP = ""; 36 | 37 | /** 38 | * 构造函数 39 | */ 40 | public HttpGetTest(Map headerMap, String url, List responseDataList, String httpStatus, String hostIP) throws Exception { 41 | this.headerMap = headerMap; 42 | this.url = url; 43 | //做非空判断,避免空指针 44 | if (hostIP!= null && hostIP.length()>0) { 45 | this.hostIP = hostIP; 46 | } 47 | this.responseDataList = responseDataList; 48 | this.httpStatus = httpStatus; 49 | httpresponse = httpGetRequest(); 50 | responseBody = EntityUtils.toString(httpresponse.getEntity(), "utf-8"); 51 | isRequestSuccessful(); 52 | } 53 | 54 | public Boolean isRequestSuccessful() throws Exception { 55 | //以UTF-8格式,返回包含内容的字符串 56 | //HttpResponse.getEntity(),返回响应实体,如果没有,则为null 57 | int i = responseDataList.size(); 58 | int j = 0; 59 | boolean isRequestSuccessful = false; 60 | if(responseDataList.size()>0) { 61 | for (String responseData : responseDataList) { 62 | CharSequence s1 = responseData.subSequence(0, responseData.length()); 63 | if (responseBody.contains(s1)) { 64 | j++; //遍历断言,每次断言成功,j+1 65 | } else { 66 | Reporter.log(">>>>>>>>>>>>>>>>>>>>断言失败的ResponseData是:" + responseData + "<<<<<<<<<<<<<<<<<<<<"); 67 | System.out.println(">>>>>>>>>>>>>>>>>>>>断言失败的ResponseData是:" + responseData + "<<<<<<<<<<<<<<<<<<<<"); 68 | } 69 | } 70 | } 71 | Integer realHttpStatus = httpresponse.getStatusLine().getStatusCode(); 72 | String s = realHttpStatus.toString(); 73 | boolean statusAssertion = httpStatus.equals(s); 74 | if (statusAssertion) { 75 | Reporter.log("HttpStatus断言成功"); 76 | //断言 77 | if (i == j) { 78 | isRequestSuccessful = true; 79 | Reporter.log("所有ResponseData均断言成功"); 80 | } else { 81 | Reporter.log(">>>>>>>>>>>>>>>>>>>>ResponseData断言失败<<<<<<<<<<<<<<<<<<<<"); 82 | System.out.println(">>>>>>>>>>>>>>>>>>>>ResponseData断言失败<<<<<<<<<<<<<<<<<<<<"); 83 | } 84 | } else { 85 | isRequestSuccessful = false; 86 | Reporter.log(">>>>>>>>>>>>>>>>>>>>" + "状态码校验失败,实际返回状态码为:" + httpresponse.getStatusLine().getStatusCode() 87 | + "\n断言的状态码httpStatus为:" + httpStatus + "<<<<<<<<<<<<<<<<<<<<"); 88 | System.out.println(">>>>>>>>>>>>>>>>>>>>" + "状态码校验失败,实际返回状态码为:" + httpresponse.getStatusLine().getStatusCode() 89 | + "\n断言的状态码httpStatus为:" + httpStatus + "<<<<<<<<<<<<<<<<<<<<"); 90 | } 91 | 92 | 93 | 94 | try { 95 | if(isRequestSuccessful) { 96 | System.out.println("请求成功的接口URL为:\n" + url); 97 | Reporter.log("请求成功的接口URL为:\n" + url); 98 | System.out.println("responseBody: \n" + responseBody); 99 | Reporter.log("responseBody: \n" + responseBody); 100 | Assert.assertTrue(true); 101 | } else { 102 | System.err.println("请求失败的接口URL为:\n" + url); 103 | Reporter.log("请求失败的接口URL为:\n" + url); 104 | System.err.println("responseBody: \n" + responseBody); 105 | Reporter.log("responseBody: \n" + responseBody); 106 | Assert.assertTrue(false); 107 | } 108 | } catch (Exception e) { 109 | e.printStackTrace(); 110 | } 111 | 112 | return isRequestSuccessful; 113 | } 114 | 115 | 116 | public HttpResponse httpGetRequest() throws Exception{ 117 | //基于要发送的HTTP请求类型创建HttpGet或者HttpPost实例 118 | HttpGet httpGet = new HttpGet(url); 119 | 120 | //get请求,添加header 121 | for(Map.Entry entry:headerMap.entrySet()){ 122 | httpGet.addHeader(entry.getKey(),entry.getValue()); 123 | } 124 | 125 | //创建HttpClient对象,HttpClients.createDefault()。 126 | HttpClient httpClient = HttpClients.createDefault(); 127 | HttpResponse httpresponse = null; 128 | 129 | 130 | //做非空判断,避免空指针 131 | if (hostIP!= null && hostIP.length()>0) { 132 | //绑定host 133 | HttpHost httpHost = new HttpHost(hostIP); 134 | 135 | // 调用HttpClient对象的execute(HttpUriRequest request)发送请求,该方法返回一个HttpResponse 136 | httpresponse = httpClient.execute(httpHost, httpGet); 137 | } else { 138 | // 调用HttpClient对象的execute(HttpUriRequest request)发送请求,该方法返回一个HttpResponse 139 | httpresponse = httpClient.execute(httpGet); 140 | } 141 | return httpresponse; 142 | } 143 | 144 | public String getResponseHeader() throws Exception{ 145 | return httpresponse.toString(); 146 | } 147 | 148 | public String getResponseBody() throws Exception{ 149 | return responseBody; 150 | } 151 | 152 | public String getHttpStatus() throws Exception{ 153 | Integer realHttpStatus = httpresponse.getStatusLine().getStatusCode(); 154 | String s = realHttpStatus.toString(); 155 | return s; 156 | } 157 | 158 | } 159 | -------------------------------------------------------------------------------- /src/main/java/tools/httprequest/HttpJmeterExcelData.java: -------------------------------------------------------------------------------- 1 | package tools.httprequest; 2 | 3 | import jxl.read.biff.BiffException; 4 | import org.testng.Assert; 5 | import org.testng.annotations.DataProvider; 6 | import org.testng.annotations.Test; 7 | import tools.excelread.GetHostIp; 8 | import tools.excelread.GetTestCaseExcel; 9 | 10 | import java.io.IOException; 11 | import java.util.HashMap; 12 | import java.util.LinkedList; 13 | import java.util.List; 14 | import java.util.Map; 15 | 16 | /** 17 | * @author 李振7 18 | * Created Time: 2018/1/22 上午10:27 19 | */ 20 | 21 | public class HttpJmeterExcelData { 22 | //文件路径src/testExampleForJmeterData/GetTestCaseExcel/dubbo 23 | public String filePath = ""; 24 | //文件名,不包含文件后缀.xls 25 | public String fileName = ""; 26 | //sheet名 27 | public String caseName = ""; 28 | 29 | 30 | public HttpJmeterExcelData(String filePath, String fileName, String caseName) throws IOException, BiffException { 31 | this.filePath = filePath; 32 | this.fileName = fileName; 33 | this.caseName = caseName; 34 | } 35 | 36 | 37 | @DataProvider 38 | public Object[][] Numbers() throws BiffException, IOException { 39 | GetTestCaseExcel e=new GetTestCaseExcel(filePath, fileName, caseName); 40 | return e.getExcelData(); 41 | } 42 | 43 | @Test(dataProvider = "Numbers") 44 | public void test(HashMap data) throws IOException, BiffException { 45 | //Map paramMap,为post请求的参数列表 46 | Map paramMap = new HashMap(100); 47 | //Map headerMap,为header列表 48 | Map headerMap = new HashMap(100); 49 | //String url为post请求的url 50 | String url = ""; 51 | //断言list,元素为String类型 52 | List responseDataList = new LinkedList<>(); 53 | 54 | String caseTestOrNot = data.get("CaseTestOrNot"); 55 | String lastOrNot = data.get("LastOrNot"); 56 | String caseID = data.get("CaseID"); 57 | String testCaseName = data.get("TestCaseName"); 58 | String protocol = data.get("Protocol"); 59 | String requstMethod = data.get("RequstMethod"); 60 | String domain = data.get("Domain"); 61 | String path = data.get("Path"); 62 | String port = data.get("Port"); 63 | String requstData = data.get("RequstData"); 64 | String httpStatus = data.get("HttpStatus"); 65 | String responseMessage = data.get("ResponseMessage"); 66 | String responseData1 = data.get("ResponseData1").replaceAll("\\\\",""); 67 | String responseData2 = data.get("ResponseData2").replaceAll("\\\\",""); 68 | String responseData3 = data.get("ResponseData3").replaceAll("\\\\",""); 69 | //获取要绑定的hostIP 70 | String hostIP = ""; 71 | 72 | String hostdemo = new GetHostIp(domain).getHostIP(); 73 | //做非空判断,避免空指针 74 | if (hostdemo!= null && hostdemo.length()>0) { 75 | hostIP = hostdemo; 76 | } else { 77 | hostIP = ""; 78 | } 79 | 80 | 81 | //配置Header 82 | headerMap.put("mEncodeMethod", "none"); 83 | headerMap.put("User-Agent", "LetvShop;1.6.7.0;Letv+X500;android-phone;21;zh_CN"); 84 | headerMap.put("Content-Type", "application/json"); 85 | headerMap.put("cookie", "ssouid=2126494707; sso_tk=102XXXO0EZzx5TDSj2oFRbam2avyAm3El7RLin1zm2tvubfEFUy1cJfHZElJVW3Um30ffBYl7GvOkm2Mfdim38Aaipj2SlKPxORcufgm1O5EyBfhFbP2PDbcm4"); 86 | 87 | //配置ResponseData 88 | if (responseData1.length()>0){ 89 | responseDataList.add(responseData1); 90 | } 91 | if (responseData1.length()>0) { 92 | responseDataList.add(responseData2); 93 | } 94 | if (responseData1.length()>0) { 95 | responseDataList.add(responseData3); 96 | } 97 | System.out.println(responseData1 + "\n" + responseData2 + "\n" + responseData3); 98 | 99 | //配置http status 100 | httpStatus = httpStatus; 101 | String get = "get"; 102 | String post = "post"; 103 | if (get.equalsIgnoreCase(requstMethod)) { 104 | // url生成 105 | if (port == null || port.length() == 0) { 106 | url = protocol + "://" + domain + path + "?" + requstData; 107 | } else { 108 | url = protocol + "://" + domain + ":" + port + path + "?" + requstData; 109 | } 110 | 111 | try { 112 | System.out.println(url); 113 | HttpGetTest httpGetTest = new HttpGetTest(headerMap, url, responseDataList, httpStatus, hostIP); 114 | if(httpGetTest.isRequestSuccessful()) { 115 | Assert.assertTrue(true); 116 | } else { 117 | Assert.assertTrue(false); 118 | } 119 | } catch (Exception e) { 120 | e.printStackTrace(); 121 | } 122 | 123 | } else if (post.equalsIgnoreCase(requstMethod)) { 124 | // url生成 125 | if (port == null || port.length() == 0) { 126 | url = protocol + "://" + domain + path; 127 | } else { 128 | url = protocol + "://" + domain + ":" + port + path; 129 | } 130 | 131 | //将RequstData字符串分解保存到paramMap中 132 | String[] requestParam = requstData.split("&", 0); 133 | for (int i=0; i paramMap = new HashMap(); 158 | 159 | String RequstData = "name=lizhen&age=27&city=beijing"; 160 | String[] requestParam = RequstData.split("&", 0); 161 | System.out.println(requestParam.length); 162 | System.err.println(requestParam[0] + ", " + requestParam[1]); 163 | 164 | for (int i=0; i responseDataList = new LinkedList<>(); 35 | private String httpStatus = ""; 36 | private HttpResponse httpresponse; 37 | private String responseBody; 38 | private String hostIP = ""; 39 | 40 | /** 41 | * 构造函数 42 | */ 43 | public HttpPostTest(Map paramMap, Map headerMap, String url, List responseDataList, String httpStatus, String hostIP) throws Exception { 44 | this.paramMap = paramMap; 45 | this.headerMap = headerMap; 46 | this.url = url; 47 | //做非空判断,避免空指针 48 | if (hostIP!= null && hostIP.length()>0) { 49 | this.hostIP = hostIP; 50 | } 51 | this.responseDataList = responseDataList; 52 | this.httpStatus = httpStatus; 53 | httpresponse = httpPostRequest(); 54 | //以UTF-8格式,返回包含内容的字符串 55 | //HttpResponse.getEntity(),返回响应实体,如果没有,则为null 56 | responseBody = EntityUtils.toString(httpresponse.getEntity(), "utf-8"); 57 | isRequestSuccessful(); 58 | } 59 | 60 | public Boolean isRequestSuccessful() throws Exception { 61 | int i = responseDataList.size(); 62 | int j = 0; 63 | boolean isRequestSuccessful = false; 64 | 65 | if(responseDataList.size()>0) { 66 | for (String responseData : responseDataList) { 67 | CharSequence s1 = responseData.subSequence(0, responseData.length()); 68 | if (responseBody.contains(s1)) { 69 | j++; //遍历断言,每次断言成功,j+1 70 | } else { 71 | Reporter.log(">>>>>>>>>>>>>>>>>>>>断言失败的ResponseData是:" + responseData + "<<<<<<<<<<<<<<<<<<<<"); 72 | System.out.println(">>>>>>>>>>>>>>>>>>>>断言失败的ResponseData是:" + responseData + "<<<<<<<<<<<<<<<<<<<<"); 73 | } 74 | } 75 | } 76 | 77 | Integer realHttpStatus = httpresponse.getStatusLine().getStatusCode(); 78 | String s = realHttpStatus.toString(); 79 | boolean statusAssertion = httpStatus.equals(s); 80 | if (statusAssertion) { 81 | System.out.println("HttpStatus断言成功"); 82 | //断言 83 | if (i == j) { 84 | isRequestSuccessful = true; 85 | Reporter.log("所有ResponseData均断言成功"); 86 | } else { 87 | Reporter.log(">>>>>>>>>>>>>>>>>>>>ResponseData断言失败<<<<<<<<<<<<<<<<<<<<"); 88 | System.out.println(">>>>>>>>>>>>>>>>>>>>ResponseData断言失败<<<<<<<<<<<<<<<<<<<<"); 89 | } 90 | } else { 91 | isRequestSuccessful = false; 92 | Reporter.log(">>>>>>>>>>>>>>>>>>>>" + "状态码校验失败,实际返回状态码为:" + httpresponse.getStatusLine().getStatusCode() 93 | + "\n断言的状态码httpStatus为:" + httpStatus + "<<<<<<<<<<<<<<<<<<<<"); 94 | System.out.println(">>>>>>>>>>>>>>>>>>>>" + "状态码校验失败,实际返回状态码为:" + httpresponse.getStatusLine().getStatusCode() 95 | + "\n断言的状态码httpStatus为:" + httpStatus + "<<<<<<<<<<<<<<<<<<<<"); 96 | } 97 | 98 | try { 99 | if(isRequestSuccessful) { 100 | System.out.println("请求成功的接口URL为:\n" + url); 101 | Reporter.log("请求成功的接口URL为:\n" + url); 102 | System.out.println("responseBody: \n" + responseBody); 103 | Reporter.log("responseBody: \n" + responseBody); 104 | Assert.assertTrue(true); 105 | } else { 106 | System.err.println("请求失败的接口URL为:\n" + url); 107 | Reporter.log("请求失败的接口URL为:\n" + url); 108 | System.err.println("responseBody: \n" + responseBody); 109 | Reporter.log("responseBody: \n" + responseBody); 110 | Assert.assertTrue(false); 111 | } 112 | } catch (Exception e) { 113 | e.printStackTrace(); 114 | } 115 | return isRequestSuccessful; 116 | } 117 | 118 | 119 | public HttpResponse httpPostRequest() throws Exception{ 120 | List paramlist = new LinkedList(); 121 | //Map.Entry 映射项(键-值对) 122 | // Set> entrySet() 返回此映射中包含的映射关系的 Set 视图 123 | for(Map.Entry entry:paramMap.entrySet()){ 124 | paramlist.add(new BasicNameValuePair(entry.getKey(),entry.getValue())); 125 | } 126 | UrlEncodedFormEntity paramformEntity = new UrlEncodedFormEntity(paramlist,"utf-8"); 127 | 128 | //基于要发送的HTTP请求类型创建HttpGet或者HttpPost实例 129 | org.apache.http.client.methods.HttpPost httpPost = new org.apache.http.client.methods.HttpPost(url); 130 | 131 | //对于POST请求,创建NameValuePair列表,并添加所有的表单参数.然后把它填充进HttpPost实体.添加所有参数 132 | httpPost.setEntity(paramformEntity); 133 | //post请求,添加header 134 | for(Map.Entry entry:headerMap.entrySet()){ 135 | httpPost.addHeader(entry.getKey(),entry.getValue()); 136 | } 137 | //创建HttpClient对象,HttpClients.createDefault()。 138 | HttpClient httpClient = HttpClients.createDefault(); 139 | HttpResponse httpresponse = null; 140 | 141 | //做非空判断,避免空指针 142 | if (hostIP!= null && hostIP.length()>0) { 143 | //绑定host 144 | HttpHost httpHost = new HttpHost(hostIP); 145 | 146 | // 调用HttpClient对象的execute(HttpHost httpHost, HttpUriRequest request)发送请求,该方法返回一个HttpResponse 147 | httpresponse = httpClient.execute(httpHost, httpPost); 148 | } else { 149 | // 调用HttpClient对象的execute(HttpUriRequest request)发送请求,该方法返回一个HttpResponse 150 | httpresponse = httpClient.execute(httpPost); 151 | } 152 | 153 | return httpresponse; 154 | } 155 | 156 | public String getResponseHeader() throws Exception{ 157 | return httpresponse.toString(); 158 | } 159 | 160 | public String getResponseBody() throws Exception{ 161 | return responseBody; 162 | } 163 | 164 | public String getHttpStatus() throws Exception{ 165 | Integer realHttpStatus = httpresponse.getStatusLine().getStatusCode(); 166 | String s = realHttpStatus.toString(); 167 | return s; 168 | } 169 | 170 | } 171 | -------------------------------------------------------------------------------- /src/main/java/tools/mail/MailConfig.java: -------------------------------------------------------------------------------- 1 | package tools.mail; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.util.Properties; 6 | 7 | /** 8 | * @author 李振7 9 | * Created Time: 2017/10/23 上午10:21 10 | */ 11 | public class MailConfig { 12 | private static final String PROPERTIES_DEFAULT = "mailConfig.properties"; 13 | public static String host; 14 | public static Integer port; 15 | public static String userName; 16 | public static String passWord; 17 | public static String emailForm; 18 | public static String timeout; 19 | public static String personal; 20 | public static Properties properties; 21 | static{ 22 | init(); 23 | } 24 | 25 | /** 26 | * 初始化 27 | */ 28 | private static void init() { 29 | properties = new Properties(); 30 | InputStream inputStream = null; 31 | try{ 32 | 33 | inputStream = MailConfig.class.getClassLoader().getResourceAsStream(PROPERTIES_DEFAULT); 34 | properties.load(inputStream); 35 | inputStream.close(); 36 | host = properties.getProperty("mailHost"); 37 | port = Integer.parseInt(properties.getProperty("mailPort")); 38 | userName = properties.getProperty("mailUsername"); 39 | passWord = properties.getProperty("mailPassword"); 40 | emailForm = properties.getProperty("mailFrom"); 41 | timeout = properties.getProperty("mailTimeout"); 42 | personal = "乐视商城自动化测试"; 43 | } catch(IOException e){ 44 | e.printStackTrace(); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/tools/mail/MailListener.java: -------------------------------------------------------------------------------- 1 | package tools.mail; 2 | 3 | import jxl.read.biff.BiffException; 4 | import tools.filetozip.FileToZip; 5 | 6 | import javax.mail.MessagingException; 7 | import javax.mail.internet.AddressException; 8 | import javax.mail.internet.InternetAddress; 9 | import java.io.IOException; 10 | import java.io.UnsupportedEncodingException; 11 | import java.text.SimpleDateFormat; 12 | import java.util.Date; 13 | 14 | /** 15 | * @author 李振7 16 | * Created Time: 2017/11/24 下午3:07 17 | */ 18 | public class MailListener { 19 | /** 20 | * 邮件主题 21 | */ 22 | public String subject; 23 | /**邮件组*/ 24 | public InternetAddress[] testAddressList; 25 | /**邮件内容*/ 26 | public String mailHtml; 27 | 28 | public MailListener() throws AddressException, IOException, BiffException { 29 | testAddressList = new TestAddressList().getAddressList(); 30 | } 31 | 32 | public void failMailTest() { 33 | /* 34 | 压缩报告文件 35 | */ 36 | Date now = new Date(); 37 | 38 | //可以方便地修改日期格式 39 | SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); 40 | String datatime = dateFormat.format(now); 41 | String sourceFilePath = "target/surefire-reports/html"; 42 | String zipFilePath = "target/surefire-reports/"; 43 | String fileName = "ReportHTMLFile" + datatime; 44 | boolean flag = FileToZip.fileToZip(sourceFilePath, zipFilePath, fileName); 45 | if (flag) { 46 | System.out.println("文件打包成功!"); 47 | } else { 48 | System.out.println("文件打包失败!"); 49 | } 50 | 51 | /* 52 | 发送邮件 53 | */ 54 | String filePath = "target/surefire-reports/" + fileName + ".zip"; 55 | MailUtil mailUtil = new MailUtil(); 56 | 57 | try { 58 | mailUtil.sendMail(testAddressList, subject, mailHtml, fileName+ ".zip", filePath); 59 | } catch (MessagingException e) { 60 | e.printStackTrace(); 61 | } catch (UnsupportedEncodingException e) { 62 | e.printStackTrace(); 63 | } 64 | } 65 | 66 | } 67 | 68 | -------------------------------------------------------------------------------- /src/main/java/tools/mail/MailUtil.java: -------------------------------------------------------------------------------- 1 | package tools.mail; 2 | 3 | import org.springframework.mail.javamail.JavaMailSenderImpl; 4 | import org.springframework.mail.javamail.MimeMessageHelper; 5 | 6 | import javax.mail.MessagingException; 7 | import javax.mail.internet.InternetAddress; 8 | import javax.mail.internet.MimeMessage; 9 | import java.io.File; 10 | import java.io.UnsupportedEncodingException; 11 | import java.util.Properties; 12 | 13 | /** 14 | * @author 李振7 15 | * Created Time: 2017/10/23 上午10:25 16 | */ 17 | public class MailUtil { 18 | private static final String HOST = MailConfig.host; 19 | private static final Integer PORT = MailConfig.port; 20 | private static final String USERNAME = MailConfig.userName; 21 | private static final String PASSWORD = MailConfig.passWord; 22 | private static final String EMAIL_FORM = MailConfig.emailForm; 23 | private static final String TIMEOUT = MailConfig.timeout; 24 | private static final String PERSONAL = MailConfig.personal; 25 | 26 | /** 27 | * 邮件发送器 28 | * 29 | * @return 配置好的工具 30 | */ 31 | private static JavaMailSenderImpl createMailSender() { 32 | JavaMailSenderImpl sender = new JavaMailSenderImpl(); 33 | sender.setHost(HOST); 34 | sender.setPort(PORT); 35 | sender.setUsername(USERNAME); 36 | sender.setPassword(PASSWORD); 37 | sender.setDefaultEncoding("Utf-8"); 38 | Properties p = new Properties(); 39 | p.setProperty("mail.smtp.timeout", TIMEOUT); 40 | p.setProperty("mail.smtp.auth", "false"); 41 | sender.setJavaMailProperties(p); 42 | return sender; 43 | } 44 | 45 | private static JavaMailSenderImpl mailSender = createMailSender(); 46 | 47 | /** 48 | * 发送邮件 49 | * 50 | * @param to 接受人 51 | * @param subject 主题 52 | * @param mailHtml 发送html内容 53 | * @throws MessagingException 异常 54 | * @throws UnsupportedEncodingException 异常 55 | */ 56 | public void sendMail(InternetAddress[] to, String subject, String mailHtml, String fileName, String filePath) throws MessagingException,UnsupportedEncodingException { 57 | 58 | MimeMessage mimeMessage = mailSender.createMimeMessage(); 59 | // 设置utf-8或GBK编码,否则邮件会有乱码 60 | MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8"); 61 | 62 | messageHelper.setFrom(EMAIL_FORM, PERSONAL); 63 | messageHelper.setTo(to); 64 | messageHelper.setSubject(subject); 65 | messageHelper.setText(mailHtml, true); 66 | messageHelper.addAttachment(fileName,new File(filePath)); 67 | 68 | mailSender.send(mimeMessage); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/tools/mail/TestAddressList.java: -------------------------------------------------------------------------------- 1 | package tools.mail; 2 | 3 | import jxl.read.biff.BiffException; 4 | import org.testng.annotations.Test; 5 | import tools.excelread.GetTestCaseExcel; 6 | 7 | import javax.mail.internet.AddressException; 8 | import javax.mail.internet.InternetAddress; 9 | import java.io.IOException; 10 | import java.util.ArrayList; 11 | import java.util.HashMap; 12 | import java.util.Map; 13 | 14 | /** 15 | * @author 李振7 16 | * Created Time: 2017/12/8 下午3:17 17 | */ 18 | public class TestAddressList { 19 | //邮件组 20 | private InternetAddress[] testAddressList; 21 | private ArrayList emailList = new ArrayList(); 22 | //文件路径src/testExampleForJmeterData/GetTestCaseExcel/dubbo 23 | private String filePath = "/src/test/TestCaseExcelData/emailList/"; 24 | //文件名,不包含文件后缀.xls 25 | private String fileName = "emailList"; 26 | //sheet名 27 | private String caseName = "emailList"; 28 | private GetTestCaseExcel e; 29 | private HashMap[][] hostMap; 30 | 31 | @Test 32 | public TestAddressList() throws IOException, BiffException, AddressException { 33 | this.caseName = caseName; 34 | e=new GetTestCaseExcel(filePath, fileName, caseName); 35 | hostMap = (HashMap[][]) e.getExcelData(); 36 | getAddressList(); 37 | } 38 | 39 | public InternetAddress[] getAddressList() throws AddressException { 40 | for (HashMap[] data : hostMap) { 41 | for (HashMap data1 : data) { 42 | for(Map.Entry entry: data1.entrySet()) 43 | { 44 | String emailStr = entry.getValue(); 45 | if (emailStr!=null && emailStr.length()>0) { 46 | emailList.add(emailStr); 47 | } 48 | } 49 | } 50 | } 51 | int emailListSize = emailList.size(); 52 | if (emailListSize>0) { 53 | testAddressList = new InternetAddress[emailList.size()]; 54 | } 55 | for(int i=0; i0) { 58 | testAddressList[i] = new InternetAddress(email); 59 | } 60 | } 61 | return testAddressList; 62 | } 63 | 64 | 65 | } -------------------------------------------------------------------------------- /src/main/java/tools/sqlRequest/DBHelper.java: -------------------------------------------------------------------------------- 1 | package tools.sqlRequest; 2 | 3 | import org.testng.Reporter; 4 | 5 | import java.sql.*; 6 | import java.util.regex.Pattern; 7 | 8 | /** 9 | * @author 李振7 10 | * Created Time: 2017/12/26 上午10:50 11 | */ 12 | public class DBHelper { 13 | private String DBurl = "jdbc:mysql://127.0.0.1/student"; 14 | private String JdbcName = "com.mysql.jdbc.Driver"; 15 | private String UserName = "root"; 16 | private String PassWord = "root"; 17 | private String sql = ""; 18 | 19 | private Connection conn = null; 20 | private PreparedStatement pst = null; 21 | private Statement stmt = null; 22 | private boolean isSuccessful = false; 23 | 24 | public DBHelper(String DBurl, String JdbcName, String UserName, String PassWord, String sql) { 25 | this.DBurl = DBurl; 26 | this.JdbcName = JdbcName; 27 | this.UserName = UserName; 28 | this.PassWord = PassWord; 29 | this.sql = sql; 30 | 31 | // 1. 加载驱动程序 32 | try { 33 | Class.forName(JdbcName); 34 | } catch (ClassNotFoundException e1) { 35 | e1.printStackTrace(); 36 | } 37 | 38 | // 2. 获取DB连接 39 | try { 40 | conn = DriverManager.getConnection(DBurl, UserName, PassWord); 41 | }catch (SQLException e2) { 42 | System.out.println("数据库登录失败,数据库为:" + DBurl + ",用户名为:" + UserName + ",密码为:" + PassWord); 43 | Reporter.log("数据库登录失败,数据库为:" + DBurl + ",用户名为:" + UserName + ",密码为:" + PassWord); 44 | Reporter.log("数据路登录失败原因为:" +e2.getMessage()); 45 | e2.printStackTrace(); 46 | } 47 | 48 | // 3. 通过数据库的连接操作数据库,实现增删改查 49 | if (conn != null) { 50 | 51 | try { 52 | pst = conn.prepareStatement(sql);//准备执行语句 53 | } catch (SQLException e3) { 54 | e3.printStackTrace(); 55 | } 56 | 57 | try { 58 | stmt = conn.createStatement(); 59 | 60 | // (?i)相当于 Pattern.CASE_INSENSITIVE,启用不区分大小写的匹配 61 | if(Pattern.compile("(?i)select.*").matcher(sql).find()) { 62 | boolean sqlResult = pst.execute(sql); 63 | if(sqlResult){ 64 | System.out.println("sql语句执行成功,sql语句为:" + sql); 65 | isSuccessful = true; 66 | }else { 67 | Reporter.log("sql语句执行失败,sql语句为:" + sql); 68 | System.out.println("sql语句执行失败,sql语句为:" + sql); 69 | isSuccessful = false; 70 | } 71 | } else if(Pattern.compile("(?i)update.*").matcher(sql).find()) { 72 | int rowsAffected = stmt.executeUpdate(sql); 73 | if(rowsAffected>0) { 74 | System.out.println("sql语句执行成功,sql语句为:" + sql); 75 | isSuccessful = true; 76 | }else { 77 | Reporter.log("sql语句执行失败,sql语句为:" + sql); 78 | System.out.println("sql语句执行失败,sql语句为:" + sql); 79 | isSuccessful = false; 80 | } 81 | } else if (Pattern.compile("(?i)insert.*").matcher(sql).find()) { 82 | int rowsAffected = stmt.executeUpdate(sql); 83 | if(rowsAffected>0) { 84 | System.out.println("sql语句执行成功,sql语句为:" + sql); 85 | isSuccessful = true; 86 | }else { 87 | Reporter.log("sql语句执行失败,sql语句为:" + sql); 88 | System.out.println("sql语句执行失败,sql语句为:" + sql); 89 | isSuccessful = false; 90 | } 91 | } else if (Pattern.compile("(?i)delete.*").matcher(sql).find()) { 92 | int rowsAffected = stmt.executeUpdate(sql); 93 | if(rowsAffected>0) { 94 | System.out.println("sql语句执行成功,sql语句为:" + sql); 95 | isSuccessful = true; 96 | }else { 97 | Reporter.log("sql语句执行失败,sql语句为:" + sql); 98 | System.out.println("sql语句执行失败,sql语句为:" + sql); 99 | isSuccessful = false; 100 | } 101 | } 102 | } catch (SQLException e6) { 103 | Reporter.log("sql语句执行失败,sql语句为:" + sql); 104 | System.out.println("sql语句执行失败,sql语句为:" + sql); 105 | Reporter.log("sql执行失败原因:" + e6.getMessage()); 106 | e6.printStackTrace(); 107 | } 108 | 109 | close(); 110 | 111 | } else { 112 | isSuccessful = false; 113 | } 114 | 115 | } 116 | 117 | public Boolean isRequestSuccessful() { 118 | if (isSuccessful) { 119 | return true; 120 | } else { 121 | return false; 122 | } 123 | } 124 | 125 | 126 | public void close() { 127 | try { 128 | this.conn.close(); 129 | this.pst.close(); 130 | } catch (SQLException e5) { 131 | e5.printStackTrace(); 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /src/test/TestCaseExcelData/HostIP/HostIP.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OnTheWay111/Avatar/9c26e2630aaf46b6d0e4641e3555465b78383a5e/src/test/TestCaseExcelData/HostIP/HostIP.xls -------------------------------------------------------------------------------- /src/test/TestCaseExcelData/dubbo/com.xxxx.order.promise.api.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OnTheWay111/Avatar/9c26e2630aaf46b6d0e4641e3555465b78383a5e/src/test/TestCaseExcelData/dubbo/com.xxxx.order.promise.api.xls -------------------------------------------------------------------------------- /src/test/TestCaseExcelData/emailList/emailList.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OnTheWay111/Avatar/9c26e2630aaf46b6d0e4641e3555465b78383a5e/src/test/TestCaseExcelData/emailList/emailList.xls -------------------------------------------------------------------------------- /src/test/TestCaseExcelData/http/testcase.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OnTheWay111/Avatar/9c26e2630aaf46b6d0e4641e3555465b78383a5e/src/test/TestCaseExcelData/http/testcase.xls -------------------------------------------------------------------------------- /src/test/TestCaseExcelData/http/tradeservice.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OnTheWay111/Avatar/9c26e2630aaf46b6d0e4641e3555465b78383a5e/src/test/TestCaseExcelData/http/tradeservice.xls -------------------------------------------------------------------------------- /src/test/java/com/testcase/dubbo/TestIPromiseForOrderService.java: -------------------------------------------------------------------------------- 1 | package com.testcase.dubbo; 2 | 3 | import com.alibaba.dubbo.common.serialize.support.kryo.RestRequest; 4 | import com.alibaba.dubbo.common.serialize.support.kryo.RestResponse; 5 | import com.lemall.srd.order.promise.api.IPromiseForOrderService; 6 | import com.lemall.srd.order.promise.domain.common.PromiseVersion; 7 | import com.lemall.srd.order.promise.domain.request.FreeStockForOrderParam; 8 | import jxl.read.biff.BiffException; 9 | import org.springframework.context.ApplicationContext; 10 | import org.springframework.context.support.ClassPathXmlApplicationContext; 11 | import org.testng.Assert; 12 | import org.testng.Reporter; 13 | import org.testng.annotations.DataProvider; 14 | import org.testng.annotations.Test; 15 | import tools.excelread.GetTestCaseExcel; 16 | 17 | import java.io.IOException; 18 | import java.util.HashMap; 19 | 20 | /** 21 | * @author 李振7 22 | * Created Time: 2017/12/8 下午4:59 23 | */ 24 | public class TestIPromiseForOrderService { 25 | 26 | //不需要修改:固定值变量 27 | private static final String FILE_PATH = "/src/test/TestCaseExcelData/dubbo/"; //文件路径src/testExampleForJmeterData/GetTestCaseExcel/dubbo 28 | public static final ApplicationContext CONTEXT = new ClassPathXmlApplicationContext("dubbo-config.xml"); 29 | private GetTestCaseExcel excelData; 30 | 31 | 32 | //1、fileName是dubbo接口的包名, caseName是dubbo接口名 33 | private String fileName = "com.xxxx.order.promise.api"; //dubbo接口的包名作为文件名,不包含文件后缀.xls 34 | private String caseName = "IPromiseForOrderService"; //dubbo接口名作为sheet名 35 | 36 | 37 | //2、request随着dubbo接口的不同,需要定义指定类型 38 | private FreeStockForOrderParam requestParam = new FreeStockForOrderParam(); 39 | 40 | 41 | //3、新建dubbo的消费者对象,需要修改类名 42 | private IPromiseForOrderService ClassConsumer = (IPromiseForOrderService) CONTEXT.getBean(caseName); 43 | 44 | 45 | //不需要修改: 从excel文件中读取数据,不需要修改 46 | @DataProvider 47 | public Object[][] Numbers() throws BiffException, IOException { 48 | excelData = new GetTestCaseExcel(FILE_PATH, fileName, caseName); 49 | return excelData.getExcelData(); 50 | } 51 | 52 | //不需要修改:dubbo接口访问Provider 53 | @Test(dataProvider = "Numbers") 54 | public void test(HashMap data) { 55 | 56 | //4、从excel中取出各项参数 57 | String orderNo = data.get("orderNo"); 58 | String operater = data.get("operater"); 59 | String channel = data.get("channel"); 60 | String operateId = data.get("operateId"); 61 | String version = PromiseVersion.V_1_0_0.getVersion(); 62 | String status = data.get("Status"); 63 | String message = data.get("Message"); 64 | String Result = data.get("Result"); 65 | 66 | //5、将请求参数导入对象requestParam中 67 | requestParam.setOrderNo(orderNo); 68 | requestParam.setOperater(operater); 69 | requestParam.setChannel(channel); 70 | requestParam.setOperateId(operateId); 71 | requestParam.setVersion(version); 72 | 73 | //6、定义dubbo接口请求参数,修改类名 74 | RestRequest request = new RestRequest(); 75 | 76 | //不需要修改:向生产者发送请求 77 | request.setRequest(requestParam); 78 | 79 | //7、修改dubbo接口方法名 和 responseData类型 80 | RestResponse responseData = ClassConsumer.freeSaleStock(request); 81 | 82 | //8、自定义log记录内容及校验数据(根据responseData来判断dubbo接口是否请求成功) 83 | if (responseData!=null) { 84 | String responseStatus = responseData.getStatus().toString(); 85 | String responseMessage = responseData.getMessage().toString(); 86 | if (responseStatus.equals(status) && responseMessage.equals(message)) { 87 | Reporter.log("期望的Status:" + status + ",期望的Message:" + message + "\n" + "实际的Status:" + responseStatus + ",实际的Message:" + responseMessage); 88 | System.out.println("期望的Status:" + status + ",期望的Message:" + message + "\n" + "实际的Status:" + responseStatus + ",实际的Message:" + responseMessage); 89 | Assert.assertTrue(true); 90 | 91 | } else { 92 | Reporter.log("期望的Status:" + status + ",期望的Message:" + message + "\n" + "实际的Status:" + responseStatus + ",实际的Message:" + responseMessage); 93 | System.out.println("期望的Status:" + status + ",期望的Message:" + message + "\n" + "实际的Status:" + responseStatus + ",实际的Message:" + responseMessage); 94 | Assert.assertTrue(false); 95 | 96 | } 97 | } else { 98 | Reporter.log("responseData为空"); 99 | Assert.assertTrue(false); 100 | } 101 | 102 | } 103 | } -------------------------------------------------------------------------------- /src/test/java/com/testcase/dubbo/TestOrderStatusService.java: -------------------------------------------------------------------------------- 1 | package com.testcase.dubbo; 2 | 3 | import com.alibaba.dubbo.common.serialize.support.kryo.RestRequest; 4 | import com.alibaba.dubbo.common.serialize.support.kryo.RestResponse; 5 | import com.letv.shop.order.status.flow.bean.OrderParam; 6 | import com.letv.shop.order.status.flow.bean.Result; 7 | import com.letv.shop.order.status.flow.service.OrderStatusService; 8 | import jxl.read.biff.BiffException; 9 | import org.springframework.context.ApplicationContext; 10 | import org.springframework.context.support.ClassPathXmlApplicationContext; 11 | import org.testng.Assert; 12 | import org.testng.Reporter; 13 | import org.testng.annotations.DataProvider; 14 | import org.testng.annotations.Test; 15 | import tools.excelread.GetTestCaseExcel; 16 | 17 | import java.io.IOException; 18 | import java.util.HashMap; 19 | 20 | /** 21 | * @author 李振7 22 | * Created Time: 2018/1/24 下午5:53 23 | */ 24 | public class TestOrderStatusService { 25 | 26 | //不需要修改:固定值变量 27 | private static final String filePath = "/src/test/TestCaseExcelData/dubbo/"; //文件路径src/testExampleForJmeterData/GetTestCaseExcel/dubbo 28 | public static final ApplicationContext CONTEXT = new ClassPathXmlApplicationContext("dubbo-config.xml"); 29 | private GetTestCaseExcel excelData; 30 | 31 | 32 | //1、fileName是dubbo接口的包名, caseName是dubbo接口名 33 | private String fileName = "com.xxxx.order.promise.api"; //dubbo接口的包名作为文件名,不包含文件后缀.xls 34 | private String caseName = "OrderStatusService"; //dubbo接口名作为sheet名 35 | 36 | 37 | //2、request随着dubbo接口的不同,需要定义指定类型 38 | private OrderParam requestParam = new OrderParam(); 39 | 40 | 41 | //3、新建dubbo的消费者对象,需要修改类名 42 | private OrderStatusService ClassConsumer = (OrderStatusService) CONTEXT.getBean(caseName); 43 | 44 | 45 | //不需要修改: 从excel文件中读取数据,不需要修改 46 | @DataProvider 47 | public Object[][] Numbers() throws BiffException, IOException { 48 | excelData = new GetTestCaseExcel(filePath, fileName, caseName); 49 | return excelData.getExcelData(); 50 | } 51 | 52 | //不需要修改:dubbo接口访问Provider 53 | @Test(dataProvider = "Numbers") 54 | public void test(HashMap data) { 55 | 56 | //4、从excel中取出各项参数 57 | String orderId = data.get("orderId"); 58 | String userId = data.get("userId"); 59 | String status = data.get("Status"); 60 | String message = data.get("Message"); 61 | String result = data.get("Result"); 62 | 63 | //5、将请求参数导入对象requestParam中 64 | requestParam.setOrderId(orderId); 65 | requestParam.setUserId(userId); 66 | 67 | //6、定义dubbo接口请求参数,修改类名 68 | RestRequest request = new RestRequest(); 69 | 70 | //不需要修改:向生产者发送请求 71 | request.setRequest(requestParam); 72 | 73 | //7、修改dubbo接口方法名 和 responseData类型 74 | RestResponse responseData = ClassConsumer.cancelByUser(request); 75 | 76 | //8、自定义log记录内容及校验数据(根据responseData来判断dubbo接口是否请求成功) 77 | if (responseData!=null) { 78 | String responseStatus = responseData.getResult().getStatus().toString(); 79 | String responseMessage = responseData.getResult().getMessage().toString(); 80 | if (responseStatus.equals(status) && responseMessage.equals(message)) { 81 | Reporter.log("期望的Status:" + status + ",期望的Message:" + message + "\n" + "实际的Status:" + responseStatus + ",实际的Message:" + responseMessage); 82 | System.out.println("期望的Status:" + status + ",期望的Message:" + message + "\n" + "实际的Status:" + responseStatus + ",实际的Message:" + responseMessage); 83 | Assert.assertTrue(true); 84 | 85 | } else { 86 | Reporter.log("期望的Status:" + status + ",期望的Message:" + message + "\n" + "实际的Status:" + responseStatus + ",实际的Message:" + responseMessage); 87 | System.out.println("期望的Status:" + status + ",期望的Message:" + message + "\n" + "实际的Status:" + responseStatus + ",实际的Message:" + responseMessage); 88 | Assert.assertTrue(false); 89 | 90 | } 91 | } else { 92 | Reporter.log("responseData为空"); 93 | Assert.assertTrue(false); 94 | } 95 | 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/test/java/com/testcase/http/testExampleForGet.java: -------------------------------------------------------------------------------- 1 | package com.testcase.http; 2 | 3 | import org.testng.annotations.Test; 4 | import tools.excelread.GetHostIp; 5 | import tools.httprequest.HttpGetTest; 6 | 7 | import java.util.HashMap; 8 | import java.util.LinkedList; 9 | import java.util.List; 10 | import java.util.Map; 11 | 12 | /** 13 | * @author 李振7 14 | * Created Time: 2017/12/18 下午5:15 15 | * 16 | */ 17 | public class testExampleForGet { 18 | private Map headerMap = new HashMap(); //Map headerMap,为header列表 19 | private String url = ""; //String url为post请求的url 20 | private List responseDataList = new LinkedList<>(); //断言list,元素为String类型 21 | private String httpStatus = ""; 22 | private String hostIP = ""; 23 | private String hostName = "mcart-go.lemall.com"; 24 | 25 | @Test 26 | public void DoGetTest() throws Exception { 27 | headerMap.put("User-Agent", "smatisance"); 28 | headerMap.put("Content-type", "application/x-www-form-urlencoded;charset:UTF-8"); 29 | headerMap.put("cookie", "ssouid=2126494707; sso_tk=415dfhjkb5678vhj5jhgasyucibniagcnaohbahdhskhasc"); 30 | 31 | hostIP = new GetHostIp(hostName).getHostIP(); //从host参数化文件中读取HOST IP 32 | // System.out.println("===================" + hostIP); 33 | 34 | url = "https://ascdsca-go.asd.com/api/query/viewCart.jsonp?asdasd=10002&cityId=10048&arrivalId=10501&toPay=0&deviceid=&version=4.0&rs=1100&_=1503543771058&callback=Zepto1503543771015"; 35 | 36 | responseDataList.add("Hellosabiasnas"); 37 | responseDataList.add("lizhen"); 38 | responseDataList.add("bvghkl"); 39 | httpStatus = "200"; 40 | 41 | HttpGetTest httpGetTest = new HttpGetTest(headerMap, url, responseDataList, httpStatus, hostIP); 42 | 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/test/java/com/testcase/http/testExampleForJmeterData.java: -------------------------------------------------------------------------------- 1 | package com.testcase.http; 2 | 3 | import jxl.read.biff.BiffException; 4 | import org.testng.annotations.DataProvider; 5 | import org.testng.annotations.Test; 6 | import tools.httprequest.HttpJmeterExcelData; 7 | 8 | import java.io.IOException; 9 | import java.util.HashMap; 10 | 11 | /** 12 | * @author 李振7 13 | * Created Time: 2018/1/22 下午3:58 14 | */ 15 | 16 | public class testExampleForJmeterData { 17 | String filePath = "/src/test/TestCaseExcelData/http/"; //文件路径src/testExampleForJmeterData/GetTestCaseExcel/dubbo 18 | String fileName = "testcase"; //文件名,不包含文件后缀.xls 19 | String caseName = "testcase"; //sheet名 20 | public HttpJmeterExcelData httpJmeterExcelDatademo; 21 | public testExampleForJmeterData() throws IOException, BiffException { 22 | httpJmeterExcelDatademo = new HttpJmeterExcelData(filePath,fileName,caseName); 23 | } 24 | 25 | @DataProvider 26 | public Object[][] Numbers() throws BiffException, IOException { 27 | return httpJmeterExcelDatademo.Numbers(); 28 | } 29 | 30 | @Test(dataProvider = "Numbers") 31 | public void test(HashMap data) throws IOException, BiffException { 32 | httpJmeterExcelDatademo.test(data); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/test/java/com/testcase/http/testExampleForPost.java: -------------------------------------------------------------------------------- 1 | package com.testcase.http; 2 | 3 | import org.testng.annotations.Test; 4 | import tools.excelread.GetHostIp; 5 | import tools.httprequest.HttpPostTest; 6 | 7 | import java.util.HashMap; 8 | import java.util.LinkedList; 9 | import java.util.List; 10 | import java.util.Map; 11 | 12 | /** 13 | * @author 李振7 14 | * Created Time: 2017/12/18 下午5:15 15 | */ 16 | 17 | public class testExampleForPost { 18 | private Map paramMap = new HashMap(); //Map paramMap,为post请求的参数列表 19 | private Map headerMap = new HashMap(); //Map headerMap,为header列表 20 | private String url = ""; //String url为post请求的url 21 | private List responseDataList = new LinkedList<>(); //断言list,元素为String类型 22 | private String httpStatus = ""; 23 | private String hostIP = ""; 24 | private String hostName = "mproduct-go.lemall.com"; 25 | 26 | @Test 27 | public void DoPostTest() throws Exception { 28 | //request Body 29 | paramMap.put("params","{\"mobileHead\":\"mobileBody\":{\"proNo\":\"GWGT550623\",\"skuNo\":\"\"}}"); 30 | 31 | //request header 32 | headerMap.put("cookie", "ssouid=1234567892345678; sso_tk=415dfhjkb5678vhj5jhgasyucibniagcnaohbahdhskhasc"); 33 | headerMap.put("mEncodeMethod", "none"); 34 | headerMap.put("User-Agent", "android-phone;21;zh_CN"); 35 | 36 | //从host ip参数化文件中获取hostname对应的host ip 37 | hostIP = new GetHostIp(hostName).getHostIP(); 38 | 39 | //post请求的URL 40 | url = "https://adsad-go.asdasdas.com:443/api/query/v2/asdasd.json?sso_tk=415dfhjkb5678vhj5jhgasyucibniagcnaohbahdhskhasc"; 41 | 42 | //需要校验的response data 43 | responseDataList.add("message\":\"服务调用成功\""); 44 | 45 | //需要校验的http状态码 46 | httpStatus = "200"; 47 | 48 | //调用http post请求类 49 | HttpPostTest httpPostTest = new HttpPostTest(paramMap, headerMap, url, responseDataList, httpStatus, hostIP); 50 | 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/test/java/com/testcase/sql/SqlTest.java: -------------------------------------------------------------------------------- 1 | package com.testcase.sql; 2 | 3 | import org.testng.Assert; 4 | import org.testng.Reporter; 5 | import org.testng.annotations.Test; 6 | import org.w3c.tidy.Report; 7 | import tools.sqlRequest.DBHelper; 8 | 9 | import java.text.SimpleDateFormat; 10 | import java.util.*; 11 | 12 | /** 13 | * @author 李振7 14 | * Created Time: 2017/12/26 上午11:05 15 | */ 16 | public class SqlTest { 17 | //jdbc路径 18 | private String DBurl = "jdbc:mysql://127.0.0.1/test"; 19 | //jdbc驱动 20 | private String JdbcName = "com.mysql.jdbc.Driver"; 21 | //mysql用户名 22 | private String UserName = "root"; 23 | //密码 24 | private String PassWord = "root"; 25 | 26 | private SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式 27 | String strDate = df.format(new Date()); 28 | 29 | //要执行的sql语句,支持增删改查 30 | private String sql = "INSERT INTO runoob_tbl1 (runoob_title, runoob_author, submission_date) VALUES (\"Memcached\", \"Memcached.com\", '" + strDate + "')"; 31 | 32 | //sql请求、执行,并判断用例成功与否 33 | @Test 34 | public void SqlTest() { 35 | DBHelper dbHelper = new DBHelper(DBurl, JdbcName, UserName, PassWord, sql); 36 | 37 | if(dbHelper.isRequestSuccessful()) { 38 | Reporter.log("sql执行成功"); 39 | Assert.assertTrue(true); 40 | } else { 41 | Reporter.log("sql执行失败"); 42 | Assert.assertTrue(false); 43 | } 44 | } 45 | 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/test/resources/dubbo-config.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/test/resources/environmentConfig.properties: -------------------------------------------------------------------------------- 1 | environmentConfig.properties 2 | 3 | #要测试环境配置,根据HostIP.xls中的sheet名来进行配置 4 | testEnvironment=test -------------------------------------------------------------------------------- /src/test/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 9 | 11 | 12 | 14 | 16 | 17 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 27 | 29 | 31 | 32 | 34 | 35 | 36 | 37 | 38 | 39 | 41 | 42 | 44 | 45 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /src/test/resources/mailConfig.properties: -------------------------------------------------------------------------------- 1 | mailConfig.properties 2 | #服务器 3 | mailHost=smtp.xxxx.cn 4 | #端口号 5 | mailPort=25 6 | #邮箱账号 7 | mailUsername=xxxx_automation 8 | #邮箱授权码 9 | mailPassword=xxxxxxxxx 10 | #时间延迟 11 | mailTimeout=25000 12 | #发送人 13 | mailFrom=xxxx_automation@xx.com 14 | #发送人姓名 15 | #personal=商城自动化测试 16 | 17 | -------------------------------------------------------------------------------- /src/test/resources/testngReportRecord.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | --------------------------------------------------------------------------------