企業系統集成點測試策略(2)

發表于:2013-08-29來源:InfoQ作者:熊節點擊數: 標簽:集成測試
by(uri(/openptk-server/login)), by(clientid=test_appclientcred=fake_password))).response(status(200)); 接下來我們告訴要測試的網絡端點,應該訪問位于localhost:12306的服務器,并

  by(uri("/openptk-server/login")),

  by("clientid=test_app&clientcred=fake_password"))).response(status(200));

  接下來我們告訴要測試的網絡端點,應該訪問位于localhost:12306的服務器,并提供用戶名和密碼:

  configuration = new IdentityServiceConfiguration();

  configuration.setHost("http://localhost:12306");

  configuration.setClientId("test_app");

  configuration.setClientCredential("fake_password");

  xmlEndPoint = new XmlEndPoint(configuration);

  然后就可以正式開始測試了。首先我們測試XmlEndPoint可以用GET方法訪問一個指定的URL,取回應答正文:

  @Test

  public void shouldBeAbleToCarryGetRequest() throws Exception {

  final String expectedResponse = "SUCCESS";

  server.get(by(uri("/get_path"))).response(expectedResponse);

  running(server, new Runnable() {

  @Override

  public void run() {

  XmlEndPointResponse response =

  xmlEndPoint.get("http://localhost:12306/get_path");

  assertThat(response.getStatusCode(), equalTo(STATUS_SUCCESS));

  assertThat(response.getResponseBody(), equalTo(expectedResponse));

  }

  });

  }

  實現了這個測試以后,我們再添加一個測試,描述“應用程序登錄失敗”的場景,這樣我們就得到了對XmlEndPoint類的get方法的完全測試覆蓋:

  @Test(expected = IdentityServiceSystemException.class)

  public void shouldRaiseExceptionIfLoginFails() throws Exception {

  configuration.setClientCredential("wrong_password");

  running(server, new Runnable() {

  @Override

  public void run() {

  xmlEndPoint.get("http://localhost:12306/get_path");

  }

  });

  }

  以此類推,也很容易給post和put方法添加測試。于是,在Moco的幫助下,我們就完成了對網絡端點的測試。雖然這部分測試真的發起了HTTP 請求,但只是針對位于localhost的Moco服務器,并且測試的內容也只是最基本的GET/POST/PUT請求,因此測試仍然快且穩定。

  Moco的前世今生

  在ThoughtWorks成都分公司,我們為一家保險企業開發在線應用。由于該企業的數據與核心保險業務邏輯存在于COBOL開發的后端系統中,我們所開發的在線應用都有大量集成工作。不止一個項目組發出這樣的抱怨:因為依賴了被集成的遠程服務,我們的測試變得緩慢而不穩定。于是,我們的一位同事鄭曄[4]開發了Moco框架,用它來簡化集成點的測試。

  除了我們已經看到的API模式(在測試用例中使用Moco提供的API)以外,Moco還支持standalone模式,用于快速創建一個測試用的服務器。例如下列配置(位于名為“foo.json”的文件中)就描述了一個最基本的HTTP服務器:

  [

  {

  "response" : {

  "text" : "Hello, Moco"

  }

  }

  ]

  把這個服務器運行起來:

  java -jar moco-runner--standalone.jar -p 12306 foo.json

  再訪問“http://localhost:12306”下面的任意URL,都會看到“Hello, Moco”的字樣。結合各種靈活的配置,我們就可以很快地模擬出需要被集成的遠程服務,用于本地的開發與功能測試。

  感謝開源社區的力量,來自澳大利亞的Garrett Heel給Moco開發了一個Maven插件[5],讓我們可以在構建過程中適時地打開和關閉Moco服務器(例如在運行Cucumber[6]功能測試之前啟動Moco服務器,運行完功能測試之后關閉),從而更好地把Moco結合到構建過程中。

  目前Moco已經被ThoughtWorks成都分公司的幾個項目使用,并且根據這些項目提出的需求繼續演進。如果你有興趣參與這個開源項目,不論是使用它并給它提出改進建議,還是為它貢獻代碼,鄭曄都會非常開心。

  其它組件的測試

  有了針對網絡端點的測試之后,其他幾個組件的測試已經可以不必發起網絡請求。理論上來說,每個組件都應該獨自隔離進行單元測試;但個人而言,對于沒有外部依賴的對象,筆者并不特別強求分別獨立測試。只要有效地覆蓋所有邏輯,將幾個對象聯合在一起測試也并無不可。

  出于這樣的考慮,我們可以針對整個集成點的façade(即IdentityService)進行測試。在實例化IdentityService對象時,需要mock[7]其中使用的XmlEndPoint對象,以隔離“發起網絡請求”的邏輯:

  xmlEndPoint = mock(XmlEndPoint.class);

  identityService = new IdentityServiceImpl(xmlEndPoint);

  然后我們就需要mock的XmlEndPoint對象表現出幾種不同的行為,以便測試IdentityService(及其內部使用的其他對象)在這些情況下都做出了正確的行為。以“查找用戶”為例,XmlEndPoint的兩種行為都是OpenPTK的文檔里所描述的:

  1. 找到用戶:HTTP狀態碼為“200 FOUND”,應答正文為包含用戶信息的XML;

  2. 找不到用戶:HTTP狀態碼為“204 NO CONTENT”,應答正文為空。

  針對第一種(“找到用戶”)情況,我們對mock的XmlEndPoint對象提出期望,要求它在get方法被調用時返回一個代表HTTP應答的對象,其中返回碼為200、正文為包含用戶信息的XML:

  when(xmlEndPoint.get(anyString())).thenReturn(

  new XmlEndPointResponse(STATUS_SUCCESS, userFoundResponse));

原文轉自:http://www.infoq.com/cn/articles/enterprise-systems-integration-points

国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97