自动化测试的分层结构(2)

发表于:2014-12-17来源:uml.org.cn作者:李贝点击数: 标签:自动化测试
ACCOUNT_INFORMATION_SHOULD_BE_RETURNED_ACTION) .Given(AN_ACCOUNT_WITH_PHONE_NUMBER, 01062736745) .When(SEARCH_WITH, 01062736745) .Then(ACCOUNT_INFORMATION_SHOULD_BE_RETURNED, 12666056628); } [Scenario

  ACCOUNT_INFORMATION_SHOULD_BE_RETURNED_ACTION)

  .Given(AN_ACCOUNT_WITH_PHONE_NUMBER, "01062736745")

  .When(SEARCH_WITH, "01062736745")

  .Then(ACCOUNT_INFORMATION_SHOULD_BE_RETURNED, "12666056628");

  }

  [Scenario]

  public void SearchWithPartialPhoneNumber()

  {

  story.WithScenario("Search with partial phone number")

  .Given(THREE_ACCOUNTS_WITH_PHONE_NUMBER_STARTS_WITH, "0106", EMPTY_ACTION)

  .When(SEARCH_WITH, "0106", SEARCH_WITH_ACTION)

  .Then(ACCOUNT_INFORMATION_SHOULD_BE_RETURNED, "13120205504",

  ACCOUNT_INFORMATION_SHOULD_BE_RETURNED_ACTION)

  .And(ACCOUNT_INFORMATION_SHOULD_BE_RETURNED, "12666056628")

  .And(ACCOUNT_INFORMATION_SHOULD_BE_RETURNED, "17948552843");

  }

  [Scenario]

  public void SearchWithAPhoneNumberWhichHasSeveralExactMatches() {...}

  [Scenario]

  public void SearchWithNonExistentPhoneNumbers() {...}

  [Scenario]

  public void SearchWithInvalidPhoneNumberValues() {...}

  ...

  ...

  }

  这些测试用例用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);

  };

  领域层

  CustomerService类以真实web服务的名称命名。在需求文档、日常对话、架构图以及代码中,都用这个名称来指代此web服务。 使用统一的名称,能除去二义,提高沟通效率。

  public class CustomerService

  {

  public Subscriber SearchWithTelephoneNumber(string telephoneNumber)

  {

  string url =

  string.Format(

  "{0}/subscribers?telephoneNumber={1}",

  endpoint, telephoneNumber);

  //Send http request to web service, parse the xml returned,

  //populate the subscriber object and etc.

  return GetResponse(url);

  }

  ...

  }

  Subscriber类建模了用户。比起用竖线分割的字符串,增加一层数据抽象,用对象表示返回的数据,能使 测试更容易理解(你应该不会偏好用pipedData[101]表示电话号码吧?)。

  public class Subscriber

  {

  public string AccountNumber { get; set; }

  public string FirstName { get; set; }

  public string Surname { get; set; }

  public string TelephoneNumber { get; set; }

  ...

  }

  有了这些领域模型,测试就能直接构建在这些对象上了。例如,可以如此验证所返回的用户名为'Bei':

  Assert.AreEqual("Bei", subscriber.FirstName);

  或者电话号码以'010'开始:

  Assert.IsTrue(subscriber.TelephoneNumber.StartsWith("010"));

  点击这里可以下载到样例代码。代码中演示了如何用分层架构组织测试自动化代码。 你可以在Visual Studio 2008中打开项目,也可以在命令行运行执行'go.bat’来运行所有测试。 'go.bat’运行完后会将测试结果保存在'artifacts’文件夹。源代码中包含三个项目。 名称以with ‘Client’的项目包含领域层。以'Client.Spec’结尾的项目为领域层对应的单元测试(TDD)。'Stories’项目包含测试用例层。这份源代码由真实项目中来,并作了相应修改。某些类返回了硬编码的值,是为了不访问真实的web服务。

原文转自:http://www.uml.org.cn/Test/200911196.asp