目 录
1 需求分析........................................................ 1
1.1 用例图.................................................... 1
1.2 用例说明.................................................. 1
1.3 对功能的一般性规定........................................ 2
1.4 运行环境.................................................. 2
1.5 运行方式.................................................. 2
2 软件设计........................................................ 3
2.1 概要设计.................................................. 3
2.1.1 功能结构.............................................. 3
2.1.2 功能点设计............................................ 3
2.1.3 技术路线.............................................. 3
2.1.4 开发环境.............................................. 4
2.1.5 领域模型.............................................. 4
2.1.6 故障处理说明.......................................... 4
2.2 数据库设计................................................ 5
2.2.1 概念模型.............................................. 5
2.2.2 物理模型.............................................. 5
3 软件实现........................................................ 7
3.1 架构实现.................................................. 7
3.2 领域模型层................................................ 8
3.3 数据访问层................................................ 9
3.4 表现层................................................... 10
4 软件测试....................................................... 18
4.1 测试环境................................................. 18
4.2 测试需求................................................. 18
4.3 测试用例设计............................................. 18
4.4 测试脚本................................................. 18
4.5 结果分析................................................. 19
4.6 测试结论................................................. 20
一、需求分析
1.1用例图
管理教材数据,包括查询、增加、修改、删除,用例如图1.1所示。
1.2用例说明
编号约定:SRS为软件需求规格说明的缩写,F表示功能性需求,xxx为功能点序号。
1)查询教材(编号:SRS-F-001)
根据教材名称进行模糊查询,返回包含查询关键字所有教材列表。
2)添加教材(编号:SRS-F-002)
为添加教材填写各类信息,包括书名、出版社、ISBN等,系统根据ISBN检查教材是否存在,如果不存在则保存改教材。活动图如图1.2所示。
3)修改教材(编号:SRS-F-003)
修改指定教材的相关信息,保存后应更新当前教材列表,活动图如图1.3所示。
4)删除教材(编号:SRS-F-004)
选取待删除教材,执行删除操作后更新教材列表。
1.3对功能的一般性规定
人机交互界面应简洁、大方,操作步骤应直观、清晰,给出相应操作状态提示和错误信息。
1.4运行环境
操作系统:Windows10及以上;数据库:SQL Server 2016;CPU:Intel 或AMD 等支持X86指令集的处理器。
1.5运行方式
桌面应用程序,无需联网即可使用全部功能。
二、软件设计
2.1概要设计
2.1.1功能结构
本软件功能结构如图2.1所示。
2.1.2功能点设计
本系统的功能模块清单如表2.1所示。
表2.1 功能清单
编号 | 名称 | 功能描述 | 需求追踪 |
SDS-F-001 | 查询 Get | 查询教材,支持教材名称的模糊查询 | SRS-F-001 |
SDS-F-002 | 添加 Add | 新增单册教材 | SRS-F-002 |
SDS-F-003 | 修改 Modify | 修改已有单册教材信息 | SRS-F-003 |
SDS-F-004 | 删除 Remove | 删除已有单册教材 | SRS-F-004 |
2.1.3技术路线
整体采用分层结构,逻辑架构如图2.2所示。表现层(Presentation Layer)处理数据输入、结果呈现与交互逻辑,数据访问层(Data Access Layer)负责存取DBMS数据,领域模型层负责业务模型、数据访问接口。
2.1.4开发环境
软件环境:操作系统:Windows 10;集成开发环境IDE:Visual Studio 2022;数据库:SQL Server Express 2016;
硬件环境:处理器:Intel i5-12500H;内存:8G;磁盘:512G。
2.1.5领域模型
本项目只有一个业务类Book,如图2.3所示。属性包括作者Author、主键Id、版次Isbn、出版社Press、价格Price、书名Title。
2.1.6故障处理说明
采用弹窗处理操作状态与提示错误消息。
2.2数据库设计
2.2.1概念模型
1)实体-关系图
实体-关系图如图2.4所示。
2)实体描述
每本教材的信息,包括有教材ID,教材名字,教材作者,教材出版社,教材版次,教材价格。其中ID是为区别每本教材所设计的。
3)关系描述
由于本系统只有一个教材实体,故无与其它实体存在联系。
2.2.2物理模型
1)表设计
根据SQL SERVER,数据库物理模型结构如图2.5所示。
教材表定义见表2.2。
表2.2 Book表
字段 | 类型 | 字段说明 | 是否可空 |
Id | Int | 教材ID(主键) | NO |
Title | Nvarchar(MAX) | 教材名字 | NO |
Author | Nvarchar(MAX) | 教材作者 | NO |
Press | Nvarchar(MAX) | 教材出版社 | NO |
Isbn | Nvarchar(MAX) | 教材版次 | NO |
Price | Float | 教材价格 | NO |
2)数据库账号及权限说明
数据库命名为BookDB,采用SQL Server身份验证登陆到数据库。指定账号登陆后可以对本数据库和其相关内容进行管理。
三、软件实现
3.1架构实现
实现采用.Net Framework技术栈,表现层采用windows窗体WinForms,DAL层采用Entity Framework。实现架构如图3.1所示。
解决方案整体结构如图3.2所示,包含4个项目。Domain对应领域模型层,包括教材类、数据访问接口;SqlServerRepository对应数据访问层,采用SQL SERVER实现数据访问;Winforms对应表现层,提供人机交互界面以及消息弹窗;SqlServerRepository.Test为数据访问层的单元测试。
3.2领域模型层
为直接比较教材对象,Book实现了相等比较接口IEquatable,Equals方法执行判定逻辑,Id相等则视为同一本教材。
IRepository为泛型数据访问接口,定义了通用的数据访问方法,包括依据Id查询单个对象Get,查询全部对象GetAll,添加对象Add,修改对象Modify,删除对象Remove。
表3.1 IRepository接口说明
类名称 | IRepository | ||||
父接口 | 无 | ||||
功能描述 | 通用数据访问方法 | ||||
函数 | 函数名 | 参数 | 参数类型 | 参数描述 | 返回值 |
获取全部对象信息 | GetAll() | 无 | 无 | 无 | List |
根据Id查询单个对象信息 | Get(int id) | Id | Int | 对象的Id | T |
添加对象 | Add | T | 泛型 | 对象 | Bool |
修改对象信息 | Modify | T | 泛型 | 对象 | Bool |
删除对象 | Remove | T | 泛型 | 对象 | Bool |
IBookRepository是IRepository在Book类上的实例化,用Book类替换上表中的泛型T,即针对Book的数据访问接口。IBookRepository还可以定义专用方法,如依据出版社查询、根据出版日期查询等。
接口IBookRepository和IRepository共同构成数据访问接口IDAL,实现数据访问行为与具体DAL之间的隔离,使得上层只依赖于IDAL操作数据。假设将SQL SERVER更换为MySQL,上层代码无需知道DAL变更的事实。
3.3数据访问层
SqlServerRepository层实现了IBookRepository,支持Sql Server操作。采用Entity Framework实现对象关系映射ORM(Object/Relational Mapping),建立业务类与数据记录之间的映射。创建数据上下文类MsSqlContext,该类继承DbContext,DbContext、DbSet<T>、T分别对应数据库、数据表、数据记录,本例中T为Book。重写MsSqlContext的方法OnModelCreating,通过BookInitiliazer类的Seed方法实现初始化数据记录。
其中Seed方法代码为:
OnModelCreating代码为:
App.config配置数据库连接字符串,如下图所示。
3.4表现层
1)整体布局
采用单个窗体实现,整体界面如图3.8所示。
2)查询教材
UI包括两个部分,关键字输入与结果列表,分别采用Textbox、Button与DataGridView,查询关键字由Textbox输入,Button的click事件处理模糊查询逻辑,DataGridView显示结果列表。
模糊查询Button点击事件代码:
<hc:SearchBar Style="{StaticResource SearchBarExtend}"
Width="380" Margin="10 0 0 0"
Command="{s:Action Query}"
Text="{Binding Keyword}"
hc:InfoElement.Placeholder="请输入教材名称"
hc:InfoElement.TitleWidth="60"
hc:InfoElement.Title="教材名称"
hc:InfoElement.TitlePlacement="Left" />
<Button x:Name="BtnQuery" Margin="10 0 0 0"
Content="查询" Foreground="Black" Background="White" hc:IconElement.Geometry="{StaticResource SearchGeometry}"
Command="{s:Action Query}" />
3)添加教材
UI包括DataGridView以及一组Textbox和Button。通过在下方输入教材的各种信息,点击添加可将书籍添加至数据库中。
添加成功后给出消息弹窗。
添加后即可查询
4)修改教材
通过DataGridView的CellClick事件处理选中教材并展示教材详细信息,Textbox显示教材属性,此时可进行编辑,保存Button的Click事件处理存储逻辑。
修改单价为55
修改教材事件代码:
/// <summary>
/// 新建教材
/// Create a new book
/// </summary>
public void Add()
{
var view = _container.Get<ModifyBookViewModel>();
view.SelectedBook = new Book();
view.RefreshBooks = Query;
_windowManager.ShowDialog(view);
}
/// <summary>
/// 根据id修改教材属性
/// Modify book property value depends on its id
/// </summary>
/// <param name="id"></param>
public void Modify(int id)
{
var book = Books.FirstOrDefault(t => t.Id == id);
var view = _container.Get<ModifyBookViewModel>();
view.SelectedBook = book;
view.RefreshBooks = Query;
_windowManager.ShowDialog(view);
}
/// <summary>
/// 根据id删除教材
/// Remove book depends on its id
/// </summary>
/// <param name="id"></param>
public void Remove(int id)
{
var book = Books.FirstOrDefault(t => t.Id == id);
var message = $"确定删除 {book.Author} 的 {book.Title} 吗?";
var result = _windowManager.ShowMessageBox(message, "提示",
MessageBoxButton.OKCancel, MessageBoxImage.Warning);
// 如果是确定,就执行下面代码,记得换上自己的代码喔
if (result == MessageBoxResult.OK)
{
_repository.Remove(book);
Query(new FunctionEventArgs<int>(1));
}
}
UI控件显示教材属性信息的方法
<DataGridTextColumn Header="编号" Foreground="Red" Width="60" Binding="{Binding Id}"/>
<DataGridTextColumn Header="书名" Width="300" Binding="{Binding Title}"/>
<DataGridTextColumn Header="作者" Width="120" Binding="{Binding Author}"/>
<DataGridTextColumn Header="出版社" Width="120" Binding="{Binding Press}"/>
保存成功后给出弹窗提示。
点击弹窗后,刷新DataGridView。
5)删除教材
删除Button的Click事件处理删除逻辑,先给出提示是否确定删除,删除后更新DataGridView。
删除时确认弹窗代码为:
删除Button事件代码:
删除后刷新DataGridView。
四、软件测试
本系统是对教材的管理,用户可以增加教材,删除教材,查询全部教材或者查询特定教材,还可以修改教材,在查询时,用户可以根据教材某信息进行模糊查询,如根据版号,名称等,并将结果显示到页面上。
4.1测试环境
软件环境:操作系统:Windows 10;集成开发环境IDE:Visual Studio 2022;数据库:SQL Server Express 2016;单元测试框架:MsTest。
硬件环境:处理器:Intel i5-12500H;内存:8G;磁盘:512G。
4.2测试需求
根据接口IBookRepository,对数据访问类SqlServerRepository实施测试。
4.3测试用例设计
表4.1测试用例说明
编号 | 用例名称 | 测试需求 | 输入 | 前置条件 | 预期输出 |
1 | Add_Book_CountIncreaseOne | 添加教材 | book对象 | 无 | true |
2 | Remove_Book_CountDecreaseOne | 删除教材 | Id=1 | DB存在Id=1的教材 | true |
3 | Modify_Title_AreEqual | 修改教材 | Title=input | DB存在Id=1的教材 | 修改前后Title不同 |
4 | FindAll_None_CountGreatThanOne | 查询全部教材 | 无 | DB至少存在一本教材 | 返回记录>=1 |
5 | FindById_One_InstanceOfBook | 依据id查询教材 | Id=1 | DB存在Id=1的教材 | 结果对象为教材 |
4.4测试脚本
根据上表,使用Visual Studio2022内置单元测试框架MsTest编写测试脚本,以下为Add_Book_CountIncreaseOne的代码。
4.5结果分析
从测试结果来看,系统的各个接口都能正常运行,增删查改功能完好;测试结果如图4.2所示。
4.6测试结论
覆盖了大部分测试需求,但没有达到测试覆盖率百分百。为提高充分性,可增加测试对象,如Book的Equals方法,或增加覆盖率,如为SqlServerRepository设计更多用例。