提交 fe91e65f authored 作者: 黄承天's avatar 黄承天

Initial commit

上级
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**
!**/src/test/**
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
### VS Code ###
.vscode/
/*
* Copyright 2007-present the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.net.*;
import java.io.*;
import java.nio.channels.*;
import java.util.Properties;
public class MavenWrapperDownloader {
private static final String WRAPPER_VERSION = "0.5.6";
/**
* Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
*/
private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
+ WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
/**
* Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
* use instead of the default one.
*/
private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
".mvn/wrapper/maven-wrapper.properties";
/**
* Path where the maven-wrapper.jar will be saved to.
*/
private static final String MAVEN_WRAPPER_JAR_PATH =
".mvn/wrapper/maven-wrapper.jar";
/**
* Name of the property which should be used to override the default download url for the wrapper.
*/
private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
public static void main(String args[]) {
System.out.println("- Downloader started");
File baseDirectory = new File(args[0]);
System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
// If the maven-wrapper.properties exists, read it and check if it contains a custom
// wrapperUrl parameter.
File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
String url = DEFAULT_DOWNLOAD_URL;
if(mavenWrapperPropertyFile.exists()) {
FileInputStream mavenWrapperPropertyFileInputStream = null;
try {
mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
Properties mavenWrapperProperties = new Properties();
mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
} catch (IOException e) {
System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
} finally {
try {
if(mavenWrapperPropertyFileInputStream != null) {
mavenWrapperPropertyFileInputStream.close();
}
} catch (IOException e) {
// Ignore ...
}
}
}
System.out.println("- Downloading from: " + url);
File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
if(!outputFile.getParentFile().exists()) {
if(!outputFile.getParentFile().mkdirs()) {
System.out.println(
"- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
}
}
System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
try {
downloadFileFromURL(url, outputFile);
System.out.println("Done");
System.exit(0);
} catch (Throwable e) {
System.out.println("- Error downloading");
e.printStackTrace();
System.exit(1);
}
}
private static void downloadFileFromURL(String urlString, File destination) throws Exception {
if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
String username = System.getenv("MVNW_USERNAME");
char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
Authenticator.setDefault(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
}
URL website = new URL(urlString);
ReadableByteChannel rbc;
rbc = Channels.newChannel(website.openStream());
FileOutputStream fos = new FileOutputStream(destination);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
fos.close();
rbc.close();
}
}
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
差异被折叠。
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at
@REM
@REM https://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Maven Start Up Batch script
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
@REM M2_HOME - location of maven2's installed home dir
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM ----------------------------------------------------------------------------
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM set title of command window
title %0
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
:skipRcPre
@setlocal
set ERROR_CODE=0
@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal
@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome
echo.
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init
echo.
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
@REM ==== END VALIDATION ====
:init
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
IF EXIST "%WDIR%"\.mvn goto baseDirFound
cd ..
IF "%WDIR%"=="%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir
:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
cd "%EXEC_DIR%"
goto endDetectBaseDir
:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
cd "%EXEC_DIR%"
:endDetectBaseDir
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
:endReadAdditionalConfig
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
)
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
if exist %WRAPPER_JAR% (
if "%MVNW_VERBOSE%" == "true" (
echo Found %WRAPPER_JAR%
)
) else (
if not "%MVNW_REPOURL%" == "" (
SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
)
if "%MVNW_VERBOSE%" == "true" (
echo Couldn't find %WRAPPER_JAR%, downloading it ...
echo Downloading from: %DOWNLOAD_URL%
)
powershell -Command "&{"^
"$webclient = new-object System.Net.WebClient;"^
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
"}"^
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
"}"
if "%MVNW_VERBOSE%" == "true" (
echo Finished downloading %WRAPPER_JAR%
)
)
@REM End of extension
@REM Provide a "standardized" way to retrieve the CLI args that will
@REM work with both Windows and non-Windows executions.
set MAVEN_CMD_LINE_ARGS=%*
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
if ERRORLEVEL 1 goto error
goto end
:error
set ERROR_CODE=1
:end
@endlocal & set ERROR_CODE=%ERROR_CODE%
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
:skipRcPost
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%" == "on" pause
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
exit /B %ERROR_CODE%
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.BUILD-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.zjty</groupId>
<artifactId>automated-testing</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>automated-testing</name>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.5</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>21.0</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
<!--fastJson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.46</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.18</version>
</dependency>
<!--lombok 用于简化domain配置-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.20</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</pluginRepository>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>
package com.zjty.automatedtesting;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class AutomatedTestingApplication {
public static void main(String[] args) {
SpringApplication.run(AutomatedTestingApplication.class, args);
}
}
package com.zjty.automatedtesting.common.action;
/**
* <p>Description : measurement
* <p>Date : 2020/1/8 11:37
* <p>@author : C
*/
public interface Action {
String INPUT = "input";
String CLICK = "click";
String GET_TEXT = "gettext";
String READ_ONLY = "readonly";
String REGISTER = "register";
}
package com.zjty.automatedtesting.common.action;
public interface Assertion {
String VALUE = "value";
String TITLE = "tiele";
}
package com.zjty.automatedtesting.common.action;
/**
* <p>Description : measurement
* <p>Date : 2020/1/14 10:38
* <p>@author : C
*/
public interface Browser {
String FIREFOX = "firefox";
String CHROME = "chrome";
String IE = "ie";
}
package com.zjty.automatedtesting.common.action;
/**
* <p>Description : measurement
* <p>Date : 2020/1/13 16:41
* <p>@author : C
*/
public interface ByType {
String XPATH = "xpath";
String CSS = "css";
String ID = "id";
String NAME = "name";
}
package com.zjty.automatedtesting.common.action;
/**
* <p>Description : measurement
* <p>Date : 2020/1/13 9:56
* <p>@author : C
*/
public interface LabelType {
String A = "a";
String INPUT = "input";
String LINK = "link";
String SPAN = "span";
}
package com.zjty.automatedtesting.config;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* fusion-platform. swagger2 autoDocument interface for {@link Swagger2Config}
*
* @author : Matrix [xhyrzldf@gmail.com]
* 19-1-10 .
*/
@Target({TYPE, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Documented
public @interface AutoDocument {
String value() default "";
}
package com.zjty.automatedtesting.config;
import com.google.common.collect.Sets;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* fusion-platform.
*
* @author : Matrix [xhyrzldf@gmail.com]
* 19-1-10 .
*/
@Configuration
@EnableSwagger2
public class Swagger2Config {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.produces(Sets.newHashSet("application/json"))
.consumes(Sets.newHashSet("application/json"))
.protocols(Sets.newHashSet("http","https"))
.apiInfo(apiInfo())
.forCodeGeneration(true)
.useDefaultResponseMessages(true)
.select()
// 指定controller存放的目录路径
.apis(RequestHandlerSelectors.basePackage("com.zjty.automatedtesting"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
// 文档标题
.title("测评系统接口测试")
// 文档描述
.description("测评系统接口测试页面")
.version("v1")
.build();
}
}
package com.zjty.automatedtesting.controller;
import com.google.common.collect.ImmutableMap;
import com.zjty.automatedtesting.pojo.report.Report;
import com.zjty.automatedtesting.pojo.test.TestCaseVo;
import com.zjty.automatedtesting.service.SeleniumService;
import com.zjty.automatedtesting.service.TestCaseService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
/**
* @author C
*/
@SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection")
@RequestMapping("/testcase")
@RestController
@Api(value = "自动化测试管理接口")
public class TestCaseController {
@Autowired
SeleniumService seleniumService;
@Autowired
TestCaseService testCaseService;
@CrossOrigin
@ApiOperation(value = "提供测试用例数据.执行测试并返回测试结果报告.")
@PostMapping(value="/execute")
public ResponseEntity<Report> execute(@RequestBody TestCaseVo testCaseVo){
Report execute = seleniumService.execute(testCaseVo);
return ResponseEntity.ok(execute);
}
@CrossOrigin
@ApiOperation(value = "保存测试用例.",notes = "不附带id为新增 附带id为修改")
@PostMapping(value="/save")
public ResponseEntity<Map<String,String>> save(@RequestBody TestCaseVo testCaseVo){
testCaseService.save(testCaseVo);
return ResponseEntity.ok(ImmutableMap.of("message","success"));
}
@CrossOrigin
@ApiOperation(value = "删除测试用例.")
@DeleteMapping(value="/delete/{id}")
public ResponseEntity<Map<String,String>> findTestText(@PathVariable Integer id){
testCaseService.delete(id);
return ResponseEntity.ok(ImmutableMap.of("message","success"));
}
@CrossOrigin
@ApiOperation(value = "获取全部测试用例.")
@GetMapping(value="/get")
public ResponseEntity<List<TestCaseVo>> get(){
return ResponseEntity.ok(testCaseService.findAll());
}
@CrossOrigin
@ApiOperation(value = "获取单个测试用例.")
@GetMapping(value="/get/{id}")
public ResponseEntity<TestCaseVo> getById(@PathVariable Integer id){
return ResponseEntity.ok(testCaseService.findById(id));
}
}
package com.zjty.automatedtesting.pojo.report;
import com.alibaba.fastjson.annotation.JSONField;
import com.zjty.automatedtesting.config.AutoDocument;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* <p>Description : measurement
* <p>Date : 2020/1/16 13:39
* <p>@author : C
*/
@AutoDocument
@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(value = "测试步骤结果")
public class Measure {
/**
* 步骤序号
*/
@ApiModelProperty(value = "步骤序号",example = "1")
@JSONField(ordinal = 1)
private Integer order;
/**
* 步骤名
*/
@ApiModelProperty(value = "步骤名",example = "输入关键字")
@JSONField(ordinal = 2)
private String title;
/**
* 是否成功
*/
@ApiModelProperty(value = "是否成功",example = "true")
@JSONField(ordinal = 3)
private Boolean success;
/**
* 判断类型
*/
@ApiModelProperty(value = "判断类型",example = "value",notes = "目前有2种:value-当前元素的值 title-页面标题")
@JSONField(ordinal = 4)
private String assertion;
/**
* 期望结果
*/
@ApiModelProperty(value = "期望结果",example = "ty")
@JSONField(ordinal = 5)
private String expected;
/**
* 实际结果
*/
@ApiModelProperty(value = "实际结果",example = "ty")
@JSONField(ordinal = 6)
private String practice;
/**
* 信息
*/
@ApiModelProperty(value = "相关信息",example = "成功.")
@JSONField(ordinal = 7)
private String message;
}
package com.zjty.automatedtesting.pojo.report;
import com.zjty.automatedtesting.config.AutoDocument;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* <p>Description : selenium-test
* <p>Date : 2020/1/3 9:43
* <p>@author : C
*/
@AutoDocument
@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(value = "测试报告结果")
public class Report {
/**
* url
*/
@ApiModelProperty(value = "网站地址",example = "http://www.baidu.com")
private String url;
/**
* 浏览器
*/
@ApiModelProperty(value = "浏览器",example = "firefox")
private String explorer;
/**
* 每个步骤结果详情
*/
@ApiModelProperty(value = "每个步骤结果详情")
private List<Measure> measures;
}
package com.zjty.automatedtesting.pojo.test;
import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.zjty.automatedtesting.config.AutoDocument;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* <p>Description : selenium-test
* <p>Date : 2020/1/3 9:47
* <p>@author : C
*/
@AutoDocument
@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(value = "测试用例步骤")
public class Step {
/**
* 步骤序号
*/
@ApiModelProperty(value = "序号",example = "1")
@JSONField(ordinal = 1)
private Integer order;
/**
* 标题
*/
@ApiModelProperty(value = "步骤的标题",example = "输入关键字")
@JSONField(ordinal = 2)
private String title;
/**
* 元素的定位类型
*/
@ApiModelProperty(value = "元素的定位类型",example = "id")
@JSONField(ordinal = 3)
private String type;
/**
* 元素的定位关键值
*/
@ApiModelProperty(value = "元素的定位关键值",example = "kw")
@JSONField(ordinal = 4)
private String key;
/**
* 元素的操作方式
*/
@ApiModelProperty(value = "元素的操作方式",example = "input",notes = "目前有2种:input-输入 click-点击")
@JSONField(ordinal = 5)
private String action;
/**
* 输入值 操作为input时需要
*/
@ApiModelProperty(value = "输入值 操作为input时需要",example = "ty")
@JSONField(ordinal = 6)
private String value;
/**
* 判断类型
*/
@ApiModelProperty(value = "判断类型",example = "value",notes = "目前有2种:value-当前元素的值 title-页面标题")
@JSONField(ordinal = 7)
private String assertion;
/**
* 期望结果
*/
@ApiModelProperty(value = "期望结果",example = "ty")
@JSONField(ordinal = 8)
private String expected;
}
package com.zjty.automatedtesting.pojo.test;
import com.zjty.automatedtesting.config.AutoDocument;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
/**
* <p>Description : assess
* <p>Date : 2020/1/3 17:04
* <p>@author : C
*/
@AutoDocument
@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(value = "测试用例")
@Entity
public class TestCase {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Integer id;
/**
* 浏览器
*/
String browser;
/**
* 起始网站
*/
String url;
/**
* 步骤详情
*/
String steps;
}
package com.zjty.automatedtesting.pojo.test;
import com.zjty.automatedtesting.config.AutoDocument;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.util.List;
@AutoDocument
@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(value = "测试用例")
public class TestCaseVo {
@ApiModelProperty(value = "主键",example = "1")
Integer id;
/**
* 浏览器
*/
@ApiModelProperty(value = "浏览器",example = "firefox")
String browser;
/**
* 起始网站
*/
@ApiModelProperty(value = "网站地址",example = "http://www.baidu.com")
String url;
/**
* 步骤详情
*/
@ApiModelProperty(value = "步骤详情")
List<Step> steps;
}
package com.zjty.automatedtesting.repository;
import com.zjty.automatedtesting.pojo.test.TestCase;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface TestCaseRepository extends JpaRepository<TestCase, Integer> {
}
package com.zjty.automatedtesting.service;
import com.zjty.automatedtesting.pojo.report.Report;
import com.zjty.automatedtesting.pojo.test.TestCaseVo;
import org.springframework.stereotype.Service;
/**
* <p>Description : measurement
* <p>Date : 2020/1/16 15:22
* <p>@author : C
* 使用SeleniumAPI进行自动化测试的Service
* 相关实现:{@link SeleniumServiceImpl}
*/
@Service
public interface SeleniumService {
/**
* 给定一个配置好的测试用例类型数据
* 执行测试
* 然后返回测试结果报告类型
* @param testCaseVo testCaseVo
* @return Report
*/
Report execute(TestCaseVo testCaseVo);
}
package com.zjty.automatedtesting.service;
import com.google.common.collect.Lists;
import com.zjty.automatedtesting.common.action.Assertion;
import com.zjty.automatedtesting.common.action.Browser;
import com.zjty.automatedtesting.pojo.report.Measure;
import com.zjty.automatedtesting.pojo.report.Report;
import com.zjty.automatedtesting.pojo.test.Step;
import com.zjty.automatedtesting.pojo.test.TestCaseVo;
import com.zjty.automatedtesting.util.CommonUtils;
import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.springframework.stereotype.Service;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import static com.zjty.automatedtesting.common.action.Action.*;
import static com.zjty.automatedtesting.common.action.ByType.*;
import static java.util.Objects.isNull;
/**
* @author C
*/
@Slf4j
@Service
public class SeleniumServiceImpl implements SeleniumService {
@Override
public Report execute(TestCaseVo testCase) {
WebDriver driver = initDriver(testCase.getBrowser());
driver.get(testCase.getUrl());
return executeSteps(driver, testCase);
}
/**
* 初始化driver
*
* @return driver
*/
private WebDriver initDriver(String browser) {
if (Objects.equals(browser, Browser.FIREFOX)) {
System.setProperty("webdriver.firefox.driver", CommonUtils.FIRE_FOX_EXE);
return new FirefoxDriver();
} else if (Objects.equals(browser, Browser.CHROME)) {
System.setProperty("webdriver.chrome.driver", CommonUtils.CHROME_EXE);
return new ChromeDriver();
} else if (Objects.equals(browser, Browser.IE)) {
System.setProperty("webdriver.ie.driver", CommonUtils.IE_EXE);
return new ChromeDriver();
}else {
throw new RuntimeException("该浏览器不存在:" + browser);
}
}
private Report executeSteps(WebDriver driver, TestCaseVo testCase) {
List<Measure> measures = Lists.newArrayList();
List<Step> steps = testCase.getSteps().stream().sorted(Comparator.comparingInt(Step::getOrder)).collect(Collectors.toList());
for (Step step : steps) {
boolean success = false;
String practice = "";
String message;
log.info("Executing Step:{}", step.getTitle());
try {
if (Objects.equals(step.getAction(), INPUT)) {
String value = isNull(step.getValue()) ? "" : step.getValue();
WebElement webElement = getWebElement(step.getType(), step.getKey(), driver);
webElement.sendKeys(value);
} else if (Objects.equals(step.getAction(), CLICK)) {
WebElement webElement = getWebElement(step.getType(), step.getKey(), driver);
webElement.click();
} else {
throw new RuntimeException("不匹配的操作类型:" + step.getAction());
}
if (Objects.equals(step.getAssertion(), Assertion.VALUE)) {
WebElement webElement = getWebElement(step.getType(), step.getKey(), driver);
practice = webElement.getAttribute("value");
if (Objects.equals(practice, step.getExpected())) {
success = true;
message = String.format("[%s] success.", step.getTitle());
} else {
message = String.format("[%s] failed.the value is incorrect. expected:%s practice:[%s] ", step.getTitle(), step.getExpected(), practice);
}
} else if (Objects.equals(step.getAssertion(), Assertion.TITLE)){
practice = driver.getTitle();
if (Objects.equals(practice, step.getExpected())) {
success = true;
message = String.format("[%s] success.", step.getTitle());
} else {
message = String.format("[%s] failed.the page is incorrect. expected:[%s] practice:[%s] ", step.getTitle(), step.getExpected(), practice);
}
}else {
throw new RuntimeException("不匹配的判断类型:" + step.getAssertion());
}
} catch (Exception e) {
e.printStackTrace();
success = false;
message = String.format("error detected:[%s]", e.getMessage());
}
measures.add(new Measure(
step.getOrder(),
step.getTitle(),
success,
step.getAssertion(),
step.getExpected(),
practice,
message
));
}
return new Report(
testCase.getUrl(),
testCase.getBrowser(),
measures
);
}
private WebElement getWebElement(String getMethod, String key, WebDriver driver) {
WebElement webElement;
if (Objects.equals(getMethod, XPATH)) {
webElement = driver.findElement(By.xpath(key));
} else if (Objects.equals(getMethod, CSS)) {
webElement = driver.findElement(By.cssSelector(key));
} else if (Objects.equals(getMethod, ID)) {
webElement = driver.findElement(By.id(key));
} else if (Objects.equals(getMethod, NAME)) {
webElement = driver.findElement(By.name(key));
} else {
throw new RuntimeException("未找到元素 type:" + getMethod + " key: " + key);
}
return webElement;
}
}
package com.zjty.automatedtesting.service;
import com.zjty.automatedtesting.pojo.test.TestCase;
import com.zjty.automatedtesting.pojo.test.TestCaseVo;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public interface TestCaseService {
/**
* 保存测试用例
* 不附带id为新增
* 附带id为修改
* @param testCaseVo testCaseVo
*/
void save(TestCaseVo testCaseVo);
/**
* 指定id删除测试用例
* @param id id
*/
void delete(Integer id);
/**
* 查询所有测试用例
* @return list
*/
List<TestCaseVo> findAll();
/**
* 指定id查询测试用例
* @param id id
* @return testcase
*/
TestCaseVo findById(Integer id);
}
package com.zjty.automatedtesting.service;
import com.zjty.automatedtesting.pojo.test.TestCase;
import com.zjty.automatedtesting.pojo.test.TestCaseVo;
import com.zjty.automatedtesting.repository.TestCaseRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
@SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection")
@Service
public class TestCaseServiceImpl implements TestCaseService {
@Autowired
TestCaseRepository repository;
@Autowired
TransHelper transHelper;
@Override
public void save(TestCaseVo testCaseVo) {
TestCase testCase = transHelper.toDo(testCaseVo);
if (Objects.isNull(testCase.getId())){
repository.save(testCase);
}else if(repository.existsById(testCase.getId())){
repository.save(testCase);
}else {
throw new RuntimeException("指定的id不存在:"+testCase.getId());
}
}
@Override
public void delete(Integer id) {
if (repository.existsById(id)){
repository.deleteById(id);
} else {
throw new RuntimeException("指定的id不存在:"+id);
}
}
@Override
public List<TestCaseVo> findAll() {
return repository.findAll().stream().map(transHelper::toVo).collect(Collectors.toList());
}
@Override
public TestCaseVo findById(Integer id) {
Optional<TestCaseVo> testCaseVo = repository.findById(id).map(transHelper::toVo);
if (testCaseVo.isPresent()) {
return testCaseVo.get();
}else {
throw new RuntimeException("指定的id不存在:"+id);
}
}
}
package com.zjty.automatedtesting.service;
import com.zjty.automatedtesting.pojo.test.Step;
import com.zjty.automatedtesting.pojo.test.TestCase;
import com.zjty.automatedtesting.pojo.test.TestCaseVo;
import com.zjty.automatedtesting.util.JsonUtil;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class TransHelper {
public TestCase toDo(TestCaseVo testCaseVo){
String steps = JsonUtil.toJSon(testCaseVo.getSteps());
return new TestCase(
testCaseVo.getId(),
testCaseVo.getBrowser(),
testCaseVo.getUrl(),
steps
);
}
public TestCaseVo toVo(TestCase testCase){
List<Step> steps = JsonUtil.readValueToList(testCase.getSteps(),Step.class);
return new TestCaseVo(
testCase.getId(),
testCase.getBrowser(),
testCase.getUrl(),
steps
);
}
}
package com.zjty.automatedtesting.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.SimpleDateFormat;
import java.util.Date;
public class CommonUtils {
private static final Logger logger = LoggerFactory.getLogger(CommonUtils.class);
/* 公共的 */
public final static String CHROME_EXE = System.getProperty("user.dir")+"\\chromedriver.exe";
public final static String FIRE_FOX_EXE = System.getProperty("user.dir")+"\\geckodriver.exe";
public final static String IE_EXE = System.getProperty("user.dir")+"\\IEDriverServer.exe";
/**
* 结束所有残留进程
* @param
*/
public static void killSelenium(){
String[] pss = new String[]{
"chromedriver*",// google驱动
"IEDriver*",// IE 驱动
"geckodriver*",// Firefox 驱动
"operadriver*"// opera 驱动
};
for(String p1:pss){
kill_process(p1);
}
}
/**
* 结束残留进程
* @param s
*/
public static void kill_process(String s){
try {
Runtime runtime = Runtime.getRuntime();
runtime.exec("taskkill /f /t /im "+s);
} catch (Exception e) {
logger.error("结束进程失败!进程名:"+s+""+ e.getMessage(),e );
}
}
/**
* 获取当前日期和时间
* @return
*/
public static String getNowDateTimeByFormat(String formatString) {
if( null==formatString ){
formatString = "yyyy-MM-dd HH:mm:ss";
}
return new SimpleDateFormat(formatString).format(new Date());
}
}
package com.zjty.automatedtesting.util;
import com.zjty.automatedtesting.pojo.test.TestCase;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
/**
* <p>Description : measurement
* <p>Date : 2020/1/16 15:27
* <p>@author : C
*/
public class FileUtil {
private final static String WORK_PATH = System.getProperty("user.dir") + "\\";
private TestCase parseFilToTestCase(String fileName) throws IOException {
List<String> lines = Files.readAllLines(Paths.get(WORK_PATH + fileName));
StringBuilder builder = new StringBuilder();
lines.forEach(builder::append);
String data = builder.toString();
return JsonUtil.readValue(data, TestCase.class);
}
}
package com.zjty.automatedtesting.util;
import org.openqa.selenium.*;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class JavaEncapsulationUtil {
public static String getCurrentSystemTime() {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
return dateFormat.format(new Date());
}
public static void errorScreenshot(WebDriver driver, String path, String pictureFormat) throws IOException {
String systemTime = JavaEncapsulationUtil.getCurrentSystemTime();
String pictureName = systemTime + pictureFormat;
File jpg = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
}
public static WebElement elementException(WebDriver driver, By by, String elementName, String className) throws Exception {
try {
WebElement element = driver.findElement(by);
element.isDisplayed();
System.out.println(elementName + "元素存在");
return element;
} catch (Exception e) {
System.out.println(elementName + "元素不存在,浏览器关闭,请查看截图并查找原因");
throw (e);
}
}
}
package com.zjty.automatedtesting.util;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* @author C
*/
public final class JsonUtil {
private static ObjectMapper objectMapper;
/**
* 使用泛型方法,把json字符串转换为相应的JavaBean对象。
* (1)转换为普通JavaBean:readValue(json,Student.class)
* (2)转换为List,如List<Student>,将第二个参数传递为Student
* [].class.然后使用Arrays.asList();方法把得到的数组转换为特定类型的List
*/
public static <T> T readValue(String jsonStr, Class<T> valueType) {
if (objectMapper == null) {
objectMapper = new ObjectMapper();
}
try {
return objectMapper.readValue(jsonStr, valueType);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 转换为指定类型的集合
*
* @param jsonStr 待转换的json字符串
* @param valueType 指定类型的Class对象
* @return 指定类型的集合
*/
public static <T> List<T> readValueToList(String jsonStr, Class<T> valueType) {
T[] arrays = readValue(jsonStr, new TypeReference<T[]>() {
});
List<T> list = Collections.emptyList();
if (arrays != null) {
list = Arrays.asList(arrays);
}
return list;
}
/**
* json数组转List
*
* @param jsonStr 待转换的json字符串
* @param valueTypeRef 指定类型的Class对象
* @return 指定类型的集合
*/
public static <T> T readValue(String jsonStr, TypeReference<T> valueTypeRef) {
if (objectMapper == null) {
objectMapper = new ObjectMapper();
}
try {
return objectMapper.readValue(jsonStr, valueTypeRef);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 把JavaBean转换为json字符串
*/
public static String toJSon(Object object) {
if (objectMapper == null) {
objectMapper = new ObjectMapper();
}
try {
return objectMapper.writeValueAsString(object);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/automated_testing?useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.hibernate.ddl-auto=update
spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
spring.jpa.show-sql=true
\ No newline at end of file
package com.zjty.automatedtesting;
import org.junit.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class AutomatedTestingApplicationTests {
@Test
void contextLoads() {
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论