├── .gitignore ├── LICENSE ├── README.md ├── hrun4j-api └── pom.xml ├── hrun4j-cli ├── pom.xml └── src │ ├── main │ ├── java │ │ ├── META-INF │ │ │ └── MANIFEST.MF │ │ └── vip │ │ │ └── lematech │ │ │ └── hrun4j │ │ │ ├── Hrun4j.java │ │ │ ├── cli │ │ │ ├── commands │ │ │ │ ├── AllCommands.java │ │ │ │ ├── Har2Case.java │ │ │ │ ├── Postman2Case.java │ │ │ │ ├── Run.java │ │ │ │ ├── StartProject.java │ │ │ │ ├── Swagger2Api.java │ │ │ │ ├── Version.java │ │ │ │ └── ViewHar.java │ │ │ ├── constant │ │ │ │ └── CliConstants.java │ │ │ ├── handler │ │ │ │ ├── Command.java │ │ │ │ ├── CommandHandler.java │ │ │ │ └── CommandParser.java │ │ │ ├── helper │ │ │ │ ├── GsonHepler.java │ │ │ │ └── HarHelper.java │ │ │ ├── service │ │ │ │ ├── IProjectGenerator.java │ │ │ │ └── impl │ │ │ │ │ └── ProjectGeneratorImpl.java │ │ │ └── testsuite │ │ │ │ ├── TemplateEngine.java │ │ │ │ └── TestNGEngine.java │ │ │ └── model │ │ │ ├── har │ │ │ ├── Har.java │ │ │ ├── HarBaseModel.java │ │ │ ├── HarCache.java │ │ │ ├── HarCacheDetails.java │ │ │ ├── HarContent.java │ │ │ ├── HarCookie.java │ │ │ ├── HarCreator.java │ │ │ ├── HarEntry.java │ │ │ ├── HarHeader.java │ │ │ ├── HarLog.java │ │ │ ├── HarPage.java │ │ │ ├── HarPageTiming.java │ │ │ ├── HarPostData.java │ │ │ ├── HarPostParam.java │ │ │ ├── HarQueryParm.java │ │ │ ├── HarRequest.java │ │ │ ├── HarResponse.java │ │ │ └── HarTiming.java │ │ │ ├── postman │ │ │ ├── PostmanCollection.java │ │ │ ├── PostmanCollectionInfo.java │ │ │ ├── PostmanEvent.java │ │ │ ├── PostmanItem.java │ │ │ ├── PostmanKeyValue.java │ │ │ ├── PostmanRequest.java │ │ │ ├── PostmanRequestBodyModeEnum.java │ │ │ ├── PostmanResponse.java │ │ │ ├── PostmanScript.java │ │ │ └── PostmanUrl.java │ │ │ └── scaffolding │ │ │ ├── ApplicationInfo.java │ │ │ └── ProjectInfo.java │ └── resources │ │ ├── META-INF │ │ └── MANIFEST.MF │ │ └── vm │ │ └── scaffold │ │ ├── hrun4j │ │ ├── cli │ │ │ ├── Hrun4j.vm │ │ │ ├── apis │ │ │ │ ├── get.vm │ │ │ │ ├── postFormData.vm │ │ │ │ └── postRawText.vm │ │ │ ├── bsh │ │ │ │ └── test.vm │ │ │ ├── data │ │ │ │ └── csvFile.vm │ │ │ ├── env.vm │ │ │ ├── gitignore.vm │ │ │ ├── readMe.vm │ │ │ ├── testcases │ │ │ │ ├── get │ │ │ │ │ └── getScene.vm │ │ │ │ └── post │ │ │ │ │ └── postScene.vm │ │ │ └── testsuite │ │ │ │ └── testsuite.vm │ │ └── pom │ │ │ ├── meta-info │ │ │ ├── env.vm │ │ │ ├── gitignore.vm │ │ │ └── readMe.vm │ │ │ ├── resources │ │ │ ├── Hrun4j.vm │ │ │ ├── apis │ │ │ │ ├── get.vm │ │ │ │ ├── postFormData.vm │ │ │ │ └── postRawText.vm │ │ │ ├── data │ │ │ │ └── csvFile.vm │ │ │ └── testcases │ │ │ │ ├── get │ │ │ │ └── getScene.vm │ │ │ │ └── post │ │ │ │ └── postScene.vm │ │ │ └── template │ │ │ ├── function │ │ │ ├── Hrun4j.vm │ │ │ └── functions │ │ │ │ └── MyFunction.vm │ │ │ ├── pom.vm │ │ │ ├── testcase │ │ │ ├── get │ │ │ │ └── GetTest.vm │ │ │ └── post │ │ │ │ └── PostTest.vm │ │ │ └── testsuite │ │ │ ├── testsuite.vm │ │ │ └── testsuite_all.vm │ │ └── springboot │ │ ├── application.vm │ │ ├── ignore.vm │ │ ├── package-info.vm │ │ ├── pom.vm │ │ ├── test.vm │ │ └── yml.vm │ └── test │ ├── java │ └── vip │ │ └── lematech │ │ └── hrun4j │ │ └── parse │ │ └── Postman2CaseTest.java │ └── resources │ ├── postman │ ├── Writing test scripts │ │ ├── Postman Echo DELETE.yml │ │ ├── Postman Echo GET.yml │ │ ├── Postman Echo POST.yml │ │ └── Postman Echo PUT.yml │ └── postman_collection.json │ └── testsutie │ └── .DS_Store ├── hrun4j-core ├── README.md ├── pom.xml └── src │ ├── main │ ├── java │ │ └── vip │ │ │ └── lematech │ │ │ └── hrun4j │ │ │ ├── base │ │ │ └── TestBase.java │ │ │ ├── common │ │ │ ├── Constant.java │ │ │ └── DefinedException.java │ │ │ ├── config │ │ │ ├── Env.java │ │ │ ├── NamespaceMap.java │ │ │ ├── RunnerConfig.java │ │ │ └── i18n │ │ │ │ └── I18NFactory.java │ │ │ ├── core │ │ │ ├── converter │ │ │ │ └── ObjectConverter.java │ │ │ ├── engine │ │ │ │ ├── TemplateEngine.java │ │ │ │ └── TestCaseExecutorEngine.java │ │ │ ├── loader │ │ │ │ ├── HotLoader.java │ │ │ │ ├── Searcher.java │ │ │ │ ├── TestDataLoaderFactory.java │ │ │ │ ├── impl │ │ │ │ │ └── TestDataLoaderImpl.java │ │ │ │ └── service │ │ │ │ │ └── ITestDataLoader.java │ │ │ ├── processor │ │ │ │ ├── BuiltInAviatorEvaluator.java │ │ │ │ ├── DataExtractor.java │ │ │ │ ├── ExpProcessor.java │ │ │ │ └── PreAndPostProcessor.java │ │ │ ├── provider │ │ │ │ ├── DataConstructor.java │ │ │ │ └── NGDataProvider.java │ │ │ ├── runner │ │ │ │ └── TestCaseRunner.java │ │ │ └── validator │ │ │ │ ├── AssertChecker.java │ │ │ │ └── SchemaValidator.java │ │ │ ├── entity │ │ │ ├── base │ │ │ │ └── BaseModel.java │ │ │ ├── http │ │ │ │ ├── RequestEntity.java │ │ │ │ └── ResponseEntity.java │ │ │ └── testcase │ │ │ │ ├── ApiModel.java │ │ │ │ ├── Comparator.java │ │ │ │ ├── Config.java │ │ │ │ ├── TestCase.java │ │ │ │ ├── TestStep.java │ │ │ │ ├── TestSuite.java │ │ │ │ └── TestSuiteCase.java │ │ │ └── helper │ │ │ ├── FilesHelper.java │ │ │ ├── JavaIdentifierHelper.java │ │ │ ├── JsonHelper.java │ │ │ ├── LittleHelper.java │ │ │ ├── LogHelper.java │ │ │ ├── OkHttpsHelper.java │ │ │ └── RegExpHelper.java │ └── resources │ │ ├── locales │ │ ├── message_en_US.properties │ │ └── message_zh_CN.properties │ │ ├── logback.xml │ │ ├── schemas │ │ ├── api.json │ │ ├── common.json │ │ ├── testcase.json │ │ └── testsuite.json │ │ └── vm │ │ └── ngtemplate │ │ └── testClass.vm │ └── test │ └── java │ └── vip │ └── lematech │ └── hrun4j │ └── okhttp │ ├── JsonCompareTest.java │ ├── ObjectConverterTest.java │ └── OkHttpTest.java ├── hrun4j-test-demo ├── pom.xml └── src │ ├── main │ └── java │ │ └── vip │ │ └── lematech │ │ └── hrun4j │ │ ├── Hrun4j.java │ │ └── functions │ │ └── MyFunction.java │ └── test │ ├── java │ └── vip │ │ └── lematech │ │ └── hrun4j │ │ └── testcases │ │ ├── demo │ │ └── DemoTest.java │ │ ├── demojson │ │ └── DemoJsonTest.java │ │ ├── postman │ │ ├── get │ │ │ └── GetTest.java │ │ └── post │ │ │ └── PostTest.java │ │ └── scene │ │ └── SceneTest.java │ └── resources │ ├── .env │ ├── Hrun4j.bsh │ ├── apis │ ├── getSimpleToken.yml │ ├── getToken.json │ ├── getToken.yml │ ├── postman │ │ ├── get.yml │ │ ├── postFormData.yml │ │ └── postRawText.yml │ └── user │ │ ├── addUser.yml │ │ ├── delUser.yml │ │ ├── queryUser.yml │ │ ├── resetAll.yml │ │ ├── updateUser.yml │ │ └── uploadUser.yml │ ├── bsh │ └── test.bsh │ ├── data │ ├── AssociatedCsvFile.csv │ ├── csvFile.csv │ ├── uploadFile1.txt │ └── uploadFile2.txt │ ├── testcases │ ├── demo │ │ ├── testApiReferenceDemo.yml │ │ ├── testAviatorExpDemo.yml │ │ ├── testBeanShellDemo.yml │ │ ├── testComplexSingleDemo.yml │ │ ├── testCurrentStepRequestAndResponseDataDemo.yml │ │ ├── testDataAssociatedProviderDemo.yml │ │ ├── testDataProviderFromCsvDemo.yml │ │ ├── testDefineRequestConfigDemo.yml │ │ ├── testFileDownloadDemo.yml │ │ ├── testJsonSchemaValidateTest.yml │ │ ├── testJsonValidateTest.yml │ │ ├── testMoreComplexSingleDemo.yml │ │ ├── testMultipleGetDataDemo.yml │ │ ├── testReferenceEnvDemo.yml │ │ ├── testSimpleSingleDemo.yml │ │ ├── testTestCaseReferenceDemo.yml │ │ ├── testVariablePriorityDemo.yml │ │ └── 测试接口定义应用中文.yml │ ├── demojson │ │ └── testApiReferenceDemo.json │ ├── postman │ │ ├── get │ │ │ └── getScene.yml │ │ └── post │ │ │ └── postScene.yml │ └── scene │ │ ├── delAssignUserInfo.yml │ │ ├── loginAndAddUser.yml │ │ ├── loginAndResetAll.yml │ │ ├── loginAndUpdateUser.yml │ │ ├── loginAndUploadUser.yml │ │ └── queryAssignUserInfo.yml │ ├── testng.xml │ └── testsuites │ ├── testng.xml │ └── testng.yml ├── hrun4j-test-server ├── pom.xml └── src │ └── main │ ├── java │ └── vip │ │ └── lematech │ │ └── hrun4j │ │ ├── DemoApplication.java │ │ ├── controller │ │ └── Hrun4jController.java │ │ ├── core │ │ ├── annotation │ │ │ └── ValidateRequest.java │ │ ├── aop │ │ │ ├── RequestValidateAspect.java │ │ │ └── WebLogAspect.java │ │ ├── config │ │ │ └── SwaggerConfig.java │ │ ├── constant │ │ │ └── CommonConstant.java │ │ ├── entity │ │ │ ├── User.java │ │ │ └── UserDto.java │ │ ├── enums │ │ │ ├── BusinessCode.java │ │ │ └── CommonBusinessCode.java │ │ ├── exception │ │ │ └── PlatformException.java │ │ ├── handler │ │ │ └── GlobalExceptionHandler.java │ │ └── helper │ │ │ └── ApplicationContextHelper.java │ │ ├── service │ │ ├── TokenService.java │ │ ├── UserService.java │ │ └── impl │ │ │ ├── TokenServiceImpl.java │ │ │ └── UserServiceImpl.java │ │ └── vo │ │ ├── TokenVO.java │ │ ├── UserVO.java │ │ └── base │ │ └── R.java │ └── resources │ ├── application-dev.yml │ ├── application-local.yml │ ├── application-prod.yml │ ├── application.yml │ └── banner.txt └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | pom.xml.versionsBackup 2 | # Compiled class file 3 | *.class 4 | 5 | # Log file 6 | *.log 7 | .idea 8 | # BlueJ files 9 | *.ctxt 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | target 13 | *.iml 14 | # Package Files # 15 | *.dmg 16 | .gitee 17 | .gitignore 18 | *.war 19 | *.nar 20 | *.ear 21 | *.zip 22 | *.tar.gz 23 | *.rar 24 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 25 | hs_err_pid* 26 | .idea 27 | /hrun4j-core/test-output/ 28 | /test-output/ 29 | !/logs/ 30 | /hrun4j-core/src/test/resources/test-output/hrun4j/ 31 | /resources/ 32 | /hrun4j-core/src/test/resources/test-output/ 33 | !/pom.xml.versionsBackup 34 | /hrun4j-test-demo/test-output/ 35 | dist 36 | /jacoco/ 37 | *.exec -------------------------------------------------------------------------------- /hrun4j-api/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | hrun4j 7 | vip.lematech 8 | 1.0.2 9 | 10 | 4.0.0 11 | 12 | hrun4j-api 13 | 14 | UTF-8 15 | 1.8 16 | 1.8 17 | true 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /hrun4j-cli/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | hrun4j 7 | vip.lematech 8 | 1.0.2 9 | 10 | 4.0.0 11 | hrun4j-cli 12 | 13 | UTF-8 14 | 1.8 15 | 1.8 16 | true 17 | 18 | 19 | 20 | args4j 21 | args4j 22 | 2.33 23 | 24 | 25 | com.google.code.gson 26 | gson 27 | 2.8.5 28 | 29 | 30 | org.projectlombok 31 | lombok 32 | 1.18.12 33 | provided 34 | 35 | 36 | com.sangupta 37 | jerry-core 38 | 1.3.0 39 | 40 | 41 | commons-io 42 | commons-io 43 | 44 | 45 | 46 | 47 | commons-io 48 | commons-io 49 | 2.7 50 | 51 | 52 | 53 | io.swagger.parser.v3 54 | swagger-parser 55 | 2.0.24 56 | 57 | 58 | commons-io 59 | commons-io 60 | 61 | 62 | 63 | 64 | vip.lematech 65 | hrun4j-core 66 | 1.0.2 67 | compile 68 | 69 | 70 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Main-Class: vip.lematech.hrun4j.Hrun4j 3 | 4 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/Hrun4j.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j; 2 | 3 | import vip.lematech.hrun4j.cli.handler.Command; 4 | import vip.lematech.hrun4j.cli.handler.CommandHandler; 5 | import vip.lematech.hrun4j.cli.handler.CommandParser; 6 | import org.kohsuke.args4j.Argument; 7 | import org.kohsuke.args4j.CmdLineException; 8 | 9 | import java.io.PrintWriter; 10 | import java.io.Writer; 11 | 12 | /** 13 | * Entry point for all command line operations. 14 | * website https://www.lematech.vip/ 15 | * @author lematech@foxmail.com 16 | * @version 1.0.1 17 | */ 18 | 19 | public class Hrun4j extends Command { 20 | 21 | private final String[] args; 22 | private static final PrintWriter NUL = new PrintWriter(new Writer() { 23 | @Override 24 | public void write(final char[] arg0, final int arg1, final int arg2) 25 | { 26 | } 27 | 28 | @Override 29 | public void flush() { 30 | } 31 | 32 | @Override 33 | public void close() { 34 | } 35 | }); 36 | 37 | @Argument(handler = CommandHandler.class, required = true) 38 | Command command; 39 | 40 | Hrun4j(final String... args) { 41 | this.args = args; 42 | } 43 | 44 | @Override 45 | public String description() { 46 | return "Command line interface for hrun4j."; 47 | } 48 | 49 | @Override 50 | public String usage(final CommandParser parser) { 51 | return JAVACMD + "--help | "; 52 | } 53 | 54 | @Override 55 | public int execute(PrintWriter out, PrintWriter err) throws Exception { 56 | 57 | final CommandParser mainParser = new CommandParser(this); 58 | try { 59 | mainParser.parseArgument(args); 60 | } catch (final CmdLineException e) { 61 | ((CommandParser) e.getParser()).getCommand().printHelp(err); 62 | err.println(); 63 | err.println(e.getMessage()); 64 | return -1; 65 | } 66 | if (help) { 67 | printHelp(out); 68 | return 0; 69 | } 70 | if (command.help) { 71 | command.printHelp(out); 72 | return 0; 73 | } 74 | if (command.quiet) { 75 | out = NUL; 76 | } 77 | return command.execute(out, err); 78 | } 79 | 80 | /** 81 | * Main entry point for program invocations. 82 | * 83 | * @param args program arguments 84 | * @throws Exception All internal exceptions are directly passed on to get printed 85 | * on the console 86 | */ 87 | public static void main(final String... args) throws Exception { 88 | final PrintWriter out = new PrintWriter(System.out, true); 89 | final PrintWriter err = new PrintWriter(System.err, true); 90 | final int returnCode = new Hrun4j(args).execute(out, err); 91 | System.exit(returnCode); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/cli/commands/AllCommands.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.cli.commands; 2 | 3 | import vip.lematech.hrun4j.cli.handler.Command; 4 | 5 | import java.util.Arrays; 6 | import java.util.List; 7 | 8 | /** 9 | * List of all available commands. 10 | * 11 | * @author lematech@foxmail.com 12 | * @version 1.0.1 13 | * website https://www.lematech.vip/ 14 | */ 15 | public final class AllCommands { 16 | private AllCommands() { 17 | } 18 | 19 | /** 20 | * @return list of new instances of all available commands 21 | */ 22 | public static List get() { 23 | return Arrays.asList(new Version() 24 | , new Run(), new ViewHar(), new Har2Case(), new Swagger2Api(), new Postman2Case() 25 | , new StartProject()); 26 | } 27 | 28 | /** 29 | * @return String containing all available command names 30 | */ 31 | public static String names() { 32 | final StringBuilder sb = new StringBuilder(); 33 | for (final Command c : get()) { 34 | if (sb.length() > 0) { 35 | sb.append('|'); 36 | } 37 | sb.append(c.name()); 38 | } 39 | return sb.toString(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/cli/commands/StartProject.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.cli.commands; 2 | 3 | 4 | import cn.hutool.core.io.FileUtil; 5 | import cn.hutool.core.util.StrUtil; 6 | import vip.lematech.hrun4j.cli.constant.CliConstants; 7 | import vip.lematech.hrun4j.helper.JavaIdentifierHelper; 8 | import vip.lematech.hrun4j.helper.LogHelper; 9 | import vip.lematech.hrun4j.model.scaffolding.ProjectInfo; 10 | import vip.lematech.hrun4j.cli.service.impl.ProjectGeneratorImpl; 11 | import vip.lematech.hrun4j.cli.handler.Command; 12 | import vip.lematech.hrun4j.cli.service.IProjectGenerator; 13 | import vip.lematech.hrun4j.common.Constant; 14 | import vip.lematech.hrun4j.config.RunnerConfig; 15 | import org.kohsuke.args4j.Argument; 16 | import org.kohsuke.args4j.Option; 17 | 18 | import java.io.File; 19 | import java.io.PrintWriter; 20 | 21 | /** 22 | * website https://www.lematech.vip/ 23 | * @author lematech@foxmail.com 24 | * @version 1.0.1 25 | * The startproject command. 26 | */ 27 | public class StartProject extends Command { 28 | 29 | @Override 30 | public String description() { 31 | return "Print startproject command information."; 32 | } 33 | 34 | @Argument(usage = "Enter project name", metaVar = "") 35 | String projectName; 36 | 37 | @Option(name = "--group_id", usage = "Specify maven project groupId.") 38 | String groupId = "vip.lematech.hrun4j"; 39 | 40 | @Option(name = "--version", usage = "Specify maven project version.") 41 | String version = "1.0.1-SNAPSHOT"; 42 | 43 | @Option(name = "--type", usage = "Project type, default is hrun4j POM type, support CLI/SRPINGBOOT ") 44 | String type = CliConstants.HRUN4J_POM_TYPE; 45 | 46 | @Override 47 | public int execute(PrintWriter out, PrintWriter err) { 48 | if (StrUtil.isEmpty(projectName)) { 49 | LogHelper.warn("Please enter a project name"); 50 | return -1; 51 | } 52 | JavaIdentifierHelper.isValidJavaFullClassName(groupId); 53 | ProjectInfo projectInfo = new ProjectInfo(groupId, projectName 54 | , version, projectName, String.format("Demo project for %s", projectName)); 55 | RunnerConfig.getInstance().setWorkDirectory(new File(Constant.DOT_PATH)); 56 | String projectRoot = FileUtil.getAbsolutePath(RunnerConfig.getInstance().getWorkDirectory()) + File.separator; 57 | LogHelper.info("工作区路径:{}", projectRoot); 58 | IProjectGenerator projectGenerator = new ProjectGeneratorImpl(); 59 | if (CliConstants.SRPINGBOOT_PROJECT_TYPE.equalsIgnoreCase(type)) { 60 | LogHelper.info("正在初始化SpringBoot项目信息"); 61 | projectGenerator.springbootGenerator(projectRoot, projectInfo); 62 | } else if (CliConstants.HRUN4J_CLI_TYPE.equalsIgnoreCase(type)) { 63 | LogHelper.info("正在初始化hrun4j Cli项目信息"); 64 | projectGenerator.cliGenerator(projectRoot, projectName); 65 | } else { 66 | LogHelper.info("正在初始化hrun4j POM项目信息"); 67 | projectGenerator.pomGenerator(projectRoot, projectInfo); 68 | } 69 | return 1; 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/cli/commands/Version.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.cli.commands; 2 | 3 | import vip.lematech.hrun4j.cli.handler.Command; 4 | 5 | import java.io.PrintWriter; 6 | 7 | /** 8 | * The version command. 9 | * website https://www.lematech.vip/ 10 | * @author lematech@foxmail.com 11 | * @version 1.0.1 12 | */ 13 | public class Version extends Command { 14 | public static final String VERSION = "1.0.1"; 15 | @Override 16 | public String description() { 17 | return "Print hrun4j version information."; 18 | } 19 | 20 | /** 21 | * Print hrun4j version information. 22 | * 23 | * @param out std out 24 | * @param err std err 25 | * @return Command line execution results 26 | */ 27 | @Override 28 | public int execute(PrintWriter out, PrintWriter err) { 29 | out.println(VERSION); 30 | return 0; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/cli/commands/ViewHar.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.cli.commands; 2 | 3 | import cn.hutool.core.collection.CollectionUtil; 4 | import cn.hutool.core.io.FileUtil; 5 | import vip.lematech.hrun4j.cli.helper.HarHelper; 6 | import vip.lematech.hrun4j.helper.LogHelper; 7 | import vip.lematech.hrun4j.model.har.Har; 8 | import vip.lematech.hrun4j.model.har.HarEntry; 9 | import vip.lematech.hrun4j.model.har.HarPage; 10 | import vip.lematech.hrun4j.cli.handler.Command; 11 | import org.kohsuke.args4j.Option; 12 | 13 | import java.io.File; 14 | import java.io.PrintWriter; 15 | import java.util.List; 16 | import java.util.Objects; 17 | 18 | 19 | /** 20 | * The viewhar command. 21 | * website https://www.lematech.vip/ 22 | * @author lematech@foxmail.com 23 | * @version 1.0.1 24 | */ 25 | 26 | public class ViewHar extends Command { 27 | 28 | @Option(name = "--file", usage = "Specify the HAR file path.") 29 | String file; 30 | 31 | @Option(name = "--filter_suffix", usage = "Filter out the specified request suffix, support multiple suffix formats, multiple in English status ';' division.") 32 | String filterSuffix; 33 | 34 | @Option(name = "--filter_uri", usage = "Filter out the URIs that meet the requirements by keyword, multiple in English status ';' division.") 35 | String filterUriByKeywords; 36 | 37 | @Override 38 | public String description() { 39 | return "View the HAR file information."; 40 | } 41 | 42 | /** 43 | * View the HAR file information 44 | * 45 | * @param out std out 46 | * @param err std err 47 | * @return Command line execution results 48 | */ 49 | @Override 50 | public int execute(PrintWriter out, PrintWriter err) { 51 | File harFilePath = new File(this.file); 52 | Har har; 53 | try { 54 | har = HarHelper.read(harFilePath); 55 | } catch (Exception e) { 56 | String exceptionMsg = String.format("Error reading HAR file:%s,Exception information:%s", FileUtil.getAbsolutePath(harFilePath), e.getMessage()); 57 | LogHelper.error(exceptionMsg); 58 | return 1; 59 | } 60 | 61 | if (Objects.isNull(har.getLog()) || CollectionUtil.isEmpty(har.getLog().getPages())) { 62 | String exceptionMsg = String.format("HAR file %s has no pages!", FileUtil.getAbsolutePath(harFilePath)); 63 | LogHelper.error(exceptionMsg); 64 | return 1; 65 | } 66 | HarHelper.connectReferences(har, filterSuffix, filterUriByKeywords); 67 | List harPages = har.getLog().getPages(); 68 | viewInConsole(harPages); 69 | return 0; 70 | } 71 | 72 | private void viewInConsole(List harPages) { 73 | LogHelper.info("hrun4j start displaying: "); 74 | LogHelper.info("Number of pages viewed: " + harPages.size()); 75 | for (HarPage page : harPages) { 76 | LogHelper.info(page.toString()); 77 | LogHelper.info("Output the calls for this page: "); 78 | for (HarEntry entry : page.getEntries()) { 79 | LogHelper.info("\t" + entry); 80 | } 81 | } 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/cli/handler/Command.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.cli.handler; 2 | 3 | /** 4 | * website https://www.lematech.vip/ 5 | * @author lematech@foxmail.com 6 | * @version 1.0.1 7 | */ 8 | 9 | import org.kohsuke.args4j.Option; 10 | 11 | import java.io.PrintWriter; 12 | import java.io.StringWriter; 13 | 14 | /** 15 | * Common interface for all commands. 16 | */ 17 | public abstract class Command { 18 | /** 19 | * Common command line prefix. 20 | */ 21 | public static final String JAVACMD = "java -jar hrun4j.jar "; 22 | 23 | /** 24 | * Flag whether help should be printed for this command. 25 | */ 26 | @Option(name = "--help", usage = "show help", help = true) 27 | public boolean help = false; 28 | 29 | /** 30 | * Flag whether output to stdout should be suppressed. 31 | */ 32 | @Option(name = "--quiet", usage = "suppress all output on stdout") 33 | public boolean quiet = false; 34 | 35 | /** 36 | * @return Short description of the command. 37 | */ 38 | public abstract String description(); 39 | 40 | /** 41 | * @return name of the command 42 | */ 43 | public String name() { 44 | return getClass().getSimpleName().toLowerCase(); 45 | } 46 | 47 | 48 | /** 49 | * @param parser parser for this command 50 | * @return usage string displayed for help 51 | */ 52 | public String usage(final CommandParser parser) { 53 | final StringWriter writer = new StringWriter(); 54 | parser.printSingleLineUsage(writer, null); 55 | return JAVACMD + name() + writer; 56 | } 57 | 58 | /** 59 | * Executes the given command. 60 | * 61 | * @param out std out 62 | * @param err std err 63 | * @return exit code, should be 0 for normal operation 64 | * @throws Exception any exception that my occur during execution 65 | */ 66 | public abstract int execute(PrintWriter out, PrintWriter err) 67 | throws Exception; 68 | 69 | /** 70 | * Prints textual help for this command. 71 | * 72 | * @param writer output destination 73 | */ 74 | public void printHelp(final PrintWriter writer) { 75 | final CommandParser parser = new CommandParser(this); 76 | writer.println(description()); 77 | writer.println(); 78 | writer.println("Usage: " + parser.getCommand().usage(parser)); 79 | parser.printUsage(writer, null); 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/cli/handler/CommandHandler.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.cli.handler; 2 | 3 | import vip.lematech.hrun4j.cli.commands.AllCommands; 4 | import org.kohsuke.args4j.CmdLineException; 5 | import org.kohsuke.args4j.CmdLineParser; 6 | import org.kohsuke.args4j.OptionDef; 7 | import org.kohsuke.args4j.spi.Messages; 8 | import org.kohsuke.args4j.spi.OptionHandler; 9 | import org.kohsuke.args4j.spi.Parameters; 10 | import org.kohsuke.args4j.spi.Setter; 11 | 12 | import java.util.AbstractList; 13 | 14 | /** 15 | * website https://www.lematech.vip/ 16 | * @author lematech@foxmail.com 17 | * @version 1.0.1 18 | */ 19 | public class CommandHandler extends OptionHandler { 20 | /** 21 | * This constructor is required by the args4j framework. 22 | * 23 | * @param parser Command Parser 24 | * @param option Option defined 25 | * @param setter Setter 26 | */ 27 | public CommandHandler(final CmdLineParser parser, final OptionDef option, 28 | final Setter setter) { 29 | super(parser, 30 | new OptionDef(AllCommands.names(), "", 31 | option.required(), option.help(), option.hidden(), 32 | CommandHandler.class, option.isMultiValued()) { 33 | }, setter); 34 | } 35 | 36 | /** 37 | * @param params Command line arguments 38 | * @return Command line execution results 39 | * @throws CmdLineException command line exception 40 | */ 41 | @Override 42 | public int parseArguments(Parameters params) throws CmdLineException { 43 | final String subCmd = params.getParameter(0); 44 | 45 | for (final Command c : AllCommands.get()) { 46 | if (c.name().equals(subCmd)) { 47 | parseSubArguments(c, params); 48 | setter.addValue(c); 49 | return params.size(); 50 | } 51 | } 52 | throw new CmdLineException(owner, 53 | Messages.ILLEGAL_OPERAND.format(option.toString(), subCmd)); 54 | } 55 | 56 | @Override 57 | public String getDefaultMetaVariable() { 58 | return ""; 59 | } 60 | 61 | /** 62 | * @param c 63 | * @param params 64 | * @throws CmdLineException 65 | */ 66 | private void parseSubArguments(final Command c, final Parameters params) 67 | throws CmdLineException { 68 | final CmdLineParser p = new CommandParser(c); 69 | p.parseArgument(new AbstractList() { 70 | @Override 71 | public String get(final int index) { 72 | try { 73 | return params.getParameter(index + 1); 74 | } catch (final CmdLineException e) { 75 | // invalid index was accessed. 76 | throw new IndexOutOfBoundsException(); 77 | } 78 | } 79 | 80 | @Override 81 | public int size() { 82 | return params.size() - 1; 83 | } 84 | }); 85 | } 86 | 87 | 88 | } 89 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/cli/handler/CommandParser.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.cli.handler; 2 | 3 | import org.kohsuke.args4j.CmdLineParser; 4 | 5 | /** 6 | * Parser which remembers the parsed command to have additional context 7 | * website https://www.lematech.vip/ 8 | * @author lematech@foxmail.com 9 | * @version 1.0.1 10 | */ 11 | public class CommandParser extends CmdLineParser { 12 | private final Command command; 13 | 14 | /** 15 | * init command object 16 | * 17 | * @param command command 18 | */ 19 | public CommandParser(final Command command) { 20 | super(command); 21 | this.command = command; 22 | } 23 | 24 | /** 25 | * get command object 26 | * 27 | * @return Command object 28 | */ 29 | public Command getCommand() { 30 | return command; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/cli/helper/GsonHepler.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.cli.helper; 2 | 3 | import com.google.gson.*; 4 | 5 | import java.util.Date; 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | 9 | /** 10 | * website https://www.lematech.vip/ 11 | * @author lematech@foxmail.com 12 | * @version 1.0.1 13 | */ 14 | public class GsonHepler { 15 | private static final Map gsons = new HashMap(); 16 | private static final JsonSerializer serializer = (src, typeOfSrc, context) -> src == null ? null : new JsonPrimitive(src.getTime()); 17 | private static final JsonDeserializer deserializer = (json, typeOfT, context) -> json == null ? null : new Date(json.getAsLong()); 18 | 19 | public GsonHepler() { 20 | } 21 | 22 | public static Gson getGson() { 23 | return getGson(FieldNamingPolicy.IDENTITY); 24 | } 25 | 26 | public static Gson getGson(FieldNamingPolicy fieldNamingPolicy) { 27 | if (gsons.containsKey(fieldNamingPolicy)) { 28 | return gsons.get(fieldNamingPolicy); 29 | } else { 30 | Gson gson = (new GsonBuilder()).setFieldNamingPolicy(fieldNamingPolicy).registerTypeAdapter(Date.class, serializer).registerTypeAdapter(Date.class, deserializer).create(); 31 | synchronized (gsons) { 32 | gsons.put(fieldNamingPolicy, gson); 33 | return gson; 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/cli/service/IProjectGenerator.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.cli.service; 2 | 3 | import vip.lematech.hrun4j.model.scaffolding.ProjectInfo; 4 | 5 | /** 6 | * website https://www.lematech.vip/ 7 | * @author lematech@foxmail.com 8 | * @version 1.0.1 9 | */ 10 | public interface IProjectGenerator { 11 | 12 | /** 13 | * Generate Maven springboot project scaffolding 14 | * 15 | * @param projectRoot project root 16 | * @param projectInfo project info 17 | */ 18 | void springbootGenerator(String projectRoot, ProjectInfo projectInfo); 19 | 20 | /** 21 | * Hrun4j CLi dependency generation 22 | * 23 | * @param projectRoot project root 24 | * @param projectName project info 25 | */ 26 | void cliGenerator(String projectRoot, String projectName); 27 | /** 28 | * Hrun4j POM dependency generation 29 | * @param projectRoot project root 30 | * @param projectInfo project info 31 | */ 32 | void pomGenerator(String projectRoot, ProjectInfo projectInfo); 33 | } 34 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/model/har/Har.java: -------------------------------------------------------------------------------- 1 | /** 2 | * har - HAR file reader, writer and viewer 3 | * Copyright (c) 2014-2016, Sandeep Gupta 4 | *

5 | * http://sangupta.com/projects/har 6 | *

7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | *

11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | *

13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | package vip.lematech.hrun4j.model.har; 21 | 22 | import lombok.Data; 23 | 24 | /** 25 | * Top level model object for the HAR file 26 | * website https://www.lematech.vip/ 27 | * @author lematech@foxmail.com 28 | * @version 1.0.1 29 | */ 30 | 31 | @Data 32 | public class Har { 33 | 34 | private HarLog log; 35 | @Override 36 | public String toString() { 37 | return "Har [log=" + log + "]"; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/model/har/HarBaseModel.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.model.har; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * website https://www.lematech.vip/ 7 | * @author lematech@foxmail.com 8 | * @version 1.0.1 9 | */ 10 | @Data 11 | public class HarBaseModel { 12 | String name; 13 | 14 | String value; 15 | 16 | String comment; 17 | } 18 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/model/har/HarCache.java: -------------------------------------------------------------------------------- 1 | /** 2 | * har - HAR file reader, writer and viewer 3 | * Copyright (c) 2014-2016, Sandeep Gupta 4 | *

5 | * http://sangupta.com/projects/har 6 | *

7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | *

11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | *

13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | package vip.lematech.hrun4j.model.har; 21 | 22 | import lombok.Data; 23 | 24 | /** 25 | * Request information cached from the browser 26 | * @author sangupta/lematech@foxmail.com 27 | * website https://www.lematech.vip/ 28 | * @version 1.0.1 29 | */ 30 | 31 | @Data 32 | public class HarCache { 33 | 34 | private HarCacheDetails beforeRequest; 35 | 36 | private HarCacheDetails afterRequest; 37 | 38 | private String comment; 39 | 40 | } 41 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/model/har/HarCacheDetails.java: -------------------------------------------------------------------------------- 1 | /** 2 | * har - HAR file reader, writer and viewer 3 | * Copyright (c) 2014-2016, Sandeep Gupta 4 | *

5 | * http://sangupta.com/projects/har 6 | *

7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | *

11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | *

13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | package vip.lematech.hrun4j.model.har; 21 | 22 | import lombok.Data; 23 | 24 | /** 25 | * A detailed list of buffer information 26 | * @author sangupta/lematech@foxmail.com 27 | * @version 1.0.1 28 | */ 29 | 30 | @Data 31 | public class HarCacheDetails { 32 | 33 | private String expires; 34 | 35 | private String lastAccess; 36 | 37 | private String etag; 38 | 39 | private String hitCount; 40 | 41 | private String comment; 42 | 43 | } 44 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/model/har/HarContent.java: -------------------------------------------------------------------------------- 1 | /** 2 | * har - HAR file reader, writer and viewer 3 | * Copyright (c) 2014-2016, Sandeep Gupta 4 | *

5 | * http://sangupta.com/projects/har 6 | *

7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | *

11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | *

13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | package vip.lematech.hrun4j.model.har; 21 | 22 | import lombok.Data; 23 | 24 | /** 25 | * @author sangupta/lematech@foxmail.com 26 | * website https://www.lematech.vip/ 27 | * @version 1.0.1 28 | */ 29 | 30 | @Data 31 | public class HarContent { 32 | 33 | private long size; 34 | 35 | private String mimeType; 36 | 37 | private long compression; 38 | 39 | private String text; 40 | 41 | private String comment; 42 | 43 | private String encoding; 44 | 45 | } 46 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/model/har/HarCookie.java: -------------------------------------------------------------------------------- 1 | /** 2 | * har - HAR file reader, writer and viewer 3 | * Copyright (c) 2014-2016, Sandeep Gupta 4 | *

5 | * http://sangupta.com/projects/har 6 | *

7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | *

11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | *

13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | package vip.lematech.hrun4j.model.har; 21 | 22 | import lombok.Data; 23 | 24 | /** 25 | * @author sangupta/lematech@foxmail.com 26 | * website https://www.lematech.vip/ 27 | * @version 1.0.1 28 | */ 29 | 30 | @Data 31 | public class HarCookie extends HarBaseModel { 32 | 33 | private String path; 34 | 35 | private String expires; 36 | 37 | private boolean httpOnly; 38 | 39 | private boolean secure; 40 | 41 | @Override 42 | public String toString() { 43 | return "[Cookie: " + this.name + "=" + this.value + "]"; 44 | } 45 | 46 | @Override 47 | public int hashCode() { 48 | if (this.name == null) { 49 | return -1; 50 | } 51 | 52 | return this.name.hashCode(); 53 | } 54 | 55 | @Override 56 | public boolean equals(Object obj) { 57 | if (!(obj instanceof HarCookie)) { 58 | return false; 59 | } 60 | 61 | if (this.name == null) { 62 | return false; 63 | } 64 | 65 | HarCookie harCookie = (HarCookie) obj; 66 | return this.name.equals(harCookie.name); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/model/har/HarCreator.java: -------------------------------------------------------------------------------- 1 | /** 2 | * har - HAR file reader, writer and viewer 3 | * Copyright (c) 2014-2016, Sandeep Gupta 4 | *

5 | * http://sangupta.com/projects/har 6 | *

7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | *

11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | *

13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | package vip.lematech.hrun4j.model.har; 21 | 22 | import lombok.Data; 23 | 24 | /** 25 | * HAR file creator and version information 26 | * @author sangupta/lematech@foxmail.com 27 | * website https://www.lematech.vip/ 28 | * @version 1.0.1 29 | */ 30 | 31 | @Data 32 | public class HarCreator { 33 | 34 | private String name; 35 | 36 | private String version; 37 | 38 | private String comment; 39 | 40 | @Override 41 | public String toString() { 42 | return "[HARCreator: " + this.name + " (" + this.version + ") ]"; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/model/har/HarEntry.java: -------------------------------------------------------------------------------- 1 | /** 2 | * har - HAR file reader, writer and viewer 3 | * Copyright (c) 2014-2016, Sandeep Gupta 4 | *

5 | * http://sangupta.com/projects/har 6 | *

7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | *

11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | *

13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | package vip.lematech.hrun4j.model.har; 21 | 22 | import com.sangupta.jerry.util.UriUtils; 23 | import lombok.Data; 24 | 25 | import java.util.Objects; 26 | 27 | /** 28 | * An array containing all requests, each item of the array is an object composed of the data of a request, sorted according to StartedDateTime 29 | * @author sangupta/lematech@foxmail.com 30 | * website https://www.lematech.vip/ 31 | * @version 1.0.1 32 | */ 33 | 34 | @Data 35 | public class HarEntry implements Comparable { 36 | 37 | private String pageref; 38 | 39 | private String startedDateTime; 40 | 41 | private double time; 42 | 43 | private HarRequest request; 44 | 45 | private HarResponse response; 46 | 47 | private HarCache cache; 48 | 49 | private HarTiming timings; 50 | 51 | private String serverIPAddress; 52 | 53 | private String connection; 54 | 55 | private String comment; 56 | 57 | @Override 58 | public String toString() { 59 | return request.getMethod() + " " + UriUtils.extractPath(request.getUrl()); 60 | } 61 | 62 | @Override 63 | public int compareTo(HarEntry o) { 64 | if (Objects.isNull(o)) { 65 | return -1; 66 | } 67 | return this.startedDateTime.compareTo(o.startedDateTime); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/model/har/HarHeader.java: -------------------------------------------------------------------------------- 1 | /** 2 | * har - HAR file reader, writer and viewer 3 | * Copyright (c) 2014-2016, Sandeep Gupta 4 | *

5 | * http://sangupta.com/projects/har 6 | *

7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | *

11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | *

13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | package vip.lematech.hrun4j.model.har; 21 | 22 | import cn.hutool.core.util.StrUtil; 23 | import lombok.Data; 24 | 25 | /** 26 | * @author sangupta/lematech@foxmail.com 27 | * website https://www.lematech.vip/ 28 | * @version 1.0.1 29 | */ 30 | 31 | @Data 32 | public class HarHeader extends HarBaseModel { 33 | 34 | @Override 35 | public String toString() { 36 | return "[Header: " + this.name + "=" + this.value + "]"; 37 | } 38 | 39 | @Override 40 | public int hashCode() { 41 | if (StrUtil.isEmpty(this.name)) { 42 | return -1; 43 | } 44 | return this.name.hashCode(); 45 | } 46 | 47 | @Override 48 | public boolean equals(Object obj) { 49 | if (!(obj instanceof HarHeader)) { 50 | return false; 51 | } 52 | 53 | if (StrUtil.isEmpty(this.name)) { 54 | return false; 55 | } 56 | HarHeader harHeader = (HarHeader) obj; 57 | return this.name.equals(harHeader.name); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/model/har/HarLog.java: -------------------------------------------------------------------------------- 1 | /** 2 | * har - HAR file reader, writer and viewer 3 | * Copyright (c) 2014-2016, Sandeep Gupta 4 | *

5 | * http://sangupta.com/projects/har 6 | *

7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | *

11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | *

13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | package vip.lematech.hrun4j.model.har; 21 | 22 | import lombok.Data; 23 | 24 | import java.util.List; 25 | 26 | /** 27 | * @author sangupta/lematech@foxmail.com 28 | * website https://www.lematech.vip/ 29 | * @version 1.0.1 30 | */ 31 | 32 | @Data 33 | public class HarLog { 34 | 35 | public static final String DEFAULT_HAR_VERSION = "1.1"; 36 | 37 | private String version = DEFAULT_HAR_VERSION; 38 | 39 | private HarCreator creator; 40 | 41 | private HarCreator browser; 42 | 43 | private List pages; 44 | 45 | private List entries; 46 | 47 | private String comment; 48 | 49 | @Override 50 | public String toString() { 51 | return "HarLog [version=" + version + ", creator=" + creator + ", browser=" + browser + ", pages=" + pages + ", entries=" + entries + ", comment=" + comment + "]"; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/model/har/HarPage.java: -------------------------------------------------------------------------------- 1 | /** 2 | * har - HAR file reader, writer and viewer 3 | * Copyright (c) 2014-2016, Sandeep Gupta 4 | *

5 | * http://sangupta.com/projects/har 6 | *

7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | *

11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | *

13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | package vip.lematech.hrun4j.model.har; 21 | 22 | import lombok.Data; 23 | 24 | import java.util.List; 25 | 26 | /** 27 | * @author sangupta/lematech@foxmail.com 28 | * website https://www.lematech.vip/ 29 | * @version 1.0.1 30 | */ 31 | 32 | @Data 33 | public class HarPage { 34 | 35 | private String startedDateTime; 36 | 37 | private String id; 38 | 39 | private String title; 40 | 41 | private HarPageTiming pageTimings; 42 | 43 | private String comment; 44 | 45 | private transient List entries; 46 | 47 | @Override 48 | public String toString() { 49 | return "[Page: " + this.id + " (" + this.title + ") ]"; 50 | } 51 | 52 | @Override 53 | public int hashCode() { 54 | if (this.id == null) { 55 | return -1; 56 | } 57 | 58 | return this.id.hashCode(); 59 | } 60 | 61 | @Override 62 | public boolean equals(Object obj) { 63 | if (!(obj instanceof HarPage)) { 64 | return false; 65 | } 66 | 67 | if (this.id == null) { 68 | return false; 69 | } 70 | 71 | HarPage harPage = (HarPage) obj; 72 | return this.id.equals(harPage.id); 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/model/har/HarPageTiming.java: -------------------------------------------------------------------------------- 1 | /** 2 | * har - HAR file reader, writer and viewer 3 | * Copyright (c) 2014-2016, Sandeep Gupta 4 | *

5 | * http://sangupta.com/projects/har 6 | *

7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | *

11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | *

13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | package vip.lematech.hrun4j.model.har; 21 | 22 | 23 | import lombok.Data; 24 | 25 | /** 26 | * @author sangupta/lematech@foxmail.com 27 | * website https://www.lematech.vip/ 28 | * @version 1.0.1 29 | */ 30 | 31 | @Data 32 | public class HarPageTiming { 33 | 34 | private double onContentLoad; 35 | 36 | private double onLoad; 37 | 38 | private String comment; 39 | 40 | @Override 41 | public String toString() { 42 | return "HarPageTiming [onContentLoad=" + onContentLoad + ", onLoad=" + onLoad + ", comment=" + comment + "]"; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/model/har/HarPostData.java: -------------------------------------------------------------------------------- 1 | /** 2 | * har - HAR file reader, writer and viewer 3 | * Copyright (c) 2014-2016, Sandeep Gupta 4 | *

5 | * http://sangupta.com/projects/har 6 | *

7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | *

11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | *

13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | package vip.lematech.hrun4j.model.har; 21 | 22 | import lombok.Data; 23 | 24 | import java.util.List; 25 | 26 | /** 27 | * @author sangupta/lematech@foxmail.com 28 | * website https://www.lematech.vip/ 29 | * @version 1.0.1 30 | */ 31 | 32 | @Data 33 | public class HarPostData { 34 | 35 | private String mimeType; 36 | 37 | private List params; 38 | 39 | private String text; 40 | 41 | private String comment; 42 | 43 | } 44 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/model/har/HarPostParam.java: -------------------------------------------------------------------------------- 1 | /** 2 | * har - HAR file reader, writer and viewer 3 | * Copyright (c) 2014-2016, Sandeep Gupta 4 | *

5 | * http://sangupta.com/projects/har 6 | *

7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | *

11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | *

13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | package vip.lematech.hrun4j.model.har; 21 | 22 | 23 | import lombok.Data; 24 | 25 | /** 26 | * @author sangupta/lematech@foxmail.com 27 | * website https://www.lematech.vip/ 28 | * @version 1.0.1 29 | */ 30 | 31 | @Data 32 | public class HarPostParam extends HarBaseModel { 33 | 34 | private String fileName; 35 | 36 | private String contentType; 37 | 38 | @Override 39 | public String toString() { 40 | return "[Post Param: " + this.name + "=" + this.value + "]"; 41 | } 42 | 43 | @Override 44 | public int hashCode() { 45 | if (this.name == null) { 46 | return -1; 47 | } 48 | 49 | return this.name.hashCode(); 50 | } 51 | 52 | @Override 53 | public boolean equals(Object obj) { 54 | if (!(obj instanceof HarPostParam)) { 55 | return false; 56 | } 57 | 58 | if (this.name == null) { 59 | return false; 60 | } 61 | 62 | HarPostParam harPostParam = (HarPostParam) obj; 63 | return this.name.equals(harPostParam.name); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/model/har/HarQueryParm.java: -------------------------------------------------------------------------------- 1 | /** 2 | * har - HAR file reader, writer and viewer 3 | * Copyright (c) 2014-2016, Sandeep Gupta 4 | *

5 | * http://sangupta.com/projects/har 6 | *

7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | *

11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | *

13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | package vip.lematech.hrun4j.model.har; 21 | 22 | import lombok.Data; 23 | 24 | /** 25 | * @author sangupta/lematech@foxmail.com 26 | * website https://www.lematech.vip/ 27 | * @version 1.0.1 28 | */ 29 | 30 | @Data 31 | public class HarQueryParm extends HarBaseModel { 32 | 33 | 34 | @Override 35 | public String toString() { 36 | return "[Query Param: " + this.name + "=" + this.value + "]"; 37 | } 38 | 39 | @Override 40 | public int hashCode() { 41 | if (this.name == null) { 42 | return -1; 43 | } 44 | 45 | return this.name.hashCode(); 46 | } 47 | 48 | @Override 49 | public boolean equals(Object obj) { 50 | if (!(obj instanceof HarQueryParm)) { 51 | return false; 52 | } 53 | 54 | if (this.name == null) { 55 | return false; 56 | } 57 | 58 | HarQueryParm harQueryParm = (HarQueryParm) obj; 59 | return this.name.equals(harQueryParm.name); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/model/har/HarRequest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * har - HAR file reader, writer and viewer 3 | * Copyright (c) 2014-2016, Sandeep Gupta 4 | *

5 | * http://sangupta.com/projects/har 6 | *

7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | *

11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | *

13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | package vip.lematech.hrun4j.model.har; 21 | 22 | import lombok.Data; 23 | 24 | import java.util.List; 25 | 26 | /** 27 | * HAR request information 28 | * @author sangupta/lematech@foxmail.com 29 | * website https://www.lematech.vip/ 30 | * @version 1.0.1 31 | */ 32 | 33 | @Data 34 | public class HarRequest { 35 | 36 | private String method; 37 | 38 | private String url; 39 | 40 | private String httpVersion; 41 | 42 | private List cookies; 43 | 44 | private List headers; 45 | 46 | private List queryString; 47 | 48 | private HarPostData postData; 49 | 50 | private long headersSize; 51 | 52 | private long bodySize; 53 | 54 | private String comment; 55 | 56 | @Override 57 | public String toString() { 58 | return this.method + " " + this.url + " " + this.httpVersion; 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/model/har/HarResponse.java: -------------------------------------------------------------------------------- 1 | /** 2 | * har - HAR file reader, writer and viewer 3 | * Copyright (c) 2014-2016, Sandeep Gupta 4 | *

5 | * http://sangupta.com/projects/har 6 | *

7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | *

11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | *

13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | package vip.lematech.hrun4j.model.har; 21 | 22 | import lombok.Data; 23 | 24 | import java.util.List; 25 | 26 | /** 27 | * HAR response information 28 | * @author sangupta/lematech@foxmail.com 29 | * website https://www.lematech.vip/ 30 | * @version 1.0.1 31 | */ 32 | 33 | @Data 34 | public class HarResponse { 35 | 36 | private int status; 37 | 38 | private String statusText; 39 | 40 | private String httpVersion; 41 | 42 | private List headers; 43 | 44 | private List cookies; 45 | 46 | private HarContent content; 47 | 48 | private String redirectURL; 49 | 50 | private long headersSize; 51 | 52 | private long bodySize; 53 | 54 | @Override 55 | public String toString() { 56 | return "HTTP " + this.status + " (" + this.statusText + ")"; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/model/har/HarTiming.java: -------------------------------------------------------------------------------- 1 | /** 2 | * har - HAR file reader, writer and viewer 3 | * Copyright (c) 2014-2016, Sandeep Gupta 4 | *

5 | * http://sangupta.com/projects/har 6 | *

7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | *

11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | *

13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | package vip.lematech.hrun4j.model.har; 21 | 22 | 23 | /** 24 | * 25 | * The time between sending a request and receiving a response is measured in milliseconds 26 | * @author sangupta/lematech@foxmail.com 27 | * website https://www.lematech.vip/ 28 | * @version 1.0.1 29 | */ 30 | public class HarTiming { 31 | 32 | public double blocked; 33 | 34 | public double dns; 35 | 36 | public double connect; 37 | 38 | public double send; 39 | 40 | public double wait; 41 | 42 | public double receive; 43 | 44 | public double ssl; 45 | 46 | public String comment; 47 | 48 | 49 | @Override 50 | public String toString() { 51 | return "HarTiming [blocked=" + blocked + ", dns=" + dns + ", connect=" + connect + ", send=" + send + ", wait=" + wait + ", receive=" + receive + ", ssl=" + ssl + ", comment=" + comment + "]"; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/model/postman/PostmanCollection.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.model.postman; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * website https://www.lematech.vip/ 9 | * @author chenfanghang 10 | * @version 1.0.1 11 | */ 12 | @Data 13 | public class PostmanCollection { 14 | 15 | private PostmanCollectionInfo info; 16 | private List item; 17 | private List variable; 18 | } 19 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/model/postman/PostmanCollectionInfo.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.model.postman; 2 | 3 | import com.alibaba.fastjson.annotation.JSONField; 4 | import lombok.Data; 5 | 6 | /** 7 | * website https://www.lematech.vip/ 8 | * @author chenfanghang 9 | * @version 1.0.1 10 | */ 11 | @Data 12 | public class PostmanCollectionInfo { 13 | 14 | @JSONField(name = "_postman_id") 15 | private String postmanId; 16 | private String name; 17 | private String schema; 18 | } 19 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/model/postman/PostmanEvent.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.model.postman; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * website https://www.lematech.vip/ 7 | * @author chenfanghang 8 | * @version 1.0.1 9 | */ 10 | @Data 11 | public class PostmanEvent { 12 | private String listen; 13 | private PostmanScript script; 14 | } 15 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/model/postman/PostmanItem.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.model.postman; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * website https://www.lematech.vip/ 9 | * @author chenfanghang 10 | * @version 1.0.1 11 | */ 12 | @Data 13 | public class PostmanItem { 14 | private String name; 15 | private List event; 16 | private PostmanRequest request; 17 | private List item; 18 | private List response; 19 | } 20 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/model/postman/PostmanKeyValue.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.model.postman; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * website https://www.lematech.vip/ 7 | * @author chenfanghang 8 | * @version 1.0.1 9 | */ 10 | @Data 11 | public class PostmanKeyValue { 12 | private String key; 13 | private String value; 14 | private String type; 15 | private String description; 16 | private String contentType; 17 | 18 | public PostmanKeyValue() { 19 | } 20 | 21 | public PostmanKeyValue(String key, String value) { 22 | this.key = key; 23 | this.value = value; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/model/postman/PostmanRequest.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.model.postman; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import lombok.Data; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * website https://www.lematech.vip/ 10 | * @author chenfanghang 11 | * @version 1.0.1 12 | */ 13 | @Data 14 | public class PostmanRequest { 15 | 16 | private String method; 17 | private String schema; 18 | private List header; 19 | private JSONObject body; 20 | private JSONObject auth; 21 | private PostmanUrl url; 22 | private String description; 23 | } 24 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/model/postman/PostmanRequestBodyModeEnum.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.model.postman; 2 | 3 | /** 4 | * website https://www.lematech.vip/ 5 | * @author chenfanghang 6 | * @version 1.0.1 7 | */ 8 | public enum PostmanRequestBodyModeEnum { 9 | 10 | RAW("raw"), FORM_DATA("formdata"), URLENCODED("urlencoded"), FILE("file"); 11 | 12 | private String value; 13 | 14 | PostmanRequestBodyModeEnum(String value) { 15 | this.value = value; 16 | } 17 | 18 | public String value() { 19 | return this.value; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/model/postman/PostmanResponse.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.model.postman; 2 | 3 | 4 | import lombok.Data; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * website https://www.lematech.vip/ 10 | * @author chenfanghang 11 | * @version 1.0.1 12 | */ 13 | @Data 14 | public class PostmanResponse { 15 | private String name; 16 | private String status; 17 | private String code; 18 | private String _postman_previewlanguage; 19 | private List header; 20 | private String body; 21 | } 22 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/model/postman/PostmanScript.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.model.postman; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * website https://www.lematech.vip/ 9 | * @author chenfanghang 10 | * @version 1.0.1 11 | */ 12 | @Data 13 | public class PostmanScript { 14 | private List exec; 15 | private String type; 16 | } 17 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/model/postman/PostmanUrl.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.model.postman; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * website https://www.lematech.vip/ 9 | * @author chenfanghang 10 | * @version 1.0.1 11 | */ 12 | @Data 13 | public class PostmanUrl { 14 | 15 | private String raw; 16 | private String protocol; 17 | private List host; 18 | private String port; 19 | private List path; 20 | private List query; 21 | } 22 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/model/scaffolding/ApplicationInfo.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.model.scaffolding; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | /** 8 | * website https://www.lematech.vip/ 9 | * @author lematech@foxmail.com 10 | * @version 1.0.1 11 | */ 12 | 13 | @Data 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class ApplicationInfo { 17 | private String packageName; 18 | private String className; 19 | } 20 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/java/vip/lematech/hrun4j/model/scaffolding/ProjectInfo.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.model.scaffolding; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | /** 8 | * website https://www.lematech.vip/ 9 | * @author lematech@foxmail.com 10 | * @version 1.0.1 11 | */ 12 | 13 | @Data 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class ProjectInfo { 17 | private String groupId; 18 | private String artifactId; 19 | private String version; 20 | private String name; 21 | private String description; 22 | } 23 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/resources/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Main-Class: vip.lematech.hrun4j.Hrun4j 3 | 4 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/resources/vm/scaffold/hrun4j/cli/Hrun4j.vm: -------------------------------------------------------------------------------- 1 | #!/bin/java bsh.Interpreter 2 | print("hrun4j.bsh文件所在路径即为项目工程路径"); 3 | print("你好,欢迎使用hrun4j!"); 4 | print("官网:http://www.lematech.vip"); 5 | print("微信公众号:lematech"); 6 | print("技术交流微信:wytest"); -------------------------------------------------------------------------------- /hrun4j-cli/src/main/resources/vm/scaffold/hrun4j/cli/apis/get.vm: -------------------------------------------------------------------------------- 1 | name: Postman Echo GET Request 2 | base_url: https://postman-echo.com 3 | variables: 4 | website: http://lematech.vip_api 5 | project: hrun4j_api 6 | author: lematech_api 7 | request: 8 | url: /get?website=${website}&project=${project}&author=${author} 9 | method: GET -------------------------------------------------------------------------------- /hrun4j-cli/src/main/resources/vm/scaffold/hrun4j/cli/apis/postFormData.vm: -------------------------------------------------------------------------------- 1 | name: Postman Echo POST Raw Text Request 2 | base_url: http://lematech.vip 3 | variables: 4 | website: http://lematech.vip_api 5 | project: hrun4j_api 6 | author: lematech_api 7 | request: 8 | url: /post 9 | method: POST 10 | headers: 11 | data: 12 | website: ${website} 13 | project: ${project} 14 | author: ${author} -------------------------------------------------------------------------------- /hrun4j-cli/src/main/resources/vm/scaffold/hrun4j/cli/apis/postRawText.vm: -------------------------------------------------------------------------------- 1 | name: Postman Echo POST Raw Text Request 2 | base_url: https://postman-echo.com 3 | variables: 4 | data: "This is expected to be sent back as part of response body._api" 5 | request: 6 | url: /post 7 | method: POST 8 | data: ${data} -------------------------------------------------------------------------------- /hrun4j-cli/src/main/resources/vm/scaffold/hrun4j/cli/bsh/test.vm: -------------------------------------------------------------------------------- 1 | #!/bin/java bsh.Interpreter 2 | 3 | 1>2; 4 | foo = "Foo"; 5 | four = (2 + 2)*2/2; 6 | print( foo + " = " + four ); 7 | for (i=0; i<5; i++) 8 | print(i); 9 | int multiply(a, b) 10 | { 11 | return a*b; 12 | } 13 | result = multiply(12,14); 14 | print(result);//打印出168 15 | 16 | //import RequestEntity; 17 | //print($aaa); 18 | 19 | print("请求参数:"+$REQUEST); 20 | print("响应参数:"+$RESPONSE); 21 | print("上下文参数:"+$ENV); 22 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/resources/vm/scaffold/hrun4j/cli/data/csvFile.vm: -------------------------------------------------------------------------------- 1 | parameterName 2 | 1 3 | 2 -------------------------------------------------------------------------------- /hrun4j-cli/src/main/resources/vm/scaffold/hrun4j/cli/env.vm: -------------------------------------------------------------------------------- 1 | kev=value -------------------------------------------------------------------------------- /hrun4j-cli/src/main/resources/vm/scaffold/hrun4j/cli/gitignore.vm: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.war 15 | *.nar 16 | *.ear 17 | *.zip 18 | *.tar.gz 19 | *.rar 20 | .env 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* -------------------------------------------------------------------------------- /hrun4j-cli/src/main/resources/vm/scaffold/hrun4j/cli/readMe.vm: -------------------------------------------------------------------------------- 1 | # 工程案例 2 | 3 | >本工程由hrun4j脚手架工具生成,该工程以CLI方式集成hrun4j能力 4 | 5 | ## 工程目录 6 | 7 | 使用方法参考:http://lematech.vip -------------------------------------------------------------------------------- /hrun4j-cli/src/main/resources/vm/scaffold/hrun4j/cli/testcases/get/getScene.vm: -------------------------------------------------------------------------------- 1 | config: 2 | name: Postman Echo GET Request 3 | base_url: https://postman-echo.com 4 | variables: 5 | website: http://lematech.vip 6 | project: hrun4j 7 | author: lematechvipVar 8 | teststeps: 9 | - name: Postman Echo GET Request And Reference Api 10 | variables: 11 | author: lematech 12 | setup_hooks: 13 | - $\{BSH\('Hrun4j.bsh'\)\} 14 | request: 15 | url: /get?website=${website}&project=${project}&author=${author}&page={page} 16 | method: GET 17 | validate: 18 | - equalTo: [status_code,200] 19 | - equalTo: [body.args.website,http://lematech.vip] 20 | - equalTo: ["${author}", lematech] 21 | - equalTo: ["^website\":\"(.*?)\"$", website":"http://lematech.vip"] 22 | extract: 23 | - website: body.args.website 24 | output: 25 | - variables 26 | - extract 27 | - name: Reference Api 28 | api: apis/get.yml 29 | variables: 30 | author: ${website} 31 | validate: 32 | - equalTo: [status_code,200] -------------------------------------------------------------------------------- /hrun4j-cli/src/main/resources/vm/scaffold/hrun4j/cli/testcases/post/postScene.vm: -------------------------------------------------------------------------------- 1 | config: 2 | name: Postman Echo postFormData And postRawText Request 3 | base_url: https://postman-echo.com 4 | teststeps: 5 | - name: Reference postFormData Api 6 | api: apis/postFormData.yml 7 | variables: 8 | website: http://lematech.vip 9 | project: hrun4j 10 | author: lematech 11 | validate: 12 | - equalTo: [status_code,200] 13 | - name: Reference postRawText Api 14 | api: apis/postRawText.yml 15 | variables: 16 | data: "This is expected to be sent back as part of response body." 17 | validate: 18 | - equalTo: [status_code,200] -------------------------------------------------------------------------------- /hrun4j-cli/src/main/resources/vm/scaffold/hrun4j/cli/testsuite/testsuite.vm: -------------------------------------------------------------------------------- 1 | config: 2 | name: 测试用例集配置 3 | base_url: https://api.apiopen.top 4 | parameters: 5 | varA: "$\{P\(data/csvFile.csv\)\}" 6 | testcases: 7 | - name: Postman Echo GET Request 8 | testcase: testcases/get/getScene.yml 9 | - name: Postman Echo postFormData And postRawText Request 10 | testcase: testcases/post/postScene.yml -------------------------------------------------------------------------------- /hrun4j-cli/src/main/resources/vm/scaffold/hrun4j/pom/meta-info/env.vm: -------------------------------------------------------------------------------- 1 | kev=value -------------------------------------------------------------------------------- /hrun4j-cli/src/main/resources/vm/scaffold/hrun4j/pom/meta-info/gitignore.vm: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.war 15 | *.nar 16 | *.ear 17 | *.zip 18 | *.tar.gz 19 | *.rar 20 | .env 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* -------------------------------------------------------------------------------- /hrun4j-cli/src/main/resources/vm/scaffold/hrun4j/pom/meta-info/readMe.vm: -------------------------------------------------------------------------------- 1 | # 工程案例 2 | 3 | >本工程由hrun4j脚手架工具生成,该工程以POM方式集成hrun4j能力 4 | 5 | ## 工程目录 6 | 7 | ``` 8 | ├── README.md 案例说明 9 | ├── firstProject.iml 10 | ├── pom.xml POM案例 11 | └── src 12 | ├── main 13 | │   └── java 14 | │   └── io 15 | │   └── lematech 16 | │   └── firstproject 17 | │   └── testcases 18 | │   ├── Hrun4j.java --工程关键,继承Hrun4j类即可引入框架,另外配置、动态表达式引入可在此处完成 19 | │   └── functions -- 自定义方法集合 20 | │   └── MyFunction.java -- 方法实现 21 | └── test 22 | ├── java 23 | │   └── io 24 | │   └── lematech 25 | │   └── firstproject 26 | │   └── testcases 27 | │   ├── get 28 | │   │   └── GetTest.java -- 单测用例,一个目录下只需一个,目录名称要喝resources/testcases/get对应 29 | │   └── post 30 | │   └── PostTest.java -- 单测用例,一个目录下只需一个,目录名称要喝resources/testcases/post对应 31 | └── resources 32 | ├── apis -- 接口定义 33 | │   ├── get.yml 34 | │   └── post.yml 35 | ├── data -- 数据文件 36 | ├── testcases --用例文件 37 | │   ├── get 38 | │   │   └── getScene.yml 39 | │   └── post 40 | │   └── postScene.yml 41 | └── testsuite --用例集文件夹 42 | ├── testsuite.xml -- 用例集 43 | └── testsuite_all.xml -- 用例集 44 | 45 | ``` 46 | 47 | ## 参数化构建 48 | 49 | 构建命令:`mvn clean test -DxmlFileName=src/test/resources/testsuite/testsuite.xml` 50 | 51 | ```xml 52 | 53 | org.apache.maven.plugins 54 | maven-surefire-plugin 55 | 2.17 56 | 57 | 58 | ${xmlFileName} 59 | 60 | 61 | 62 | ``` 63 | 其中: 64 | 1. xmlFileName代表pom.xml配置的suiteXmlFile值 65 | 2. `src/test/resources/testsuite/testsuite.xml`当前工程下测试用例集相对或绝对路径 66 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/resources/vm/scaffold/hrun4j/pom/resources/Hrun4j.vm: -------------------------------------------------------------------------------- 1 | #!/bin/java bsh.Interpreter 2 | print("Hrun4j.bsh文件所在路径即为项目工程路径"); 3 | print("你好,欢迎使用Hrun4j!"); 4 | print("官网:http://www.lematech.vip"); 5 | print("微信公众号:lematech"); 6 | print("技术交流微信:wytest"); -------------------------------------------------------------------------------- /hrun4j-cli/src/main/resources/vm/scaffold/hrun4j/pom/resources/apis/get.vm: -------------------------------------------------------------------------------- 1 | name: Postman Echo GET Request 2 | base_url: https://postman-echo.com 3 | variables: 4 | website: http://lematech.vip_api 5 | project: hrun4j_api 6 | author: lematech_api 7 | request: 8 | url: /get?website=${website}&project=${project}&author=${author} 9 | method: GET -------------------------------------------------------------------------------- /hrun4j-cli/src/main/resources/vm/scaffold/hrun4j/pom/resources/apis/postFormData.vm: -------------------------------------------------------------------------------- 1 | name: Postman Echo POST Raw Text Request 2 | base_url: http://lematech.vip 3 | variables: 4 | website: http://lematech.vip_api 5 | project: hrun4j_api 6 | author: lematech_api 7 | request: 8 | url: /post 9 | method: POST 10 | headers: 11 | data: 12 | website: ${website} 13 | project: ${project} 14 | author: ${author} -------------------------------------------------------------------------------- /hrun4j-cli/src/main/resources/vm/scaffold/hrun4j/pom/resources/apis/postRawText.vm: -------------------------------------------------------------------------------- 1 | name: Postman Echo POST Raw Text Request 2 | base_url: https://postman-echo.com 3 | variables: 4 | data: "This is expected to be sent back as part of response body._api" 5 | request: 6 | url: /post 7 | method: POST 8 | data: ${data} -------------------------------------------------------------------------------- /hrun4j-cli/src/main/resources/vm/scaffold/hrun4j/pom/resources/data/csvFile.vm: -------------------------------------------------------------------------------- 1 | parameterName 2 | 1 3 | 2 -------------------------------------------------------------------------------- /hrun4j-cli/src/main/resources/vm/scaffold/hrun4j/pom/resources/testcases/get/getScene.vm: -------------------------------------------------------------------------------- 1 | config: 2 | name: Postman Echo GET Request 3 | base_url: https://postman-echo.com 4 | variables: 5 | website: http://lematech.vip 6 | project: hrun4j 7 | author: lematechvipVar 8 | teststeps: 9 | - name: Postman Echo GET Request And Reference Api 10 | variables: 11 | author: lematech 12 | setup_hooks: 13 | - $\{BSH\('Hrun4j.bsh'\)\} 14 | - $\{shFunction\(page,count,type\)\} 15 | request: 16 | url: /get?website=${website}&project=${project}&author=${author}&page={page} 17 | method: GET 18 | extract: 19 | - website: body.args.website 20 | output: 21 | - variables 22 | - extract 23 | teardown_hooks: 24 | - $\{tdFunction\("This is a joke!"\)\} 25 | validate: 26 | - equalTo: [status_code,200] 27 | - equalTo: [body.args.website,http://lematech.vip] 28 | - equalTo: ["${author}", lematech] 29 | - equalTo: ["^website\":\"(.*?)\"$", website":"http://lematech.vip"] 30 | - name: Reference Api 31 | api: apis/get.yml 32 | variables: 33 | author: lematechvip 34 | website: ${website} 35 | validate: 36 | - equalTo: [status_code,200] -------------------------------------------------------------------------------- /hrun4j-cli/src/main/resources/vm/scaffold/hrun4j/pom/resources/testcases/post/postScene.vm: -------------------------------------------------------------------------------- 1 | config: 2 | name: Postman Echo postFormData And postRawText Request 3 | base_url: https://postman-echo.com 4 | teststeps: 5 | - name: Reference postFormData Api 6 | api: apis/postFormData.yml 7 | variables: 8 | website: http://lematech.vip 9 | project: hrun4j 10 | author: lematech 11 | validate: 12 | - equalTo: [status_code,200] 13 | - name: Reference postRawText Api 14 | api: apis/postRawText.yml 15 | variables: 16 | data: "This is expected to be sent back as part of response body." 17 | validate: 18 | - equalTo: [status_code,200] -------------------------------------------------------------------------------- /hrun4j-cli/src/main/resources/vm/scaffold/hrun4j/pom/template/function/Hrun4j.vm: -------------------------------------------------------------------------------- 1 | package ${application.packageName}; 2 | 3 | import com.googlecode.aviator.AviatorEvaluator; 4 | import ${application.packageName}.functions.MyFunction; 5 | import vip.lematech.hrun4j.base.TestBase; 6 | import vip.lematech.hrun4j.common.Constant; 7 | import vip.lematech.hrun4j.config.RunnerConfig; 8 | import org.testng.annotations.BeforeSuite; 9 | import vip.lematech.hrun4j.helper.LogHelper; 10 | 11 | /** 12 | * Extension function 13 | * @author lematech@foxmail.com 14 | * @version 1.0.1 15 | */ 16 | public class Hrun4j extends TestBase { 17 | @Override 18 | @BeforeSuite 19 | public void beforeSuite(){ 20 | LogHelper.info(" Add function to static code block !"); 21 | AviatorEvaluator.addFunction(new MyFunction.SetupHookFunction()); 22 | AviatorEvaluator.addFunction(new MyFunction.TearDownHookFunction()); 23 | /** 24 | * 包名,资源路径下查找测试用例前置,默认:vip.lematech.hrun4j 25 | */ 26 | RunnerConfig.getInstance().setPkgName("${application.packageName}"); 27 | /** 28 | * Test case file suffix 29 | */ 30 | RunnerConfig.getInstance().setTestCaseExtName(Constant.SUPPORT_TEST_CASE_FILE_EXT_YML_NAME); 31 | } 32 | } 33 | 34 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/resources/vm/scaffold/hrun4j/pom/template/function/functions/MyFunction.vm: -------------------------------------------------------------------------------- 1 | package ${application.packageName}.functions; 2 | 3 | import com.googlecode.aviator.runtime.function.AbstractFunction; 4 | import com.googlecode.aviator.runtime.function.FunctionUtils; 5 | import com.googlecode.aviator.runtime.type.AviatorObject; 6 | import com.googlecode.aviator.runtime.type.AviatorString; 7 | import vip.lematech.hrun4j.helper.LogHelper; 8 | 9 | import java.util.Map; 10 | 11 | /** 12 | * @author lematech@foxmail.com 13 | * @version 1.0.1 14 | */ 15 | 16 | public class MyFunction { 17 | 18 | /** 19 | * Custom function, set the function name will be implemented in the call supplement function 20 | */ 21 | public static class SetupHookFunction extends AbstractFunction { 22 | @Override 23 | public AviatorObject call(Map env, AviatorObject page, AviatorObject type, AviatorObject count) { 24 | LogHelper.info("正在执行:{}方法,方法参数:page={},count={},type={}",this.getName(), page,count,type); 25 | String typeValue = FunctionUtils.getStringValue(type, env); 26 | Number pageValue = FunctionUtils.getNumberValue(page, env); 27 | Number countValue = FunctionUtils.getNumberValue(count, env); 28 | String spiceString = String.format("page=%s&count=%s&page=type",pageValue,countValue,typeValue); 29 | return new AviatorString(String.valueOf(spiceString)); 30 | } 31 | @Override 32 | public String getName() { 33 | return "shFunction"; 34 | } 35 | } 36 | 37 | /** 38 | * Custom function, set the function name will be implemented in the call supplement function 39 | */ 40 | public static class TearDownHookFunction extends AbstractFunction { 41 | @Override 42 | public AviatorObject call(Map env,AviatorObject type) { 43 | LogHelper.info("正在执行:{}方法,方法参数:{}",this.getName(),type.toString()); 44 | LogHelper.info("当前请求参数详细信息:{}", env.get("$REQUEST")); 45 | LogHelper.info("当前响应参数详细信息:{}", env.get("$RESPONSE")); 46 | return new AviatorString("defineResult"); 47 | } 48 | @Override 49 | public String getName() { 50 | return "tdFunction"; 51 | } 52 | } 53 | 54 | 55 | } 56 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/resources/vm/scaffold/hrun4j/pom/template/pom.vm: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | ${projectInfo.groupId} 6 | ${projectInfo.artifactId} 7 | ${projectInfo.version} 8 | ${projectInfo.name} 9 | hrun4j pom scaffolding 10 | 11 | UTF-8 12 | 13 | 14 | 15 | 16 | vip.lematech 17 | hrun4j-core 18 | 1.0.2 19 | 20 | 21 | 22 | 23 | 24 | ${project.basedir}/src/main/java 25 | 26 | 27 | ${project.basedir}/src/main/resources 28 | 29 | 30 | 31 | 32 | ${project.basedir}/src/test/java 33 | 34 | 35 | ${project.basedir}/src/test/resources 36 | 37 | 38 | 39 | 40 | org.apache.maven.plugins 41 | maven-surefire-plugin 42 | 43 | 44 | ${xmlFileName} 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/resources/vm/scaffold/hrun4j/pom/template/testcase/get/GetTest.vm: -------------------------------------------------------------------------------- 1 | package ${application.packageName}.testcases.get; 2 | 3 | import org.testng.annotations.Test; 4 | import ${application.packageName}.Hrun4j; 5 | import vip.lematech.hrun4j.core.engine.TestCaseExecutorEngine; 6 | import vip.lematech.hrun4j.entity.testcase.TestCase; 7 | 8 | 9 | /** 10 | * @author lematech@foxmail.com 11 | * @version 1.0.1 12 | */ 13 | public class GetTest extends Hrun4j { 14 | @Test(dataProvider = "dataProvider") 15 | public void getScene(TestCase testCase) { 16 | TestCaseExecutorEngine.getInstance().execute(testCase); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/resources/vm/scaffold/hrun4j/pom/template/testcase/post/PostTest.vm: -------------------------------------------------------------------------------- 1 | package ${application.packageName}.testcases.post; 2 | 3 | import org.testng.annotations.Test; 4 | import ${application.packageName}.Hrun4j; 5 | import vip.lematech.hrun4j.core.engine.TestCaseExecutorEngine; 6 | import vip.lematech.hrun4j.entity.testcase.TestCase; 7 | 8 | 9 | /** 10 | * @author lematech@foxmail.com 11 | * @version 1.0.1 12 | */ 13 | public class PostTest extends Hrun4j { 14 | @Test(dataProvider = "dataProvider") 15 | public void postScene(TestCase testCase) { 16 | TestCaseExecutorEngine.getInstance().execute(testCase); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/resources/vm/scaffold/hrun4j/pom/template/testsuite/testsuite.vm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/resources/vm/scaffold/hrun4j/pom/template/testsuite/testsuite_all.vm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/resources/vm/scaffold/springboot/application.vm: -------------------------------------------------------------------------------- 1 | package ${application.packageName}; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class ${application.className} { 8 | public static void main(String[] args) { 9 | SpringApplication.run(${application.className}.class, args); 10 | } 11 | } -------------------------------------------------------------------------------- /hrun4j-cli/src/main/resources/vm/scaffold/springboot/ignore.vm: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.war 15 | *.nar 16 | *.ear 17 | *.zip 18 | *.tar.gz 19 | *.rar 20 | .env 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* -------------------------------------------------------------------------------- /hrun4j-cli/src/main/resources/vm/scaffold/springboot/package-info.vm: -------------------------------------------------------------------------------- 1 | package ${application.packageName}; -------------------------------------------------------------------------------- /hrun4j-cli/src/main/resources/vm/scaffold/springboot/pom.vm: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.6.RELEASE 9 | 10 | 11 | ${projectInfo.groupId} 12 | ${projectInfo.artifactId} 13 | ${projectInfo.version} 14 | ${projectInfo.name} 15 | ${projectInfo.description} 16 | 17 | 18 | 1.8 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-web 25 | 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-test 30 | test 31 | 32 | 33 | 34 | 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-maven-plugin 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /hrun4j-cli/src/main/resources/vm/scaffold/springboot/test.vm: -------------------------------------------------------------------------------- 1 | package ${application.packageName}; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class ApiTest { 11 | @Test 12 | public void testApi() { 13 | } 14 | } -------------------------------------------------------------------------------- /hrun4j-cli/src/main/resources/vm/scaffold/springboot/yml.vm: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8081 -------------------------------------------------------------------------------- /hrun4j-cli/src/test/java/vip/lematech/hrun4j/parse/Postman2CaseTest.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.parse; 2 | 3 | import org.testng.Assert; 4 | import org.testng.annotations.Test; 5 | import vip.lematech.hrun4j.cli.commands.Postman2Case; 6 | 7 | import java.io.File; 8 | 9 | /** 10 | * website https://www.lematech.vip/ 11 | * @author chenfanghang 12 | * @version 1.0.1 13 | */ 14 | public class Postman2CaseTest { 15 | 16 | @Test 17 | public void testPostman2Case() { 18 | Postman2Case postman2Case = new Postman2Case(); 19 | File file = new File("src/test/resources/postman/postman_collection.json"); 20 | String target = "src/test/resources/postman"; 21 | int code = postman2Case.parse(file, target); 22 | Assert.assertEquals(code, 0); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /hrun4j-cli/src/test/resources/postman/Writing test scripts/Postman Echo DELETE.yml: -------------------------------------------------------------------------------- 1 | config: 2 | baseUrl: https://postman-echo 3 | name: Postman Echo DELETE 4 | verify: false 5 | teststeps: 6 | - name: Postman Echo DELETE 7 | request: 8 | url: /delete 9 | method: DELETE 10 | headers: 11 | Content-Type: application/json 12 | json: 13 | method: DELETE 14 | allowRedirects: true 15 | stream: true 16 | validate: 17 | - eq: 18 | - status_code 19 | - 200 20 | -------------------------------------------------------------------------------- /hrun4j-cli/src/test/resources/postman/Writing test scripts/Postman Echo GET.yml: -------------------------------------------------------------------------------- 1 | config: 2 | baseUrl: https://postman-echo 3 | name: Postman Echo GET 4 | verify: false 5 | teststeps: 6 | - name: Postman Echo GET 7 | request: 8 | url: /get 9 | method: GET 10 | allowRedirects: true 11 | stream: true 12 | validate: 13 | - eq: 14 | - status_code 15 | - 200 16 | -------------------------------------------------------------------------------- /hrun4j-cli/src/test/resources/postman/Writing test scripts/Postman Echo POST.yml: -------------------------------------------------------------------------------- 1 | config: 2 | baseUrl: https://postman-echo 3 | name: Postman Echo POST 4 | verify: false 5 | teststeps: 6 | - name: Postman Echo POST 7 | request: 8 | url: /post 9 | method: POST 10 | headers: 11 | Content-Type: application/json 12 | json: 13 | method: POST 14 | allowRedirects: true 15 | stream: true 16 | validate: 17 | - eq: 18 | - status_code 19 | - 200 20 | -------------------------------------------------------------------------------- /hrun4j-cli/src/test/resources/postman/Writing test scripts/Postman Echo PUT.yml: -------------------------------------------------------------------------------- 1 | config: 2 | baseUrl: https://postman-echo 3 | name: Postman Echo PUT 4 | verify: false 5 | teststeps: 6 | - name: Postman Echo PUT 7 | request: 8 | url: /put 9 | method: PUT 10 | headers: 11 | Content-Type: application/json 12 | json: 13 | method: PUT 14 | allowRedirects: true 15 | stream: true 16 | validate: 17 | - eq: 18 | - status_code 19 | - 200 20 | -------------------------------------------------------------------------------- /hrun4j-cli/src/test/resources/testsutie/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lematechvip/hrun4j/d41d80059c99c9eb5f84f98f609733f088413b82/hrun4j-cli/src/test/resources/testsutie/.DS_Store -------------------------------------------------------------------------------- /hrun4j-core/README.md: -------------------------------------------------------------------------------- 1 | # hrun4j -------------------------------------------------------------------------------- /hrun4j-core/src/main/java/vip/lematech/hrun4j/base/TestBase.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.base; 2 | 3 | import cn.hutool.core.io.FileUtil; 4 | import vip.lematech.hrun4j.common.DefinedException; 5 | import vip.lematech.hrun4j.core.provider.NGDataProvider; 6 | import vip.lematech.hrun4j.helper.LogHelper; 7 | import org.testng.annotations.*; 8 | 9 | import java.lang.reflect.Method; 10 | 11 | /** 12 | * Test base classes for pre -, post -, and data loading 13 | * 14 | * website https://www.lematech.vip/ 15 | * @author lematech@foxmail.com 16 | * @version 1.0.1 17 | * 18 | */ 19 | 20 | public class TestBase { 21 | private String testCaseName; 22 | @BeforeSuite 23 | public void beforeSuite(){ 24 | LogHelper.info("[========================================]@beforeSuite()"); 25 | } 26 | @BeforeMethod 27 | public void setUp() { 28 | LogHelper.info("[====================" + this.testCaseName + "====================]@START"); 29 | } 30 | @AfterMethod 31 | public void tearDown() { 32 | LogHelper.info("[====================" + this.testCaseName + "====================]@END"); 33 | } 34 | @AfterSuite 35 | public void afterSuite(){ 36 | LogHelper.info("[========================================]@afterSuite()"); 37 | } 38 | @DataProvider 39 | public Object[][] dataProvider(Method method) { 40 | Object[][] objects; 41 | this.testCaseName = method.getName(); 42 | String packageName = FileUtil.mainName(method.getDeclaringClass().getName()); 43 | try { 44 | objects = new NGDataProvider().dataProvider(packageName, testCaseName); 45 | } catch (DefinedException e) { 46 | throw e; 47 | } catch (Exception e) { 48 | String exceptionMsg = String.format("Abnormal testng data loading occurs, and the reason for the exception is as follows: %s", e.getMessage()); 49 | throw new DefinedException(exceptionMsg); 50 | } 51 | return objects; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /hrun4j-core/src/main/java/vip/lematech/hrun4j/common/DefinedException.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.common; 2 | 3 | 4 | import vip.lematech.hrun4j.helper.LogHelper; 5 | 6 | /** 7 | * throw defined exception 8 | * website https://www.lematech.vip/ 9 | * @author lematech@foxmail.com 10 | * @version 1.0.1 11 | */ 12 | 13 | 14 | public class DefinedException extends RuntimeException { 15 | /** 16 | * define exception 17 | * 18 | * @param msg exception message 19 | */ 20 | public DefinedException(String msg) { 21 | LogHelper.error(msg); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /hrun4j-core/src/main/java/vip/lematech/hrun4j/config/Env.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.config; 2 | 3 | import cn.hutool.core.io.FileUtil; 4 | import vip.lematech.hrun4j.helper.FilesHelper; 5 | import vip.lematech.hrun4j.helper.LogHelper; 6 | import vip.lematech.hrun4j.common.Constant; 7 | 8 | import java.io.File; 9 | import java.io.FileInputStream; 10 | import java.io.IOException; 11 | import java.net.URL; 12 | import java.util.HashMap; 13 | import java.util.Map; 14 | import java.util.Objects; 15 | import java.util.Properties; 16 | 17 | 18 | /** 19 | * website https://www.lematech.vip/ 20 | * @author lematech@foxmail.com 21 | * @version 1.0.1 22 | */ 23 | public class Env { 24 | public static Map getEnvMap() { 25 | if (envMap == null) { 26 | initializeEnv(); 27 | } 28 | return envMap; 29 | } 30 | 31 | private static Map envMap; 32 | 33 | private static synchronized void initializeEnv() { 34 | if (envMap == null) { 35 | RunnerConfig.RunMode runMode = RunnerConfig.getInstance().getRunMode(); 36 | envMap = new HashMap<>(); 37 | envMap.putAll(System.getenv()); 38 | Properties properties = new Properties(); 39 | try { 40 | String envFilePath = (runMode == RunnerConfig.RunMode.POM) ? Constant.ENV_FILE_NAME : RunnerConfig.getInstance().getDotEnvPath(); 41 | File searchFile = null; 42 | if (runMode == RunnerConfig.RunMode.CLI) { 43 | if(Objects.isNull(envFilePath)){ 44 | return ; 45 | } 46 | if (FileUtil.isAbsolutePath(envFilePath)) { 47 | searchFile = new File(envFilePath); 48 | } else { 49 | searchFile = new File(RunnerConfig.getInstance().getWorkDirectory() 50 | , FilesHelper.filePathDecode(envFilePath)); 51 | } 52 | } else if (runMode == RunnerConfig.RunMode.POM) { 53 | URL url = Thread.currentThread().getContextClassLoader().getResource(envFilePath); 54 | searchFile = new File(FilesHelper.filePathDecode(url.getPath())); 55 | } 56 | if(!searchFile.isDirectory()&&FileUtil.exist(searchFile)){ 57 | properties.load(new FileInputStream(searchFile)); 58 | envMap.putAll((Map) properties); 59 | }else{ 60 | String exceptionMsg = Constant.ENV_FILE_NAME + " is not exist"; 61 | LogHelper.warn(exceptionMsg); 62 | } 63 | } catch (Exception e) { 64 | e.printStackTrace(); 65 | LogHelper.error("An error occurred loading the.env file"); 66 | } 67 | } 68 | 69 | } 70 | 71 | 72 | public static void setEnv(String key, Object value) { 73 | if (envMap == null) { 74 | initializeEnv(); 75 | } 76 | envMap.put(key, value); 77 | } 78 | 79 | public static Object getEnv(String key) { 80 | Object value = null; 81 | if (envMap == null) { 82 | initializeEnv(); 83 | } 84 | if (envMap.containsKey(key)) { 85 | value = envMap.get(key); 86 | } 87 | return value; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /hrun4j-core/src/main/java/vip/lematech/hrun4j/config/NamespaceMap.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.config; 2 | 3 | import vip.lematech.hrun4j.entity.testcase.TestCase; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | /** 9 | * website https://www.lematech.vip/ 10 | * @author lematech@foxmail.com 11 | * @version 1.0.1 12 | */ 13 | public class NamespaceMap { 14 | public static Map getNamespaceMap() { 15 | if (namespaceMap == null) { 16 | initializeEnv(); 17 | } 18 | return namespaceMap; 19 | } 20 | 21 | private static Map namespaceMap; 22 | 23 | private static synchronized void initializeEnv() { 24 | if (namespaceMap == null) { 25 | namespaceMap = new HashMap<>(); 26 | } 27 | } 28 | 29 | public static void setDataObject(String key, TestCase value) { 30 | if (namespaceMap == null) { 31 | initializeEnv(); 32 | } 33 | namespaceMap.put(key, value); 34 | } 35 | 36 | public static TestCase getDataObject(String key) { 37 | TestCase value = null; 38 | if (namespaceMap == null) { 39 | initializeEnv(); 40 | } 41 | if (namespaceMap.containsKey(key)) { 42 | value = namespaceMap.get(key); 43 | } 44 | return value; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /hrun4j-core/src/main/java/vip/lematech/hrun4j/config/RunnerConfig.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.config; 2 | 3 | import cn.hutool.core.util.StrUtil; 4 | import vip.lematech.hrun4j.helper.JavaIdentifierHelper; 5 | import vip.lematech.hrun4j.common.Constant; 6 | import vip.lematech.hrun4j.common.DefinedException; 7 | import lombok.Data; 8 | 9 | import java.io.File; 10 | import java.util.*; 11 | 12 | /** 13 | * Initialize the run configuration parameters 14 | * 15 | * website https://www.lematech.vip/ 16 | * @author lematech@foxmail.com 17 | * @version 1.0.1 18 | */ 19 | 20 | @Data 21 | public class RunnerConfig { 22 | 23 | /** 24 | * internationalization support,support en/zh 25 | */ 26 | private String i18n; 27 | 28 | public String getDotEnvPath() { 29 | return dotEnvPath; 30 | } 31 | 32 | public void setDotEnvPath(String dotEnvPath) { 33 | this.dotEnvPath = dotEnvPath; 34 | } 35 | 36 | /** 37 | * .env file path 38 | */ 39 | private String dotEnvPath; 40 | 41 | 42 | /** 43 | * supports cli 、api integration 44 | */ 45 | private RunMode runMode = RunMode.POM; 46 | 47 | public File getWorkDirectory() { 48 | return Objects.isNull(this.workDirectory) ? new File(Constant.DOT_PATH) : this.workDirectory; 49 | } 50 | 51 | /** 52 | * work directory 53 | */ 54 | private File workDirectory; 55 | 56 | public String getPkgName() { 57 | return StrUtil.isEmpty(this.pkgName) ? Constant.SELF_ROOT_PKG_NAME : this.pkgName; 58 | } 59 | 60 | /** 61 | * package name 62 | */ 63 | private String pkgName; 64 | /** 65 | * testcase extension name 66 | */ 67 | private String testCaseExtName; 68 | /** 69 | * test case paths 70 | */ 71 | private List testCasePaths; 72 | 73 | private static RunnerConfig instance = new RunnerConfig(); 74 | 75 | /** 76 | * set package name 77 | * @param pkgName package name 78 | */ 79 | public void setPkgName(String pkgName) { 80 | if (!JavaIdentifierHelper.isValidJavaFullClassName(pkgName)) { 81 | String exceptionMsg = String.format("The package name %s is invalid", pkgName); 82 | throw new DefinedException(exceptionMsg); 83 | } 84 | this.pkgName = pkgName; 85 | } 86 | 87 | private RunnerConfig() { 88 | testCasePaths = new ArrayList<>(); 89 | testCaseExtName = Constant.SUPPORT_TEST_CASE_FILE_EXT_YML_NAME; 90 | } 91 | 92 | public static RunnerConfig getInstance() { 93 | return instance; 94 | } 95 | 96 | /** 97 | * supports cli 、api integration 98 | * 99 | * @author lematech@foxmail.com 100 | * @version 1.0.1 101 | */ 102 | public enum RunMode { 103 | CLI, POM, PLATFORM 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /hrun4j-core/src/main/java/vip/lematech/hrun4j/config/i18n/I18NFactory.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.config.i18n; 2 | 3 | import vip.lematech.hrun4j.common.Constant; 4 | import vip.lematech.hrun4j.config.RunnerConfig; 5 | 6 | import java.util.Locale; 7 | import java.util.ResourceBundle; 8 | 9 | /** 10 | * 11 | * website https://www.lematech.vip/ 12 | * @author lematech@foxmail.com 13 | * @version 1.0.1 14 | */ 15 | public class I18NFactory { 16 | private synchronized static ResourceBundle getBundle(String locale) { 17 | Locale localeLang; 18 | if (Constant.I18N_US.equalsIgnoreCase(locale)) { 19 | localeLang = new Locale("en", "US"); 20 | } else if (Constant.I18N_CN.equalsIgnoreCase(locale)) { 21 | localeLang = new Locale("zh", "CN"); 22 | } else { 23 | localeLang = new Locale("zh", "CN"); 24 | } 25 | return ResourceBundle.getBundle("locales.message", localeLang); 26 | } 27 | public synchronized static String getLocaleMessage(String key) { 28 | return getBundle(RunnerConfig.getInstance().getI18n()).getString(key); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /hrun4j-core/src/main/java/vip/lematech/hrun4j/core/engine/TemplateEngine.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.core.engine; 2 | 3 | import vip.lematech.hrun4j.common.DefinedException; 4 | import org.apache.velocity.Template; 5 | import org.apache.velocity.VelocityContext; 6 | import org.apache.velocity.app.VelocityEngine; 7 | import org.apache.velocity.runtime.RuntimeConstants; 8 | import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader; 9 | 10 | import java.io.StringWriter; 11 | 12 | 13 | /** 14 | * website https://www.lematech.vip/ 15 | * @author lematech@foxmail.com 16 | * @version 1.0.1 17 | */ 18 | 19 | public class TemplateEngine { 20 | private static VelocityEngine velocityEngine; 21 | 22 | /** 23 | * get velocity engine instance 24 | * 25 | * @return velocity engine instance 26 | */ 27 | private static synchronized VelocityEngine getInstance() { 28 | if (velocityEngine == null) { 29 | velocityEngine = new VelocityEngine(); 30 | velocityEngine.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath"); 31 | velocityEngine.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName()); 32 | try { 33 | velocityEngine.init(); 34 | } catch (Exception e) { 35 | String exceptionMsg = String.format("Velocity engine init exception :%s", e.getMessage()); 36 | throw new DefinedException(exceptionMsg); 37 | } 38 | } 39 | return velocityEngine; 40 | } 41 | 42 | /** 43 | * render template by context self-defined variables 44 | * @param templateName template of name 45 | * @param context context 46 | * @return The contents of the template after rendering 47 | */ 48 | public static String getTemplateRenderContent(String templateName, VelocityContext context){ 49 | Template template; 50 | try { 51 | template = getInstance().getTemplate(templateName); 52 | } catch (Exception e) { 53 | String exceptionMsg = String.format("There was an exception getting the template %s,Exception Informations: ", templateName, e.getMessage()); 54 | throw new DefinedException(exceptionMsg); 55 | } 56 | 57 | StringWriter sw = new StringWriter(); 58 | try { 59 | template.merge(context, sw); 60 | } catch (Exception e) { 61 | String exceptionMsg = String.format("An exception occurred in the rendering engine template %s based on the constructed data,,Exception Informations: %s", templateName, e.getMessage()); 62 | throw new DefinedException(exceptionMsg); 63 | } 64 | return sw.toString(); 65 | } 66 | 67 | 68 | } 69 | 70 | -------------------------------------------------------------------------------- /hrun4j-core/src/main/java/vip/lematech/hrun4j/core/engine/TestCaseExecutorEngine.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.core.engine; 2 | 3 | 4 | import vip.lematech.hrun4j.core.runner.TestCaseRunner; 5 | 6 | 7 | /** 8 | * testcase executor engine 9 | * 10 | * website https://www.lematech.vip/ 11 | * @author lematech@foxmail.com 12 | * @version 1.0.1 13 | */ 14 | 15 | public class TestCaseExecutorEngine { 16 | private static TestCaseRunner tcr = null; 17 | public static synchronized TestCaseRunner getInstance() { 18 | tcr = new TestCaseRunner(); 19 | return tcr; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /hrun4j-core/src/main/java/vip/lematech/hrun4j/core/loader/TestDataLoaderFactory.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.core.loader; 2 | 3 | import cn.hutool.core.util.StrUtil; 4 | import vip.lematech.hrun4j.common.Constant; 5 | import vip.lematech.hrun4j.common.DefinedException; 6 | import vip.lematech.hrun4j.core.loader.impl.TestDataLoaderImpl; 7 | import vip.lematech.hrun4j.core.loader.service.ITestDataLoader; 8 | import vip.lematech.hrun4j.helper.LogHelper; 9 | 10 | 11 | /** 12 | * Test data loader factory by test case extname 13 | * 14 | * website https://www.lematech.vip/ 15 | * @author lematech@foxmail.com 16 | * @version 1.0.1 17 | */ 18 | 19 | public class TestDataLoaderFactory { 20 | /** 21 | * get file loader 22 | * @param extName extension name 23 | * @return test data loader 24 | */ 25 | public synchronized static ITestDataLoader getLoader(String extName) { 26 | if (StrUtil.isEmpty(extName)) { 27 | LogHelper.debug("Set the use case load format to YML by default"); 28 | return new TestDataLoaderImpl(extName); 29 | } 30 | if (extName.equalsIgnoreCase(Constant.SUPPORT_TEST_CASE_FILE_EXT_YML_NAME) 31 | || extName.equalsIgnoreCase(Constant.SUPPORT_TEST_CASE_FILE_EXT_JSON_NAME)) { 32 | return new TestDataLoaderImpl(extName); 33 | } else { 34 | String exceptionMsg = String.format("The current extension %s is not supported.", extName); 35 | throw new DefinedException(exceptionMsg); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /hrun4j-core/src/main/java/vip/lematech/hrun4j/core/loader/service/ITestDataLoader.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.core.loader.service; 2 | 3 | 4 | import java.io.File; 5 | 6 | 7 | /** 8 | * Data loading define class, support file loading 9 | * website https://www.lematech.vip/ 10 | * @author lematech@foxmail.com 11 | * @version 1.0.1 12 | */ 13 | public interface ITestDataLoader { 14 | 15 | /** 16 | * file load 17 | * 18 | * @param fileName The file name 19 | * @param clazz The specified class 20 | * @param The generic type 21 | * @return The specified object 22 | */ 23 | T load(File fileName, Class clazz); 24 | } 25 | -------------------------------------------------------------------------------- /hrun4j-core/src/main/java/vip/lematech/hrun4j/entity/base/BaseModel.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.entity.base; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import lombok.Data; 5 | 6 | /** 7 | * website https://www.lematech.vip/ 8 | * @author lematech@foxmail.com 9 | * @version 1.0.1 10 | */ 11 | @Data 12 | public class BaseModel { 13 | 14 | /** 15 | * array[string]:call setup hook functions, return nothing 16 | * - '${sleep(2)}' 17 | * - '${hook_print(setup)}' 18 | * - '${modify_request_json($request, android)}' 19 | * - '${alter_response($response)}' 20 | * map:call setup hook functions, return value and assign to variable(TP) 21 | * total: '${sum_two(1, 5)}' 22 | * filed_name: get_decoded_response_field($response) 23 | * array[map]:call setup hook functions, return value and assign to variable 24 | * -total: '${sum_two(1, 5)}' 25 | * total: value1 26 | * -filed_name: get_decoded_response_field($response) 27 | */ 28 | 29 | @JsonProperty(value = "setup_hooks") 30 | private T setupHooks; 31 | 32 | /** 33 | * array[string]:call teardown hook hook functions, return nothing 34 | * - '${sleep(2)}' 35 | * - '${hook_print(setup)}' 36 | * - '${modify_request_json($request, android)}' 37 | * - '${alter_response($response)}' 38 | * map:call setup hook functions, return value and assign to variable(TP) 39 | * total: '${sum_two(1, 5)}' 40 | * filed_name: get_decoded_response_field($response) 41 | * array[map]:call teardown hook functions, return value and assign to variable 42 | * -total: '${sum_two(1, 5)}' 43 | * total: value1 44 | * -filed_name: get_decoded_response_field($response) 45 | */ 46 | @JsonProperty(value = "teardown_hooks") 47 | private T teardownHooks; 48 | 49 | /** 50 | * array[string]:if exp and execute exp, return value and assign to variable 51 | * $prepared_variables 52 | * map:assign to variable(TP) 53 | * var1: value1 54 | * var2: value2 55 | * array[map]:assign to variable 56 | * -var1: value1 57 | * var11: value11 58 | * -var2: value2 59 | * var21: value21 60 | */ 61 | @JsonProperty(value = "variables") 62 | private T variables; 63 | } 64 | 65 | -------------------------------------------------------------------------------- /hrun4j-core/src/main/java/vip/lematech/hrun4j/entity/http/RequestEntity.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.entity.http; 2 | 3 | 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.NoArgsConstructor; 7 | import com.alibaba.fastjson.annotation.JSONField; 8 | import lombok.Data; 9 | import java.util.Map; 10 | 11 | /** 12 | * website https://www.lematech.vip/ 13 | * @author lematech@foxmail.com 14 | * @version 1.0.1 15 | */ 16 | @Data 17 | @Builder 18 | @NoArgsConstructor 19 | @AllArgsConstructor 20 | public class RequestEntity { 21 | @JSONField(ordinal = 2) 22 | private String method; 23 | @JSONField(ordinal = 1) 24 | private String url; 25 | /** 26 | * 1、query string for request url 27 | */ 28 | @JSONField(ordinal = 4) 29 | private Map params; 30 | /** 31 | * 1、request body in json format 32 | * 2、request body in application/x-www-form-urlencoded format 33 | * 3、request body prepared with function, or reference a variable 34 | */ 35 | @JSONField(ordinal = 6) 36 | private T data; 37 | 38 | /** 39 | * 1、request body in json format 40 | * 2、request body prepared with function, or reference a variable 41 | */ 42 | @JSONField(ordinal = 5) 43 | private T json; 44 | 45 | @JSONField(ordinal = 3) 46 | private Map headers; 47 | 48 | @JSONField(ordinal = 8) 49 | private Integer connectTimeout; 50 | 51 | /** 52 | * Enable/disable GET/OPTIONS/POST/PUT/PATCH/DELETE/HEAD redirection. Defaults to True 53 | */ 54 | @JSONField(ordinal = 11) 55 | private Boolean allowRedirects = true; 56 | @JSONField(ordinal = 9) 57 | private Integer writeTimeout; 58 | 59 | @JSONField(ordinal = 10) 60 | private Integer readTimeout; 61 | 62 | 63 | /** 64 | * request cookies 65 | */ 66 | @JSONField(ordinal = 12) 67 | private Map cookies; 68 | 69 | /** 70 | * request files, used to upload files 71 | */ 72 | @JSONField(ordinal = 7) 73 | private Object files; 74 | /** 75 | * 76 | */ 77 | @JSONField(ordinal = 13) 78 | private Object auth; 79 | /** 80 | * Dictionary mapping protocol to the URL of the proxy 81 | */ 82 | @JSONField(ordinal = 14) 83 | private Map proxy; 84 | 85 | /** 86 | * if False, the response content will be immediately downloaded. 87 | */ 88 | @JSONField(ordinal = 15) 89 | private Boolean stream = true; 90 | 91 | } 92 | -------------------------------------------------------------------------------- /hrun4j-core/src/main/java/vip/lematech/hrun4j/entity/http/ResponseEntity.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.entity.http; 2 | 3 | import com.alibaba.fastjson.annotation.JSONField; 4 | import lombok.Data; 5 | 6 | import java.util.Map; 7 | 8 | /** 9 | * website https://www.lematech.vip/ 10 | * @author lematech@foxmail.com 11 | * @version 1.0.1 12 | */ 13 | @Data 14 | public class ResponseEntity { 15 | /** 16 | * status code 17 | */ 18 | @JSONField(name = "status_code") 19 | private Integer statusCode; 20 | /** 21 | * response headers 22 | */ 23 | private Map headers; 24 | /** 25 | * response time 26 | */ 27 | private Double time; 28 | 29 | /** 30 | * response content 31 | */ 32 | @JSONField(name = "body") 33 | private Object body; 34 | /** 35 | * response cookies 36 | */ 37 | private Map cookies; 38 | 39 | /** 40 | * response content length 41 | */ 42 | private Long contentLength; 43 | } 44 | -------------------------------------------------------------------------------- /hrun4j-core/src/main/java/vip/lematech/hrun4j/entity/testcase/ApiModel.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.entity.testcase; 2 | 3 | import com.alibaba.fastjson.annotation.JSONField; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.NoArgsConstructor; 8 | import vip.lematech.hrun4j.entity.http.RequestEntity; 9 | import vip.lematech.hrun4j.entity.base.BaseModel; 10 | import lombok.Data; 11 | import java.util.List; 12 | import java.util.Map; 13 | 14 | /** 15 | * website https://www.lematech.vip/ 16 | * 17 | * @author lematech@foxmail.com 18 | * @version 1.0.1 19 | */ 20 | @Data 21 | @Builder 22 | @NoArgsConstructor 23 | @AllArgsConstructor 24 | public class ApiModel extends BaseModel { 25 | @JsonProperty(value = "name") 26 | @JSONField(ordinal = 1) 27 | private String name; 28 | @JsonProperty(value = "base_url") 29 | @JSONField(ordinal = 2) 30 | private String baseUrl; 31 | 32 | /** 33 | * array[map]:used to validate response fields,validate_func_name: [check_value, expect_value] 34 | * - equalTo: [statusCode, "200"] 35 | * array[map]:one validator definition(TP) 36 | * - "check": "statusCode" 37 | * "comparator": "equalTo" 38 | * "expect": "200" 39 | */ 40 | @JSONField(ordinal = 5) 41 | private List> validate; 42 | @JSONField(ordinal = 3) 43 | private RequestEntity request; 44 | @JSONField(ordinal = 4) 45 | private T extract; 46 | 47 | } 48 | -------------------------------------------------------------------------------- /hrun4j-core/src/main/java/vip/lematech/hrun4j/entity/testcase/Comparator.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.entity.testcase; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.Objects; 6 | 7 | /** 8 | * website https://www.lematech.vip/ 9 | * @author lematech@foxmail.com 10 | * @version 1.0.1 11 | */ 12 | @Data 13 | public class Comparator { 14 | private Object check; 15 | private String comparator; 16 | private Object expect; 17 | 18 | /** 19 | * set comparator defualt is equalTo 20 | * 21 | * @param comparator comparator object 22 | */ 23 | public void setComparator(String comparator) { 24 | if (Objects.isNull(this.comparator)) { 25 | this.comparator = "equalTo"; 26 | } 27 | this.comparator = comparator; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /hrun4j-core/src/main/java/vip/lematech/hrun4j/entity/testcase/Config.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.entity.testcase; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import vip.lematech.hrun4j.entity.base.BaseModel; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | 8 | 9 | /** 10 | * website https://www.lematech.vip/ 11 | * @author lematech@foxmail.com 12 | * @version 1.0.1 13 | */ 14 | @EqualsAndHashCode(callSuper = false) 15 | @Data 16 | public class Config extends BaseModel { 17 | @JsonProperty(value = "name") 18 | private String name; 19 | @JsonProperty(value = "base_url") 20 | private String baseUrl; 21 | @JsonProperty(value = "verify") 22 | private Boolean verify; 23 | /** 24 | * map: 25 | * user_id: [1001, 1002, 1003, 1004] 26 | */ 27 | private T parameters; 28 | } 29 | -------------------------------------------------------------------------------- /hrun4j-core/src/main/java/vip/lematech/hrun4j/entity/testcase/TestCase.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.entity.testcase; 2 | 3 | import com.alibaba.fastjson.annotation.JSONField; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | import lombok.Data; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * website https://www.lematech.vip/ 11 | * @author lematech@foxmail.com 12 | * @version 1.0.1 13 | */ 14 | 15 | @Data 16 | public class TestCase { 17 | private Config config; 18 | @JSONField(name = "teststeps") 19 | @JsonProperty(value = "teststeps") 20 | private List testSteps; 21 | } 22 | -------------------------------------------------------------------------------- /hrun4j-core/src/main/java/vip/lematech/hrun4j/entity/testcase/TestStep.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.entity.testcase; 2 | 3 | import lombok.*; 4 | import vip.lematech.hrun4j.entity.http.RequestEntity; 5 | import vip.lematech.hrun4j.entity.base.BaseModel; 6 | 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | 11 | /** 12 | * 13 | * website https://www.lematech.vip/ 14 | * @author lematech@foxmail.com 15 | * @version 1.0.1 16 | */ 17 | @EqualsAndHashCode(callSuper = false) 18 | @Data 19 | @Builder 20 | @NoArgsConstructor 21 | @AllArgsConstructor 22 | public class TestStep extends BaseModel{ 23 | 24 | private String name; 25 | /** 26 | * used to extract session variables for later requests 27 | * map:extraction rule for session variable, maybe in jsonpath/regex/jmespath(TP) 28 | * code__by_jsonpath: $.code 29 | * item_id__by_jsonpath: $..items.*.id 30 | * var_name__by_regex: '"LB[\d]*(.*)RB[\d]*"' 31 | * content_type: headers.content-type 32 | * first_name: content.person.name.first_name 33 | * array[map]: 34 | * -code__by_jsonpath: $.code 35 | * -item_id__by_jsonpath: $..items.*.id 36 | * -var_name__by_regex: '"LB[\d]*(.*)RB[\d]*"' 37 | * -content_type: headers.content-type 38 | * -first_name: content.person.name.first_name 39 | */ 40 | private T extract; 41 | 42 | /** 43 | * array[map]:used to validate response fields,validate_func_name: [check_value, expect_value],comparator default set equalTo 44 | * - equalTo: [statusCode, "200"] 45 | * array[map]:one validator definition(TP) 46 | * - "check": "statusCode" 47 | * "comparator": "equalTo" 48 | * "expect": "200" 49 | */ 50 | private List> validate; 51 | 52 | /** 53 | * http request 54 | */ 55 | private RequestEntity request; 56 | 57 | /** 58 | * api reference, value is api file relative path 59 | */ 60 | private String api; 61 | 62 | /** 63 | * testcase reference 64 | */ 65 | private String testcase; 66 | 67 | /** 68 | * The list of arguments that the entire use case outputs. The arguments that can be output include the common variable and extract arguments 69 | */ 70 | private List output; 71 | } 72 | -------------------------------------------------------------------------------- /hrun4j-core/src/main/java/vip/lematech/hrun4j/entity/testcase/TestSuite.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.entity.testcase; 2 | 3 | import com.alibaba.fastjson.annotation.JSONField; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | import lombok.Data; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * Test Case Suite 11 | * 12 | * 13 | * website https://www.lematech.vip/ 14 | * @author lematech@foxmail.com 15 | * @version 1.0.1 16 | */ 17 | @Data 18 | public class TestSuite { 19 | private Config config; 20 | @JsonProperty(value = "testcases") 21 | @JSONField(name = "testcases") 22 | private List testCases; 23 | } 24 | -------------------------------------------------------------------------------- /hrun4j-core/src/main/java/vip/lematech/hrun4j/entity/testcase/TestSuiteCase.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.entity.testcase; 2 | 3 | import com.alibaba.fastjson.annotation.JSONField; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | import lombok.Data; 6 | 7 | /** 8 | * 9 | * website https://www.lematech.vip/ 10 | * @author lematech@foxmail.com 11 | * @version 1.0.1 12 | */ 13 | @Data 14 | public class TestSuiteCase { 15 | private String name; 16 | @JsonProperty(value = "variables") 17 | private T variables; 18 | private T parameters; 19 | @JsonProperty(value = "testcase") 20 | @JSONField(name = "testcase") 21 | private String caseRelativePath; 22 | } 23 | -------------------------------------------------------------------------------- /hrun4j-core/src/main/java/vip/lematech/hrun4j/helper/LogHelper.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.helper; 2 | 3 | 4 | import cn.hutool.core.text.StrFormatter; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.testng.Reporter; 7 | 8 | /** 9 | * logger output 10 | * 11 | * website https://www.lematech.vip/ 12 | * @author lematech@foxmail.com 13 | * @version 1.0.1 14 | */ 15 | @Slf4j 16 | public class LogHelper { 17 | /** 18 | * format output 19 | * 20 | * @param logStr 21 | * @param args 22 | * @return 23 | */ 24 | private static String formatInfo(String logStr, Object... args) { 25 | return StrFormatter.format(logStr, args); 26 | } 27 | 28 | public static void info(String logStr, Object... args) { 29 | log.info(formatInfo(logStr, args)); 30 | Reporter.log("[" + LittleHelper.getSimpleDateFormat() + "] " + formatInfo(logStr, args)); 31 | } 32 | 33 | /** 34 | * error log output and reporter output 35 | * 36 | * @param logStr logger output 37 | * @param args arguments 38 | */ 39 | public static void error(String logStr, Object... args) { 40 | log.error(formatInfo(logStr, args)); 41 | Reporter.log("[" + LittleHelper.getSimpleDateFormat() + "] " + formatInfo(logStr, args)); 42 | } 43 | 44 | public static void debug(String logStr, Object... args) { 45 | log.debug(formatInfo(logStr, args)); 46 | } 47 | 48 | public static void warn(String logStr, Object... args) { 49 | log.warn(formatInfo(logStr, args)); 50 | Reporter.log("[" + LittleHelper.getSimpleDateFormat() + "] " + formatInfo(logStr, args)); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /hrun4j-core/src/main/java/vip/lematech/hrun4j/helper/RegExpHelper.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.helper; 2 | 3 | import cn.hutool.core.util.StrUtil; 4 | import vip.lematech.hrun4j.common.Constant; 5 | import vip.lematech.hrun4j.common.DefinedException; 6 | import org.apache.commons.lang.StringUtils; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | import java.util.regex.Matcher; 11 | import java.util.regex.Pattern; 12 | 13 | 14 | /** 15 | * website https://www.lematech.vip/ 16 | * @author lematech@foxmail.com 17 | * @version 1.0.1 18 | */ 19 | public class RegExpHelper { 20 | 21 | /** 22 | * is exp 23 | * 24 | * @param exp The expression 25 | * @return true or false 26 | */ 27 | public static Boolean isExp(String exp) { 28 | Boolean flag = false; 29 | if (StringUtils.isEmpty(exp)) { 30 | return false; 31 | } 32 | if (match(Constant.REGEX_EXPRESSION_FLAG, exp)) { 33 | flag = true; 34 | } 35 | return flag; 36 | } 37 | 38 | /** 39 | * Is parameterize exp 40 | * @param exp expression 41 | * @return true or false 42 | */ 43 | public static Boolean isParameterizeExp(String exp) { 44 | Boolean flag = false; 45 | if (StringUtils.isEmpty(exp)) { 46 | return false; 47 | } 48 | if (match(Constant.REGEX_PARAMETERIZE_EXPRESSION_FLAG, exp)) { 49 | flag = true; 50 | } 51 | return flag; 52 | } 53 | 54 | /** 55 | * @param reg 56 | * @param str 57 | * @return 58 | */ 59 | private static boolean match(String reg, String str) { 60 | return Pattern.matches(reg, str); 61 | } 62 | 63 | /** 64 | * @param reg regex pattern 65 | * @param str string 66 | * @return find result 67 | */ 68 | public static List find(String reg, String str) { 69 | Matcher matcher = Pattern.compile(reg).matcher(str); 70 | List list = new ArrayList<>(); 71 | while (matcher.find()) { 72 | list.add(matcher.group()); 73 | } 74 | return list; 75 | } 76 | 77 | /** 78 | * According to the regular search to meet the requirements 79 | * 80 | * @param reg regular expression 81 | * @param str The character to be found 82 | * @return find result 83 | */ 84 | public static String findString(String reg, String str) { 85 | if (StrUtil.isEmpty(reg)) { 86 | String exceptionMsg = String.format("regex expresssion can not empty or null: %s", reg); 87 | throw new DefinedException(exceptionMsg); 88 | } 89 | if (StrUtil.isEmpty(str)) { 90 | String exceptionMsg = String.format("search str can not empty or null: %s", str); 91 | throw new DefinedException(exceptionMsg); 92 | } 93 | String returnStr = null; 94 | List list = find(reg, str); 95 | if (list.size() != 0) { 96 | returnStr = list.get(0); 97 | } 98 | return returnStr; 99 | } 100 | 101 | /** 102 | * is url 103 | * @param s url 104 | * @return true if url,otherwise false 105 | */ 106 | public static boolean isUrl(String s) { 107 | Matcher matcher = Pattern.compile(Constant.URL_REGEX).matcher(s); 108 | return matcher.matches(); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /hrun4j-core/src/main/resources/locales/message_en_US.properties: -------------------------------------------------------------------------------- 1 | request.method=Request Method\uff1a%s 2 | request.url=Request Url\uff1a%s 3 | request.header=Request Header\uff1a%s 4 | request.cookie=Request Cookie\uff1a%s 5 | request.parameter=Request Parameter\uff1a%s 6 | request.json=Request Json\uff1a%s 7 | response.status.code=Response StatusCode\uff1a%s 8 | response.body=Response Body\uff1a%s 9 | response.time=Response Time\uff1a%s 10 | response.header=Response Header\uff1a%s 11 | response.cookie=Response Cookie\uff1a%s 12 | response.content.length=Response ContentLength\uff1a%s 13 | runner.current.step=Step\uff1a%s 14 | assert.check.point=Assert Check Point\uff1a 15 | assert.actual.value=,ActualValue\uff1a 16 | assert.expect.value=,ExpectValue\uff1a 17 | assert.check.result=,CheckResult\uff1a 18 | assert.check.result.pass=Pass 19 | assert.check.result.fail=Fail 20 | output.variables=Output Variables 21 | output.extract=Output Extracts 22 | file.download.process=File download process: 23 | file.upload.process=File upload progress: 24 | file.total.bytes=Total number of bytes: %s 25 | file.done.bytes=Number of bytes downloaded: %s 26 | file.done.rate=Sent Rate: %s 27 | file.is.done=Whether send is done: %s 28 | file.failure=Failed to download or upload the file, failure reason: %s 29 | file.success=File downloaded, store path: %s 30 | json.compare.success=On the %s node: expected value: %s, actual value: %s, verification result: passed 31 | json.compare.fail=[Failed] On the %s node: Expected value: %s, actual value: %s, verification result: failed -------------------------------------------------------------------------------- /hrun4j-core/src/main/resources/locales/message_zh_CN.properties: -------------------------------------------------------------------------------- 1 | request.method=\u8bf7\u6c42\u7c7b\u578b\uff1a%s 2 | request.url=\u8bf7\u6c42\u5730\u5740\uff1a%s 3 | request.header=\u8bf7\u6c42\u5934\uff1a%s 4 | request.cookie=\u8bf7\u6c42cookie\uff1a%s 5 | request.parameter=\u8bf7\u6c42\u53c2\u6570\uff1a%s 6 | request.json=\u8bf7\u6c42json\uff1a%s 7 | response.status.code=\u54cd\u5e94\u7801\uff1a%s 8 | response.body=\u54cd\u5e94\u4f53\uff1a%s 9 | response.time=\u54cd\u5e94\u65f6\u95f4\uff1a%s \u79d2 10 | response.header=\u54cd\u5e94\u5934\uff1a%s 11 | response.cookie=\u54cd\u5e94cookie\uff1a%s 12 | response.content.length=\u54cd\u5e94\u5185\u5bb9\u957f\u5ea6\uff1a%s 13 | runner.current.step=\u5f53\u524d\u6b65\u9aa4\uff1a%s 14 | assert.check.point=\u68c0\u67e5\u70b9\uff1a 15 | assert.actual.value=\uff0c\u5b9e\u9645\u503c\uff1a 16 | assert.expect.value=\uff0c\u9884\u671f\u503c\uff1a 17 | assert.check.result=\uff0c\u6d4b\u8bd5\u7ed3\u8bba\uff1a 18 | assert.check.result.pass=\u901a\u8fc7 19 | assert.check.result.fail=\u5931\u8d25 20 | output.variables=\u8f93\u51fa\u53d8\u91cf: 21 | output.extract=\u8f93\u51fa\u4e0a\u4e0b\u6587\u63d0\u53d6: 22 | file.download.process=\u6587\u4ef6\u4e0b\u8f7d\u8fdb\u5ea6\uff1a: 23 | file.upload.process=\u6587\u4ef6\u4e0a\u4f20\u8fdb\u5ea6 24 | file.total.bytes=\u603b\u5171\u7684\u5b57\u8282\u6570\uff1a%s 25 | file.done.bytes=\u5df2\u4e0b\u8f7d\u5b57\u8282\u6570\uff1a%s 26 | file.done.rate=\u5df2\u53d1\u9001\u7684\u6bd4\u4f8b\uff1a%s 27 | file.is.done=\u662f\u5426\u53d1\u9001\u5b8c\u6210\uff1a%s 28 | file.failure=\u6587\u4ef6\u4e0b\u8f7d\u6216\u4e0a\u4f20\u5931\u8d25\uff0c\u5931\u8d25\u539f\u56e0\uff1a%s 29 | file.success=\u6587\u4ef6\u4e0b\u8f7d\u5b8c\u6bd5\uff0c\u5b58\u50a8\u8def\u5f84\uff1a%s 30 | json.compare.success=\u5728\u0025\u0073\u0020\u8282\u70b9\uff1a\u9884\u671f\u503c\uff1a\u0025\u0073\uff0c\u5b9e\u9645\u503c\uff1a\u0025\u0073\uff0c\u9a8c\u8bc1\u7ed3\u679c\uff1a\u901a\u8fc7 31 | json.compare.fail=\u005b\u5931\u8d25\u005d\u5728\u0025\u0073\u0020\u8282\u70b9\uff1a\u9884\u671f\u503c\uff1a\u0025\u0073\uff0c\u5b9e\u9645\u503c\uff1a\u0025\u0073\uff0c\u9a8c\u8bc1\u7ed3\u679c\uff1a\u5931\u8d25 -------------------------------------------------------------------------------- /hrun4j-core/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | hrun4j 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | ${pattern} 14 | 15 | 16 | 17 | 18 | 19 | 20 | ${pattern.color} 21 | 22 | 23 | 24 | 25 | 26 | 27 | ${log.home}/${app.name}.%d.%i.log 28 | 29 | 10MB 30 | 31 | 30 32 | 33 | 34 | ${pattern} 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /hrun4j-core/src/main/resources/schemas/api.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "description": "hrun4j api schema definition", 4 | "type": "object", 5 | "properties": { 6 | "name": { 7 | "$ref": "resource:/schemas/common.json#/definitions/name" 8 | }, 9 | "base_url": { 10 | "$ref": "resource:/schemas/common.json#/definitions/base_url" 11 | }, 12 | "variables": { 13 | "$ref": "resource:/schemas/common.json#/definitions/variables" 14 | }, 15 | "request": { 16 | "$ref": "resource:/schemas/common.json#/definitions/request" 17 | }, 18 | "setup_hooks": { 19 | "$ref": "resource:/schemas/common.json#/definitions/hook" 20 | }, 21 | "teardown_hooks": { 22 | "$ref": "resource:/schemas/common.json#/definitions/hook" 23 | }, 24 | "extract": { 25 | "$ref": "resource:/schemas/common.json#/definitions/extract" 26 | }, 27 | "validate": { 28 | "$ref": "resource:/schemas/common.json#/definitions/validate" 29 | } 30 | }, 31 | "required": [ 32 | "name", 33 | "request" 34 | ], 35 | "examples": [ 36 | { 37 | "name": "demo api", 38 | "variables": { 39 | "var1": "value1", 40 | "var2": "value2" 41 | }, 42 | "request": { 43 | "url": "/api/path/$var1", 44 | "method": "POST", 45 | "headers": { 46 | "Content-Type": "application/json" 47 | }, 48 | "json": { 49 | "key": "$var2" 50 | }, 51 | "validate": [ 52 | { 53 | "eq": [ 54 | "status_code", 55 | 200 56 | ] 57 | } 58 | ] 59 | } 60 | } 61 | ] 62 | } -------------------------------------------------------------------------------- /hrun4j-core/src/main/resources/schemas/testsuite.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "description": "hrun4j testsuite schema v2 definition", 4 | "type": "object", 5 | "definitions": { 6 | "testcase": { 7 | "type": "object", 8 | "properties": { 9 | "name": { 10 | "$ref": "resource:/schemas/common.json#/definitions/name" 11 | }, 12 | "variables": { 13 | "$ref": "resource:/schemas/common.json#/definitions/variables" 14 | }, 15 | "parameters": { 16 | "description": "generate cartesian product variables with parameters, each group of variables will be run once", 17 | "type": "object" 18 | }, 19 | "testcase": { 20 | "description": "testcase reference, value is testcase file relative path", 21 | "type": "string" 22 | } 23 | }, 24 | "required": [ 25 | "testcase" 26 | ] 27 | } 28 | }, 29 | "properties": { 30 | "config": { 31 | "$ref": "resource:/schemas/common.json#/definitions/config" 32 | }, 33 | "testcases": { 34 | "description": "testcase of a testsuite", 35 | "type": "array", 36 | "minItems": 1, 37 | "items": { 38 | "$ref": "resource:/schemas/testsuite.json#/definitions/testcase" 39 | } 40 | } 41 | }, 42 | "required": [ 43 | "config", 44 | "testcases" 45 | ], 46 | "examples": [ 47 | { 48 | "config": { 49 | "name": "testsuite name" 50 | }, 51 | "testcases": [ 52 | { 53 | "name": "testcase 1", 54 | "testcase": "/path/to/testcase1" 55 | }, 56 | { 57 | "name": "testcase 2", 58 | "testcase": "/path/to/testcase2" 59 | } 60 | ] 61 | }, 62 | { 63 | "config": { 64 | "name": "demo testsuite", 65 | "variables": { 66 | "device_sn": "XYZ" 67 | }, 68 | "base_url": "http://127.0.0.1:5000" 69 | }, 70 | "testcases": [ 71 | { 72 | "name": "call demo_testcase with data 1", 73 | "testcase": "path/to/demo_testcase.yml", 74 | "variables": { 75 | "device_sn": "${device_sn}" 76 | } 77 | }, 78 | { 79 | "name": "call demo_testcase with data 2", 80 | "testcase": "path/to/demo_testcase.yml", 81 | "variables": { 82 | "device_sn": "${device_sn}" 83 | } 84 | } 85 | ] 86 | } 87 | ] 88 | } 89 | -------------------------------------------------------------------------------- /hrun4j-core/src/main/resources/vm/ngtemplate/testClass.vm: -------------------------------------------------------------------------------- 1 | package $pkgName; 2 | 3 | import vip.lematech.hrun4j.core.engine.TestCaseExecutorEngine; 4 | import vip.lematech.hrun4j.entity.testcase.TestCase; 5 | import vip.lematech.hrun4j.base.TestBase; 6 | import org.testng.annotations.Test; 7 | 8 | public class $className extends TestBase { 9 | #foreach($methodName in $methodList) 10 | @Test(dataProvider = "dataProvider") 11 | public void $methodName(TestCase testCase){ 12 | TestCaseExecutorEngine.getInstance().execute(testCase); 13 | } 14 | #end 15 | } 16 | 17 | -------------------------------------------------------------------------------- /hrun4j-test-demo/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 4.0.0 6 | 7 | hrun4j 8 | vip.lematech 9 | 1.0.2 10 | 11 | vip.lematech 12 | hrun4j-test-demo 13 | 1.0.2 14 | hrun4j-test-demo 15 | 16 | 17 | UTF-8 18 | 1.8 19 | 1.8 20 | true 21 | 22 | 23 | 24 | 25 | vip.lematech 26 | hrun4j-core 27 | 1.0.2 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | org.jacoco 36 | jacoco-maven-plugin 37 | 0.8.7 38 | 39 | target/coverage-reports/jacoco.exec 40 | target/coverage-reports/jacoco.exec 41 | 42 | 43 | 44 | jacoco-initialize 45 | 46 | prepare-agent 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /hrun4j-test-demo/src/main/java/vip/lematech/hrun4j/Hrun4j.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j; 2 | 3 | 4 | import com.googlecode.aviator.AviatorEvaluator; 5 | import org.testng.annotations.BeforeSuite; 6 | import vip.lematech.hrun4j.common.Constant; 7 | import vip.lematech.hrun4j.config.RunnerConfig; 8 | import vip.lematech.hrun4j.functions.MyFunction; 9 | import vip.lematech.hrun4j.helper.LogHelper; 10 | import vip.lematech.hrun4j.base.TestBase; 11 | 12 | /** 13 | * Extension function 14 | * 15 | * @author lematech@foxmail.com 16 | * @version 1.0.1 17 | */ 18 | public class Hrun4j extends TestBase { 19 | 20 | @Override 21 | @BeforeSuite 22 | public void beforeSuite() { 23 | LogHelper.info(" Add function to static code block !"); 24 | AviatorEvaluator.addFunction(new MyFunction.SetupHookFunction()); 25 | AviatorEvaluator.addFunction(new MyFunction.TearDownHookFunction()); 26 | AviatorEvaluator.addFunction(new MyFunction.SignGenerateFunction()); 27 | AviatorEvaluator.addFunction(new MyFunction.DefinedFunctionAdd()); 28 | AviatorEvaluator.addFunction(new MyFunction.DefinedFunctionDivide()); 29 | AviatorEvaluator.addFunction(new MyFunction.DefinedFunctionMultiply()); 30 | AviatorEvaluator.addFunction(new MyFunction.DefinedFunctionDivide()); 31 | AviatorEvaluator.addFunction(new MyFunction.DefinedFunctionSubtract()); 32 | AviatorEvaluator.addFunction(new MyFunction.RequestAndResponseHook()); 33 | AviatorEvaluator.addFunction(new MyFunction.DefinedHookFunction()); 34 | 35 | /** 36 | * 包名,资源路径下查找测试用例前置,默认:vip.lematech.hrun4j 37 | */ 38 | RunnerConfig.getInstance().setPkgName("vip.lematech.hrun4j"); 39 | /** 40 | * Test case file suffix 41 | */ 42 | RunnerConfig.getInstance().setI18n(Constant.I18N_US); 43 | RunnerConfig.getInstance().setTestCaseExtName(Constant.SUPPORT_TEST_CASE_FILE_EXT_YML_NAME); 44 | } 45 | } 46 | 47 | -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/java/vip/lematech/hrun4j/testcases/demojson/DemoJsonTest.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.testcases.demojson; 2 | 3 | import vip.lematech.hrun4j.Hrun4j; 4 | import vip.lematech.hrun4j.core.engine.TestCaseExecutorEngine; 5 | import vip.lematech.hrun4j.entity.testcase.TestCase; 6 | import vip.lematech.hrun4j.common.Constant; 7 | import vip.lematech.hrun4j.config.RunnerConfig; 8 | import org.testng.annotations.BeforeClass; 9 | import org.testng.annotations.Test; 10 | 11 | /** 12 | * @author lematech@foxmail.com 13 | * @version 1.0.1 14 | */ 15 | public class DemoJsonTest extends Hrun4j { 16 | @BeforeClass 17 | public void configRunner() { 18 | RunnerConfig.getInstance().setTestCaseExtName(Constant.SUPPORT_TEST_CASE_FILE_EXT_JSON_NAME); 19 | } 20 | 21 | /** 22 | * 测试变量优先级 23 | * 24 | * @param testCase 25 | */ 26 | @Test(dataProvider = "dataProvider") 27 | public void testApiReferenceDemo(TestCase testCase) { 28 | TestCaseExecutorEngine.getInstance().execute(testCase); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/java/vip/lematech/hrun4j/testcases/postman/get/GetTest.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.testcases.postman.get; 2 | 3 | import org.testng.annotations.Test; 4 | import vip.lematech.hrun4j.Hrun4j; 5 | import vip.lematech.hrun4j.core.engine.TestCaseExecutorEngine; 6 | import vip.lematech.hrun4j.entity.testcase.TestCase; 7 | 8 | 9 | /** 10 | * @author lematech@foxmail.com 11 | * @version 1.0.1 12 | */ 13 | public class GetTest extends Hrun4j { 14 | @Test(dataProvider = "dataProvider") 15 | public void getScene(TestCase testCase) { 16 | TestCaseExecutorEngine.getInstance().execute(testCase); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/java/vip/lematech/hrun4j/testcases/postman/post/PostTest.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.testcases.postman.post; 2 | 3 | import org.testng.annotations.Test; 4 | import vip.lematech.hrun4j.Hrun4j; 5 | import vip.lematech.hrun4j.core.engine.TestCaseExecutorEngine; 6 | import vip.lematech.hrun4j.entity.testcase.TestCase; 7 | 8 | 9 | /** 10 | * @author lematech@foxmail.com 11 | * @version 1.0.1 12 | */ 13 | public class PostTest extends Hrun4j { 14 | @Test(dataProvider = "dataProvider") 15 | public void postScene(TestCase testCase) { 16 | TestCaseExecutorEngine.getInstance().execute(testCase); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/java/vip/lematech/hrun4j/testcases/scene/SceneTest.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.testcases.scene; 2 | 3 | import vip.lematech.hrun4j.Hrun4j; 4 | import vip.lematech.hrun4j.core.engine.TestCaseExecutorEngine; 5 | import vip.lematech.hrun4j.entity.testcase.TestCase; 6 | import org.testng.annotations.Test; 7 | 8 | /** 9 | * @author lematech@foxmail.com 10 | * @version 1.0.1 11 | */ 12 | public class SceneTest extends Hrun4j { 13 | 14 | /** 15 | * 重置系统 16 | * 17 | * @param testCase 18 | */ 19 | @Test(dataProvider = "dataProvider") 20 | public void loginAndResetAll(TestCase testCase) { 21 | TestCaseExecutorEngine.getInstance().execute(testCase); 22 | } 23 | 24 | /** 25 | * 登录并添加用户信息 26 | * 27 | * @param testCase 28 | */ 29 | @Test(dataProvider = "dataProvider") 30 | public void loginAndAddUser(TestCase testCase) { 31 | TestCaseExecutorEngine.getInstance().execute(testCase); 32 | } 33 | 34 | /** 35 | * 查询新增用户信息 36 | * 37 | * @param testCase 38 | */ 39 | @Test(dataProvider = "dataProvider") 40 | public void queryAssignUserInfo(TestCase testCase) { 41 | TestCaseExecutorEngine.getInstance().execute(testCase); 42 | } 43 | 44 | /** 45 | * 删除新增用户 46 | * 47 | * @param testCase 48 | */ 49 | @Test(dataProvider = "dataProvider") 50 | public void delAssignUserInfo(TestCase testCase) { 51 | TestCaseExecutorEngine.getInstance().execute(testCase); 52 | } 53 | 54 | 55 | /** 56 | * 登录并添更新用户信息 57 | * 58 | * @param testCase 59 | */ 60 | @Test(dataProvider = "dataProvider") 61 | public void loginAndUpdateUser(TestCase testCase) { 62 | TestCaseExecutorEngine.getInstance().execute(testCase); 63 | } 64 | 65 | /** 66 | * 上用户头像 67 | * 68 | * @param testCase 69 | */ 70 | @Test(dataProvider = "dataProvider") 71 | public void loginAndUploadUser(TestCase testCase) { 72 | TestCaseExecutorEngine.getInstance().execute(testCase); 73 | } 74 | 75 | 76 | } 77 | -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/.env: -------------------------------------------------------------------------------- 1 | local=http://127.0.0.1:8000 2 | dev=http://10.9.16.179 3 | prod=http://10.9.16.223 4 | -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/Hrun4j.bsh: -------------------------------------------------------------------------------- 1 | #!/bin/java bsh.Interpreter 2 | print("Hrun4j.bsh文件所在路径即为项目工程路径"); 3 | print("你好,欢迎使用Hrun4j!"); 4 | print("官网:http://www.lematech.vip"); 5 | print("微信公众号:lematech"); 6 | print("技术交流微信:wytest"); -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/apis/getSimpleToken.yml: -------------------------------------------------------------------------------- 1 | name: 获取Token信息 2 | base_url: http://127.0.0.1:8000 3 | request: 4 | url: /api/get-token 5 | method: POST 6 | headers: 7 | device_sn: ${device_sn} 8 | os_platform: ${os_platform} 9 | app_version: ${app_version} 10 | json: 11 | sign: ${signGenerate(device_sn,os_platform,app_version)} 12 | validate: 13 | - equalTo: [status_code,200] 14 | - equalTo: [body.code,"00"] 15 | extract: 16 | token: body.data.token -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/apis/getToken.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ApiModel之获取Token信息", 3 | "base_url": "http://127.0.0.1:8000", 4 | "setup_hooks": [ 5 | "${hook(config_setup_hooks1)}", 6 | "${hook(config_setup_hooks2)}" 7 | ], 8 | "teardown_hooks": [ 9 | "${hook(config_teardown_hooks1)}", 10 | "${hook(config_teardown_hooks2)}" 11 | ], 12 | "variables": [ 13 | { 14 | "configVariable1": "configVariableValue1" 15 | }, 16 | { 17 | "configVariable2": "configVariableValue2" 18 | } 19 | ], 20 | "request": { 21 | "url": "/api/get-token", 22 | "method": "POST", 23 | "headers": { 24 | "device_sn": 2021032311113, 25 | "os_platform": "MacOS", 26 | "app_version": "1.0.1" 27 | }, 28 | "params": { 29 | "a": "apiA", 30 | "b": "apiB" 31 | }, 32 | "connectTimeout": 15, 33 | "writeTimeout": 15, 34 | "readTimeout": 15, 35 | "allowRedirects": false, 36 | "cookies": { 37 | "k1": "apiK1", 38 | "k2": "apiK2" 39 | }, 40 | "auth": [ 41 | { 42 | "auth1": "auth1" 43 | }, 44 | { 45 | "auth2": "auth2" 46 | } 47 | ], 48 | "stream": true, 49 | "json": { 50 | "sign": "594231b6dcf1c0d7970d2d77a5dfe6777518acdb" 51 | } 52 | }, 53 | "validate": [ 54 | { 55 | "equalTo": [ 56 | "status_code", 57 | 200 58 | ] 59 | }, 60 | { 61 | "equalTo": [ 62 | "body.code", 63 | "00" 64 | ] 65 | }, 66 | { 67 | "equalTo": [ 68 | "body.message", 69 | "ok!" 70 | ] 71 | } 72 | ] 73 | } -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/apis/getToken.yml: -------------------------------------------------------------------------------- 1 | name: ApiModel之获取Token信息 2 | base_url: http://127.0.0.1:8000 3 | setup_hooks: 4 | - "${hook(config_setup_hooks1)}" 5 | - "${hook(config_setup_hooks2)}" 6 | teardown_hooks: 7 | - "${hook(config_teardown_hooks1)}" 8 | - "${hook(config_teardown_hooks2)}" 9 | variables: 10 | configVariable1: configVariableValue1 11 | configVariable2: configVariableValue2 12 | device_sn: 2021032311118 13 | os_platform: MacOS 14 | app_version: 1.0.1 15 | test_step_variable_exp: "${2+2}" 16 | request: 17 | url: /api/get-token 18 | method: POST 19 | headers: 20 | device_sn: ${device_sn} 21 | os_platform: ${os_platform} 22 | app_version: ${app_version} 23 | params: 24 | a: apiA 25 | b: apiB 26 | connectionTimeout: 15 27 | writeTimeout: 15 28 | readTimeout: 15 29 | allowRedirects: false 30 | cookies: 31 | k1: apiK1 32 | k2: apiK2 33 | auth: 34 | - auth1: auth1 35 | - auth2: auth2 36 | verify: true 37 | stream: true 38 | json: 39 | sign: ${signGenerate(device_sn,os_platform,app_version)} 40 | validate: 41 | - equalTo: [status_code,200] 42 | - equalTo: [body.code,"00"] 43 | - equalTo: [body.message,"ok!"] 44 | -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/apis/postman/get.yml: -------------------------------------------------------------------------------- 1 | name: Postman Echo GET Request 2 | base_url: https://postman-echo.com_api 3 | variables: 4 | website: http://lematech.vip_api 5 | project: hrun4j_api 6 | author: lematech_api 7 | request: 8 | url: /get?website=${website}&project=${project}&author=${author} 9 | method: GET -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/apis/postman/postFormData.yml: -------------------------------------------------------------------------------- 1 | name: Postman Echo POST Raw Text Request 2 | base_url: http://lematech.vip_api 3 | variables: 4 | website: http://lematech.vip_api 5 | project: hrun4j_api 6 | author: lematech_api 7 | request: 8 | url: /post 9 | method: POST 10 | headers: 11 | data: 12 | website: ${website} 13 | project: ${project} 14 | author: ${author} -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/apis/postman/postRawText.yml: -------------------------------------------------------------------------------- 1 | name: Postman Echo POST Raw Text Request 2 | base_url: https://postman-echo.com 3 | variables: 4 | data: "This is expected to be sent back as part of response body._api" 5 | request: 6 | url: /post 7 | method: POST 8 | data: ${data} -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/apis/user/addUser.yml: -------------------------------------------------------------------------------- 1 | name: 添加用户信息接口定义 2 | base_url: http://127.0.0.1:8000 3 | request: 4 | url: /api/user/${uid} 5 | method: POST 6 | headers: 7 | device_sn: ${device_sn} 8 | token: ${token} 9 | json: 10 | name: lematech 11 | password: qweqwe123 12 | setup_hooks: 13 | ${hook(addUser_api_define_setup_hooks)} 14 | teardown_hooks: 15 | ${hook(addUser_api_define_teardown_hooks)} -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/apis/user/delUser.yml: -------------------------------------------------------------------------------- 1 | name: 查询用户信息接口定义 2 | base_url: http://127.0.0.1:8000 3 | request: 4 | url: /api/user/${uid} 5 | method: DELETE 6 | headers: 7 | device_sn: ${device_sn} 8 | token: ${token} 9 | validate: 10 | - equalTo: [status_code,200] 11 | - equalTo: [body.code,"00"] -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/apis/user/queryUser.yml: -------------------------------------------------------------------------------- 1 | name: 查询用户信息接口定义 2 | base_url: http://127.0.0.1:8000 3 | request: 4 | url: /api/user/${uid} 5 | method: GET 6 | headers: 7 | device_sn: ${device_sn} 8 | token: ${token} 9 | validate: 10 | - equalTo: [status_code,200] 11 | - equalTo: [body.code,"00"] -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/apis/user/resetAll.yml: -------------------------------------------------------------------------------- 1 | name: 查询用户信息接口定义 2 | base_url: http://127.0.0.1:8000 3 | request: 4 | url: /api/users/reset-all 5 | method: GET 6 | headers: 7 | device_sn: ${device_sn} 8 | token: ${token} 9 | validate: 10 | - equalTo: [status_code,200] 11 | - equalTo: [body.code,"00"] -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/apis/user/updateUser.yml: -------------------------------------------------------------------------------- 1 | name: 添加用户信息接口定义 2 | base_url: http://127.0.0.1:8000 3 | request: 4 | url: /api/user/${uid} 5 | method: PUT 6 | headers: 7 | device_sn: ${device_sn} 8 | token: ${token} 9 | json: 10 | name: lematechxxx 11 | password: qweqwe123 -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/apis/user/uploadUser.yml: -------------------------------------------------------------------------------- 1 | name: 添加用户信息接口定义 2 | base_url: http://127.0.0.1:8000 3 | request: 4 | url: /api/users/upload-image 5 | method: POST 6 | headers: 7 | device_sn: ${device_sn} 8 | token: ${token} 9 | files: 10 | file1: uploadFile1.txt 11 | file2: uploadFile2.txt 12 | setup_hooks: 13 | ${hook(addUser_api_define_setup_hooks)} 14 | teardown_hooks: 15 | ${hook(addUser_api_define_teardown_hooks)} -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/bsh/test.bsh: -------------------------------------------------------------------------------- 1 | #!/bin/java bsh.Interpreter 2 | 3 | 1>2; 4 | foo = "Foo"; 5 | four = (2 + 2)*2/2; 6 | print( foo + " = " + four ); 7 | for (i=0; i<5; i++) 8 | print(i); 9 | int multiply(a, b) 10 | { 11 | return a*b; 12 | } 13 | result = multiply(12,14); 14 | print(result);//打印出168 15 | 16 | //import RequestEntity; 17 | //print($aaa); 18 | 19 | print("请求参数:"+$REQUEST); 20 | print("响应参数:"+$RESPONSE); 21 | print("上下文参数:"+$ENV); 22 | -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/data/AssociatedCsvFile.csv: -------------------------------------------------------------------------------- 1 | varA,varB 2 | 1,11 3 | 2,22 4 | 3,33 5 | 4,44 6 | 5,55 -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/data/csvFile.csv: -------------------------------------------------------------------------------- 1 | parameterName 2 | 1 3 | 2 4 | 3 5 | 4 6 | 5 -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/data/uploadFile1.txt: -------------------------------------------------------------------------------- 1 | 上传文件内容测试1 -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/data/uploadFile2.txt: -------------------------------------------------------------------------------- 1 | 上传文件内容测试2 -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/testcases/demo/testApiReferenceDemo.yml: -------------------------------------------------------------------------------- 1 | config: 2 | name: 复杂操作案例之获取Token信息 3 | base_url: http://127.0.0.1:8000 4 | variables: 5 | variable_exp: "${1+2}" 6 | teststeps: 7 | - name: 步骤名称 8 | setup_hooks: 9 | - "${1+2}" 10 | - "${hook(xteststep_setup_hooks2)}" 11 | - "${hook(xteststep_setup_hooks3)}" 12 | - "${hook(xteststep_setup_hooks4)}" 13 | - total1: '${add(1, 5)}' 14 | - total2: '${add(3, 5)}' 15 | api: apis/getToken 16 | variables: 17 | device_sn: 2021032311118 18 | os_platform: MacOS 19 | app_version: 1.0.1 20 | test_step_variable_exp: "${2+2}" 21 | request: 22 | url: /api/get-token 23 | method: POST 24 | headers: 25 | device_sn: ${device_sn} 26 | os_platform: ${os_platform} 27 | app_version: ${app_version} 28 | params: 29 | a: ${variable_exp} 30 | b: B 31 | cookies: 32 | k1: K1 33 | k2: K2 34 | allowRedirects: true 35 | auth: 36 | auth1: xxauth1 37 | auth2: xxauth2 38 | stream: true 39 | json: 40 | sign: ${signGenerate(device_sn,os_platform,app_version)} 41 | validate: 42 | - "check": "headers.Content-Type" 43 | "comparator": "equalTo" 44 | "expect": "application/json;charset=UTF-8" 45 | - eq: [a, "a"] 46 | - eq: [1.1, 1.1] 47 | - "check": "status_code" 48 | "comparator": "equalTo" 49 | "expect": 200 50 | - "check": "body.message" 51 | "comparator": "equalTo" 52 | "expect": "ok!" 53 | teardown_hooks: 54 | - "${hook(test_step_variable_exp)}" 55 | - "${hook(test_step_variable_exp)}" 56 | - "${hook(test_step_variable_exp)}" 57 | - "${hook(test_step_variable_exp)}" 58 | - total1: '${add(1, 5)}' 59 | - total2: '${add(3, 5)}' 60 | output: [variables] -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/testcases/demo/testAviatorExpDemo.yml: -------------------------------------------------------------------------------- 1 | config: 2 | name: 简易操作案例之获取Token信息 3 | base_url: ${ENV(local)} 4 | teststeps: 5 | - name: 步骤名称 6 | setup_hooks: 7 | - total1: "${1+2+3}" 8 | - total2: "${string.length('hello')}" 9 | - total3: "string.contains(/\"test/\",string.substring('hello',1,2))" 10 | - total4: "${string.substring('hello',1,2)}" 11 | variables: 12 | device_sn: 2021032311118 13 | os_platform: MacOS 14 | app_version: 1.0.1 15 | request: 16 | url: /api/get-token 17 | method: POST 18 | headers: 19 | device_sn: ${device_sn} 20 | os_platform: ${os_platform} 21 | app_version: ${app_version} 22 | total1: ${total1} 23 | total2: ${total2} 24 | total3: ${total3} 25 | total4: ${total4} 26 | json: 27 | sign: ${signGenerate(device_sn,os_platform,app_version)} 28 | validate: 29 | - equalTo: [status_code,200] 30 | - equalTo: [body.code,"00"] 31 | - equalTo: [body.message,"ok!"] 32 | teardown_hooks: 33 | - "${hook(xteststep_teardown_hooks1)}" 34 | - "${hook(xteststep_teardown_hooks2)}" 35 | - "${hook(xteststep_teardown_hooks3)}" 36 | - "${hook(xteststep_teardown_hooks4)}" 37 | - total1: '${add(1, 5)}' 38 | - total2: '${add(3, 5)}' -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/testcases/demo/testBeanShellDemo.yml: -------------------------------------------------------------------------------- 1 | config: 2 | name: 简易操作案例之获取Token信息 3 | base_url: http://127.0.0.1:8000 4 | teststeps: 5 | - name: 步骤名称 6 | teardown_hooks: 7 | - result: "${BSH('bsh/test.bsh')}" 8 | variables: 9 | device_sn: 2021032311118 10 | os_platform: MacOS 11 | app_version: 1.0.1 12 | request: 13 | url: /api/get-token 14 | method: POST 15 | headers: 16 | device_sn: ${device_sn} 17 | os_platform: ${os_platform} 18 | app_version: ${app_version} 19 | bsh_result: ${result} 20 | test: "${helloWorld()}" 21 | json: 22 | sign: ${signGenerate(device_sn,os_platform,app_version)} 23 | validate: 24 | - eq: 25 | - status_code 26 | - 200 27 | - equalTo: [body.code,"00"] 28 | - equalTo: [body.message,"ok!"] 29 | -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/testcases/demo/testComplexSingleDemo.yml: -------------------------------------------------------------------------------- 1 | config: 2 | name: 复杂操作案例之获取Token信息 3 | base_url: http://127.0.0.1:8000 4 | teststeps: 5 | - name: 步骤名称 6 | setup_hooks: 7 | - "${hook(teststep_setup_hooks1)}" 8 | - "${hook(teststep_setup_hooks2)}" 9 | - "${hook(teststep_setup_hooks3)}" 10 | - "${hook(teststep_setup_hooks4)}" 11 | - total1: '${add(1, 5)}' 12 | - total2: '${add(3, 5)}' 13 | variables: 14 | device_sn: 2021032311118 15 | os_platform: MacOS 16 | app_version: 1.0.1 17 | request: 18 | url: /api/get-token 19 | method: POST 20 | headers: 21 | device_sn: ${device_sn} 22 | os_platform: ${os_platform} 23 | app_version: ${app_version} 24 | total1: ${total1} 25 | total2: ${total2} 26 | json: 27 | sign: ${signGenerate(device_sn,os_platform,app_version)} 28 | validate: 29 | - equalTo: [status_code, 200] 30 | - "check": "status_code" 31 | "comparator": "equalTo" 32 | "expect": 200 33 | - "check": "body.code" 34 | "comparator": "equalTo" 35 | "expect": "00" 36 | - "check": "body.message" 37 | "comparator": "equalTo" 38 | "expect": "ok!" 39 | teardown_hooks: 40 | - "${hook(teststep_teardown_hooks1)}" 41 | - "${hook(teststep_teardown_hooks2)}" 42 | - "${hook(teststep_teardown_hooks3)}" 43 | - "${hook(teststep_teardown_hooks4)}" 44 | - total1: '${add(1, 5)}' 45 | - total2: '${add(3, 5)}' -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/testcases/demo/testCurrentStepRequestAndResponseDataDemo.yml: -------------------------------------------------------------------------------- 1 | config: 2 | name: 测试指定步骤下的request和response信息输出 3 | base_url: http://127.0.0.1:8000 4 | teststeps: 5 | - name: 步骤名称 6 | api: apis/getToken 7 | validate: 8 | - equalTo: [status_code, 200] 9 | - "check": "status_code" 10 | "comparator": "equalTo" 11 | "expect": 200 12 | - "check": "body.code" 13 | "comparator": "equalTo" 14 | "expect": "00" 15 | - "check": "body.message" 16 | "comparator": "equalTo" 17 | "expect": "ok!" 18 | teardown_hooks: 19 | - "${RRHook(xteststep_teardown_hooks1)}" -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/testcases/demo/testDataAssociatedProviderDemo.yml: -------------------------------------------------------------------------------- 1 | config: 2 | name: 测试变量优先级 3 | base_url: http://127.0.0.1:8000 4 | variables: # config variables 5 | varA: "configA" 6 | varB: "configB" 7 | varC: "configC" 8 | parameters: # parameter variables 9 | varB-varA: "${P(data/AssociatedCsvFile.csv)}" 10 | teststeps: 11 | - name: step 1 12 | variables: # step variables 13 | varA: "step1A" 14 | device_sn: 2021032311118 15 | os_platform: MacOS 16 | app_version: 1.0.1 17 | request: 18 | url: /api/get-token 19 | method: POST 20 | headers: 21 | device_sn: ${device_sn} 22 | os_platform: ${os_platform} 23 | app_version: ${app_version} 24 | variablePriority: /${varA}/${varB}/${varC} # varA="step1A", varB="paramB1", varC="configC" 25 | json: 26 | sign: ${signGenerate(device_sn,os_platform,app_version)} 27 | extract: # extracted variables 28 | varA: body.code # suppose varA="extractVarA" 29 | varB: body.message # suppose varB="extractVarB" 30 | validate: 31 | - equalTo: [status_code,200] 32 | - equalTo: [body.code,"00"] 33 | - equalTo: [body.message,"ok!"] 34 | output: 35 | - variables 36 | - extract 37 | - name: step 2 38 | variables: # step variables 39 | varA: "step2A" 40 | device_sn: 2021032311118 41 | os_platform: MacOS 42 | app_version: 1.0.1 43 | request: 44 | url: /api/get-token 45 | method: POST 46 | headers: 47 | device_sn: ${device_sn} 48 | os_platform: ${os_platform} 49 | app_version: ${app_version} 50 | variablePriority: /${varA}/${varB}/${varC} # varA="step2A", varB="extractVarB", varC="configC" 51 | json: 52 | sign: ${signGenerate(device_sn,os_platform,app_version)} 53 | validate: 54 | - equalTo: [status_code,200] 55 | - equalTo: [body.code,"00"] 56 | - equalTo: [body.message,"ok!"] 57 | extract: # extracted variables 58 | varA: body.code # suppose varA="extractVarA" 59 | varB: body.message # suppose varB="extractVarB" -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/testcases/demo/testDataProviderFromCsvDemo.yml: -------------------------------------------------------------------------------- 1 | config: 2 | name: 测试变量优先级 3 | base_url: http://127.0.0.1:8000 4 | variables: # config variables 5 | varA: "configA" 6 | varB: "configB" 7 | varC: "configC" 8 | parameters: # parameter variables 9 | varA: "${P(data/csvFile.csv)}" 10 | varB: "${P(data/csvFile.csv)}" 11 | teststeps: 12 | - name: step 1 13 | variables: # step variables 14 | varA: "step1A" 15 | device_sn: 2021032311118 16 | os_platform: MacOS 17 | app_version: 1.0.1 18 | request: 19 | url: /api/get-token 20 | method: POST 21 | headers: 22 | device_sn: ${device_sn} 23 | os_platform: ${os_platform} 24 | app_version: ${app_version} 25 | variablePriority: /${varA}/${varB}/${varC} # varA="step1A", varB="paramB1", varC="configC" 26 | json: 27 | sign: ${signGenerate(device_sn,os_platform,app_version)} 28 | extract: # extracted variables 29 | varA: body.code # suppose varA="extractVarA" 30 | varB: body.message # suppose varB="extractVarB" 31 | validate: 32 | - equalTo: [status_code,200] 33 | - equalTo: [body.code,"00"] 34 | - equalTo: [body.message,"ok!"] 35 | output: 36 | - variables 37 | - extract 38 | - name: step 2 39 | variables: # step variables 40 | varA: "step2A" 41 | device_sn: 2021032311118 42 | os_platform: MacOS 43 | app_version: 1.0.1 44 | request: 45 | url: /api/get-token 46 | method: POST 47 | headers: 48 | device_sn: ${device_sn} 49 | os_platform: ${os_platform} 50 | app_version: ${app_version} 51 | variablePriority: /${varA}/${varB}/${varC} # varA="step2A", varB="extractVarB", varC="configC" 52 | json: 53 | sign: ${signGenerate(device_sn,os_platform,app_version)} 54 | validate: 55 | - equalTo: [status_code,200] 56 | - equalTo: [body.code,"00"] 57 | - equalTo: [body.message,"ok!"] 58 | extract: # extracted variables 59 | varA: body.code # suppose varA="extractVarA" 60 | varB: body.message # suppose varB="extractVarB" -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/testcases/demo/testDefineRequestConfigDemo.yml: -------------------------------------------------------------------------------- 1 | config: 2 | name: 复杂操作案例之获取Token信息 3 | base_url: http://127.0.0.1:8000 4 | teststeps: 5 | - name: 步骤名称 6 | setup_hooks: 7 | - "${hook(xteststep_setup_hooks1)}" 8 | - "${hook(xteststep_setup_hooks2)}" 9 | - "${hook(xteststep_setup_hooks3)}" 10 | - "${hook(xteststep_setup_hooks4)}" 11 | - total1: '${add(1, 5)}' 12 | - total2: '${add(3, 5)}' 13 | api: apis/getToken 14 | variables: 15 | device_sn: 2021032311118 16 | os_platform: MacOS 17 | app_version: 1.0.1 18 | request: 19 | url: /api/get-token 20 | method: POST 21 | headers: 22 | device_sn: ${device_sn} 23 | os_platform: ${os_platform} 24 | app_version: ${app_version} 25 | params: 26 | a: A 27 | b: B 28 | cookies: 29 | k1: K1 30 | k2: K2 31 | connectionTimeout: 15 32 | writeTimeout: 15 33 | readTimeout: 15 34 | allowRedirects: true 35 | auth: 36 | auth1: xxauth1 37 | auth2: xxauth2 38 | verify: false 39 | stream: true 40 | json: 41 | sign: ${signGenerate(device_sn,os_platform,app_version)} 42 | validate: 43 | - equalTo: [status_code, 200] 44 | - "check": "status_code" 45 | "comparator": "equalTo" 46 | "expect": 200 47 | - "check": "body.code" 48 | "comparator": "equalTo" 49 | "expect": "00" 50 | - "check": "body.message" 51 | "comparator": "equalTo" 52 | "expect": "ok!" 53 | teardown_hooks: 54 | - "${hook(xteststep_teardown_hooks1)}" 55 | - "${hook(xteststep_teardown_hooks2)}" 56 | - "${hook(xteststep_teardown_hooks3)}" 57 | - "${hook(xteststep_teardown_hooks4)}" 58 | - total1: '${add(1, 5)}' 59 | - total2: '${add(3, 5)}' 60 | output: [variables] -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/testcases/demo/testFileDownloadDemo.yml: -------------------------------------------------------------------------------- 1 | config: 2 | name: 测试文件下载 3 | base_url: https://cdn.lematech.vip 4 | teststeps: 5 | - name: 测试文件下载 6 | request: 7 | url: /gongzhonghao.jpg 8 | method: GET 9 | stream: false 10 | validate: 11 | - eq: 12 | - status_code 13 | - 200 14 | 15 | -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/testcases/demo/testJsonValidateTest.yml: -------------------------------------------------------------------------------- 1 | config: 2 | name: 简易操作案例之获取Token信息 3 | base_url: http://127.0.0.1:8000 4 | teststeps: 5 | - name: 步骤名称 6 | variables: 7 | device_sn: 2021032311118 8 | os_platform: MacOS 9 | app_version: 1.0.1 10 | request: 11 | url: /api/get-token 12 | method: POST 13 | headers: 14 | device_sn: ${device_sn} 15 | os_platform: ${os_platform} 16 | app_version: ${app_version} 17 | json: 18 | sign: ${signGenerate(device_sn,os_platform,app_version)} 19 | validate: 20 | - eq: 21 | - status_code 22 | - 200 23 | - jsonValidate: [{ 24 | "k": "a", 25 | "v": "b" 26 | },{ 27 | "k": "a", 28 | "v": "b" 29 | }] -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/testcases/demo/testMoreComplexSingleDemo.yml: -------------------------------------------------------------------------------- 1 | config: 2 | name: 复杂操作案例之获取Token信息 3 | base_url: http://127.0.0.1:8000 4 | setup_hooks: 5 | - "${hook(config_setup_hooks1)}" 6 | - "${hook(config_setup_hooks2)}" 7 | teardown_hooks: 8 | - "${hook(config_teardown_hooks1)}" 9 | - "${hook(config_teardown_hooks2)}" 10 | variables: 11 | - configVariable1: configVariableValue1 12 | - configVariable2: configVariableValue2 13 | teststeps: 14 | - name: 步骤名称 15 | variables: 16 | device_sn: 2021032311118 17 | os_platform: MacOS 18 | app_version: 1.0.1 19 | request: 20 | url: /api/get-token 21 | method: POST 22 | headers: 23 | device_sn: ${device_sn} 24 | os_platform: ${os_platform} 25 | app_version: ${app_version} 26 | total1: ${total1} 27 | total2: ${total2} 28 | configVariable1: ${configVariable1} 29 | json: 30 | sign: ${signGenerate(device_sn,os_platform,app_version)} 31 | validate: 32 | - equalTo: [status_code, 200] 33 | - "check": "status_code" 34 | "comparator": "equalTo" 35 | "expect": 200 36 | - "check": "body.code" 37 | "comparator": "equalTo" 38 | "expect": "00" 39 | - "check": "body.message" 40 | "comparator": "equalTo" 41 | "expect": "ok!" 42 | teardown_hooks: 43 | - "${hook(teststep_teardown_hooks1)}" 44 | - "${hook(teststep_teardown_hooks2)}" 45 | - "${hook(teststep_teardown_hooks3)}" 46 | - "${hook(teststep_teardown_hooks4)}" 47 | - total1: '${add(1, 5)}' 48 | - total2: '${add(3, 5)}' -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/testcases/demo/testMultipleGetDataDemo.yml: -------------------------------------------------------------------------------- 1 | config: 2 | name: 复杂操作案例之获取Token信息 3 | base_url: http://127.0.0.1:8000 4 | variables: 5 | expectCode: "00" 6 | teststeps: 7 | - name: 步骤名称 8 | variables: 9 | device_sn: 2021032311118 10 | os_platform: MacOS 11 | app_version: 1.0.1 12 | request: 13 | url: /api/get-token 14 | method: POST 15 | headers: 16 | device_sn: ${device_sn} 17 | os_platform: ${os_platform} 18 | app_version: ${app_version} 19 | json: 20 | sign: ${signGenerate(device_sn,os_platform,app_version)} 21 | validate: 22 | - equalTo: [status_code, 200] 23 | - equalTo: [body.message, "ok!"] 24 | - equalTo: [body.code, "00"] 25 | - equalTo: ["${expectCode}", "00"] 26 | - equalTo: [$.body.code, "00"] 27 | - equalTo: [$.body.code, "00"] 28 | - equalTo: ["^message\":\"(.*?)\"$", "message\":\"ok!\""] 29 | - equalTo: [$.headers.Content-Type, "application/json;charset=UTF-8"] -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/testcases/demo/testReferenceEnvDemo.yml: -------------------------------------------------------------------------------- 1 | config: 2 | name: 简易操作案例之获取Token信息 3 | base_url: ${ENV(local)} 4 | teststeps: 5 | - name: 步骤名称 6 | variables: 7 | device_sn: 2021032311118 8 | os_platform: MacOS 9 | app_version: 1.0.1 10 | request: 11 | url: /api/get-token 12 | method: POST 13 | headers: 14 | device_sn: ${device_sn} 15 | os_platform: ${os_platform} 16 | app_version: ${app_version} 17 | json: 18 | sign: ${signGenerate(device_sn,os_platform,app_version)} 19 | validate: 20 | - equalTo: [status_code,200] 21 | - equalTo: [body.code,"00"] 22 | - equalTo: [body.message,"ok!"] 23 | -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/testcases/demo/testSimpleSingleDemo.yml: -------------------------------------------------------------------------------- 1 | config: 2 | name: 简易操作案例之获取Token信息 3 | base_url: http://127.0.0.1:8000 4 | teststeps: 5 | - name: 步骤名称 6 | variables: 7 | device_sn: 2021032311118 8 | os_platform: MacOS 9 | app_version: 1.0.1 10 | request: 11 | url: /api/get-token 12 | method: POST 13 | headers: 14 | device_sn: ${device_sn} 15 | os_platform: ${os_platform} 16 | app_version: ${app_version} 17 | json: 18 | sign: ${signGenerate(device_sn,os_platform,app_version)} 19 | validate: 20 | - eq: 21 | - status_code 22 | - 200 23 | - equalTo: [body.code,"00"] 24 | - equalTo: [body.message,"ok!"] 25 | -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/testcases/demo/testTestCaseReferenceDemo.yml: -------------------------------------------------------------------------------- 1 | config: 2 | name: 引用测试用例 3 | base_url: http://127.0.0.1:8000 4 | teststeps: 5 | - name: 获取Token 6 | api: apis/getToken 7 | validate: 8 | - equalTo: [status_code, 200] 9 | - equalTo: [body.code, "00"] 10 | - name: 引用测试用例 11 | testcase: testcases/demojson/testApiReferenceDemo.json -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/testcases/demo/testVariablePriorityDemo.yml: -------------------------------------------------------------------------------- 1 | config: 2 | name: 测试变量优先级 3 | base_url: http://127.0.0.1:8000 4 | variables: # config variables 5 | varA: "configA" 6 | varB: "configB" 7 | varC: "configC" 8 | parameters: # parameter variables 9 | varA: ["paramA1","paramA2","paramA3","paramA4"] 10 | varB: ["paramB1"] 11 | teststeps: 12 | - name: step 1 13 | variables: # step variables 14 | device_sn: 2021032311118 15 | os_platform: MacOS 16 | app_version: 1.0.1 17 | request: 18 | url: /api/get-token 19 | method: POST 20 | headers: 21 | device_sn: ${device_sn} 22 | os_platform: ${os_platform} 23 | app_version: ${app_version} 24 | variablePriority: /${varA}/${varB}/${varC} # varA="step1A", varB="paramB1", varC="configC" 25 | json: 26 | sign: ${signGenerate(device_sn,os_platform,app_version)} 27 | extract: # extracted variables 28 | varA: body.code # suppose varA="extractVarA" 29 | varB: body.message # suppose varB="extractVarB" 30 | validate: 31 | - equalTo: [status_code,200] 32 | - equalTo: [body.code,"00"] 33 | - equalTo: [body.message,"ok!"] 34 | output: 35 | - variables 36 | - extract 37 | - name: step 2 38 | variables: # step variables 39 | varA: "step2A" 40 | device_sn: 2021032311118 41 | os_platform: MacOS 42 | app_version: 1.0.1 43 | request: 44 | url: /api/get-token 45 | method: POST 46 | headers: 47 | device_sn: ${device_sn} 48 | os_platform: ${os_platform} 49 | app_version: ${app_version} 50 | variablePriority: /${varA}/${varB}/${varC} # varA="step2A", varB="extractVarB", varC="configC" 51 | json: 52 | sign: ${signGenerate(device_sn,os_platform,app_version)} 53 | validate: 54 | - equalTo: [status_code,200] 55 | - equalTo: [body.code,"00"] 56 | - equalTo: [body.message,"ok!"] 57 | extract: # extracted variables 58 | varA: body.code # suppose varA="extractVarA" 59 | varB: body.message # suppose varB="extractVarB" -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/testcases/demo/测试接口定义应用中文.yml: -------------------------------------------------------------------------------- 1 | config: 2 | name: 复杂操作案例之获取Token信息 3 | base_url: http://127.0.0.1:8000 4 | teststeps: 5 | - name: 步骤名称 6 | setup_hooks: 7 | - "${hook(xteststep_setup_hooks1)}" 8 | - "${hook(xteststep_setup_hooks2)}" 9 | - "${hook(xteststep_setup_hooks3)}" 10 | - "${hook(xteststep_setup_hooks4)}" 11 | - total1: '${add(1, 5)}' 12 | - total2: '${add(3, 5)}' 13 | api: apis/getToken 14 | request: 15 | url: /api/get-token 16 | method: POST 17 | headers: 18 | device_sn: ${device_sn} 19 | os_platform: ${os_platform} 20 | app_version: ${app_version} 21 | params: 22 | a: A 23 | b: B 24 | cookies: 25 | k1: K1 26 | k2: K2 27 | allowRedirects: true 28 | auth: 29 | auth1: xxauth1 30 | auth2: xxauth2 31 | verify: false 32 | stream: true 33 | json: 34 | sign: ${signGenerate(device_sn,os_platform,app_version)} 35 | validate: 36 | - equalTo: [status_code, 200] 37 | - "check": "status_code" 38 | "comparator": "equalTo" 39 | "expect": 200 40 | - "check": "body.code" 41 | "comparator": "equalTo" 42 | "expect": "00" 43 | - "check": "body.message" 44 | "comparator": "equalTo" 45 | "expect": "ok!" 46 | teardown_hooks: 47 | - "${hook(xteststep_teardown_hooks1)}" 48 | - "${hook(xteststep_teardown_hooks2)}" 49 | - "${hook(xteststep_teardown_hooks3)}" 50 | - "${hook(xteststep_teardown_hooks4)}" 51 | - total1: '${add(1, 5)}' 52 | - total2: '${add(3, 5)}' 53 | output: [variables] -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/testcases/demojson/testApiReferenceDemo.json: -------------------------------------------------------------------------------- 1 | { 2 | "config": { 3 | "name": "复杂操作案例之获取Token信息", 4 | "base_url": "http://127.0.0.1:8000", 5 | "variables": { 6 | "variable_exp": "${1+2}" 7 | } 8 | }, 9 | "teststeps": [ 10 | { 11 | "name": "步骤名称", 12 | "setup_hooks": [ 13 | "${1+2}", 14 | "${hook(xteststep_setup_hooks2)}", 15 | "${hook(xteststep_setup_hooks3)}", 16 | "${hook(xteststep_setup_hooks4)}", 17 | { 18 | "total1": "${add(1, 5)}" 19 | }, 20 | { 21 | "total2": "${add(3, 5)}" 22 | } 23 | ], 24 | "api": "apis/getToken", 25 | "variables": { 26 | "device_sn": 2021032311118, 27 | "os_platform": "MacOS", 28 | "app_version": "1.0.1", 29 | "test_step_variable_exp": "${2+2}" 30 | }, 31 | "request": { 32 | "url": "/api/get-token", 33 | "method": "POST", 34 | "headers": { 35 | "device_sn": "${device_sn}", 36 | "os_platform": "${os_platform}", 37 | "app_version": "${app_version}" 38 | }, 39 | "params": { 40 | "a": "${variable_exp}", 41 | "b": "B" 42 | }, 43 | "cookies": { 44 | "k1": "K1", 45 | "k2": "K2" 46 | }, 47 | "allowRedirects": true, 48 | "auth": { 49 | "auth1": "xxauth1", 50 | "auth2": "xxauth2" 51 | }, 52 | "stream": true, 53 | "json": { 54 | "sign": "${signGenerate(device_sn,os_platform,app_version)}" 55 | } 56 | }, 57 | "validate": [ 58 | { 59 | "check": "headers.Content-Type", 60 | "comparator": "equalTo", 61 | "expect": "application/json;charset=UTF-8" 62 | }, 63 | { 64 | "eq": [ 65 | "a", 66 | "a" 67 | ] 68 | }, 69 | { 70 | "eq": [ 71 | 1.1, 72 | 1.1 73 | ] 74 | }, 75 | { 76 | "check": "status_code", 77 | "comparator": "equalTo", 78 | "expect": 200 79 | }, 80 | { 81 | "check": "body.message", 82 | "comparator": "equalTo", 83 | "expect": "ok!" 84 | } 85 | ], 86 | "teardown_hooks": [ 87 | "${hook(test_step_variable_exp)}", 88 | "${hook(test_step_variable_exp)}", 89 | "${hook(test_step_variable_exp)}", 90 | "${hook(test_step_variable_exp)}", 91 | { 92 | "total1": "${add(1, 5)}" 93 | }, 94 | { 95 | "total2": "${add(3, 5)}" 96 | } 97 | ], 98 | "output": [ 99 | "variables" 100 | ] 101 | } 102 | ] 103 | } -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/testcases/postman/get/getScene.yml: -------------------------------------------------------------------------------- 1 | config: 2 | name: Postman Echo GET Request 3 | base_url: https://postman-echo.com 4 | variables: 5 | website: http://lematech.vip 6 | project: hrun4j 7 | author: lematechvipVar 8 | teststeps: 9 | - name: Postman Echo GET Request And Reference Api 10 | variables: 11 | author: lematech 12 | setup_hooks: 13 | - ${BSH('Hrun4j.bsh')} 14 | request: 15 | url: /get?website=${website}&project=${project}&author=${author}&page={page} 16 | method: GET 17 | validate: 18 | - equalTo: [status_code,200] 19 | - equalTo: [headers.Content-Type,application/json; charset=utf-8] 20 | - equalTo: [body.args.website,http://lematech.vip] 21 | - equalTo: ["${author}", lematech] 22 | - equalTo: [$.body.args.website,http://lematech.vip] 23 | - equalTo: ["^website\":\"(.*?)\"$", website":"http://lematech.vip"] 24 | - name: Reference Api 25 | api: apis/postman/get.yml 26 | variables: 27 | author: lematechvip 28 | validate: 29 | - equalTo: [status_code,200] -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/testcases/postman/post/postScene.yml: -------------------------------------------------------------------------------- 1 | config: 2 | name: Postman Echo postFormData And postRawText Request 3 | base_url: https://postman-echo.com 4 | teststeps: 5 | - name: Reference postFormData Api 6 | api: apis/postman/postFormData.yml 7 | variables: 8 | website: http://lematech.vip 9 | project: hrun4j 10 | author: lematech 11 | validate: 12 | - equalTo: [status_code,200] 13 | - name: Reference postRawText Api 14 | api: apis/postman/postRawText.yml 15 | variables: 16 | data: "This is expected to be sent back as part of response body." 17 | validate: 18 | - equalTo: [status_code,200] -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/testcases/scene/delAssignUserInfo.yml: -------------------------------------------------------------------------------- 1 | config: 2 | name: 登入系统并添加用户信息 3 | base_url: http://127.0.0.1:8000 4 | variables: 5 | device_sn: 2021032311113 6 | os_platform: MacOS 7 | app_version: 1.0.1 8 | parameters: 9 | uid: [1,2,3,4,5] 10 | teststeps: 11 | - name: 登录并添加用户信息 12 | testcase: scene/loginAndAddUser 13 | - name: 删除用户信息 14 | api: apis/user/delUser 15 | -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/testcases/scene/loginAndAddUser.yml: -------------------------------------------------------------------------------- 1 | config: 2 | name: 登入系统并添加用户信息 3 | base_url: http://127.0.0.1:8000 4 | variables: 5 | device_sn: 2021032311113 6 | os_platform: MacOS 7 | app_version: 1.0.1 8 | parameters: 9 | uid: [1,2,3,4,5] 10 | teststeps: 11 | - name: 登录系统 12 | api: apis/getSimpleToken 13 | validate: 14 | - equalTo: [status_code,200] 15 | - name: 添加用户 16 | api: apis/user/addUser 17 | validate: 18 | - equalTo: [status_code,200] 19 | - equalTo: [body.code,"00"] 20 | - equalTo: [body.message,"用户创建成功!"] 21 | -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/testcases/scene/loginAndResetAll.yml: -------------------------------------------------------------------------------- 1 | config: 2 | name: 登入系统并添加用户信息 3 | base_url: http://127.0.0.1:8000 4 | variables: 5 | device_sn: 2021032311113 6 | os_platform: MacOS 7 | app_version: 1.0.1 8 | teststeps: 9 | - name: 登录系统 10 | api: apis/getSimpleToken 11 | validate: 12 | - equalTo: [status_code,200] 13 | - name: 添加用户 14 | api: apis/user/resetAll -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/testcases/scene/loginAndUpdateUser.yml: -------------------------------------------------------------------------------- 1 | config: 2 | name: 登入系统并添加用户信息 3 | base_url: http://127.0.0.1:8000 4 | variables: 5 | device_sn: 2021032311113 6 | os_platform: MacOS 7 | app_version: 1.0.1 8 | parameters: 9 | uid: [1] 10 | teststeps: 11 | - name: 登录系统 12 | api: apis/getSimpleToken 13 | validate: 14 | - equalTo: [status_code,200] 15 | - name: 更新用户信息 16 | api: apis/user/updateUser 17 | validate: 18 | - equalTo: [status_code,200] 19 | - equalTo: [body.code,"09"] 20 | - equalTo: [body.message,"用户:1 不存在"] 21 | -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/testcases/scene/loginAndUploadUser.yml: -------------------------------------------------------------------------------- 1 | config: 2 | name: 登入系统并添加用户信息 3 | base_url: http://127.0.0.1:8000 4 | variables: 5 | device_sn: 2021032311113 6 | os_platform: MacOS 7 | app_version: 1.0.1 8 | parameters: 9 | uid: [1,2,3,4,5] 10 | teststeps: 11 | - name: 登录系统 12 | api: apis/getSimpleToken 13 | validate: 14 | - equalTo: [status_code,200] 15 | - name: 添加用户 16 | api: apis/user/uploadUser 17 | validate: 18 | - equalTo: [status_code,200] 19 | - equalTo: [body.code,"00"] 20 | - equalTo: [body.message,"文件上传成功!"] 21 | -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/testcases/scene/queryAssignUserInfo.yml: -------------------------------------------------------------------------------- 1 | config: 2 | name: 登入系统并添加用户信息 3 | base_url: http://127.0.0.1:8000 4 | variables: 5 | device_sn: 2021032311113 6 | os_platform: MacOS 7 | app_version: 1.0.1 8 | parameters: 9 | uid: [1,2,3,4,5] 10 | teststeps: 11 | - name: 登录并添加用户信息 12 | testcase: scene/loginAndAddUser 13 | - name: 查询用户信息 14 | api: apis/user/queryUser 15 | -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/testng.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/testsuites/testng.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /hrun4j-test-demo/src/test/resources/testsuites/testng.yml: -------------------------------------------------------------------------------- 1 | config: 2 | name: 测试用例集配置 3 | base_url: https://api.apiopen.top 4 | testcases: 5 | - name: Postman Echo GET Request 6 | testcase: testcases/postman/get/getScene.yml 7 | parameters: 8 | page: [1,2,3,4,5] 9 | - name: Postman Echo postFormData And postRawText Request 10 | testcase: testcases/postman/post/postScene.yml -------------------------------------------------------------------------------- /hrun4j-test-server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | hrun4j 7 | vip.lematech 8 | 1.0.2 9 | 10 | 4.0.0 11 | hrun4j-test-server 12 | 13 | 1.2.5 14 | 8.0.18 15 | 1.2.72 16 | 1.1.17 17 | true 18 | 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-dependencies 25 | 2.1.6.RELEASE 26 | pom 27 | import 28 | 29 | 30 | 31 | 32 | 33 | io.springfox 34 | springfox-swagger2 35 | 2.4.0 36 | 37 | 38 | io.springfox 39 | springfox-swagger-ui 40 | 2.4.0 41 | 42 | 43 | org.springframework.boot 44 | spring-boot-starter-aop 45 | 46 | 47 | org.springframework.boot 48 | spring-boot-starter-web 49 | 50 | 51 | com.google.code.gson 52 | gson 53 | 54 | 55 | org.projectlombok 56 | lombok 57 | 1.18.12 58 | 59 | 60 | vip.lematech 61 | hrun4j-core 62 | 1.0.1 63 | compile 64 | 65 | 66 | 67 | hrun4j-test-demo 68 | 69 | 70 | org.springframework.boot 71 | spring-boot-maven-plugin 72 | 2.1.6.RELEASE 73 | 74 | true 75 | vip.lematech.hrun4j.DemoApplication 76 | 77 | 78 | 79 | 80 | repackage 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /hrun4j-test-server/src/main/java/vip/lematech/hrun4j/DemoApplication.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | /** 7 | * @author lematech@foxmail.com 8 | * @version 1.0.1 9 | * website https://www.lematech.vip/ 10 | */ 11 | @SpringBootApplication 12 | public class DemoApplication { 13 | public static void main(String[] args) { 14 | SpringApplication.run(DemoApplication.class, args); 15 | } 16 | } 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /hrun4j-test-server/src/main/java/vip/lematech/hrun4j/core/annotation/ValidateRequest.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.core.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @author lematech@foxmail.com 7 | * @version 1.0.1 8 | * website https://www.lematech.vip/ 9 | */ 10 | @Documented 11 | @Target({ElementType.METHOD, ElementType.TYPE}) 12 | @Retention(RetentionPolicy.RUNTIME) 13 | public @interface ValidateRequest { 14 | /** 15 | * Without default value means this argument is required 16 | * 17 | * @return Header names 18 | */ 19 | String[] headerNames(); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /hrun4j-test-server/src/main/java/vip/lematech/hrun4j/core/aop/RequestValidateAspect.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.core.aop; 2 | 3 | import cn.hutool.core.util.StrUtil; 4 | import vip.lematech.hrun4j.core.annotation.ValidateRequest; 5 | import vip.lematech.hrun4j.core.enums.CommonBusinessCode; 6 | import vip.lematech.hrun4j.core.exception.PlatformException; 7 | import vip.lematech.hrun4j.service.TokenService; 8 | import vip.lematech.hrun4j.core.helper.ApplicationContextHelper; 9 | import lombok.extern.slf4j.Slf4j; 10 | import org.aspectj.lang.annotation.Aspect; 11 | import org.aspectj.lang.annotation.Before; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.stereotype.Component; 14 | 15 | import javax.servlet.http.HttpServletRequest; 16 | import java.util.Objects; 17 | 18 | /** 19 | * @author lematech@foxmail.com 20 | * @version 1.0.1 21 | * website https://www.lematech.vip/ 22 | */ 23 | @Slf4j 24 | @Aspect 25 | @Component 26 | public class RequestValidateAspect { 27 | @Autowired 28 | private TokenService tokenServiceImpl; 29 | 30 | @Before("@within(validateRequest)") 31 | public void doBeforeForClass(ValidateRequest validateRequest) { 32 | doBefore(validateRequest); 33 | } 34 | 35 | @Before("@annotation(validateRequest)") 36 | public void doBefore(ValidateRequest validateRequest) { 37 | HttpServletRequest request = ApplicationContextHelper.getHttpServletRequest(); 38 | if (Objects.isNull(request)) { 39 | log.info("without request,skip"); 40 | return; 41 | } 42 | String[] headerNames = validateRequest.headerNames(); 43 | for (String headerName : headerNames) { 44 | String headerValue = request.getHeader(headerName); 45 | if (StrUtil.isNotBlank(headerValue)) { 46 | continue; 47 | } 48 | String exceptionMsg = String.format(" header %s is required", headerName); 49 | throw new PlatformException(exceptionMsg); 50 | } 51 | String deviceSN = request.getHeader("device_sn"); 52 | String actualToken = request.getHeader("token"); 53 | String expectToken = tokenServiceImpl.queryToken(deviceSN); 54 | if (!tokenServiceImpl.validateToken(actualToken, expectToken)) { 55 | throw new PlatformException(CommonBusinessCode.Authorization_FAILED_EXCEPTION); 56 | } 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /hrun4j-test-server/src/main/java/vip/lematech/hrun4j/core/aop/WebLogAspect.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.core.aop; 2 | 3 | import com.google.gson.Gson; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.aspectj.lang.JoinPoint; 6 | import org.aspectj.lang.ProceedingJoinPoint; 7 | import org.aspectj.lang.annotation.*; 8 | import org.springframework.stereotype.Component; 9 | import vip.lematech.hrun4j.core.helper.ApplicationContextHelper; 10 | 11 | import javax.servlet.http.HttpServletRequest; 12 | 13 | /** 14 | * @author lematech@foxmail.com 15 | * @version 1.0.1 16 | * website https://www.lematech.vip/ 17 | */ 18 | 19 | @Component 20 | @Aspect 21 | @Slf4j 22 | public class WebLogAspect { 23 | @Pointcut("execution(public * vip.lematech.hrun4j.controller.*.*(..))") 24 | public void webLog() { 25 | 26 | } 27 | 28 | /** 29 | * 在切入点之前 30 | * 31 | * @param joinPoint 切入点 32 | */ 33 | @Before("webLog()") 34 | public void deBefore(JoinPoint joinPoint) { 35 | HttpServletRequest request = ApplicationContextHelper.getHttpServletRequest(); 36 | log.info("========================================== 请求调用开始 =========================================="); 37 | log.info("请求地址: {}", request.getRequestURL().toString()); 38 | log.info("请求方法: {}", request.getMethod()); 39 | log.info("请求参数: {}", new Gson().toJson(joinPoint.getArgs())); 40 | log.info("请求处理器: {}#{}", joinPoint.getSignature().getDeclaringTypeName() 41 | , joinPoint.getSignature().getName()); 42 | log.info("请求方IP地址: {}", request.getRemoteAddr()); 43 | } 44 | 45 | @Around("webLog()") 46 | public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { 47 | long startTime = System.currentTimeMillis(); 48 | Object result = proceedingJoinPoint.proceed(); 49 | log.info("响应参数: {}", new Gson().toJson(result)); 50 | log.info("请求耗时: {} ms", System.currentTimeMillis() - startTime); 51 | log.info("=========================================== 请求调用结束 ==========================================="); 52 | return result; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /hrun4j-test-server/src/main/java/vip/lematech/hrun4j/core/config/SwaggerConfig.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.core.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import springfox.documentation.builders.ApiInfoBuilder; 6 | import springfox.documentation.builders.PathSelectors; 7 | import springfox.documentation.builders.RequestHandlerSelectors; 8 | import springfox.documentation.service.ApiInfo; 9 | import springfox.documentation.service.Contact; 10 | import springfox.documentation.spi.DocumentationType; 11 | import springfox.documentation.spring.web.plugins.Docket; 12 | import springfox.documentation.swagger2.annotations.EnableSwagger2; 13 | 14 | /** 15 | * @author lematech@foxmail.com 16 | * @version 1.0.1 17 | * website https://www.lematech.vip/ 18 | */ 19 | 20 | @Configuration 21 | @EnableSwagger2 22 | public class SwaggerConfig { 23 | 24 | @Bean 25 | public Docket createRestApi() { 26 | return new Docket(DocumentationType.SWAGGER_2) 27 | .apiInfo(apiInfo()) 28 | .select() 29 | .apis(RequestHandlerSelectors.basePackage("vip.lematech.hrun4j.controller")) 30 | .paths(PathSelectors.any()) 31 | .build(); 32 | } 33 | 34 | private ApiInfo apiInfo() { 35 | Contact contact = new Contact("lematech", "http://lematech.vip", "lematech@foxmail.com"); 36 | return new ApiInfoBuilder() 37 | .title("测试管理平台接口使用文档") 38 | .description("Restful接口信息") 39 | .version("1.0.1") 40 | .license("Apache 2.0") 41 | .licenseUrl("http://www.apache.org/licenses/LICENSE-2.0") 42 | .contact(contact) 43 | .build(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /hrun4j-test-server/src/main/java/vip/lematech/hrun4j/core/constant/CommonConstant.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.core.constant; 2 | 3 | /** 4 | * @author lematech@foxmail.com 5 | * @version 1.0.1 6 | * website https://www.lematech.vip/ 7 | * 8 | */ 9 | public class CommonConstant { 10 | public static final String TOKEN_KEY = "hrun4j"; 11 | public static final String PAGE_NUM = "1"; 12 | public static final String PAGE_SIZE = "10"; 13 | } 14 | -------------------------------------------------------------------------------- /hrun4j-test-server/src/main/java/vip/lematech/hrun4j/core/entity/User.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.core.entity; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author lematech@foxmail.com 7 | * @version 1.0.1 8 | * website https://www.lematech.vip/ 9 | */ 10 | @Data 11 | public class User { 12 | private Integer uid; 13 | private String name; 14 | private String password; 15 | } 16 | -------------------------------------------------------------------------------- /hrun4j-test-server/src/main/java/vip/lematech/hrun4j/core/entity/UserDto.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.core.entity; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author lematech@foxmail.com 7 | * @version 1.0.1 8 | * website https://www.lematech.vip/ 9 | */ 10 | @Data 11 | public class UserDto { 12 | private int index; 13 | private User user; 14 | } 15 | -------------------------------------------------------------------------------- /hrun4j-test-server/src/main/java/vip/lematech/hrun4j/core/enums/BusinessCode.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.core.enums; 2 | 3 | /** 4 | * @author lematech@foxmail.com 5 | * @version 1.0.1 6 | * website https://www.lematech.vip/ 7 | */ 8 | public interface BusinessCode { 9 | /** 10 | * 获取响应提示信息 11 | * 12 | * @return 提升信息 13 | */ 14 | String getMessage(); 15 | 16 | /** 17 | * 获取响应码 18 | * 19 | * @return 响应码 20 | */ 21 | String getCode(); 22 | } 23 | -------------------------------------------------------------------------------- /hrun4j-test-server/src/main/java/vip/lematech/hrun4j/core/enums/CommonBusinessCode.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.core.enums; 2 | 3 | /** 4 | * @author lematech@foxmail.com 5 | * @version 1.0.1 6 | * website https://www.lematech.vip/ 7 | */ 8 | public enum CommonBusinessCode implements BusinessCode { 9 | /** 10 | * 公共领域 11 | */ 12 | SUCCESS("00", "ok!"), 13 | Authorization_FAILED_EXCEPTION("403", "认证失败!"), 14 | USER_IS_NOT_EXISTS_EXCEPTION("404", "用户不存在!"), 15 | SYS_ERROR_EXCEPTION("09", "系统错误!"); 16 | /** 17 | * 响应码 18 | */ 19 | private String code; 20 | /** 21 | * 响应提示信息 22 | */ 23 | private String message; 24 | 25 | CommonBusinessCode(String code, String message) { 26 | this.code = code; 27 | this.message = message; 28 | } 29 | 30 | @Override 31 | public String getMessage() { 32 | 33 | return this.message; 34 | } 35 | 36 | @Override 37 | public String getCode() { 38 | return this.code; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /hrun4j-test-server/src/main/java/vip/lematech/hrun4j/core/exception/PlatformException.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.core.exception; 2 | 3 | 4 | import vip.lematech.hrun4j.core.enums.BusinessCode; 5 | 6 | /** 7 | * @author lematech@foxmail.com 8 | * @version 1.0.1 9 | * website https://www.lematech.vip/ 10 | */ 11 | public class PlatformException extends RuntimeException { 12 | public String getMsg() { 13 | return msg; 14 | } 15 | 16 | public void setMsg(String msg) { 17 | this.msg = msg; 18 | } 19 | 20 | private String code; 21 | private String msg; 22 | private BusinessCode businessCode; 23 | 24 | public PlatformException(BusinessCode businessCode) { 25 | super(businessCode.getMessage()); 26 | this.code = businessCode.getCode(); 27 | this.businessCode = businessCode; 28 | } 29 | 30 | public PlatformException(String message) { 31 | super(message); 32 | this.msg = message; 33 | } 34 | 35 | public PlatformException(Throwable cause) { 36 | super(cause.getMessage()); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /hrun4j-test-server/src/main/java/vip/lematech/hrun4j/core/handler/GlobalExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.core.handler; 2 | 3 | 4 | import vip.lematech.hrun4j.core.exception.PlatformException; 5 | import vip.lematech.hrun4j.vo.base.R; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.springframework.web.bind.annotation.ControllerAdvice; 8 | import org.springframework.web.bind.annotation.ExceptionHandler; 9 | import org.springframework.web.bind.annotation.ResponseBody; 10 | import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; 11 | 12 | /** 13 | * @author lematech@foxmail.com 14 | * @version 1.0.1 15 | * website https://www.lematech.vip/ 16 | */ 17 | @ControllerAdvice 18 | @ResponseBody 19 | @Slf4j 20 | public class GlobalExceptionHandler { 21 | 22 | @ExceptionHandler(value = PlatformException.class) 23 | public R bizExceptionHandler(PlatformException platformException) { 24 | log.error("响应异常码:{},响应异常信息:{}", platformException.getMessage(), platformException.getLocalizedMessage()); 25 | return R.fail(platformException.getMsg() == null ? platformException.getMessage() : platformException.getMsg()); 26 | } 27 | 28 | @ExceptionHandler(value = MethodArgumentTypeMismatchException.class) 29 | public R methodArgumentExceptionHandler(MethodArgumentTypeMismatchException exception) { 30 | String exceptionMsg = String.format("参数%s类型不匹配异常:%s", exception.getName(), exception.getMessage()); 31 | log.error(exceptionMsg); 32 | return R.fail(exceptionMsg); 33 | } 34 | 35 | @ExceptionHandler(value = Exception.class) 36 | public R exceptionHandler(Exception exception) { 37 | exception.printStackTrace(); 38 | log.error("未知异常:{}", exception.getMessage()); 39 | return R.fail(exception.getMessage()); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /hrun4j-test-server/src/main/java/vip/lematech/hrun4j/core/helper/ApplicationContextHelper.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.core.helper; 2 | 3 | import org.springframework.web.context.request.RequestContextHolder; 4 | import org.springframework.web.context.request.ServletRequestAttributes; 5 | 6 | import javax.servlet.http.HttpServletRequest; 7 | /** 8 | * @author lematech@foxmail.com 9 | * @version 1.0.1 10 | * website https://www.lematech.vip/ 11 | */ 12 | public class ApplicationContextHelper { 13 | public static HttpServletRequest getHttpServletRequest() { 14 | ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); 15 | if (servletRequestAttributes == null) { 16 | throw new RuntimeException("ServletRequestAttributes object is null"); 17 | } 18 | return servletRequestAttributes.getRequest(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /hrun4j-test-server/src/main/java/vip/lematech/hrun4j/service/TokenService.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.service; 2 | 3 | 4 | /** 5 | * @author lematech@foxmail.com 6 | * @version 1.0.1 7 | * website https://www.lematech.vip/ 8 | */ 9 | public interface TokenService { 10 | /** 11 | * 生成签名 12 | * 13 | * @param deviceSN deviceSN 14 | * @param osPlatform osPlatform 15 | * @param appVersion appVersion 16 | * @return token value 17 | */ 18 | String generateToken(String deviceSN, String osPlatform, String appVersion); 19 | 20 | /** 21 | * 验签 22 | * 23 | * @param actualToken actualToken 24 | * @param expectToken expectToken 25 | * @return 验证token通过或不通过 26 | */ 27 | boolean validateToken(String actualToken, String expectToken); 28 | 29 | /** 30 | * 建立token和devicesn映射关系并存储 31 | * 32 | * @param deviceSN deviceSN 33 | * @param token token 34 | */ 35 | void storyToken(String deviceSN, String token); 36 | 37 | /** 38 | * 根据devicesn提取token 39 | * 40 | * @param deviceSN deviceSN 41 | * @return token 42 | */ 43 | String queryToken(String deviceSN); 44 | 45 | } 46 | -------------------------------------------------------------------------------- /hrun4j-test-server/src/main/java/vip/lematech/hrun4j/service/UserService.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.service; 2 | 3 | import vip.lematech.hrun4j.core.entity.User; 4 | import vip.lematech.hrun4j.core.entity.UserDto; 5 | 6 | import java.util.List; 7 | 8 | 9 | /** 10 | * @author lematech@foxmail.com 11 | * @version 1.0.1 12 | * website https://www.lematech.vip/ 13 | */ 14 | public interface UserService { 15 | /** 16 | * 通过uid查询用户 17 | * 18 | * @param uid 用户id 19 | * @return 用户信息 20 | */ 21 | UserDto findUserIndexByUid(int uid); 22 | 23 | /** 24 | * 通过uid查询用户 25 | * 26 | * @param uid user id 27 | * @return 用户信息 28 | */ 29 | User findByUid(int uid); 30 | 31 | /** 32 | * 添加用户 33 | * 34 | * @param user user 35 | */ 36 | void addUser(User user); 37 | 38 | /** 39 | * 更新用户信息 40 | * 41 | * @param user user 42 | */ 43 | void updateUser(User user); 44 | 45 | /** 46 | * 删除用户 47 | * 48 | * @param uid user id 49 | * @return 删除标志 50 | */ 51 | boolean deleteUser(int uid); 52 | 53 | /** 54 | * 查询用户列表 55 | * 56 | * @return 用户信息列表 57 | */ 58 | List lists(); 59 | 60 | /** 61 | * 删库跑路 62 | */ 63 | void deleteUsers(); 64 | } 65 | -------------------------------------------------------------------------------- /hrun4j-test-server/src/main/java/vip/lematech/hrun4j/service/impl/TokenServiceImpl.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.service.impl; 2 | 3 | import cn.hutool.core.util.StrUtil; 4 | import cn.hutool.crypto.SecureUtil; 5 | import cn.hutool.crypto.digest.HmacAlgorithm; 6 | import com.google.common.collect.Maps; 7 | import vip.lematech.hrun4j.core.constant.CommonConstant; 8 | import vip.lematech.hrun4j.core.exception.PlatformException; 9 | import vip.lematech.hrun4j.service.TokenService; 10 | import lombok.extern.slf4j.Slf4j; 11 | import org.springframework.stereotype.Service; 12 | 13 | import java.util.Map; 14 | 15 | /** 16 | * @author lematech@foxmail.com 17 | * @version 1.0.1 18 | * website https://www.lematech.vip/ 19 | */ 20 | @Service("TokenServiceImpl") 21 | @Slf4j 22 | public class TokenServiceImpl implements TokenService { 23 | private static Map tokenMap = Maps.newHashMap(); 24 | 25 | @Override 26 | public String generateToken(String deviceSN, String osPlatform, String appVersion) { 27 | String sign; 28 | try { 29 | StringBuffer content = new StringBuffer(); 30 | content.append(deviceSN).append(osPlatform).append(appVersion); 31 | String crypContent = content.toString(); 32 | sign = SecureUtil.hmac(HmacAlgorithm.HmacSHA1, CommonConstant.TOKEN_KEY).digestHex(crypContent); 33 | log.info("加密秘钥:{},加密内容:{},生成的签名:{}", CommonConstant.TOKEN_KEY, crypContent, sign); 34 | } catch (Exception e) { 35 | String exceptionMsg = String.format("加签异常,异常信息:%s", e.getMessage()); 36 | throw new PlatformException(exceptionMsg); 37 | } 38 | return sign; 39 | } 40 | 41 | @Override 42 | public boolean validateToken(String actaulToken, String expectToken) { 43 | if (StrUtil.isEmpty(actaulToken)) { 44 | return false; 45 | } 46 | if (StrUtil.isEmpty(expectToken)) { 47 | return false; 48 | } 49 | return expectToken.equals(actaulToken); 50 | } 51 | 52 | @Override 53 | public void storyToken(String deviceSN, String token) { 54 | tokenMap.put(deviceSN, token); 55 | } 56 | 57 | @Override 58 | public String queryToken(String deviceSN) { 59 | return tokenMap.get(deviceSN); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /hrun4j-test-server/src/main/java/vip/lematech/hrun4j/service/impl/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.service.impl; 2 | 3 | 4 | import vip.lematech.hrun4j.core.entity.User; 5 | import vip.lematech.hrun4j.core.entity.UserDto; 6 | import vip.lematech.hrun4j.core.exception.PlatformException; 7 | import vip.lematech.hrun4j.service.UserService; 8 | import org.springframework.stereotype.Service; 9 | 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | import java.util.Objects; 13 | 14 | /** 15 | * @author lematech@foxmail.com 16 | * @version 1.0.1 17 | * website https://www.lematech.vip/ 18 | */ 19 | @Service 20 | public class UserServiceImpl implements UserService { 21 | private static List users = new ArrayList(); 22 | 23 | @Override 24 | public UserDto findUserIndexByUid(int uid) { 25 | for (int index = 0; index < users.size(); index++) { 26 | User user = users.get(index); 27 | if (user.getUid() == uid) { 28 | UserDto userDto = new UserDto(); 29 | userDto.setIndex(index); 30 | userDto.setUser(user); 31 | return userDto; 32 | } 33 | } 34 | return null; 35 | } 36 | 37 | @Override 38 | public User findByUid(int uid) { 39 | for (User user : users) { 40 | if (user.getUid() == uid) { 41 | return user; 42 | } 43 | } 44 | return null; 45 | } 46 | 47 | @Override 48 | public void addUser(User user) { 49 | int uid = user.getUid(); 50 | User queryUser = findByUid(uid); 51 | if (Objects.isNull(queryUser)) { 52 | users.add(user); 53 | return; 54 | } 55 | String exceptionMsg = String.format("用户:%s 已存在", uid); 56 | throw new PlatformException(exceptionMsg); 57 | } 58 | 59 | @Override 60 | public void updateUser(User user) { 61 | int uid = user.getUid(); 62 | UserDto queryUser = findUserIndexByUid(uid); 63 | if (Objects.isNull(queryUser)) { 64 | String exceptionMsg = String.format("用户:%s 不存在", uid); 65 | throw new PlatformException(exceptionMsg); 66 | } 67 | queryUser.getUser().setName(user.getName()); 68 | queryUser.getUser().setPassword(user.getPassword()); 69 | users.set(queryUser.getIndex(), queryUser.getUser()); 70 | } 71 | 72 | @Override 73 | public boolean deleteUser(int uid) { 74 | User user = this.findByUid(uid); 75 | return users.remove(user); 76 | } 77 | 78 | @Override 79 | public List lists() { 80 | return users; 81 | } 82 | 83 | @Override 84 | public void deleteUsers() { 85 | users.clear(); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /hrun4j-test-server/src/main/java/vip/lematech/hrun4j/vo/TokenVO.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.vo; 2 | 3 | import lombok.Data; 4 | 5 | 6 | /** 7 | * @author lematech@foxmail.com 8 | * @version 1.0.1 9 | * website https://www.lematech.vip/ 10 | */ 11 | @Data 12 | public class TokenVO { 13 | private String sign; 14 | } 15 | -------------------------------------------------------------------------------- /hrun4j-test-server/src/main/java/vip/lematech/hrun4j/vo/UserVO.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.vo; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author lematech@foxmail.com 7 | * @version 1.0.1 8 | * website https://www.lematech.vip/ 9 | */ 10 | @Data 11 | public class UserVO { 12 | private String name; 13 | private String password; 14 | } 15 | -------------------------------------------------------------------------------- /hrun4j-test-server/src/main/java/vip/lematech/hrun4j/vo/base/R.java: -------------------------------------------------------------------------------- 1 | package vip.lematech.hrun4j.vo.base; 2 | 3 | import lombok.*; 4 | import vip.lematech.hrun4j.core.enums.BusinessCode; 5 | import vip.lematech.hrun4j.core.enums.CommonBusinessCode; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * @author lematech 11 | */ 12 | @EqualsAndHashCode 13 | @Data 14 | @AllArgsConstructor 15 | @NoArgsConstructor 16 | @Builder 17 | public class R implements Serializable { 18 | /** 19 | * 错误码 20 | */ 21 | private String code; 22 | /** 23 | * 响应提示信息 24 | */ 25 | private String message; 26 | /** 27 | * 响应数据 28 | */ 29 | private T data; 30 | 31 | /** 32 | * 响应时间戳 33 | */ 34 | private Long timestamp = System.currentTimeMillis(); 35 | 36 | /** 37 | * 业务处理异常,自定义业务响应码及响应提示信息 38 | * 39 | * @param businessCode 业务码 40 | * @return 响应数 41 | */ 42 | public static R fail(BusinessCode businessCode) { 43 | return new R(businessCode); 44 | } 45 | 46 | /** 47 | * 业务处理异常,系统错误 48 | * 49 | * @return 响应数据 50 | */ 51 | public static R fail() { 52 | return new R(CommonBusinessCode.SYS_ERROR_EXCEPTION); 53 | } 54 | 55 | /** 56 | * 业务处理异常,按指定异常信息提示 57 | * 58 | * @param message 提升信息 59 | * @return 响应数据 60 | */ 61 | public static R fail(String message) { 62 | R restResponseResult = fail(); 63 | restResponseResult.setMessage(message); 64 | return restResponseResult; 65 | } 66 | 67 | /** 68 | * 响应成功,返回响应数据 69 | * 70 | * @param data 响应数据 71 | * @param 所属类型 72 | * @return 响应结果 73 | */ 74 | public static R ok(T data) { 75 | R restResponseResult = ok(); 76 | restResponseResult.setData(data); 77 | return restResponseResult; 78 | } 79 | 80 | /** 81 | * 自定义响应提示信息 82 | * @param message message 83 | * @return 响应数据 84 | */ 85 | public static R ok(String message) { 86 | R restResponseResult = ok(); 87 | restResponseResult.setMessage(message); 88 | return restResponseResult; 89 | } 90 | 91 | /** 92 | * 响应成功,不返回响应数据 93 | * 94 | * @return 响应数据 95 | */ 96 | public static R ok() { 97 | return new R(CommonBusinessCode.SUCCESS); 98 | } 99 | 100 | public R(BusinessCode businessCode) { 101 | this.code = businessCode.getCode(); 102 | this.message = businessCode.getMessage(); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /hrun4j-test-server/src/main/resources/application-dev.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8000 -------------------------------------------------------------------------------- /hrun4j-test-server/src/main/resources/application-local.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8000 -------------------------------------------------------------------------------- /hrun4j-test-server/src/main/resources/application-prod.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8000 -------------------------------------------------------------------------------- /hrun4j-test-server/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | profiles: 3 | active: prod -------------------------------------------------------------------------------- /hrun4j-test-server/src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | ${AnsiColor.BLUE} 2 | __ _ _ _ 3 | [ | | | | | (_) 4 | | |--. _ .--. __ _ _ .--. | |__| |_ __ 5 | | .-. | [ `/'`\][ | | | [ `.-. ||____ _| [ | 6 | | | | | | | | \_/ |, | | | | _| |_ _ | | 7 | [___]|__][___] '.__.'_/[___||__] |_____|[ \_| | 8 | \____/ 9 | 10 | 11 | _____ _ __ 12 | |_ _| / |_ [ | 13 | | | .---. _ .--..--. ,--. `| |-'.---. .---. | |--. 14 | | | _ / /__\\[ `.-. .-. | `'_\ : | | / /__\\/ /'`\] | .-. | 15 | _| |__/ || \__., | | | | | | // | |,| |,| \__.,| \__. | | | | 16 | |________| '.__.'[___||__||__]\'-;__/\__/ '.__.''.___.'[___]|__] 17 | 18 | --------------------------------------------------------------------------------