开发团队成员
阎覃 张雪
竹间社团是一款面向高校社团管理的移动应用软件。
针对目前高效社团管理混乱,效率低下,社团活动推广困难,商家赞助不能有效对接等问题,竹间社团设置有社团管理、活动管理、商家管理等功能,构建了学生—社团—商家—学生,三者的闭环系统,为高效、有效地管理社团提供了专业的服务平台。
竹间社团极大地提高了社团管理的效率,解决了目前许多社团管理的难点,记录并培养了社团文化,打造了一个生态化的校园社团服务平台,拓宽了活动宣传渠道,让大学社团生活更加丰富多彩,同时也为商家带来丰厚的商业机遇。
从项目自身的市场调研现状、技术现状两个方面进行分析。
通过对10余所高校(各层次)学生的调研,大学生广泛参与社团活动,平均一个大学生加入1.17个社团。同时,通过对豌豆荚,安卓市场,百度应用等主流APP市场的检索,目前市场上针对于校园社团的APP大概有近20种。不过都着力于社团活动资讯的整合。目前市场上尚缺乏专业的高校社团管理类移动客户端。高校社团目前依托QQ群、微信群来进行线上交流管理,存在通知不及时,社团资料流失,活动推广困难等问题。
UI设计遵循谷歌官方的Material Design,这种设计遵循着优秀设计的经典原则,同时伴随着创新理念。在用户界面上使用实体材质,实体的表面和边缘提供基于真实效果的视觉体验,熟悉的触感让用户可以快速地理解和认知。[1]另外,界面设计并不是单纯的静态效果,动画效果可以有效地暗示、指引用户。通过动效,让物体的变化以更连续、更平滑的方式呈现给用户,让用户能够充分知晓所发生的变化。
客户端使用Java作为开发语言,运行于Android系统上。Android是一个基于Linux内核的开放源代码移动操作系统。根据最新的调研分析,Android系统的市场份额已经远远超过苹果的IOS系统,成为第一大移动操作系统[2]。Google为开发者提供了一整套的技术支持,包括开发工具包、开发文档、应用程序接口(API),开发样例等[3]。除此之外,基于Android系统的流行和开源社区的强大力量,开发者可以集成许多成熟稳定的框架,如网络操作、缓存处理、数据解析等。Android支持库(Support Library)提供了诸多未内置于框架的功能[4],其中包括了Material Design 组件和模式。通过站在巨人的肩膀上,开发者可以仅仅关心软件的业务核心,避免了重复的底层设计。
尽管开发过程中做了许多测试,但是总会有一些漏洞会导致程序的崩溃和闪退。腾讯Bugly为移动开发者提供专业的异常上报和运营统计,将用户的错误日志上传至服务器,帮助开发者快速发现并解决异常。目前这项技术已经运用在QQ、微信、迅雷等软件中[5]。Tinker是腾讯推出的一个开源的Android平台的热更新修补方案,开发者可以通过热更新在线修复软件出现的一系列紧急BUG,只要软件联网,就会接收到开发者推送的升级补丁,如图 1‑1。
图 1‑1 热更新示意图
客户端使用Git作为版本控制工具,在Github网站托管源代码。Git是一个分布式版本控制软件,可以保存代码的每次迭代,控制版本的分支,从而更好地辅助代码管理、团队合作开发和版本迭代更新。
客户端和服务端的通信采用RESTful架构,使用HTTPs协议,使用OAuth2.0进行授权认证。RESTful架构是目前最流行的一种互联网软件架构。它结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用。通过使用HTTPs协议,所有信息都是加密传播,第三方无法窃听,具有校验机制,一旦被篡改,通信双方会立刻发现。OAuth是一个关于授权的开放网络标准,在全世界得到广泛应用。
客户端运行于Android系统,最低支持Android 4.0,最高可以支持最新的Android系统。客户端可以运行于市场上99.1%的Android手机。[6]
开发工具使用Android Studio。系统使用macOS Sierra和Windows 10。
系统使用MVVM(Model-View-ViewModel)架构,采用谷歌官方的DataBinding框架实现[7]。通过数据的双向绑定,开发者无需处理视图层与模型层的数据更新。如图 1‑2。
图1‑2 MVVM示意图
-
文件扩展名为.java,编码为UTF-8。
-
import语句不使用通配符。
-
花括号的开始不换行。
-
每行代码不超过100字符。
-
方法体内,语句按照逻辑分组,以空行隔开。
-
类的连续成员(字段,方法,内部类等)以空行隔开。
-
包名为小写单词。
-
类名采用大驼峰式命名。
-
字段,变量采用小驼峰式命名。
-
常量使用大写字母,单词间用下划线分隔。
-
类的非静态成员变量使用m作为前缀。如mUserName。
-
类的静态成员变量使用s作为前缀。如sUserName。
-
布尔类型变量使用Is作为前缀。如mIsLogin。
-
Activity类需要以Activity作为后缀。例如MainActivity。
-
Fragment类需要以Fragment作为后缀。例如UserFragment。
-
BroadcastReceiver类需要以Receiver作为后缀。例如MsgReceiver。
-
Adapter类需要以Adapter作为后缀。例如ClubAdapter。
-
公共基础类需要以Base作为前缀。例如BaseActivity。
-
测试类需要以Test作为后缀。例如LoginTest。
-
命名采用小写,单词间用下划线隔开。
-
Activity的布局文件以activity作为前缀。例如activity_main.xml。
-
Fragment的布局文件以fragment作为前缀。例如fragment_user.xml。
-
自定义View需要以view作为前缀。例如view_schedule.xml。
-
列表项目的布局文件需要以item作为前缀。例如item_club.xml。
-
控件的ID以类型缩写为前缀。例如iv_avatar,tv_username。
-
命名采用小写,单词间用下划线隔开。
-
背景以bg为前缀。
-
按钮以btn为前缀。
-
图标以ic为前缀。
从用户角度分析,一共有五种使用者:未登录用户,已登录用户(简称用户),社团成员,社团管理员,社长。用户的角色并不是固定的,根据用户的状态不同,对应的角色也会不同。如图 2‑1。
图 2‑1用户状态转换图
例如当用户创建了一个社团,他就是社团创建者。当用户新加入一个社团,他就是社员。社团创建者可以为社员提升权限,成为管理员,也可以将管理员的权限降低成社员。创始人也可以将社团转让给社员,那么被转让的社员就成为了创始人,拥有社团的最高权限,而原来的创始人则成为普通社员。
将使用者按照权限从低到高排列为:未登录用户,用户,社团成员,社团管理员,社团创建者。随着权限的提高,用户可使用的功能就越多。高权限的用户也继承了低权限用户的功能。
系统用例图详细的介绍了针对每一种使用者的需求,如图 2‑2所示。未标明使用身份的用例默认为已登录用户。
图 2‑2 系统用例图
从用户界面的角度分析,系统分为三大模块:发现、社团、我的。这三大模块共同构成用户的主界面,通过底部导航相互切换。每个模块又可以细分为若干子模块,如图 2‑3所示。
图 2‑3 系统层次图
系统的架构如图 2‑4 系统架构图所示。
图 2‑4 系统架构图
整套系统由下至上分为系统层、基础层、组件层和应用层。其中,系统层、基础层、组件层以及应用层中的部分视图层使用开源项目或谷歌的官方项目,程序实现的主要目标在于数据层和业务逻辑层。
通过分析系统用例图和系统层次图,可以得到系统在业务逻辑上的详细架构。系统分为10个子系统,在源代码中以这10个子系统作为第一级目录。
主系统包括所有子系统的公共基础类,维护整个系统的生命周期,存储整个系统的全局变量,监控整个系统的统计日志和错误日志,还包括刚启动时的欢迎界面和主界面。
网络子系统封装了与服务器通信的API,包括一般请求和OAuth请求。
工具包括所有子系统可能用到的工具类。例如图像的加载和处理、文本数字操作、文件处理、时间格式化、界面操作等。
用户子系统处理的是和用户相关的逻辑。包括登录、注册、用户资料的查看和修改、收藏。
课程表包括课程表展示界面和控件、课程表爬取、空课表统计。
社团包括社团活动列表、创建社团、修改社团、解散社团、查看社团详情、查看社团成员、查看我的社团、发布社团通知、社团操作界面等。
发现包括发现主界面、发现社团、发现活动、发现商家。
活动包括创建活动、查看活动详情、修改活动。
消息包括消息的解析、接收推送、社团通知详情、消息列表界面、社团通知统计。
设置包括退出登录、软件更新和关于。
按钮按下时产生涟漪动画。
卡片按下时产生上升动画。
下拉刷新时产生旋转等待动画。
图片加载产生载入渐显动画。
列表的载入设置渐显动画。
某些ViewPager滑欢迎动时,指示器设置贝赛尔曲线动画。
FAB与列表设置协调动画:列表上拉时隐藏,下拉时显示。
对于所有的SnackBar和FAB,设置协调动画:产生SnackBar时上浮FAB,反之下降。
对于部分的Toolbar和列表设置协调动画:列表下拉时隐藏,上拉时显示。
某些Activity进行切换时设置场景转换动画。
系统第一次启动时,进入欢迎页面,展示一张欢迎图片,停留两秒钟后进入主界面。
在主界面中,底部是一个导航栏,分为三项:发现,社团,我的。点击每个按钮后均可跳转至相应模块。模块与模块之间的切换依照Material Design标准,使用渐显渐隐和移动动画。若用户已经处于某模块,再次点击相应模块的按钮,则请求刷新当前模块的数据。
每次显示主界面时都要检测刷新位是否被置位,若相关刷新位置位则请求数据刷新和界面更新。
每次显示主界面时动态创建推送接收器,以便配合推送处理界面业务逻辑。
用户未登录时,可以浏览“发现”模块,查看所有的活动,社团和商家。但是无法浏览活动详情。若用户触发某些限制操作则提示需要登录。
用户可以使用用户名,密码进行登录。若所输入的手机号与密码不匹配,界面下方提示用户名或密码错误。
用户可点击登录界面中的“立即注册”按钮,进行新用户注册。用户注册前需填入有效手机号,以获取验证码。点击“发送验证码”按钮,在界面显示的倒计时一分钟内,将会收到来自掌淘科技发送的竹间社团验证码。将短信中的验证码输入到注册界面的验证码栏,点击“下一步”按钮进入注册界面。用户需在第一栏输入昵称,在第二栏输入密码,点击“注册”按钮即可注册成功。
“我的”模块展示了用户的头像和昵称。下方有四个按钮:消息通知,基本信息,时间管理,我的收藏。其中,消息通知右侧有一个安放红点的位置,当未读消息数量大于0时则显示红点。同时在底部导航栏也显示相同的红点。本模块设置了两个刷新位:用户资料刷新和未读消息刷新。当对应的资料被更新时,置刷新位,以便下次访问界面时采取刷新策略。右上角有一个设置按钮。
界面以卡片列表形式显示了用户的所有消息通知,每项包括头像,社团名称,发布通知时间及内容。向左滑动可以选择删除。
消息通知分为若干类,如表格 3‑1所示。社团通知是一个社团的管理员或社长发布的通知,所有社团成员都可以接收到。用户点击社团通知后,打开社团通知详情,并且在后台上报通知已阅,在此界面上方为社团头像,名称,通知发布时间以及发布者,下方为通知的详细内容。
若用户是某个社团的管理员或者社长,则会接收到申请加入的请求。点击请求后可以进行处理,即通过、拒绝或忽略。
用户还会收到其他通知,如社团解散,加入社团通过,社团权限变动等等。
表格 3‑1 推送类型表
type | club | sender | receiver | title | content | image |
---|---|---|---|---|---|---|
0社团通知 | 社团名 | 管理员 | 社团成员 | 通知标题 | 通知内容 | 社团头像 |
1申请加入 | 社团名 | 申请者 | 管理员 | 加入理由 | 申请者头像 | |
2申请结果 | 社团名 | 管理员 | 申请者 | 社团头像 | ||
3踢出 | 社团名 | 社长 | 被踢出者 | 社团头像 | ||
4退出社团 | 社团名 | 退出者 | 管理员 | 退出者头像 | ||
5解散社团 | 社长 | 所有成员 | 社长头像 | |||
6系统通知 | 所有人 | 通知标题 | 通知内容 | 默认头像 | ||
7权限变更 | 社团名 | 社长 | 变更者 | 权限变更 | 新权限名 | 社团头像 |
8社团转让 | 社团名 | 所有成员 | 社团转让 | 新社长的昵称 | 社团头像 |
程序在后台接收服务端推送。当接收到推送时,首先置刷新位,以便下次用户前往主页面时请求获取最新未读消息数量。若用户当前的界面就是主界面,则自动获取最新未读消息数量。若用户当前界面是消息通知界面,则自动刷新查看最新的消息。所有消息都会在通知栏显示,标题和内容按照表格 3‑2 推送解析表解析。用户可以对每一条通知表示触发已阅操作,消息已阅后会在通知栏删除对应的通知,并且上报服务端消息已阅。每一种消息触发的规则如表格 3‑3所示。
表格 3‑2 推送解析表
type | title | 生成标题 | 生成内容 | 动作 |
---|---|---|---|---|
0社团通知 | [通知]club | title | ||
1申请加入 | 待审核 | [申请]club; | SenderName申请加入社团content | |
接受 | 已经批准了 SenderName的加入请求 | |||
拒绝 | 已经拒绝了SenderName的加入请求 | |||
2申请结果 | 待审核 | [已提交]club | 您加入社团的申请已经提交 | |
接受 | [同意]club | 管理员已经批准了你的申请 | 刷新社团列表 | |
拒绝 | [拒绝]club | 管理员拒绝了你的申请 | ||
3踢出 | [通知]club | 您已被社长请出社团 | 刷新社团列表 | |
4退出社团 | [通知]用户退出社团 | SenderName已经退出社团club | ||
5解散社团 | [通知]社团已解散 | 社长已经解散社团content | 刷新社团列表 | |
6系统通知 | 保留 | 保留 | 保留 | |
7权限变更 | [权限变更]club | 社长变更了你的权限:content | 刷新社团列表 | |
8社团转让 | [社团转让]club | 社长转让了社团:content | 刷新社团列表 |
注1:若用户填写了姓名,SenderName为“昵称(姓名)”,否则只显示昵称。
注2:所有通知都会触发共同的动作,表上已注明某些通知会触发其他的动作。
表格 3‑3 触发已阅条件表
type | 触发动作 |
---|---|
0社团通知 | 点击查看通知详情 |
1申请加入 | 通过或拒绝 |
2申请结果 | 进入消息通知列表 |
3踢出 | |
4退出社团 | |
5解散社团 | |
7权限变更 | |
8社团转让 | |
6系统通知 | 保留 |
用户登录后可以查看自己的资料,并且可以修改。头像可以拍照和从相册选择,然后进行裁剪,最终上传500*500的jpeg图片。其他资料包括昵称、姓名、性别、学号、生日以及自我介绍。资料的保存分成两次请求,第一次上传图片,第二次上传其他资料。
系统中所有涉及图片上传的操作都采用相同的处理方案,只不过图片的比例和大小随着不同的要求而不同。
用户可以通过时间管理查看自己的课程表。当用户没有导入过课程表时,系统会提示用户导入课程表,用户可点击界面上方工具栏右侧图标按钮进入导入课程界面。在此界面中,用户需根据提示填写学号、教务系统密码,即可开始进行课表导入,并且界面会提示用户课表下载进度,系统自动将Html解析后上传至服务器,然后提示用户选择当前的学年学期,用户选择当前学期后即可查看课程表。
课程表界面显示用户当前学年学期课表。若用户进入时间管理界面时,已上传过个人课表,则直接进入课表界面。用户可选择当前周,重新导入教务系统的课程,修改当前学年学期。
所有点过赞的活动都在我的收藏中。所有的界面复用发现活动中的界面。
设置界面通过“我的”模块右上角的按钮进入。
在“发现”模块,用户可以进行搜索,当输入超过两个字符时,展开搜索补全。搜索范围如表格 3‑4所示。
表格 3‑4 搜索的内容
模块 | 搜索范围 |
---|---|
活动 | 活动名、活动简介 |
社团 | 社团名称、社团简介、标签 |
商家 | 商家名称、赞助类型、赞助活动 |
在列表向上滑动时,隐藏顶部工具栏和底部的导航栏,向下滑动时显示。
发现活动列表以卡片列表形式显示了所有社团举办的所有活动。每项包括有活动名称,活动简介,点赞数以及最后一次编辑时间。列表中有两种活动,一种是普通活动,一种是精品活动。精品活动有几处不同:第一,第一个精品活动在列表中永远处于第一项。第二,背景图片较大。第三,进入详情后会展示全屏幕大小的海报。精品活动和普通活动的判定标准由服务端决定,客户端只负责分类展示。
进入活动详情后,首先延时0.5s后在后台下载海报。图片下载完毕后,将工具栏展开,附带动画效果,展开的高度为全屏幕或部分屏幕,取决于活动种类。这样做是为了提示用户工具栏可以上下拉动。在海报下方显示活动名称以及发布该活动的社团头像、名称,最后一次编辑时间,点赞数等。用户可以点击界面右下角的心形按钮点赞,同时被赞活动将收藏到“我的收藏”中。上拉宣传海报,进入该活动的详情界面,包括活动名称,活动标签,时间,地点以及活动的图文介绍。
发现社团列表以卡片形式分两列展示出了本校所有的社团,每项显示了该社团的头像,社团名,成员数量,基本资料以及标签。点击社团后进入社团详情界面。
社团详情界面上方是社团头像及社团名称,下方以卡片列表形式,由上至下依次显示了社团的基本资料,联系方式以及社团活动。其中,用户可以滑动浏览社团活动,并且点击活动进入查看活动详情,活动详情界面和发现活动中的活动详情界面相同。
右下角的FAB是加入社团按钮,点击后提示输入加入理由,确定后即送出加入请求,同时会收到系统的通知,提示用户已经提交申请。
发现商家列表以卡片形式分两列展示出了愿意提供赞助的所有商家,每项显示了该商家的图片,商家名,赞助方式,赞助活动范围以及商家评分星级,点击商家后,显示提示信息,列出了商家联系电话及其地址。用户可点击“拨打电话”按钮,界面跳转到拨号页面。
用户可以在“社团”模块看到自己加入的所有社团,界面以卡片形式分两列展示出了用户所加入的所有的社团,包括每个社团的头像及社团名。右下角的FAB是一个菜单,可以通过这个菜单加入社团和创建社团。
若用户点击加入社团,则界面跳转到发现板块中的社团模块。
若用户点击创建社团,则进入创建社团界面。在此界面中,用户根据提示信息需由上至下填写:社团名称,社团简介,负责人联系方式。填写完毕后,点击界面右下方FAB即可成功创建社团。创建社团后会自动刷新我的社团列表。
点击社团列表中自己加入的社团,即可进入社团操作面板。此界面中,上方圆形图片为社团头像,头像下方的文字,左侧为社团名称,右侧为用户在社团中的职位。界面以卡片形式列出了社团管理的基本功能,包括社团简介,成员列表,活动列表,社团通知,招新管理,空课表,解散社团,退出社团。可左右滑动浏览选择。每个卡片的显示与否有一定的前提,动态加载。如表格 3‑5所示。
表格 3‑5 社团操作面板布局表
位置 | 操作 | 显示前提 |
---|---|---|
左侧 | 社团简介 | 无 |
成员列表 | 无 | |
活动列表 | 无 | |
社团账单(保留) | 不显示 | |
社团通知 | 无 | |
右侧 | 招新管理 | 权限位5 |
空课表 | 权限位3 | |
退出社团 | 非社长 | |
解散社团 | 社长 |
社团的权限采用二进制位控制,如图 3‑1 用户权限位示意图。使用一个32位整数存储社团成员的权限。若某一位为1,则表示此社员拥有某项权限。这样就可以支持不同的用户组拥有不同的权限。目前系统暂时不加入用户组功能,服务端硬编码每个社团只有社长、管理员和社员,管理员的权限为0xFFFFFFFF。系统对相应的功能进行保留以便未来进行功能扩展。
图 3‑1 用户权限位示意图
客户端在某些管理界面通过探测权限位来处理相应按钮,视图的显示与隐藏。服务端通过探测权限位来二次检验相应操作是否合法,从而保证每项操作均符合用户的权限。
社长是一个特殊的存在,与管理员不同,社长是一个社团的创始人,权限位始终为0xFFFFFFFF。除此之外,还具有一些其他权限。
用户点击社团操作面板中的社团简介后,进入社团简介界面。本界面和发现社团中的社团详情相同。
若用户具有权限位1,则在工具栏中显示修改资料按钮。点击按钮进入修改社团资料界面。用户可点击圆形图片对社团头像进行修改,上传500*500的jpeg图片。用户可在修改资料界面根据提示修改社团简介,社团标签以及负责人联系方式。资料的保存分为三部分进行,第一次上传图片,第二次上传标签,第三次上传其他资料。
用户点击社团操作面板中的成员列表后,进入社团通讯录界面。此界面以列表形式显示了本社团内的成员信息,包括成员的头像,姓名,职位以及昵称。点击成员名片,进入查看成员详情,此界面包括有头像,手机号码,昵称,姓名,性别,学号,生日以及自我介绍等个人信息。
社长可以向左滑动除了自己以外其他成员的名片,执行社长特权:授权,转让,开除。若点击授权,可以选择授权的用户组;若点击转让,则将社团转让给该成员并将该成员身份设置为社长,自己将成为普通社员,成功后跳转回主界面,并刷新社团列表;若点击开除,可以将该成员开除,移出本社团。无论执行哪个操作,成功后均会刷新成员列表,获取最新的成员资料。
用户点击社团操作面板中的活动列表后,进入社团活动列表界面。本列表界面复用自发现活动界面。
若用户具有权限位6,则显示FAB。用户点击界面右下方的FAB可显示菜单,菜单包括创建活动和修改活动。
若用户点击创建活动,则进入创建活动界面。用户可根据提示信息由上至下依次填写活动名称,参加人数上限,活动时间,活动地点以及活动简介等信息。填写活动时间时,点击后界面跳转出日历供用户选择日期,选定日期后点击确定,界面跳转至时间供用户选择具体时间,选定后点击确定即可。全部信息填写完后点击界面右下角的浮动按钮创建成功。
若用户点击修改活动,则界面提示用户进入修改模式,并将Toolbar变为黄色,选择活动后进入修改活动界面,用户可根据提示在此界面内修改相关信息。其中图片有两张,分别为首页图片和精品活动海报。首页图片的大小为1080720,精品活动海报大小为7201080。保存资料时分为四步:首页图片,精品活动海报,活动标签和其他信息。
用户点击界面右下角的FAB,显示菜单,菜单包括删除活动和上传活动内容功能。若用户点击删除活动,确认后成功删除该活动。若用户点击上传活动内容,则进入上传活动内容界面,用户点击右下角浮动按钮选择上传图片,图片的大小为1080*720,图片选择完毕后输入图片描述,描述不可为空,确认即可上传成功。每次上传新的活动内容都会将旧的内容覆盖。
用户点击社团操作面板中的社团通知后,进入社团通知界面。此界面与我的消息通知界面相同。只不过过滤出所有当前社团的通知,并且禁止了所有的滑动删除,添加了一个菜单。
若用户具有权限位2,则显示FAB菜单。菜单包括删除通知,发布新通知以及查看统计功能。
若用户点击删除通知,则进入删除模式,Toolbar变为红色。用户点击要删除的通知后,删除该通知,此时社团所有成员的对应通知都会删除。
若用户点击查看统计,则进入统计模式,Toolbar变为黄色。选择并点击后,进入消息阅读情况,用户可在此界面内查看该通知的已阅人数、未读人数、阅读率以及未读成员清单。点击未读成员清单的某个人还可以查看某人的详细信息。界面和社团通讯录相同。
若用户点击发布新通知,则进入发布通知界面,用户可填写标题以及通知正文,确认后成功发布通知。
若用户具有权限位5,则在社团操作面板中显示招新管理。此界面和我的消息通知界面相同,只不过过滤出所有当前社团的加入申请。
若用户具有权限位3,则在社团操作面板中显示空课表。
首先进入选择成员界面。界面列出了社团的所有成员,复用自社团通讯录。此外右侧增加了勾选按钮,并且支持滑动连续勾选。选择后点击FAB,选择查看的周,即可查看空闲时间表。
空闲时间表复用自时间管理中的课程表。不过课程名称改成了有课的人数和百分比,背景颜色改成根据百分比算出的深浅不一的红色,有事的人越多红色越深。点击每一项还可以查看具体人员的名单,点击每个人查看每个人的详细信息,界面复用社团通讯录的详细信息。
社长专有按钮。点击后确认两次即可解散社团。解散后返回主界面,刷新社团列表。
非社长专有按钮。点击后确认一次即可退出社团。退出后返回主界面,刷新社团列表。
测试工具使用Android Studio,JUnit,Robolectric,Mockito,Espresso,Monkey,语言使用Kotlin。测试系统包括Android 4.0,Android 4.4,Android 5.1,Android 6.0,Android 7.1。测试环境为Android模拟器。
单元测试是参与项目开发的工程师在项目代码之外建立的白盒测试工程,用于执行项目中的目标函数并验证其状态或者结果,其中,单元指的是测试的最小模块,通常指函数。这些代码能够检测目标代码的正确性,打包时单元测试的代码不会被编译进入APK中。[8]
使用Robolectric作为单元测试框架,通过Mockito模拟数据。
在项目中,单元测试的对象是组件状态、控件行为、界面元素和自定义函数。并不推荐对每个函数进行一对一的测试,像onStart()、onDestroy()这些周期函数并不需要全部覆盖到。单元测试的case多来源于一个简短的业务逻辑,单元测试case需要对这段业务逻辑进行验证。
单元测试对象与页面是一对一的,并不建议跨页面,这样的单元测试耦合度太大,维护困难。单元测试需要找到页面的入口,分析项目页面中的元素、业务逻辑,这里的逻辑不仅仅包括界面元素的展示以及控件组件的行为,还包括代码的处理逻辑。然后可以创建单元测试case列表,用于记录项目中单元测试的范围,便于单元测试的管理以及他人了解业务流程,如表格 4‑1所示,列表中记录单元测试对象的页面,对象中的case逻辑以及名称等。
表格4‑1 测试用例示意表
目标页面 | 业务覆盖 | 界面元素 | 逻辑描述 | 最小断言数 | Case名称 |
---|---|---|---|---|---|
登录页面 LoginActivity | 登录 | 1. 用户名输入框 2. 密码输入框 3. 登录按钮 | 1. 输入用户名 2. 输入密码 3. 点击登录按钮 | 3 | testLogin() |
注册 | 1. 注册按钮 | 1. 点击注册按钮 | 1 | testRegister() | |
注册页面 RegisterActivity | 填写手机号 | 1. 手机号输入框 | 1. 输入手机号码 | 1 | testInputPhoneNumber() |
选择国家 | 1. 国家选择按钮 2. 国家选择列表 3. 国家编号展示框 | 1. 点击国家选择按钮 2. 选择国家 | 3 | testSelectCountey() |
工程师可以根据这个列表开始写单元测试代码。上述流程并不能完全覆盖重要的业务逻辑以及边界条件,因此,需要写完后,看覆盖率,找出单元测试中没有覆盖到的函数分支条件等,然后继续补充单元测试case列表,并在单元测试工程代码中补上case。直到规划的页面中所有逻辑的重要分支、边界条件都被覆盖,该项目的单元测试结束。
接下来需要在单元测试工程中实现上述case,最小断言数是业务逻辑上的判断,并不是代码的边界条件,真实的case需要考虑代码的边界条件,比如数组为空等条件,因此,最终的断言数量会大于等于最小断言数。在需求业务上,最小断言数也是该需求的业务条件。
写完case后需要跑一遍单元测试并检查覆盖率报告,当覆盖率报告中缺少有些单元测试case列表中没有但是实际逻辑中会有的逻辑时,需要更新单元测试case列表,添加遗漏的逻辑,并将对应的代码补上。直到所有需要维护的逻辑都被覆盖,该项目中的单元测试才算完成。单元测试并不是QA的黑盒测试,需要保证对代码逻辑的覆盖。
黑盒测试的思路是,把自己当成用户,只关注用户能看到的东西。开发者需要针对那些用户能看到的东西,也就是UI。用户并不关心某个网络请求返回值的具体数据是否正确,仅仅关心他能在UI上看到希望看到的结果。所以,界面测试分为三步:找到某个元素,做一些操作,检查结果。
自动化测试的目的是解放测试人员的双手,将之前需要认为点击,检查的操作转变为机器自动执行的过程。
Espresso是Google的开源自动化测试框架。它的特点是规模小、简洁,API精确,编写测试代码简单,容易快速上手。
压力测试使用Monkey工具。Monkey工具会模拟各种各样奇怪的操作,通过连续测试上百万次的点击事件,可以检测出软件中潜在的BUG。
经过一系列的自动化测试后,系统将会发布alpha版本,进入人工测试阶段。人工测试仍然是一种黑盒测试,针对每一个功能进行详细测试,判断是否符合标准。当软件通过内部人工测试后,即可发布beta版本。
阎覃:负责主要业务逻辑代码的编写和测试。
张雪:负责主要界面代码的编写和测试。
具体每个人的分工如图 5‑1所示。
图 5‑1 人员分工时间线
软件开发总共分为七个阶段:计划阶段,主框架搭建,我的,发现,社团,消息和推送,设置。开始于2016年11月19日,预计于2017年1月14日结束。
图 5‑2 项目整体甘特图
详细的项目甘特图参看附录A。
计划阶段主要撰写开发文档,计划软件的架构,模型。大概需要1周。
在主框架搭建阶段,主要搭建软件的公共基类,界面框架,网络框架。大概需要3 周。
此阶段针对“我的”模块进行开发,主要包括课程表,登录,注册,用户资料的显示和编辑,图片缓存的处理。大概需要一个月。
此阶段针对“发现”模块进行开发,主要包括发现活动,社团,商家和搜索功能。大约需要2周。
此阶段针对“社团”模块进行开发,包括社团除推送通知外所有业务逻辑。大约需要2周。
此阶段引进消息推送,开发“社团”模块,“我的”模块中所有涉及消息推送的功能。大约需要2周。
此阶段做一些收尾工作,包括设置,应用日志,统计,版本更新等功能。大约需要1周。
[1] Introduction - Materialdesign[EB/OL]. Material design guidelines, [2017-04-19].https://material.io/guidelines/.
[2] KAHN J. Report:Android inches closer to passing Windows as most popular OS for internetusage[J]. 9to5Google, 2017.
[3] 开发应用 | Android Developers[EB/OL].[2017-04-19]. https://developer.android.com/develop/index.html.
[4] 支持库 | Android Developers[EB/OL]. [2017-04-19].https://developer.android.com/topic/libraries/support-library/index.html.
[5] 产品与服务--异常上报 - 腾讯Bugly _安卓卡顿_android 崩溃捕获_iOS崩溃日志分析[EB/OL]. [2017-04-19]. https://bugly.qq.com/v2/products/crash-reporting.
[6] Dashboards |Android Developers[EB/OL]. [2017-04-19].https://developer.android.com/about/dashboards/index.html.
[7] Data BindingLibrary | Android Developers[EB/OL]. [2017-04-19].https://developer.android.com/topic/libraries/data-binding/index.html.
[8] Android单元测试研究与实践 -[EB/OL]. [2017-04-21].http://tech.meituan.com/Android_unit_test.html.
#附录A:项目开发完整甘特图