工作这么几年来,见得最多的场景是 QA 小伙伴满办公室追着开发报 bug,有时候开发会不乐意,“当时可没说要 XXX,要做 XXX。”

好像 QA 小伙伴永远比开发多一点心眼,即使单元测试覆盖率达到 80%,QA 还是变着法都能找出问题。

这其中很大一部分原因都来自于“需求背后的需求”,BA、QA 小伙伴以为你考虑到了,或者默认开发需要考虑到。

比如 CMS 系统中一个新建文章的需求,不太可能写出需要防止表单二次提交的 AC(Acceptance Criteria,验收条件),然而如果没人提出来谁会知道呢?

(最近很火的冰山图)

最终 QA 或者线上的用户会通过报 bug 告诉我们。

我们把这些隐藏在功能需求背后或 BA 默认认为开发需要考虑的需求称为非功能性需求,有时候又叫跨功能需求。

下面就来说说在工作中常见的非功能性需求和应对方式。

交互体验相关

Loading 加载状态是最容易被忽略的一个需求,尤其是在现在富客户端开发的模式下,数据的获取都是异步加载的。如果忘了考虑这条需求,在网络条件较好时会出现闪烁的情况,而在网络情况差的条件下又看起来会卡顿和没有响应。实现统一的 Loading 可以在前端的网络请求库中增加拦截器,不过需要注意使用计数器让多次网络请求中途的 Loading 图标不会间断,否则会有闪烁的问题。

表单的二次提交

有一些 QA 会使用极端的测试方法,例如快速点击按钮多次,如果页面没有进行处理,会触发表单多次提交的问题。即使后端 API 增加限制则可能同时出现成功和失败的提示,会让用户感到更加迷惑。处理这个问题有几种途径:

  • 使用蒙层的 Loading 就会自带阻塞用户的操作的效果
  • 点击后禁用表单事件或在程序中增加请求中的状态
  • 依赖后端配置一次性表单令牌(通常用来防 CRSF)

输出格式化

需求中一般会告诉开发怎么展示数据,但是往往会忘记如何格式化数据。例如我们想让数字使用千分位分隔或其他显示方式,让数字阅读不那么困难;字符串溢出的处理截取方式;时间的格式化方法,有一些项目会使用“一小时前”,“一天前”或者具体日期等更为人性化的显示方式;图片的输出需要宽度进行缩放,如果是封面图需要非拉伸截取等。

请求用户确认和提示

这两项专业 BA 一般都会考虑到,也会通知 UX 设计对应样式。不过这里面的细节还是值得讨论。

  • 如果在一系列操作的中途提示用户确认,需要明确用户点击取消后,应该回退到用户的哪一步操作状态。有很多的 APP 在用户编辑好数据后,点击提交然后系统提示是否继续,如果用户点击取消,页面上的数据会被清除。开发需要和 BA 确认好具体的交互以及提示文案。
  • 成功和错误的提示除了文案之外,和 BA 需要确认的还有:是独立的提示页还是返回到来源页面?提示需要自动关闭还是等待页面刷新后关闭?用户可以主动点击关闭吗?

交互体验这部分还有一个需求噩耗就是,保持统一!!!我想这个是交互体验上最为致命又不会写在需求中,但是 QA 往往能从中找到 bug。

安全相关

身份校验和权限

URL 上资源可以被枚举和请求的资源没有验证用户权限,这属于致命而低级的安全问题,当然 BA 会默认开发要去做这些。不过现实就是在一些遗留项目中这种例子太多了,例如通过修改 URL 上的资源 ID 甚至 userID 此类参数进而修改其他用户的数据。几年前,可以发现很多此类漏洞,甚至在我学生时期用某电信运营商的权限漏洞得手了不少付费游戏。如果系统设计了权限管理模块,在开启新功能时也应该和 BA 确认是否纳入权限管理。

表单验证

用户输入的数据如何验证这部分也是经常在需求上忘记体现出来的地方,而且这部分 QA特别容易给出 Bug,数据验证充满了大量的条件边界。还有一个老生常谈的问题,表单验证应该服务器端还是前端做? 这很显然,后端为了安全必做,前端为了体验选做

SQL 注入和 XSS 攻击

SQL 注入这两年随着成熟的 ORM 框架普遍使用几乎没有了,但是 XSS 可以说还是有很多。处理 SQL 注入和 XSS 攻击的共同点是不要相信任何用户的输入、任何来源。在浏览器中用户输入不仅有表单还有 URL,而往往 URL 输入参数很容易被数据校验忽略

文件上传

文件上传背后的需求有上传文件的类型、大小限制;需要和 BA 确认是否能批量上传,上传前是否需要预览;上传后如何命名,是否需要在上传过程中对图片或视频进行压缩。这里的安全需求是,不应该上传可执行文件;需要获取文件真实的类型信息而非后缀名。文件上传的一个陷阱就是使用了客户端来源的文件名作为文件存储的文件名,这是极为不可靠的,在上传后的文件系统中需要使用内建的唯一命名,并通过数据库来记录用户上传的文件名。

性能相关

响应时间

说实话,没见过那张卡上有明确的指标那些功能需要在多久之内完成响应。但是如果不在分析业务需求的阶段提出来,响应时间过长肯定通不过 QA 测试。在需求分析阶段的响应时间包含了三个注意点:

  • 系统性能设计要求。对一般需求而言,技术上应该达到基本的性能指标,当然实现的方式不尽相同,例如优化 SQL、优化静态资源等。
  • 该功能是否适合同步操作。然而有一些部分的需求是根本不适合使用同步的操作,例如数据导入这类耗时很长的操作,服务器应该接受用户请求然后不断返回任务处理的状态,而不是让用户端等待完成。实现上可以使用一些消息系统,例如 JMS 等。
  • 第三方系统集成。如果和第三方系统集成,需要和资源提供方沟通是否需要增加批量的数据操作,避免循环获取数据。例如 JSON API标准中提供了 include 方法聚合多个资源到一次请求中。另外调用方可以注意使用一些非阻塞的网络请求方法,如 RxJava 或AsyncRestTemplate。

实时消息通知

我们在做一些类似站内信、系统消息的功能时,有时候 BA、QA 容易默认消息的状态和数量(小红点)应该实时的显示在页面上,并及时更新。但开发小伙伴可能认为 web 上的一些信息需要用户刷新后可见,这个很容易达成理解不一致。如果实时刷新作为需求确实需要的话,从技术上需要做一些调整才能实现,比如使用轮询、HTTP 长连接、websock 等方法才能实现,这会带来额外的工作量。

游离数据管理

从事服务器开发的小伙伴可能有这种体会,有一些数据一旦创建了,用户或者管理员就没法找到或者跟踪了。比较明显的例子有两处:

  • 新建资源处,异步上传的图片或者其他资源。比如在用户操作新建文章页面,这个时候文章表可能还没有写入数据,但是需要允许用户上传一些封面或者其他图片。如果用户体完成了整个操作,图片会和文章关联,但是假如用户放弃了操作,图片就会变成游离状态无法继续管理,造成大量垃圾数据占用系统资源。
  • 删除操作,没有删除一些关联数据。例如商品表和商品属性表关联,如果删除操作不是事务性的一起删除,就会造成数据空间浪费,且可能影响后续的统计功能。

对于新建资源的图片上传,可以和 BA 沟通使用草稿的方式在用户进入创建页就完成数据插入操作,也可以设计一个图片空间来提醒用户使用已经上传的图片;对于删除操作,系统不复杂可以设计为数据库表标记删除,而不是真的删除,也可以设计回收站功能统一移动到备份表。

分布式系统延迟

由于现在稍大的系统都是用了分布式或微服务设计,系统之间存在系统存在同步延迟,比如数据库主从同步,静态资源服务器同步等。在一些对文案要求比较严格的项目中一个隐藏的需求是,需要提醒当前的信息可能存在延迟,请稍后再试。或者前端增加定时刷新页面的或者资源的回退策略,在我经历的一个项目中,上传图片成功返回图片 URL 后,前端可能会延迟 2s 左右才能从正常打开图片,因此需要增加 onload、onerror 进行重试或后续操作。

其他非功能性需求

**兼容性 **

浏览器兼容性是前端开发中头疼的事情,从 IE6 到微信 webview,无论技术发展到哪个时代都逃不掉。那么那些事情是需要和BA确认的呢?

  • 各种浏览器内核具体的型号,而不是讨论搜狗、360 这类壳浏览器。如果是 APP 内部的webview,这就需要收集相关安卓或 IOS 的版本号。
  • 是否允许一定程度上的降级策略?比如在老式的安卓手机中大量的 CSS3 特性不支持,可能会造成动画失效,是否我们可以不在老式的手机中要求过渡动画等。

升级策略

前端有兼容性问题,那么服务器端就没有了么?不幸的是如果 APP 不是同步发布的话,API 的修改需要照顾老的客户端。即使是同步发布的 APP 很难强制用户升级。在服务器端开发的时候保持一定兼容性的同时,更重要的是需要和 BA 一起设计出合理的升级方案。我的经验是设计API 时,需要在URI路径中预留版本号,例如 V1/your-api/{id}。同时也需要增加契约测试来保证API 的修改不会破坏原来的逻辑。

本地化和国际化

在一些国际化的项目中,这一点尤为重要,不过有时候容易被忽略。多语言和时区问题需要在项目之初就和 BA 确认,统一增加国际化方案。而其他本地化则需要在每个功能上注意,例如日期、货币、单位、标点符号的输出方式。

用户行为分析埋点

越来越多的项目开始使用用户的行为分析工具了,例如 Google 的 Gtag 和更加专业的 dynatrace,使用这些工具会对系统造成一定的侵入性,需要对用户的操作进行埋点。如果项目有类似的需求,针对特定的功能很多用户行为分析的系统会提前定义一些标签,那么在开始一个新功能时需要确认用户行为分析的一些规则。

最后

写作本篇的目的是分享在工作中开发在做一张卡背后需要考虑多少注意事项。在细节上想的越多,业务逻辑就会变得越完整,让开发工作变得更为顺畅。

在参加公司某次培训时,恰好也有很好的非功能性需求的课程,非常详细,以至于长达数页,但遗憾的是没有非常详细的解释和应对方法。因此决定根据自己在工作中遇到过的场景作为例子,给大家分享出来。

在敏捷团队中一个痛点是我们很少有一个大而全的需求文档,如果在开卡的时候有一些需求没有被想到或者没有在 AC 中体现出来,就需要反复找 BA、UX 反复确认。开发和 BA 沟通调整需求、交互的时候可能忘记知会 QA 或者 UX,或者没有更新故事卡内容,就又会造成沟通的麻烦。

文/ThoughtWorks林宁

更好的开卡,来聊聊非功能性需求 - ThoughtWorks洞见​insights.thoughtworks.cn

非功能性需求_更好的开卡,来聊聊非功能性需求相关推荐

  1. 故障处理 软件 需求_几款软件解决日常办公生活所有图片处理需求!

    今天开篇讲讲图像处理,当然这个级别的图像处理和PS修图是比不了的,但它可以处理一些日常应急的工作,比如压缩和转格式什么的,常言道有备无患嘛,具体有哪些一起来看吧.画像浏览器 介绍: 虽然Windows ...

  2. mysql创建非聚集索引_一文看懂聚集索引和非聚集索引的区别

    一.深入浅出理解索引结构 实际上,可以把索引理解为一种特殊的目录.微软的SQL SERVER提供了两种索引:聚集索引(clustered index,也称聚类索引.簇集索引)和非聚集索引(nonclu ...

  3. fafts sd卡开启中断_使用FreeRTOS在SD卡驱动使用非系统延时导致上电重启不工作的情况...

    一.问题描述 在一个使用FreeRTOS的工程中,只做了SD卡的驱动,由于RTOS使用了Systick,故非系统延时函数使用的是 DWT中的时钟周期(CYCCNT)计数功能,但是在SD卡驱动中使用了这 ...

  4. java 正则表达式 非贪婪模式_详解正则表达式的贪婪模式与非贪婪模式

    什么是正则表达式的贪婪与非贪婪匹配 如:String str="abcaxc"; Patter p="ab*c"; 贪婪匹配:正则表达式一般趋向于最大长度匹配, ...

  5. python实现冒泡排序算法的非递归版本_冒泡排序以及python代码实现(递归+非递归)...

    一.冒泡排序 比较简单的排序算法,适合小规模数据集,效率较低. 依次比较相邻的两个数,将比较小的数放在前面,比较大的数放在后面. 每进行一趟排序,就会少比较一个数 python代码(非递归): fro ...

  6. 如何是实现微信会员开卡组件中一个手机号绑定一个微信号(思路篇)

    微信原生开卡组件可以支持一个手机号绑定多个微信号,这个会导致比如说优惠券等等可以享受两次,现在我们需要实现的功能是一个手机号只支持绑定一个微信号.需要借助于微信现在支持的两种开卡方式! 一种是跳转型开 ...

  7. 为什么非阻塞io性能更好_提高性能:流的非阻塞处理

    为什么非阻塞io性能更好 1.简介 想象一下,我们有一个需要访问外部Web服务的应用程序,以便收集有关客户端的信息,然后对其进行处理. 更具体地说,我们无法在一次调用中获得所有这些信息. 如果我们要查 ...

  8. 给开源项目贡献代码_您可以为开源做出6种非代码贡献

    给开源项目贡献代码 贡献开源! 履历表看起来很棒! 这是可喜的工作! 在您的整个职业生涯中,您可能听说过很多人做出过这些陈述或类似的陈述. 他们没有错-为开源做贡献是一个多方面的有益工作-但是,当软件 ...

  9. 中科佑铭机器人_一个月连开四个班!犀灵机器人口碑炸裂,值得信赖!

    一.凭什么工业机器人工程师能成为现代制造业的新宠 7月,一个艳阳高照的季节 热浪滚滚的天气一度点燃了人们对机器人学习的热情 在佛山 中国(广东)机器人集成创新中心犀灵机器人培训学院 一群怀报理想的青年 ...

最新文章

  1. python和c++的相互调用教程
  2. 【笔记】web语音相关
  3. 芯片业遭双重打击:经济低迷技术难突破
  4. PHP的SQL注入攻击的技术实现以及预防措施
  5. python列出文件夹最新的几个文件_Python列出一个文件夹及其子目录的所有文件
  6. 2021年春季学期-信号与系统-第十四次作业参考答案-第三小题参考答案
  7. Spring AOP(通知、连接点、切点、切面)
  8. 将对话框(提示框)中的内容粘贴到记事本
  9. 数据结构之内部排序三
  10. 【Qt教程】2.3 - Qt5 控件 - 按钮组(QPushButton、QToolButton、QRadioButton、QCheckBox)资源编辑器导入资源
  11. 从 0 到 1:全面理解 RPC 远程调用!
  12. iOS开发之 Autolayout 详解
  13. ffmpeg 转码及多线程处理
  14. 【分享】这款微信电子名片真的很值得拥有!
  15. lenovo G480 安装无线驱动 linux
  16. 07 ,矩阵的转置,矩阵的行列式,方阵 ( 2阶行列式,3阶行列式,n 阶行列式 ) :
  17. mysql安装ecshop_如何安装ecshop
  18. error: C++ requires a type specifier for all declarations
  19. 快速获取SAS数据集观测数
  20. 速写在网站建设中的重要地位

热门文章

  1. JS使用闭包保护变量,防止污染
  2. 使用decode函数
  3. android工程的建立,第一个Android项目HelloWorld的建立及剖析
  4. 简化java_Java泛型太复杂了?如何简化?
  5. python日期格式转换成13位时间戳_python生成13位或16位时间戳以及反向解析时间戳的实例...
  6. sourceTree对git的新建项目、储藏代码、切换分支、回滚代码、提交代码
  7. Mybatis 动态传入表名 字段名 的解决办法
  8. springBoot方法上面添加@Transactional注解与类上面添加@Transactional注解的区别
  9. yum安装软件提示Another app is currently holding the yum lock
  10. django2.0 自己入门记录一些基础url 模板等