例子
假设我们要测试一个restful web服务。通过这个web服务,我们可以用电话作为关键字搜索客户信息。
要调用这个web服务,需要发起以下格式的HTTP请求:
http://{endpoint}/subscribers?telephoneNumber={telephoneNumber} |
服务端返回的以竖线分割的数据包含客户的姓名、电话、地址及其他信息:
13120205504|ST|C|SQ|112|||FIRST|ST|W|Riverfront|BC|010|68930432| |
测试这个服务的用例为:(1)用能精确匹配一个用户的电话作为关键字搜索,(2)用能精确匹配多个用户的电话作为关键字搜索,(3)用 不完整电话作为关键字搜索等。用例的完整程度完全取决于QA的想象能力。
对于每个测试用例,执行的数据基本上都一样:(1)拼装包含电话号码关键字的URL,(2)用HTTP库发出HTTP GET请求,(3)解析数据, (4)把真实值与期望值做比较。为了避免上面提到的问题,我们在这里采用分层结构:
● 测试用例层
这一层的具体实现方式与采用的测试框架有关。在这个例子中,我们采用C#及NBehave。
[Story] .Given(AN_ACCOUNT_WITH_PHONE_NUMBER, "01062736745") [Scenario] |
这些测试用例用C#写成,但是很接近英语,即使非技术人员也可以读懂。 (请参照Martin Fowler的 BusinessReadableDSL )。这样,其他的团队成员,特别是对领域更熟悉的业务人员,可以很容易的读懂测试用例, 因此也更可能指出测试中遗漏的案例及场景。
若采用支持以自然语言形式书写测试用例的框架(例如Ruby平台下的Cucumber)则会更好。
以"ACTION"结尾的变量为lambda表达式。他们是真正的测试逻辑。
SEARCH_WITH_ACTION会向web服务发出请求,并会解析返回的以竖线分割的数据。类CustomerService和Subscriber在领域层中,他们 会在多个测试中重复使用。
SEARCH_WITH_ACTION = phoneNumber => { subscribers = customerService.SearchWithTelephoneNumber(phoneNumber); }; |
ACCOUNT_INFORMATION_SHOULD_BE_RETURNED_ACTION is for verifying the data
ACCOUNT_INFORMATION_SHOULD_BE_RETURNED_ACTION = accountNumber => { //Get expected subscriber from fixture Subscriber expected = SubscriberFixture.Get(accountNumber); CustomAssert.Contains(expected, subscribers); }; |