java maven restful_使用 maven 生成一个支持端到端自动测试的 RESTful 服务项目脚手架...
額外的話: 我會非常感激如果您在讀本文的時候 Follow 文中的操作步驟在你的環境中實踐本文所講內容, 我保證這個過程不會非常復雜, 即便加上你研究代碼的時間也不需要超過 15 分鐘
和傳統后端頁面生成技術相較, RESTful 數據服務專注與數據邏輯, 而將數據呈現完全交給前端應用. 這樣做可以讓后端開發更加單純, 而且更容易測試. 本文將講述如何使用 maven 生成一個支持端到端自動測試的 RESTful 服務的項目腳手架.
1. 準備環境
如果你打算跟隨本文在你的開發機上試驗, 需要一下環境:Java SDK 1.7+
maven 3.5+
如果有 IDE 就更好. 作者推薦使用 IntelliJ IDEA, 可以使用社區版, 完全免費.
2. 定義項目包和應用名稱
項目包 (package) 和應用名稱 (artifact) 是你的項目在 Java 依賴體系中的坐標, 即使你的項目無需被其他項目引用, 也應該給出簡單明確的包和應用名字, 以便于溝通交流.
這里為我們即將生成的應用給出下面的包名和應用名:包名: demo.restful
應用名: SimpleService
3. 生成項目腳手架
我們使用 actframework 的 archetype-simple-restful-service 來生成項目腳手架. 在命令行下mvn?archetype:generate?-B?\
-DgroupId=demo.restful?\????-DartifactId=simple-service?\????-DarchetypeGroupId=org.actframework?\????-DarchetypeArtifactId=archetype-simple-restful-service?\????-DarchetypeVersion=1.8.8.1
運行以上命令大致可以看到下面的 log 信息:[INFO]?Scanning?for?projects...
[INFO]
[INFO]?------------------------------------------------------------------------
[INFO]?Building?Maven?Stub?Project?(No?POM)?1[INFO]?------------------------------------------------------------------------
[INFO]
[INFO]?>>>?maven-archetype-plugin:3.0.1:generate?(default-cli)?>?generate-sources?@?standalone-pom?>>>
[INFO]
[INFO]?<<
[INFO]
[INFO]
[INFO]?---?maven-archetype-plugin:3.0.1:generate?(default-cli)?@?standalone-pom?---
[INFO]?Generating?project?in?Batch?mode
[INFO]?Archetype?repository?not?defined.?Using?the?one?from?[org.actframework:archetype-simple-restful-service:1.8.7.3]?found?in?catalog?remote
[INFO]?----------------------------------------------------------------------------
[INFO]?Using?following?parameters?for?creating?project?from?Archetype:?archetype-simple-restful-service:1.8.8.0[INFO]?----------------------------------------------------------------------------
[INFO]?Parameter:?groupId,?Value:?demo.restful
[INFO]?Parameter:?artifactId,?Value:?simple-service
[INFO]?Parameter:?version,?Value:?1.0-SNAPSHOT
[INFO]?Parameter:?package,?Value:?demo.restful
[INFO]?Parameter:?packageInPathFormat,?Value:?demo/restful
[INFO]?Parameter:?version,?Value:?1.0-SNAPSHOT
[INFO]?Parameter:?package,?Value:?demo.restful
[INFO]?Parameter:?groupId,?Value:?demo.restful
[INFO]?Parameter:?artifactId,?Value:?simple-service
[INFO]?Executing?META-INF/archetype-post-generate.groovy?post-generation?script
[INFO]?Project?created?from?Archetype?in?dir:?/tmp/1/simple-service
[INFO]?------------------------------------------------------------------------
[INFO]?BUILD?SUCCESS
[INFO]?------------------------------------------------------------------------
[INFO]?Total?time:?10.984?s
[INFO]?Finished?at:?2018-05-13T22:15:58+10:00[INFO]?Final?Memory:?25M/305M
[INFO]?------------------------------------------------------------------------
4. 項目結構與內容
使用 tree 命令來查看項目結構:simple-service/
├──?pom.xml
├──?run_dev
├──?run_dev.bat
├──?run_e2e
├──?run_e2e.bat
├──?run_prod
└──?src
├──?main
│???├──?java
│???│???└──?demo
│???│???????└──?restful
│???│???????????├──?AppEntry.java
│???│???????????└──?Service.java
│???└──?resources
│???????├──?conf
│???????│???├──?app.properties
│???????│???├──?prod
│???????│???│???└──?app.properties
│???????│???└──?uat
│???????│???????└──?app.properties
│???????├──?demo
│???????│???└──?restful
│???????├──?e2e
│???????│???└──?scenarios.yml
│???????├──?logback.xml
│???????└──?rythm
│???????????└──?demo
│???????????????└──?restful
└──?test
└──?java
└──?demo
4.1 項目啟動入口: AppEntry
我們看到生成的項目中有一個 AppEntry.java 文件, 打開該文件, 其內容為:public?class?AppEntry?{????public?static?void?main(String[]?args)?throws?Exception?{
Act.start();
}
}
這是一個很簡單的 Java 類, 其作用是啟動 ActFramework.
4.2 服務類: Service
打開本項目中的另一個 Java 文件 Service.java:public?class?Service?{????@GetAction("hello")????public?String?hello(@DefaultValue("World")?String?who)?{????????return?"Hello?"?+?who;
}????@GetAction("date")????public?DateTime?date()?{????????return?DateTime.parse("2016-03-09");
}
}
代碼很簡單, 提供了兩個 RESTful 數據服務端口:
4.2.1 GET /hello
當訪問這個服務端口的時候, 應用返回 "Hello xxx" 形式的內容, 其中 xxx 是通過請求參數 who 傳遞的, 如果請求沒有提供這個參數, 則使用默認值 World, 即, 返回 "Hello World" 字串.
4.2.2 GET /date
這個服務端口不接受參數, 直接返回一個日期數據
4.3 運行腳本
maven 為項目生成了幾個可執行腳本文件:run_dev - 以開發模式啟動項目
run_dev.bat - run_dev 的 windows 版本
run_e2e - 運行端到端測試
run_e2e.bat - run_e2e 的 windows 版本
run_prod - 以產品模式啟動項目
我們沒有提供 run_prod 腳本的 windows 版本, 主要原因是 windows 沒有默認安裝支持解包 tar.gz 文件的命令行應用. 如果需要在 windows 下運行產品模式可以這樣做:運行 mvn clean package
到項目的 target/dist 目錄下, 找到 tar.gz 文件, 使用第三方工具, 比如 7zip 等解包, 然后運行 run.bat 文件
5. 啟動應用
下面我們使用 run_dev 腳本, 或者直接使用 mvn compile act:run 啟動應用:__??___?????????_????????_???????__???_???_?????????___???_???_
(_????|???|\/|??|_)??|???|_??__??(_???|_??|_)??\??/???|???/???|_
__)??_|_??|??|??|????|_??|_??????__)??|_??|?\???\/???_|_??\_??|_
powered?by?ActFramework?r1.8.8-RC4-aa2d4
version:?v1.0-SNAPSHOT-180513_2237
scan?pkg:
base?dir:?/tmp/1/simple-service
pid:?26126
profile:?dev
mode:?DEV
zen:?Flat?is?better?than?nested.
2018-05-13?22:37:47,875?INFO??a.Act@[main]?-?loading?application(s)?...
2018-05-13?22:37:47,885?INFO??a.a.App@[main]?-?App?starting?....
2018-05-13?22:37:48,104?WARN??a.h.b.ResourceGetter@[main]?-?URL?base?not?exists:?META-INF/resources/webjars
2018-05-13?22:37:48,119?WARN??a.a.DbServiceManager@[main]?-?DB?service?not?initialized:?No?DB?plugin?found
2018-05-13?22:37:48,741?WARN??a.m.MailerConfig@[main]?-?smtp?host?configuration?not?found,?will?use?mock?smtp?to?send?email2018-05-13?22:37:49,033?INFO??a.a.App@[main]?-?App[simple-service]?loaded?in?1148ms2018-05-13?22:37:49,037?INFO??a.a.ApiManager@[jobs-thread-3]?-?start?compiling?API?book2018-05-13?22:37:49,055?INFO??o.xnio@[main]?-?XNIO?version?3.3.8.Final2018-05-13?22:37:49,143?INFO??o.x.nio@[main]?-?XNIO?NIO?Implementation?Version?3.3.8.Final2018-05-13?22:37:49,244?INFO??a.Act@[main]?-?network?client?hooked?on?port:?54602018-05-13?22:37:49,245?INFO??a.Act@[main]?-?CLI?server?started?on?port:?54612018-05-13?22:37:49,246?INFO??a.Act@[main]?-?app?is?ready?at:?http://192.168.1.2:54602018-05-13?22:37:49,246?INFO??a.Act@[main]?-?it?takes?2149ms?to?start?the?app
項目啟動之后可以從瀏覽器來訪問. 首先來看 GET /hello 服務端口的情況:
再請求中加入一個 who 參數再試試:
最后看看 GET /date 服務端口:
6. 測試
我們已經使用瀏覽器來驗證項目可以正常運行, 也能得到期望的結果. 對于簡單的應用來講, 可以使用這種方式進行測試, 但隨著項目的開發, 更多的服務端口會加入進來, 每次都這樣來運行測試, 對開發測試人員來說是很大的負擔. 下面我們先運行一下生成的 run_e2e 腳本, 或者也可以直接使用 maven 命令 mvn compile act:e2e:Listening?for?transport?dt_socket?at?address:?5005
__??___?????????_????????_???????__???_???_?????????___???_???_
(_????|???|\/|??|_)??|???|_??__??(_???|_??|_)??\??/???|???/???|_
__)??_|_??|??|??|????|_??|_??????__)??|_??|?\???\/???_|_??\_??|_
powered?by?ActFramework?r1.8.8-RC4-aa2d4
version:?v1.0-SNAPSHOT-180513_2248
scan?pkg:
base?dir:?/tmp/1/simple-service
pid:?27429
profile:?e2e
mode:?DEV
zen:?Simple?things?should?be?simple,?complex?things?should?be?possible.
2018-05-13?22:48:52,651?INFO??a.Act@[main]?-?loading?application(s)?...
2018-05-13?22:48:52,661?INFO??a.a.App@[main]?-?App?starting?....
2018-05-13?22:48:52,882?WARN??a.h.b.ResourceGetter@[main]?-?URL?base?not?exists:?META-INF/resources/webjars
2018-05-13?22:48:52,895?WARN??a.a.DbServiceManager@[main]?-?DB?service?not?initialized:?No?DB?plugin?found
2018-05-13?22:48:53,580?WARN??a.m.MailerConfig@[main]?-?smtp?host?configuration?not?found,?will?use?mock?smtp?to?send?email2018-05-13?22:48:53,910?INFO??a.a.App@[main]?-?App[simple-service]?loaded?in?1249ms2018-05-13?22:48:53,914?INFO??a.a.ApiManager@[jobs-thread-2]?-?start?compiling?API?book2018-05-13?22:48:54,017?INFO??o.xnio@[main]?-?XNIO?version?3.3.8.Final2018-05-13?22:48:54,032?INFO??o.x.nio@[main]?-?XNIO?NIO?Implementation?Version?3.3.8.Final2018-05-13?22:48:54,130?INFO??a.Act@[main]?-?network?client?hooked?on?port:?54602018-05-13?22:48:54,131?INFO??a.Act@[main]?-?CLI?server?started?on?port:?54612018-05-13?22:48:54,132?INFO??a.Act@[main]?-?app?is?ready?at:?http://192.168.1.2:54602018-05-13?22:48:54,133?INFO??a.Act@[main]?-?it?takes?2332ms?to?start?the?appStart?running?E2E?test?scenarios
================================================================================
HELLO?SERVICE
a?service?says?hello--------------------------------------------------------------------------------[PASS]?send?request?to?hello?service?without?parameter
[PASS]?send?request?to?hello?servcie?with?parameter?specified
[PASS]?send?request?to?hello?servcie?with?parameter?specified?and?require?JSON?response--------------------------------------------------------------------------------It?takes?0s?to?run?this?scenario.
================================================================================DATE?SERVICE
A?service?returns?an?important?date?in?the?history--------------------------------------------------------------------------------[PASS]?send?request?to?the?service
[PASS]?send?request?to?the?service?and?request?response?be?JSON?format--------------------------------------------------------------------------------It?takes?0s?to?run?this?scenario.2018-05-13?22:48:55,224?INFO??a.a.App@[jobs-thread-4]?-?App?shutting?down?....
[INFO]?------------------------------------------------------------------------[INFO]?BUILD?SUCCESS[INFO]?------------------------------------------------------------------------[INFO]?Total?time:?5.874?s
[INFO]?Finished?at:?2018-05-13T22:48:55+10:00[INFO]?Final?Memory:?26M/389M
[INFO]?------------------------------------------------------------------------
我們看到項目啟動之后運行了 E2E 測試場景, 包括對 GET /hello 和 GET /date 的 5 個測試用例, 并且都通過了測試. 下面打開 src/main/resources/e2e/scenarios.yml 文件來看看測試場景和用例是如何定義的:Scenario(Hello?Service):??description:?a?service?says?hello??interactions:????-?description:?send?request?to?hello?service?without?parameter??????request:????????method:?GET????????url:?/hello??????response:????????text:?Hello?World?#?response?text?must?be?"Hello?World"????-?description:?send?request?to?hello?servcie?with?parameter?specified??????request:????????method:?GET????????url:?/hello?who=ActFramework??????response:
#?this?time?we?demonstrate?how?to?verify?text?with?a?list?of?verifiers????????text:??????????-?eq:?Hello?ActFramework?#?value?must?be?equal?to?"Hello?ActFramework"??????????-?contains:?ActFramework?#?value?must?contains?"ActFramework"??????????-?starts:?Hello?#?value?must?starts?with?"Hello"??????????-?ends:?Framework?#?value?must?ends?with?"Framework"????-?description:?send?request?to?hello?servcie?with?parameter?specified?and?require?JSON?response??????request:????????json:?true?#?specify?accept?type?is?application/json????????method:?GET????????url:?/hello?who=Java??????response:????????json:?#?treat?result?as?a?JSON?object
#?act?returns?json?result?in?`{"result":?...}`?style??????????result:?Hello?Java?#?result?property?of?the?JSON?object?must?be?"Hello?World"#?Test?Service#date()?endpoint,?which?is?available?at?`GET?/date`?endpointScenario(Date?Service):??description:?A?service?returns?an?important?date?in?the?history??interactions:????-?description:?send?request?to?the?service??????request:????????method:?GET????????url:?/date??????response:????????text:??????????-?after:?1997-05-11?#?the?returned?date?should?be?after?date?1997-05-11??????????-?before:?13/May/2018?#?the?returned?date?should?be?before?date?13/May/2018????-?description:?send?request?to?the?service?and?request?response?be?JSON?format??????request:????????json:?true????????method:?GET????????url:?/date??????response:????????json:?#?treat?result?as?a?JSON?object
#?act?returns?json?result?in?`{"result":?...}`?style??????????result:??#?thus?we?will?use?`result`?to?fetch?the?date????????????-?after:?1997-05-11?#?the?returned?date?should?be?after?date?1997-05-11????????????-?before:?13/May/2018?#?the?returned?date?should?be?before?date?13/May/2018
這個文件還是很容易理解, 其內容基本是按照下面的方式組織的:首先第一層定義測試場景 Scenario, 每個 Scenario 都會給出一個名字放進圓括弧中. 我們在文件中定義了兩個 ScenarioHello Service - 測試 GET /hello 端口
Date Service - 測試 GET /date 端口
場景 (Scenario) 下面定義一個或者多個交互 Interactions
對每個交互定義請求 Request 和 響應 Response
請求 Request 的內容包括方法和 URL, 也可以指定是否要求返回 JSON 格式的請求
響應 Response 則定義期望返回內容的驗證
針對每個服務端口可以寫一個或多個場景, 也可以在一個場景中順序測試多個服務端口. 完全有應用自己來定義.
7. 總結
本文介紹了如何使用 maven archetype 來生成一個可測試 RESTful 數據服務項目的腳手架, 以及如何通過定義 e2e/scenarios.yml 文件來提供自動測試的功能. 希望能夠對大家帶來幫助.
參考:
作者:羅格林
來源:https://my.oschina.net/greenlaw110/blog/1811714
總結
以上是生活随笔為你收集整理的java maven restful_使用 maven 生成一个支持端到端自动测试的 RESTful 服务项目脚手架...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux resin 服务功能,lin
- 下一篇: java输出华氏摄氏温度转换表_Pyth