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

增加测试报告的存储机制 增加前端页面

上级 3468b668
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
</parent> </parent>
<groupId>com.zjty</groupId> <groupId>com.zjty</groupId>
<artifactId>automated-testing</artifactId> <artifactId>automated-testing</artifactId>
<version>0.0.1-SNAPSHOT</version> <version>0.0.3-SNAPSHOT</version>
<name>automated-testing</name> <name>automated-testing</name>
<properties> <properties>
......
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 org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
.allowCredentials(true)
.maxAge(3600)
.allowedHeaders("*");
}
}
package com.zjty.automatedtesting.controller;
import com.google.common.collect.ImmutableMap;
import com.zjty.automatedtesting.pojo.report.ReportVo;
import com.zjty.automatedtesting.service.ReportService;
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;
@SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection")
@RequestMapping("/report")
@RestController
@Api(tags = "测试报告")
@CrossOrigin
public class ReportController {
@Autowired
ReportService reportService;
@ApiOperation(value = "获取全部测试报告.")
@GetMapping(value="/get")
public ResponseEntity<List<ReportVo>> get(){
return ResponseEntity.ok(reportService.findAll());
}
@ApiOperation(value = "按分页获取测试报告.页码从0开始.")
@GetMapping(value="/get/page/{page}")
public ResponseEntity<List<ReportVo>> get(@PathVariable Integer page){
return ResponseEntity.ok(reportService.findByPage(page));
}
@ApiOperation(value = "获取单个测试报告.")
@GetMapping(value="/get/{id}")
public ResponseEntity<ReportVo> getById(@PathVariable Integer id){
return ResponseEntity.ok(reportService.findById(id));
}
@ApiOperation(value = "删除测试报告.")
@DeleteMapping(value="/delete/{id}")
public ResponseEntity<Map<String,String>> findTestText(@PathVariable Integer id){
reportService.delete(id);
return ResponseEntity.ok(ImmutableMap.of("message","success"));
}
}
package com.zjty.automatedtesting.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@SuppressWarnings("SpringMVCViewInspection")
@Controller
public class ResourceController {
@RequestMapping("index")
public String index(){
return "index.html";
}
}
package com.zjty.automatedtesting.controller; package com.zjty.automatedtesting.controller;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.zjty.automatedtesting.pojo.report.Report; import com.zjty.automatedtesting.pojo.report.ReportVo;
import com.zjty.automatedtesting.pojo.test.TestCaseVo; import com.zjty.automatedtesting.pojo.test.CaseVo;
import com.zjty.automatedtesting.service.SeleniumService; import com.zjty.automatedtesting.service.SeleniumService;
import com.zjty.automatedtesting.service.TestCaseService; import com.zjty.automatedtesting.service.CaseService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
...@@ -21,50 +21,46 @@ import java.util.Map; ...@@ -21,50 +21,46 @@ import java.util.Map;
@RequestMapping("/testcase") @RequestMapping("/testcase")
@RestController @RestController
@Api(tags = "测试用例") @Api(tags = "测试用例")
@CrossOrigin
public class TestCaseController { public class TestCaseController {
@Autowired @Autowired
SeleniumService seleniumService; SeleniumService seleniumService;
@Autowired @Autowired
TestCaseService testCaseService; CaseService caseService;
@CrossOrigin
@ApiOperation(value = "提供测试用例数据.执行测试并返回测试结果报告.") @ApiOperation(value = "提供测试用例数据.执行测试并返回测试结果报告.")
@PostMapping(value="/execute") @PostMapping(value="/execute")
public ResponseEntity<Report> execute(@RequestBody TestCaseVo testCaseVo){ public ResponseEntity<ReportVo> execute(@RequestBody CaseVo caseVo){
Report execute = seleniumService.execute(testCaseVo); ReportVo execute = seleniumService.execute(caseVo);
return ResponseEntity.ok(execute); return ResponseEntity.ok(execute);
} }
@CrossOrigin
@ApiOperation(value = "保存测试用例.",notes = "不附带id为新增 附带id为修改") @ApiOperation(value = "保存测试用例.",notes = "不附带id为新增 附带id为修改")
@PostMapping(value="/save") @PostMapping(value="/save")
public ResponseEntity<Map<String,String>> save(@RequestBody TestCaseVo testCaseVo){ public ResponseEntity<Map<String,String>> save(@RequestBody CaseVo caseVo){
testCaseService.save(testCaseVo); caseService.save(caseVo);
return ResponseEntity.ok(ImmutableMap.of("message","success")); return ResponseEntity.ok(ImmutableMap.of("message","success"));
} }
@CrossOrigin
@ApiOperation(value = "删除测试用例.") @ApiOperation(value = "删除测试用例.")
@DeleteMapping(value="/delete/{id}") @DeleteMapping(value="/delete/{id}")
public ResponseEntity<Map<String,String>> findTestText(@PathVariable Integer id){ public ResponseEntity<Map<String,String>> findTestText(@PathVariable Integer id){
testCaseService.delete(id); caseService.delete(id);
return ResponseEntity.ok(ImmutableMap.of("message","success")); return ResponseEntity.ok(ImmutableMap.of("message","success"));
} }
@CrossOrigin
@ApiOperation(value = "获取全部测试用例.") @ApiOperation(value = "获取全部测试用例.")
@GetMapping(value="/get") @GetMapping(value="/get")
public ResponseEntity<List<TestCaseVo>> get(){ public ResponseEntity<List<CaseVo>> get(){
return ResponseEntity.ok(testCaseService.findAll()); return ResponseEntity.ok(caseService.findAll());
} }
@CrossOrigin
@ApiOperation(value = "获取单个测试用例.") @ApiOperation(value = "获取单个测试用例.")
@GetMapping(value="/get/{id}") @GetMapping(value="/get/{id}")
public ResponseEntity<TestCaseVo> getById(@PathVariable Integer id){ public ResponseEntity<CaseVo> getById(@PathVariable Integer id){
return ResponseEntity.ok(testCaseService.findById(id)); return ResponseEntity.ok(caseService.findById(id));
} }
......
package com.zjty.automatedtesting.pojo.report; package com.zjty.automatedtesting.pojo.report;
import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONField;
import com.zjty.automatedtesting.config.AutoDocument;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
...@@ -13,7 +12,6 @@ import lombok.NoArgsConstructor; ...@@ -13,7 +12,6 @@ import lombok.NoArgsConstructor;
* <p>Date : 2020/1/16 13:39 * <p>Date : 2020/1/16 13:39
* <p>@author : C * <p>@author : C
*/ */
@AutoDocument
@Data @Data
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
......
package com.zjty.automatedtesting.pojo.report; package com.zjty.automatedtesting.pojo.report;
import com.zjty.automatedtesting.config.AutoDocument;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import java.util.List; import javax.persistence.*;
/** /**
* <p>Description : selenium-test * <p>Description : selenium-test
* <p>Date : 2020/1/3 9:43 * <p>Date : 2020/1/3 9:43
* <p>@author : C * <p>@author : C
*/ */
@AutoDocument @SuppressWarnings("JpaDataSourceORMInspection")
@Data @Data
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
@ApiModel(value = "测试报告结果") @Entity
@Table(name = "AUTO_TEST_REPORT")
public class Report { public class Report {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
/** /**
* 测试用例标题 * 测试用例标题
*/ */
@ApiModelProperty(value = "测试用例标题",example = "百度一下",position = 1) @ApiModelProperty(value = "测试用例标题", example = "百度一下", position = 1)
private String title; private String title;
/** /**
* 浏览器 * 浏览器
*/ */
@ApiModelProperty(value = "浏览器",example = "firefox",position = 2) @ApiModelProperty(value = "浏览器", example = "firefox", position = 2)
private String browser; private String browser;
/** /**
* 网站地址 * 网站地址
*/ */
@ApiModelProperty(value = "网站地址",example = "http://www.baidu.com",position = 3) @ApiModelProperty(value = "网站地址", example = "http://www.baidu.com", position = 3)
private String url; private String url;
/** /**
* 每个步骤结果详情 * 每个步骤结果详情
*/ */
@ApiModelProperty(value = "每个步骤结果详情",position = 4) @Column(columnDefinition = "text")
private List<Measure> measures; private String measures;
} }
package com.zjty.automatedtesting.pojo.report;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(value = "测试报告结果")
public class ReportVo {
@ApiModelProperty(value = "主键id",example = "1")
private Integer id;
@ApiModelProperty(value = "测试用例标题",example = "百度一下",position = 1)
private String title;
/**
* 浏览器
*/
@ApiModelProperty(value = "浏览器",example = "firefox",position = 2)
private String browser;
/**
* 网站地址
*/
@ApiModelProperty(value = "网站地址",example = "http://www.baidu.com",position = 3)
private String url;
/**
* 每个步骤结果详情
*/
@ApiModelProperty(value = "每个步骤结果详情",position = 4)
private List<Measure> measures;
}
package com.zjty.automatedtesting.pojo.test; 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.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import javax.persistence.Entity; import javax.persistence.*;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
/** /**
...@@ -18,18 +12,21 @@ import javax.persistence.Id; ...@@ -18,18 +12,21 @@ import javax.persistence.Id;
* <p>Date : 2020/1/3 17:04 * <p>Date : 2020/1/3 17:04
* <p>@author : C * <p>@author : C
*/ */
@AutoDocument @SuppressWarnings("JpaDataSourceORMInspection")
@Data @Data
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
@ApiModel(value = "测试用例")
@Entity @Entity
public class TestCase { @Table(name = "AUTO_TEST_CASE")
public class Case {
@Id @Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
Integer id; Integer id;
/**
* 标题
*/
String title; String title;
/** /**
* 浏览器 * 浏览器
...@@ -44,6 +41,7 @@ public class TestCase { ...@@ -44,6 +41,7 @@ public class TestCase {
/** /**
* 步骤详情 * 步骤详情
*/ */
@Column(columnDefinition = "text")
String steps; String steps;
} }
package com.zjty.automatedtesting.pojo.test; package com.zjty.automatedtesting.pojo.test;
import com.zjty.automatedtesting.config.AutoDocument;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.util.List; import java.util.List;
@AutoDocument
@Data @Data
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
@ApiModel(value = "测试用例") @ApiModel(value = "测试用例")
public class TestCaseVo { public class CaseVo {
/** /**
* 主键 * 主键
*/ */
@ApiModelProperty(value = "主键",example = "1",position = 0) @ApiModelProperty(value = "主键id",example = "1")
Integer id; Integer id;
/** /**
......
package com.zjty.automatedtesting.pojo.test; 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.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
...@@ -15,7 +12,6 @@ import lombok.NoArgsConstructor; ...@@ -15,7 +12,6 @@ import lombok.NoArgsConstructor;
* <p>Date : 2020/1/3 9:47 * <p>Date : 2020/1/3 9:47
* <p>@author : C * <p>@author : C
*/ */
@AutoDocument
@Data @Data
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
......
package com.zjty.automatedtesting.repository; package com.zjty.automatedtesting.repository;
import com.zjty.automatedtesting.pojo.test.TestCase; import com.zjty.automatedtesting.pojo.test.Case;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
@Repository @Repository
public interface TestCaseRepository extends JpaRepository<TestCase, Integer> { public interface CaseRepository extends JpaRepository<Case, Integer> {
} }
package com.zjty.automatedtesting.repository;
import com.zjty.automatedtesting.pojo.report.Report;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface ReportRepository extends JpaRepository<Report,Integer> {
}
package com.zjty.automatedtesting.service; package com.zjty.automatedtesting.service;
import com.zjty.automatedtesting.pojo.test.TestCase; import com.zjty.automatedtesting.pojo.test.CaseVo;
import com.zjty.automatedtesting.pojo.test.TestCaseVo;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.List; import java.util.List;
@Service @Service
public interface TestCaseService { public interface CaseService {
/** /**
* 保存测试用例 * 保存测试用例
* 不附带id为新增 * 不附带id为新增
* 附带id为修改 * 附带id为修改
* @param testCaseVo testCaseVo * @param caseVo testCaseVo
* @return 保存的id
*/ */
void save(TestCaseVo testCaseVo); Integer save(CaseVo caseVo);
/** /**
* 指定id删除测试用例 * 指定id删除测试用例
...@@ -27,13 +27,13 @@ public interface TestCaseService { ...@@ -27,13 +27,13 @@ public interface TestCaseService {
* 查询所有测试用例 * 查询所有测试用例
* @return list * @return list
*/ */
List<TestCaseVo> findAll(); List<CaseVo> findAll();
/** /**
* 指定id查询测试用例 * 指定id查询测试用例
* @param id id * @param id id
* @return testcase * @return testcase
*/ */
TestCaseVo findById(Integer id); CaseVo findById(Integer id);
} }
package com.zjty.automatedtesting.service; package com.zjty.automatedtesting.service;
import com.zjty.automatedtesting.pojo.test.TestCase; import com.zjty.automatedtesting.pojo.test.Case;
import com.zjty.automatedtesting.pojo.test.TestCaseVo; import com.zjty.automatedtesting.pojo.test.CaseVo;
import com.zjty.automatedtesting.repository.TestCaseRepository; import com.zjty.automatedtesting.repository.CaseRepository;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
...@@ -13,47 +13,47 @@ import java.util.stream.Collectors; ...@@ -13,47 +13,47 @@ import java.util.stream.Collectors;
@SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection") @SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection")
@Service @Service
public class TestCaseServiceImpl implements TestCaseService { public class CaseServiceImpl implements CaseService {
@Autowired @Autowired
TestCaseRepository repository; CaseRepository repository;
@Autowired @Autowired
TransHelper transHelper; TransHelper transHelper;
@Override @Override
public void save(TestCaseVo testCaseVo) { public Integer save(CaseVo caseVo) {
TestCase testCase = transHelper.toDo(testCaseVo); Case aCase = transHelper.toTestCase(caseVo);
if (Objects.isNull(testCase.getId())){ Integer id;
repository.save(testCase); if (Objects.isNull(aCase.getId()) || repository.existsById(aCase.getId())) {
}else if(repository.existsById(testCase.getId())){ id = repository.save(aCase).getId();
repository.save(testCase); } else {
}else { throw new RuntimeException("指定的id不存在:" + aCase.getId());
throw new RuntimeException("指定的id不存在:"+testCase.getId());
} }
return id;
} }
@Override @Override
public void delete(Integer id) { public void delete(Integer id) {
if (repository.existsById(id)){ if (repository.existsById(id)) {
repository.deleteById(id); repository.deleteById(id);
} else { } else {
throw new RuntimeException("指定的id不存在:"+id); throw new RuntimeException("指定的id不存在:" + id);
} }
} }
@Override @Override
public List<TestCaseVo> findAll() { public List<CaseVo> findAll() {
return repository.findAll().stream().map(transHelper::toVo).collect(Collectors.toList()); return repository.findAll().stream().map(transHelper::toTestCaseVo).collect(Collectors.toList());
} }
@Override @Override
public TestCaseVo findById(Integer id) { public CaseVo findById(Integer id) {
Optional<TestCaseVo> testCaseVo = repository.findById(id).map(transHelper::toVo); Optional<CaseVo> testCaseVo = repository.findById(id).map(transHelper::toTestCaseVo);
if (testCaseVo.isPresent()) { if (testCaseVo.isPresent()) {
return testCaseVo.get(); return testCaseVo.get();
}else { } else {
throw new RuntimeException("指定的id不存在:"+id); throw new RuntimeException("指定id的数据不存在:" + id);
} }
} }
......
package com.zjty.automatedtesting.service;
import com.zjty.automatedtesting.pojo.report.ReportVo;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public interface ReportService {
/**
* 保存 测试报告
*
* @return 保存的id
*/
Integer save(ReportVo reportVo);
/**
* 查询所有
*
* @return 集合形式的测试报告
*/
List<ReportVo> findAll();
/**
* 按分页查询
* 每页10个
* @param page 页码 从0开始
* @return 集合形式的测试报告
*/
List<ReportVo> findByPage(Integer page);
/**
* 按id查询单个
*
* @param id 指定id
* @return 单个测试报告
* 报告
*/
ReportVo findById(Integer id);
/**
* 指定id删除
*
* @param id 指定的id
*/
void delete(Integer id);
}
package com.zjty.automatedtesting.service;
import com.zjty.automatedtesting.pojo.report.Report;
import com.zjty.automatedtesting.pojo.report.ReportVo;
import com.zjty.automatedtesting.repository.ReportRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
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 ReportServiceImpl implements ReportService {
@Autowired
ReportRepository repository;
@Autowired
TransHelper transHelper;
@Override
public Integer save(ReportVo reportVo) {
Report report = transHelper.toReport(reportVo);
Integer id;
if (Objects.isNull(report.getId()) || repository.existsById(report.getId())) {
id = repository.save(report).getId();
} else {
throw new RuntimeException("指定的id不存在:" + report.getId());
}
return id;
}
@Override
public List<ReportVo> findAll() {
return repository.findAll().stream().map(transHelper::toReportVo).collect(Collectors.toList());
}
@Override
public List<ReportVo> findByPage(Integer page) {
PageRequest request = PageRequest.of(page, 10);
return repository.findAll(request).stream().map(transHelper::toReportVo).collect(Collectors.toList());
}
@Override
public ReportVo findById(Integer id) {
Optional<ReportVo> reportVo = repository.findById(id).map(transHelper::toReportVo);
if (reportVo.isPresent()) {
return reportVo.get();
} else {
throw new RuntimeException("指定id的数据不存在:" + id);
}
}
@Override
public void delete(Integer id) {
if (repository.existsById(id)) {
repository.deleteById(id);
} else {
throw new RuntimeException("指定的id不存在:" + id);
}
}
}
package com.zjty.automatedtesting.service; package com.zjty.automatedtesting.service;
import com.zjty.automatedtesting.pojo.report.Report; import com.zjty.automatedtesting.pojo.report.ReportVo;
import com.zjty.automatedtesting.pojo.test.TestCaseVo; import com.zjty.automatedtesting.pojo.test.CaseVo;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
/** /**
...@@ -18,9 +18,9 @@ public interface SeleniumService { ...@@ -18,9 +18,9 @@ public interface SeleniumService {
* 给定一个配置好的测试用例类型数据 * 给定一个配置好的测试用例类型数据
* 执行测试 * 执行测试
* 然后返回测试结果报告类型 * 然后返回测试结果报告类型
* @param testCaseVo testCaseVo * @param caseVo testCaseVo
* @return Report * @return Report
*/ */
Report execute(TestCaseVo testCaseVo); ReportVo execute(CaseVo caseVo);
} }
...@@ -4,9 +4,9 @@ import com.google.common.collect.Lists; ...@@ -4,9 +4,9 @@ import com.google.common.collect.Lists;
import com.zjty.automatedtesting.common.action.Assertion; import com.zjty.automatedtesting.common.action.Assertion;
import com.zjty.automatedtesting.common.action.Browser; import com.zjty.automatedtesting.common.action.Browser;
import com.zjty.automatedtesting.pojo.report.Measure; import com.zjty.automatedtesting.pojo.report.Measure;
import com.zjty.automatedtesting.pojo.report.Report; import com.zjty.automatedtesting.pojo.report.ReportVo;
import com.zjty.automatedtesting.pojo.test.Step; import com.zjty.automatedtesting.pojo.test.Step;
import com.zjty.automatedtesting.pojo.test.TestCaseVo; import com.zjty.automatedtesting.pojo.test.CaseVo;
import com.zjty.automatedtesting.util.CommonUtils; import com.zjty.automatedtesting.util.CommonUtils;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.By; import org.openqa.selenium.By;
...@@ -14,6 +14,7 @@ import org.openqa.selenium.WebDriver; ...@@ -14,6 +14,7 @@ import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver; import org.openqa.selenium.firefox.FirefoxDriver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Comparator; import java.util.Comparator;
...@@ -29,12 +30,18 @@ import static java.util.Objects.nonNull; ...@@ -29,12 +30,18 @@ import static java.util.Objects.nonNull;
/** /**
* @author C * @author C
*/ */
@SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection")
@Slf4j @Slf4j
@Service @Service
public class SeleniumServiceImpl implements SeleniumService { public class SeleniumServiceImpl implements SeleniumService {
@Autowired
ReportService reportService;
@Override @Override
public Report execute(TestCaseVo testCase) { public ReportVo execute(CaseVo testCase) {
WebDriver driver = initDriver(testCase.getBrowser()); WebDriver driver = initDriver(testCase.getBrowser());
driver.get(testCase.getUrl()); driver.get(testCase.getUrl());
return executeSteps(testCase.getUrl(), driver, testCase); return executeSteps(testCase.getUrl(), driver, testCase);
...@@ -60,7 +67,7 @@ public class SeleniumServiceImpl implements SeleniumService { ...@@ -60,7 +67,7 @@ public class SeleniumServiceImpl implements SeleniumService {
} }
} }
private Report executeSteps(String url, WebDriver driver, TestCaseVo testCase) { private ReportVo executeSteps(String url, WebDriver driver, CaseVo testCase) {
List<Measure> measures = Lists.newArrayList(); List<Measure> measures = Lists.newArrayList();
List<Step> steps = testCase.getSteps().stream().sorted(Comparator.comparingInt(Step::getOrder)).collect(Collectors.toList()); List<Step> steps = testCase.getSteps().stream().sorted(Comparator.comparingInt(Step::getOrder)).collect(Collectors.toList());
for (Step step : steps) { for (Step step : steps) {
...@@ -70,9 +77,9 @@ public class SeleniumServiceImpl implements SeleniumService { ...@@ -70,9 +77,9 @@ public class SeleniumServiceImpl implements SeleniumService {
WebElement webElement = null; WebElement webElement = null;
log.info("执行步骤:{}", step.getTitle()); log.info("执行步骤:{}", step.getTitle());
try { try {
if (Objects.equals(step.getAction(), HOME)){ if (Objects.equals(step.getAction(), HOME)) {
driver.get(url); driver.get(url);
}else { } else {
webElement = getWebElement(step.getType(), step.getKey(), driver); webElement = getWebElement(step.getType(), step.getKey(), driver);
if (Objects.equals(step.getAction(), INPUT)) { if (Objects.equals(step.getAction(), INPUT)) {
String value = isNull(step.getValue()) ? "" : step.getValue(); String value = isNull(step.getValue()) ? "" : step.getValue();
...@@ -87,19 +94,19 @@ public class SeleniumServiceImpl implements SeleniumService { ...@@ -87,19 +94,19 @@ public class SeleniumServiceImpl implements SeleniumService {
} }
if (Objects.equals(step.getAssertion(), Assertion.VALUE)) { if (Objects.equals(step.getAssertion(), Assertion.VALUE)) {
if (nonNull(webElement)){ if (nonNull(webElement)) {
practice = webElement.getAttribute("value"); practice = webElement.getAttribute("value");
} }
}else if (Objects.equals(step.getAssertion(), Assertion.TITLE)) { } else if (Objects.equals(step.getAssertion(), Assertion.TITLE)) {
practice = driver.getTitle(); practice = driver.getTitle();
}else { } else {
throw new RuntimeException("不匹配的判断类型:" + step.getAssertion()); throw new RuntimeException("不匹配的判断类型:" + step.getAssertion());
} }
if (Objects.equals(practice, step.getExpected())) { if (Objects.equals(practice, step.getExpected())) {
success = true; success = true;
message = "成功"; message = "成功";
} else { } else {
message = String.format("失败 实际与预期不符 预期:[%s] 实际:[%s] ",step.getExpected(), practice); message = String.format("失败 实际与预期不符 预期:[%s] 实际:[%s] ", step.getExpected(), practice);
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
...@@ -117,12 +124,16 @@ public class SeleniumServiceImpl implements SeleniumService { ...@@ -117,12 +124,16 @@ public class SeleniumServiceImpl implements SeleniumService {
message message
)); ));
} }
return new Report( ReportVo reportVo = new ReportVo(
null,
testCase.getTitle(), testCase.getTitle(),
testCase.getUrl(),
testCase.getBrowser(), testCase.getBrowser(),
testCase.getUrl(),
measures measures
); );
Integer id = reportService.save(reportVo);
reportVo.setId(id);
return reportVo;
} }
@SuppressWarnings("DuplicatedCode") @SuppressWarnings("DuplicatedCode")
......
package com.zjty.automatedtesting.service; package com.zjty.automatedtesting.service;
import com.zjty.automatedtesting.pojo.report.Measure;
import com.zjty.automatedtesting.pojo.report.Report;
import com.zjty.automatedtesting.pojo.report.ReportVo;
import com.zjty.automatedtesting.pojo.test.Step; import com.zjty.automatedtesting.pojo.test.Step;
import com.zjty.automatedtesting.pojo.test.TestCase; import com.zjty.automatedtesting.pojo.test.Case;
import com.zjty.automatedtesting.pojo.test.TestCaseVo; import com.zjty.automatedtesting.pojo.test.CaseVo;
import com.zjty.automatedtesting.util.JsonUtil; import com.zjty.automatedtesting.util.JsonUtil;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
...@@ -11,26 +14,47 @@ import java.util.List; ...@@ -11,26 +14,47 @@ import java.util.List;
@Service @Service
public class TransHelper { public class TransHelper {
public TestCase toDo(TestCaseVo testCaseVo){ public Case toTestCase(CaseVo caseVo){
String steps = JsonUtil.toJSon(testCaseVo.getSteps()); String steps = JsonUtil.toJSon(caseVo.getSteps());
return new TestCase( return new Case(
testCaseVo.getId(), caseVo.getId(),
testCaseVo.getTitle(), caseVo.getTitle(),
testCaseVo.getBrowser(), caseVo.getBrowser(),
testCaseVo.getUrl(), caseVo.getUrl(),
steps steps
); );
} }
public TestCaseVo toVo(TestCase testCase){ public CaseVo toTestCaseVo(Case aCase){
List<Step> steps = JsonUtil.readValueToList(testCase.getSteps(),Step.class); List<Step> steps = JsonUtil.readValueToList(aCase.getSteps(),Step.class);
return new TestCaseVo( return new CaseVo(
testCase.getId(), aCase.getId(),
testCase.getTitle(), aCase.getTitle(),
testCase.getBrowser(), aCase.getBrowser(),
testCase.getUrl(), aCase.getUrl(),
steps steps
); );
} }
public Report toReport(ReportVo reportVo){
String measures = JsonUtil.toJSon(reportVo.getMeasures());
return new Report(
reportVo.getId(),
reportVo.getTitle(),
reportVo.getBrowser(),
reportVo.getUrl(),
measures
);
}
public ReportVo toReportVo(Report report){
List<Measure> measures = JsonUtil.readValueToList(report.getMeasures(),Measure.class);
return new ReportVo(
report.getId(),
report.getTitle(),
report.getBrowser(),
report.getUrl(),
measures
);
}
} }
package com.zjty.automatedtesting.util; package com.zjty.automatedtesting.util;
import com.zjty.automatedtesting.pojo.test.TestCase; import com.zjty.automatedtesting.pojo.test.Case;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
...@@ -17,11 +17,11 @@ public class FileUtil { ...@@ -17,11 +17,11 @@ public class FileUtil {
private final static String WORK_PATH = System.getProperty("user.dir") + "\\"; private final static String WORK_PATH = System.getProperty("user.dir") + "\\";
private TestCase parseFilToTestCase(String fileName) throws IOException { private Case parseFilToTestCase(String fileName) throws IOException {
List<String> lines = Files.readAllLines(Paths.get(WORK_PATH + fileName)); List<String> lines = Files.readAllLines(Paths.get(WORK_PATH + fileName));
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
lines.forEach(builder::append); lines.forEach(builder::append);
String data = builder.toString(); String data = builder.toString();
return JsonUtil.readValue(data, TestCase.class); return JsonUtil.readValue(data, Case.class);
} }
} }
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><link rel=icon href=favicon.ico><title>adapter</title><link href=static/css/databaseConfig.6b0f0024.css rel=prefetch><link href=static/css/dependConfig.2aaa86c3.css rel=prefetch><link href=static/css/details.34c83a51.css rel=prefetch><link href=static/css/home.0ec7bde1.css rel=prefetch><link href=static/css/middlewareConfig.e2ffc848.css rel=prefetch><link href=static/css/regularConfig.027cf8ba.css rel=prefetch><link href=static/css/serviceConfig.c2ad1146.css rel=prefetch><link href=static/js/databaseConfig.c0721f54.js rel=prefetch><link href=static/js/dependConfig.22d94790.js rel=prefetch><link href=static/js/details.551bcead.js rel=prefetch><link href=static/js/home.3e4b65f5.js rel=prefetch><link href=static/js/middlewareConfig.181174d3.js rel=prefetch><link href=static/js/regularConfig.2bb5c8b1.js rel=prefetch><link href=static/js/serviceConfig.5bdd9ad0.js rel=prefetch><link href=static/css/app.6703eb5f.css rel=preload as=style><link href=static/css/chunk-vendors.717c90ab.css rel=preload as=style><link href=static/js/app.a0fd3b5a.js rel=preload as=script><link href=static/js/chunk-vendors.5f648e7a.js rel=preload as=script><link href=static/css/chunk-vendors.717c90ab.css rel=stylesheet><link href=static/css/app.6703eb5f.css rel=stylesheet></head><body><noscript><strong>We're sorry but adapter doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script src=static/js/chunk-vendors.5f648e7a.js></script><script src=static/js/app.a0fd3b5a.js></script></body></html>
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
.horLine[data-v-065e24b9]{width:86vh;height:6px;background:rgba(72,170,253,.1)}.middleConfig[data-v-065e24b9]{height:100%;text-align:left;background-color:rgba(3,110,183,.1)}.middleConfig-left[data-v-065e24b9]{border-right:6px solid rgba(72,170,253,.1);height:74vh}.middleConfig-left>ul[data-v-065e24b9]{padding:20px 20px 0 20px}.middleConfig-left>ul>li[data-v-065e24b9]{margin:0 0 20px 0;border-bottom:4px solid rgba(72,170,253,.1)}.middleConfig-left>ul>li>i[data-v-065e24b9]{display:inline-block;width:5px;height:5px;border-radius:50%;background:#999;margin:3px 5px 3px 0}.middleLi[data-v-065e24b9]:hover{color:#59f9f7;border-bottom:4px solid #59f9f7}.middleLi[data-v-065e24b9]{color:#fff;border-bottom:4px solid rgba(72,170,253,.1)}.middleActive[data-v-065e24b9]{color:#59f9f7!important;border-bottom:4px solid #59f9f7!important}.cancel[data-v-065e24b9]{display:inline-block;width:15px;height:15px;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAACXBIWXMAAAsSAAALEgHS3X78AAAAtElEQVQoz6WTsQ3CMBBFn691403ICKwBUki8WCBuWIMRoGGOFKE+GgeFYOwgTnJz0nu++5bN2NUOuABX60PLinocDyfAyazXxOYasAEGsT4MwBa4lQQzsLc+tAKwRrAEAV5j5wQpEMCo6vKGKcAN0E95LMEknBCQAt/Gnldc4V5KXjKp7oBzLkQppLq3PlRx9w+BlJ4jrtGmBFICcwKjqkXw23Tmj49RoaqMXe1UlV/O2NXuCaHNppoc5cnEAAAAAElFTkSuQmCC) no-repeat;position:relative;left:220px}.middleConfig-left>p[data-v-065e24b9]{position:absolute;bottom:20px;height:60px;border-top:6px solid rgba(72,170,253,.1);width:28%}.middleConfig-left>p>span[data-v-065e24b9]{display:inline-block;margin:0 auto;width:110px;height:33px;font-size:16px;color:#fff;text-align:center;line-height:33px;background:url(data:image/png;base64,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) no-repeat;margin:20px}.middleConfig-left>p>span[data-v-065e24b9]:hover{background:url(data:image/png;base64,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) no-repeat}.middleConfig-right[data-v-065e24b9]{margin:10px 20px}.middleConfig-right>div[data-v-065e24b9]{background-color:rgba(1,13,25,.5)}.middleConfig-right>div>ul[data-v-065e24b9]{padding:0 20px}.middleConfig-right>p[data-v-065e24b9]{font-size:18px;color:#59f9f7}.middleConfig-right>p>i[data-v-065e24b9]{display:inline-block;width:5px;height:5px;background:#59f9f7;margin:4px 3px}.right-base[data-v-065e24b9]{width:100%;height:126px;font-size:16px;color:#fff}.right-base>span[data-v-065e24b9]{display:inline-block;margin:22px 70px}.right-base>span>p[data-v-065e24b9]{padding:9px 0}.right-base>span>p>span[data-v-065e24b9]{color:#59f9f7}.right-system[data-v-065e24b9]{margin-left:60px;position:relative;top:-47px}.right-system>img[data-v-065e24b9]{float:right;margin:-30px 10px 48px 0}.middleConfig-right>div>ul>li[data-v-065e24b9]{height:74px;border-bottom:6px solid rgba(72,170,253,.1)}.middleConfig-right>div>ul>li[data-v-065e24b9]:hover{border-bottom:6px solid #59f9f7}.right-system>p[data-v-065e24b9]{color:#999;font-size:14px}.right-system>p>span[data-v-065e24b9]{color:#59f9f7}
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论