基于SSM+MVC三层架构实现软件测试管理系统

基于SSM实现软件测试管理系统

引言

Hello,大家好,本周博主为大家带来一个基于SSM的软件测试管理系统,系统分为两大模块,用户与bug模块

其中管理员管理用户,为用户分配角色,分为开发或测试,用户管理bug模块,其中,测试提交bug,写好bug信息,进行提交,开发人员对bug进行修改,直至测试确认bug修改完成后,结束对话。

文字表达难免表达不清楚,下面看效果图

效果图时长3分钟,要耐心看下去哦

效果图

技术栈

  1. 后端:Java、Spring、Spring MVC、 MyBatis
  2. 前端:bootstrap、jsp

软件测试管理系统

系统支持防跳墙,利用Spring MVC Interceptor拦截器实现,

实体类采用lombok插件

系统采用三层架构完成

数据表准备


t_user用户表

CREATE TABLE `t_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `userpwd` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `realname` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `usertype` int(11) DEFAULT NULL COMMENT '账号类型,1:开发,2:测试',
  PRIMARY KEY (`id`)
) 

t_bug_topic bug主题表

CREATE TABLE `t_bug_topic` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `bug_title` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'bug主题',
  `bug_detail` varchar(256) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'bug详细信息',
  `bug_level` int(11) DEFAULT NULL COMMENT 'bug级别:1:功能优化、2:一般异常、3:重大异常',
  `test_user_id` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '测试用户id',
  `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '当前日期',
  `bug_status` int(11) DEFAULT '0' COMMENT '当前bug状态,1 未处理 2 修改完成待确认 3 修改被驳回 4 修改完成已确认',
  PRIMARY KEY (`id`)
)

t_bug_trace bug跟踪表

CREATE TABLE `t_bug_trace` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `topic_id` int(11) DEFAULT NULL COMMENT 'bugid',
  `send_user_id` int(11) DEFAULT NULL COMMENT '发送人员id',
  `send_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '当前日期',
  `detail_info` varchar(256) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '详细信息',
  `bug_status` int(11) DEFAULT NULL COMMENT '当前状态:0 普通沟通 2 修改完成,提交确认 3 修改驳回 4 修改完成已确认',
  PRIMARY KEY (`id`)
) 

项目结构

基于SSM+MVC三层架构实现软件测试管理系统_第1张图片

Java源码

基于SSM+MVC三层架构实现软件测试管理系统_第2张图片

配置文件

基于SSM+MVC三层架构实现软件测试管理系统_第3张图片

前端结构

基于SSM+MVC三层架构实现软件测试管理系统_第4张图片

搭建项目

以Maven方式创建Web项目

整合SSM

pom依赖文件


<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0modelVersion>

    <groupId>org.examplegroupId>
    <artifactId>APPTestManagerSystemartifactId>
    <version>1.0-SNAPSHOTversion>


    <dependencies>
        
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-aopartifactId>
            <version>5.2.4.RELEASEversion>
        dependency>

        
        <dependency>
            <groupId>org.aspectjgroupId>
            <artifactId>aspectjweaverartifactId>
            <version>1.9.4version>
        dependency>

        
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-contextartifactId>
            <version>5.2.4.RELEASEversion>
        dependency>

        
        <dependency>
            <groupId>org.mybatisgroupId>
            <artifactId>mybatisartifactId>
            <version>3.5.4version>
        dependency>

        
        
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <version>5.1.47version>
        dependency>

        
        <dependency>
            <groupId>com.mchangegroupId>
            <artifactId>c3p0artifactId>
            <version>0.9.5.2version>
        dependency>

        
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-jdbcartifactId>
            <version>5.2.4.RELEASEversion>
        dependency>

        
        <dependency>
            <groupId>org.mybatisgroupId>
            <artifactId>mybatis-springartifactId>
            <version>2.0.4version>
        dependency>

        
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-webmvcartifactId>
            <version>5.1.9.RELEASEversion>
        dependency>

        <dependency>
            <groupId>javax.servletgroupId>
            <artifactId>jstlartifactId>
            <version>1.2version>
        dependency>

        <dependency>
            <groupId>commons-fileuploadgroupId>
            <artifactId>commons-fileuploadartifactId>
            <version>1.3.1version>
        dependency>
        <dependency>
            <groupId>commons-iogroupId>
            <artifactId>commons-ioartifactId>
            <version>2.4version>
        dependency>

        
        <dependency>
            <groupId>javax.servletgroupId>
            <artifactId>javax.servlet-apiartifactId>
            <version>3.1.0version>
            <scope>providedscope>
        dependency>

        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <version>1.18.20version>
        dependency>
        <dependency>
            <groupId>commons-langgroupId>
            <artifactId>commons-langartifactId>
            <version>2.6version>
        dependency>
    dependencies>

    <build>
        <resources>
            <resource>
                <directory>src/main/javadirectory>
                <includes>
                    <include>**/*.propertiesinclude>
                    <include>**/*.xmlinclude>
                includes>
                <filtering>truefiltering>
            resource>
        resources>
    build>

project>

核心源码

bean层

User用户类

package com.wanshi.bean;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class TUser {
     

    private Integer id;
    private String username;
    private String userpwd;
    private String realname;
    private Integer usertype;
}

BugTopic Bug主题类

package com.wanshi.bean;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class BugTopic {
     

    private Integer id;
    private String bug_title;
    private String bug_detail;
    private Integer bug_level;
    private Integer test_user_id;
    private Date create_time;
    private Integer bug_status;

    private String testUsername;

    private String createTime;

}

BugTrace Bug跟踪类

package com.wanshi.bean;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class BugTrace {
     

    private Integer id;
    private Integer topic_id;
    private Integer send_user_id;
    private Date send_time;
    private String detail_info;
    private Integer bug_status;

    private String sendUserName;
    private String sendTime;
    private String userType;
}

Page 分页类

package com.wanshi.bean;

import java.util.ArrayList;
import java.util.List;

/**
 * 分页类,使用该类需传入3个参数,
 * currPage:当前页数
 * pageSize:每页显示的记录数
 * rowCount:总共的记录数
 *
 * 注意::初始化该类后,使用该类的currPageFirstRowIndex属性传入数据访问层进行分页
 * 分页完成后返回list集合,需要将返回的list集合通过该类的setList方法存入数据即可完成
 *
 * @author 王会称
 *
 * @param 
 */
public class Page<T> {
     

    /**
     * 当前页前面的页数
     */
    private static final int BeforePageNumbCount =  4;

    /**
     * 当前页后面的页数
     */
    private static final int AfterPageNumbCount = 3;

    /**
     * 当前页
     */
    private int currPage;
    /**
     * 总记录数
     */
    private int rowCount;
    /**
     * 分页的第二个参数,用于展示每页显示几条数据
     * limit arg1, arg2	arg2
     *
     */
    private int pageSize;
    /**
     * 总页数
     */
    private int pageCount;
    /**
     * 前一页
     */
    private int prevPageNumb;
    /**
     * 后一页
     */
    private int nextPageNumb;

    /**
     * 从第几条开始截取,分页的第一个参数
     * limit arg1, arg2	arg1
     *
     */
    private int currPageFirstRowIndex;
    /**
     * 当前页的集合
     */
    private List<T> list;
    /**
     * 当前显示的按钮数,前4后3
     */
    private List<Integer> pageButtonNumbs ;

    /**
     * 初始化分页类,传入当前页,每页的记录数,总记录数
     * @param _currPage
     * @param _pageSize
     * @param _rowCount
     */
    public Page(int _currPage, int _pageSize, int _rowCount){
     

        //初始化固定数据,每页的数据记录数,总记录数
        this.pageSize = _pageSize;
        this.rowCount = _rowCount;

        // 计算出当前共有多少页
        this.pageCount = this.rowCount / this.pageSize;
        if(this.rowCount% this.pageSize !=0 ){
     
            this.pageCount ++ ;
        }

        // 修正当前页
        this.currPage = _currPage ;
        if(this.currPage< 1 ){
     
            this.currPage = 1;
        }

        if(this.currPage > this.pageCount ){
     
            this.currPage = this.pageCount;
        }

        // 计算limit分页的第一个参数
        this.currPageFirstRowIndex = (this.currPage-1)* this.pageSize ;

        //如果小于0,那就从0开始截取
        if (this.currPageFirstRowIndex < 0) {
     
            this.currPageFirstRowIndex = 0;
        }

        // 计算前一页与后一页
        this.prevPageNumb = this.currPage - 1;
        this.nextPageNumb = this.currPage + 1;

        //修正前一页
        if(this.prevPageNumb<1){
     
            this.prevPageNumb = 1;
        }

        //修正后一页
        if(this.nextPageNumb >1 && this.nextPageNumb > this.pageCount){
     
            this.nextPageNumb = this.pageCount;
        }

        // 计算当前的按钮数
        this.pageButtonNumbs = new ArrayList();
        for( int i = this.currPage - BeforePageNumbCount ; i <= this.currPage+AfterPageNumbCount ;i++){
     
            if(i<1 || i> this.pageCount ){
     
                continue;
            }
            this.pageButtonNumbs.add(i);
        }

    }

    public List<T> getList() {
     
        return list;
    }

    public void setList(List<T> list) {
     
        this.list = list;
    }

    public int getCurrPage() {
     
        return currPage;
    }

    public int getRowCount() {
     
        return rowCount;
    }

    public int getPageSize() {
     
        return pageSize;
    }

    public int getPageCount() {
     
        return pageCount;
    }

    public int getPrevPageNumb() {
     
        return prevPageNumb;
    }

    public int getNextPageNumb() {
     
        return nextPageNumb;
    }

    public List<Integer> getPageButtonNumbs() {
     
        return pageButtonNumbs;
    }

    public int getCurrPageFirstRowIndex() {
     
        return currPageFirstRowIndex;
    }

    @Override
    public String toString() {
     
        return "Page [currPage=" + currPage + ", rowCount=" + rowCount + ", pageSize=" + pageSize + ", pageCount="
                + pageCount + ", prevPageNumb=" + prevPageNumb + ", nextPageNumb=" + nextPageNumb
                + ", currPageFirstRowIndex=" + currPageFirstRowIndex + ", list=" + list + ", pageButtonNumbs="
                + pageButtonNumbs + "]";
    }
}

controller层

RouteController 路由跳转类,用于携带数据跳转到指定jsp页面进行渲染

package com.wanshi.controller;

import com.wanshi.bean.BugTopic;
import com.wanshi.bean.TUser;
import com.wanshi.service.BugTopicService;
import com.wanshi.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;

@Controller
@RequestMapping("/route")
public class RouteController {
     

    @Autowired
    private UserService userService;

    @Autowired
    private BugTopicService bugTopicService;

    @GetMapping("/index")
    public String index() {
     
        return "index";
    }

    @GetMapping("/addUser")
    public String userAdd() {
     
        return "user/add";
    }

    @GetMapping("/updateUser")
    public String updateUser(String id, Model model) {
     
        TUser tUser = userService.get(Integer.valueOf(id));
        model.addAttribute("user", tUser);
        return "user/edit";
    }

    @GetMapping("/addBug")
    public String addBug() {
     
        return "bug/add";
    }

    @GetMapping("/updateBug")
    public String updateBug(String id, Model model) {
     
        BugTopic bugTopic = bugTopicService.get(Integer.valueOf(id));
        model.addAttribute("bug", bugTopic);
        return "bug/edit";
    }

    @GetMapping("/disposeBug")
    public String disposeBug(String id, HttpServletRequest request) {
     
        BugTopic bugTopic = bugTopicService.get(Integer.valueOf(id));
        request.getSession().setAttribute("bug", bugTopic);
        return "redirect:/bug_trace/list";
    }

}

BugTopicController bug主题控制器类

package com.wanshi.controller;

import com.wanshi.bean.BugTopic;
import com.wanshi.bean.Page;
import com.wanshi.service.BugTopicService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

@Controller
@RequestMapping("/bug_topic")
public class BugTopicController {
     


    @Autowired
    private BugTopicService bugTopicService;

    private static final Integer PageSize = 2;

    @GetMapping("/page")
    public String page(HttpServletRequest request, Model model) {
     
        String bugTitle = request.getParameter("bug_title");
        String bugLevel = request.getParameter("bug_level");
        String testUsername = request.getParameter("test_username");
        String pageNumb = request.getParameter("pageNumb");
        Integer currPage = 1;
        if (pageNumb != null && !pageNumb.equals("")) {
     
            currPage = Integer.valueOf(pageNumb);
        }
        Page<BugTopic> page = bugTopicService.page(bugTitle, bugLevel, testUsername, currPage, PageSize);
        model.addAttribute("pager", page);
        model.addAttribute("bugTitle", bugTitle);
        model.addAttribute("bugLevel", bugLevel);
        model.addAttribute("testUsername", testUsername);
        return "bug/list";
    }

    @PostMapping("/addHandle")
    public String addHandle(BugTopic bugTopic) {
     
        bugTopicService.insert(bugTopic);
        return "redirect:/bug_topic/page";
    }

    @PostMapping("/editHandle")
    public String editHandle(BugTopic bugTopic) {
     
        System.out.println(bugTopic);
        bugTopicService.update(bugTopic);
        return "redirect:/bug_topic/page";
    }

}

service层

BugTopicService

package com.wanshi.service;

import com.wanshi.bean.BugTopic;
import com.wanshi.bean.Page;

import java.util.List;

public interface BugTopicService {
     

    Page<BugTopic> page(String bugTitle, String bugLevel, String testUsername, Integer currPage, Integer pageSize);

    void update(BugTopic bugTopic);

    void insert(BugTopic bugTopic);

    BugTopic get(Integer id);
}

BugServiceImpl 实现类

package com.wanshi.service.impl;

import com.wanshi.bean.BugTopic;
import com.wanshi.bean.Page;
import com.wanshi.mapper.BugTopicMapper;
import com.wanshi.service.BugTopicService;

import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class BugTopicServiceImpl implements BugTopicService {
     

    private BugTopicMapper bugTopicMapper;

    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");

    public void setBugTopicMapper(BugTopicMapper bugTopicMapper) {
     
        this.bugTopicMapper = bugTopicMapper;
    }

    public Page<BugTopic> page(String bugTitle, String bugLevel, String testUsername, Integer currPage, Integer pageSize) {
     
        Map<String, Object> maps = new HashMap<String, Object>();
        maps.put("bugTitle", bugTitle);
        maps.put("bugLevel", bugLevel);
        maps.put("testUsername", testUsername);
        Integer rowCount = bugTopicMapper.getTotal(maps);
        Page<BugTopic> page = new Page<BugTopic>(currPage, pageSize, rowCount);
        maps.put("currPage", page.getCurrPageFirstRowIndex());
        maps.put("pageSize", pageSize);
        List<BugTopic> bugTopicList = bugTopicMapper.page(maps);
        for (BugTopic bugTopic : bugTopicList) {
     
            bugTopic.setCreateTime(sdf.format(bugTopic.getCreate_time()));
        }
        page.setList(bugTopicList);
        return page;
    }

    public void update(BugTopic bugTopic) {
     
        bugTopicMapper.update(bugTopic);
    }

    public void insert(BugTopic bugTopic) {
     
        bugTopicMapper.insert(bugTopic);
    }

    public BugTopic get(Integer id) {
     
        BugTopic bugTopic = bugTopicMapper.get(id);
        bugTopic.setCreateTime(sdf.format(bugTopic.getCreate_time()));
        return bugTopic;
    }
}

mapper层

BugTopicMapper

package com.wanshi.mapper;

import com.wanshi.bean.BugTopic;

import java.util.List;
import java.util.Map;

public interface BugTopicMapper {
     

    List<BugTopic> page(Map<String, Object> maps);

    void update(BugTopic bugTopic);

    void insert(BugTopic bugTopic);

    BugTopic get(Integer id);

    Integer getTotal(Map<String, Object> maps);
}

BugTopicMapper.xml


DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wanshi.mapper.BugTopicMapper">

    <select id="page" resultType="com.wanshi.bean.BugTopic">
        SELECT bug.*, user.`realname` testUsername FROM t_bug_topic bug JOIN t_user1105 USER ON user.id = bug.test_user_id
        <where>
            <if test="bugTitle != null and bugTitle != ''">
                bug_title like concat('%',#{bugTitle},'%')
            if>
            <if test="bugLevel != null and bugLevel != ''">
                and bug_level = #{bugLevel}
            if>
            <if test="testUsername != null and testUsername != ''">
                and test_user_id = (SELECT u.`id` FROM t_user1105 u WHERE realname LIKE concat('%',#{testUsername},'%'))
            if>
        where>
        limit #{currPage}, #{pageSize}
    select>

    <insert id="insert">
        insert into t_bug_topic (bug_title, bug_detail, bug_level,test_user_id)
        values (#{bug_title}, #{bug_detail}, #{bug_level}, #{test_user_id})
    insert>

    <update id="update">
        update t_bug_topic
        <set>
            <if test="bug_title != null and bug_title != ''">bug_title = #{bug_title},if>
            <if test="bug_detail != null and bug_detail != ''">bug_detail = #{bug_detail},if>
            <if test="bug_level != null and bug_level != ''">bug_level = #{bug_level},if>
            <if test="test_user_id != null and test_user_id != ''">test_user_id = #{test_user_id},if>
            <if test="bug_status != null and bug_status != ''">bug_status = #{bug_status},if>
            create_time = now()
        set>
        where id = #{id}
    update>

    <select id="get" resultType="com.wanshi.bean.BugTopic">
        SELECT bug.*, user.`realname` testUsername FROM t_bug_topic bug JOIN t_user1105 USER ON user.id = bug.test_user_id where bug.`id` = #{id}
    select>

    <select id="getTotal" resultType="int">
        select count(*) from t_bug_topic
        <where>
            <if test="bugTitle != null and bugTitle != ''">
                bug_title like concat('%',#{bugTitle},'%')
            if>
            <if test="bugLevel != null and bugLevel != ''">
                and bug_level = #{bugLevel}
            if>
            <if test="testUsername != null and testUsername != ''">
                and test_user_id = (SELECT u.`id` FROM t_user1105 u WHERE realname LIKE concat('%',#{testUsername},'%'))
            if>
        where>
    select>

mapper>

项目源码就分享到此,由于文件太多,本博客只介绍核心类,若对本项目感兴趣的老铁,可在下方链接获取完整项目

结语

本博客到此结束,系统还是有些逻辑性的,建议多练习,巩固知识,提示自己的逻辑思维能力

完整项目链接:基于SSM框架软件测试管理系统

提取码: jg3f

有任何问题均可在评论区留言或私信我

只求您能留下您宝贵的足迹,等啥呢,都看到这啦,还不来个一键三连嘛(收藏+关注+评论

感谢您的支持,我们下篇见~

你可能感兴趣的:(SSM阶段项目练习,mvc,架构,java,后端)