首页 > 代码库 > UseCase事件流描述规范

UseCase事件流描述规范

文/fasiondog

整理需求用例的编写规范,分享部分UseCase事件流描述规范。其中,准则5~10、12来自《编写有效用例》([美] Alistair Cockburn 著)一书,其它为自身实践和要求。

事件流包含正常事件流、可选事件流、异常事件流程,前述三者合在一起的本质就是用文字描述的流程。事件流由文字描述的步骤组成,写作过程中应遵循以下准则,这些准则是对用例写作过程中的常见问题和最佳实践的总结。下述规范中如没有特殊说明,事件流同时指正常事件流、可选事件流、异常事件流。


准则1:文字描述与流程图保持一致

事件流的本质其实就是文本描述的流程。因此,对用例辅以说明的流程图应与文字表述的事件流保持一致。事实上,用例是以文字描述为主,流程图为辅。编写用例应该养成“先写文字后画图”的习惯。保持一致意味着:

  • 流程图中的动作(含判断)的数量与事件流中的步骤数量一致(由于不同的图形表示方法的限制,最低程度应保证和正常事件流中的步骤数量一致)
  • 流程图中的动作(含判断)与事件流中的步骤描述一致
准则2:步骤描述遵循“主+谓+宾”结构

句子的结构应简单明了:“主语+谓语动词+直接宾语”,辅以必要的修饰词。


准则3:一个步骤描述中仅包含一个主语

在一个步骤中仅包含一个主语,这意味着一个步骤描述中可以是一个执行者执行一个动作,也可以是一个执行者执行多个连贯的动作,但不能出现多个执行者执行多个不同的任务。例如:

错误的描述形式:
1.【用户】输入订购号码,【系统】发现这个号码与本月中奖号码匹配,将用户和订购号码注册为当月的中奖者,发电子邮件给销售经理,祝贺客户,并告诉他们如何领取奖金

正确的描述形式1:
1.【用户】输入订购号码。
2.【系统】发现这个号码与本月中奖号码匹配,将用户和订购号码注册为当月的中奖者,发电子邮件给销售经理,祝贺客户,并告诉他们如何领取奖金。

正确的描述形式2:
1.【用户】输入订购号码。
2.【系统】发现这个号码与本月的中奖号码匹配。
3.【系统】将用户和订购号码注册为当月的中奖者。
4.【系统】发电子邮件给销售经理。
5.【系统】祝贺客户,并告诉他们如何领取奖金。

在编写用例时,可以根据此准则,对较冗长的多个步骤进行合理的合并。所谓合理,是指合并后的步骤,应不影响可选事件流、异常事件流的插入点。


准则4:在步骤中明确标识参与人

通过在步骤中使用“【参与人】”的方式明确标识“参与人(Actor)”,防止因遗漏主语(以及部分宾语),而使读者不知道谁是活动的执行者。示例:

“【用户】插入ATM卡并输入PIN。”


准则5:从系统外部的角度来编写用例

缺少经验的用例编写者(尤其是对系统内部实现有所了解的开发人员)在描述用例场景时,经常有意或无意实现系统内部结构并试图从系统内部动作来描述系统。他们可能写出这样的句子“读取ATM卡和PIN号码,并从账户余额中扣除一定数量。”

而从系统外部来编写用例,则是:

1.【用户】插入ATM卡并输入PIN号码;
2.【系统】从账户余额中扣除一定数量。


准则6:显示过程向前推移

选择过小的步骤将导致用例过长。如果一个用例有13~17个步骤,说明每一个步骤完成的工作过少。如果将一些小的步骤合并,可以使用例的可读性更好、更清晰,并且保持原有的基本信息。一般,一个用例的步骤数量应控制在7个以内。

为了有效合并用例步骤,应找到具有较高层次目标的步骤。可以提出这样的问题“为什么参与人需要做这件事?”。可能,需要多次询问此问题才能得到满意的答案,而这个问题的答案就是步骤实现的目标。以下是一个通过问“为什么”来提高目标层次的例子。

“用户按下Tab键”

为什么用户要按下Tab键?是为了将焦点移到地址框中。为什么她要将焦点移到地址框中呢?因为在系统开始工作前,她要输入用户名和地址。她想让系统完成一些工作,为了使系统工作,她必须输入她的用户名和地址。

因此,一个清晰描述过程向前移动的主动语态句子是:

“【用户】输入名字和地址”


准则7:显示参与人的意图而不是动作

通过操纵用户界面来描述用户的动作,这是编写用例时常见的一种严重错误,它使得编写的目标处于一个很低的层次。界面细节描述使得需求文档质量变差,主要体现在:

  • 文档冗长拖沓使阅读困难、维护费用高昂。
  • 任何用户界面的变化都将导致用例文档失效

通常情况下,当一些连续步骤的数据在同一方向上运动时,可以将这些步骤合并成一个步骤(视情况而定,合理合并)。如下面的示例及对它的修改:

修改前:
1.【系统】要求用户输入姓名
2.【用户】输入姓名
3.【系统】要求用户输入地址
4.【用户】输入地址
5.【用户】点击“确定”
6.【系统】显示用户的简介

修改后:
1.【用户】输入姓名与地址
2.【系统】显示用户的简介


准则8:“确认”而不是“检查是否”

大家经常会遇到描述系统检查某个条件的步骤。而在步骤描述中,使用“检查”这个动词并不好,这样说并没有让过程明显的向前发展,它并不是真正的目的,同时它使得检查的结果是不确定的。那么为什么系统要检查条件?答案是为了确认、验证或确保某些事情。这些都是很好的可以表示目标的动词。例如,可以将“系统检查密码是否正确”替换为:

“【系统】验证密码正确”


准则9:习惯用语:“用户让系统A与系统B交互”

在编写用例时,可能会遇到如下情况,正在设计的系统A需要从系统B中获取信息,或者与系统B有一个交互过程。通常可以使用两个步骤来描述:

1.【用户】通知【系统A】从【系统B】获取数据
2.【系统A】从【系统B】获取后台数据。

上述写法虽然可以接受,但在某些情况下显得笨拙和冗余,尤其是用例比较复杂时。更好的写法如下:

1.【用户】命令【系统A】从【系统B】获取后台数据


准则10:习惯用语:“循环执行步骤X到Y,直到条件满足”

有时候,我们会遇到需要重复的步骤。对于只有一个步骤需要重复,可以直接在步骤中描述,如:“【用户】在各种各样的产品目录中寻找、直到发现所需要的产品。”

对于多个步骤需要重复的情况,可以把表达重复执行的语句放在这些重复步骤的前面或后面。例如:

1.【客户】提供账号或名字和地址
2.【系统】查出客户的爱好信息
3.【客户】选择一个商品,并做上购买的标记
4.【系统】将该商品加入客户的“购物车”中
  客户重复步骤3、4,直到客户指明自己完成了选购
5.【客户】购买所有在“购物车”中的商品

另一种形式:
1.【客户】提供账号或名字和地址
2.【系统】查出客户的爱好信息
  步骤3、4可重复执行
3.【客户】选择一个商品,并做上购买的标记
4.【系统】将该商品加入客户的“购物车”中
5.【客户】购买所有在“购物车”中的商品

注意:在表达重复语句前面不需要加上序号。


准则11:命名可选与异常事件流分支

为可选事件流、异常事件流中的分支进行适当的命名,有助于测试和理解。通过简单的命名,有利于检视分支的覆盖情况,保证所有的分支情况都得到了处理。例如某系统登录时的异常事件流:

5a.(录入密码方式认证失败)如果密码方式认证失败,返回步骤3
5b.(连续输入密码错误限制)如果连续3次输出密码错误,则锁定登录,用例结束。
5c.(录入指纹方式认证失败)如果指纹认证方式失败,返回步骤3a


准则12:条件处理的缩排方式

缩进那些指明条件如何处理的执行步骤,并在字母后重新从编号1开始,执行步骤遵循前面的准则。示例:

5a.如果输入密码错误:
  5a1.(密码错误)如果密码错误,系统提示错误信息,返回步骤4。
  5a2.(连续密码错误限制)如果连续3次输入密码错误,账户锁死,用例结束。
  5a3.(累计密码错误限制)如果当日密码错误达到10次,账户锁死,用例结束。


准则13:同一条件处理的分支应在一起

提出此准则的原因是在某些条件处理的分支中,被分别放置在可选事件流和异常事件流中,影响阅读和理解,也不利于检视发现错误。

错误的示例如下:
正常事件流:
……
3.柜面通过核心系统检验账户支取方式为预留密码;
……
可选事件流:
3a.柜面通过核心系统检验账户支取方式为印鉴——
  3a1.柜面提示“请核对印鉴”
  3a2.柜员核对印鉴后,点击任意键提交,返回6

修改后,将其统一放在可选事件流中:
可选事件流:
3a.(印鉴方式支取)如果账户支取方式为印鉴:
  3a1.【系统】提示客户核对印鉴;
  3a2.【柜员】核对印鉴后,提交系统确认,执行步骤6。
3b.(无印密或凭有效证件支取)如果账户支取方式为无印密或凭有效证件支取,【系统】提示“无印密账户不支持理财账户开户”,用例结束。


UseCase事件流描述规范