使用JBehave,Gradle和Jenkins的行為驅動開發(BDD)

行為驅動開發 (BDD)是一個協作過程 ,產品負責人,開發人員和測試人員可以合作交付可為企業帶來價值的軟件。

BDD是 測試驅動開發 (TDD) 的合理下一步 。

行為驅動的發展

本質上,BDD是一種交付需求的方法。 但不僅有任何要求,還包括可執行要求! 使用BDD,您可以以可以針對該軟件運行的格式來編寫方案 ,以確定該軟件是否按預期運行。

情境

場景以“ 給定,何時,然后”格式(也稱為Gherkin)編寫:

Given the ATM has $250
And my balance is $200
When I withdraw $150
Then the ATM has $100
And my balance is $50

Given表示初始上下文, When表示發生有趣的事件, 然后斷言預期的結果。 并且可以用來代替重復的關鍵字,以使方案更具可讀性。

Give / When / Then是一個非常強大的習慣用法 ,幾乎可以描述任何要求。 這種格式的場景也很容易解析,因此我們可以自動運行它們。

BDD場景對開發人員非常有用,因為它們提供了有關故事是否完成的快速而明確的反饋。 不僅可以提供主要成功方案,還可以提供替代方案和異常方案 ,如濫用案例 。 后者要求產品負責人不僅要與測試人員和開發人員合作,還要與安全專家合作。 結果是, 管理安全要求變得更加容易。

盡管BDD實際上是關于協作過程的,而不是關于工具的,但在本文的其余部分中,我將專注于工具。 請記住, 工具永遠無法挽救您,而溝通和協作則可以 。 消除了這一警告,讓我們開始使用一些開源工具來實現BDD。

杰貝夫

JBehave是Java的BDD工具。 它從故事文件中解析場景,將它們映射到Java代碼,通過JUnit測試運行它們,并生成報告。

JUnit的

這是我們使用JUnit運行故事的方式:

@RunWith(AnnotatedEmbedderRunner.class)
@UsingEmbedder(embedder = Embedder.class, generateViewAfterStories = true,ignoreFailureInStories = true, ignoreFailureInView = false, verboseFailures = true)
@UsingSteps(instances = { NgisRestSteps.class })
public class StoriesTest extends JUnitStories {@Overrideprotected List<String> storyPaths() {return new StoryFinder().findPaths(CodeLocations.codeLocationFromClass(getClass()).getFile(),Arrays.asList(getStoryFilter(storyPaths)), null);}private String getStoryFilter(String storyPaths) {if (storyPaths == null) {return '*.story';}if (storyPaths.endsWith('.story')) {return storyPaths;}return storyPaths + '.story';}private List<String> specifiedStoryPaths(String storyPaths) {List<String> result = new ArrayList<String>();URI cwd = new File('src/test/resources').toURI();for (String storyPath : storyPaths.split(File.pathSeparator)) {File storyFile = new File(storyPath);if (!storyFile.exists()) {throw new IllegalArgumentException('Story file not found: ' + storyPath);}result.add(cwd.relativize(storyFile.toURI()).toString());}return result;}@Overridepublic Configuration configuration() {return super.configuration().useStoryReporterBuilder(new StoryReporterBuilder().withFormats(Format.XML, Format.STATS, Format.CONSOLE).withRelativeDirectory('../build/jbehave')).usePendingStepStrategy(new FailingUponPendingStep()).useFailureStrategy(new SilentlyAbsorbingFailure());}}

這使用JUnit 4的@RunWith注釋指示將運行測試的類。 AnnotatedEmbedderRunner是JBehave提供的JUnit Runner 。 它尋找@UsingEmbedder批注以確定如何運行故事:

  • generateViewAfterStories指示JBehave在運行故事后創建測試報告
  • 當故事失敗時, ignoreFailureInStories防止JBehave引發異常。 這對于與Jenkins集成至關重要,如下所示

@UsingSteps批注將方案中的步驟鏈接到Java代碼。 下面的更多內容。 您可以列出多個類別。

我們的測試類重新使用了JBehave的JUnitStories類,這使得運行多個故事變得容易。 我們只需要實現兩種方法: storyPaths()configuration()

storyPaths()方法告訴JBehave在哪里找到要運行的故事。 我們的版本有點復雜,因為我們希望能夠從IDE和命令行運行測試,并且希望能夠運行所有故事或特定子集。

我們使用系統屬性bdd.stories指示要運行的故事。 這包括對通配符的支持。 我們的命名約定要求故事文件名以角色開頭,因此我們可以使用-Dbdd.stories=wanda_*類的-Dbdd.stories=wanda_*輕松地為單個角色運行所有故事。

configuration()方法告訴JBehave 如何運行故事并對其進行報告 。 我們需要XML輸出,以便在Jenkins中進行進一步處理,如下所示。

感興趣的一件事是報告的位置。 JBehave支持Maven,這很好,但是他們假定每個人都遵循Maven約定,但事實并非如此。 默認情況下,輸出進入一個名為target的目錄,但是我們可以通過指定相對于target目錄的路徑來覆蓋該目錄。 我們使用Gradle代替Maven,并且Gradle的臨時文件進入build目錄,而不是target 。 有關Gradle的更多信息,請參見下文。

腳步

現在我們可以運行我們的故事,但是它們會失敗。 我們需要告訴JBehave如何將場景中的Given / When / Then步驟映射到Java代碼。 步驟類確定可以在方案中使用的詞匯表。 因此,他們定義了一種用于接受測試我們的應用程序的領域特定語言 (DSL)。

我們的應用程序具有RESTful接口,因此我們編寫了通用的REST DSL。 但是,由于REST中的HATEOAS約束,客戶端需要大量調用才能發現其應使用的URI。 這樣寫場景變得很無聊和重復,因此我們在REST DSL之上添加了特定于應用程序的DSL。 這使我們可以用產品負責人理解的術語來編寫方案 。

在通用REST步驟之上分層特定于應用程序的步驟具有一些優點:

  • 實施新的特定于應用程序的DSL很容易,因為他們只需要調用REST特定的DSL
  • REST專用的DSL可以與其他項目共享

搖籃

有了步驟,我們可以從我們最喜歡的IDE中運行我們的故事。 這對開發人員來說效果很好,但不能用于持續集成 (CI)。

我們的CI服務器運行無頭構建,因此我們需要能夠從命令行運行BDD方案。 我們使用Gradle使構建自動化,并且Gradle已經可以運行JUnit測試。 但是,我們的構建是一個多項目構建。 在構建所有項目,創建發行版并啟動應用程序之前,我們不希望運行BDD方案。

因此,首先,我們禁止在包含BDD故事的項目上運行測試:

test {onlyIf { false } // We need a running server
}

接下來,我們創建另一個可以在啟動應用程序后運行的任務:

task acceptStories(type: Test) {ignoreFailures = truedoFirst {// Need 'target' directory on *nix systems to get any outputfile('target').mkdirs()def filter = System.getProperty('bdd.stories') if (filter == null) {filter = '*'}def stories = sourceSets.test.resources.matching { it.include filter}.asPathsystemProperty('bdd.stories', stories)}
}

在這里,我們看到了Gradle的力量。 我們定義了一個Test類型的新任務,以便它已經可以運行JUnit測試。 接下來,我們使用一些Groovy腳本配置該任務。

首先,我們必須確保target目錄存在。 我們不需要甚至不需要它,但是如果沒有它,JBehave將無法在* nix系統上正常工作。 我想這有點Maven主義

接下來,再次使用bdd.stories系統屬性添加對運行故事子集的支持。 我們的故事文件位于src/test/resources ,因此我們可以使用標準Gradle test 源集輕松訪問它們。 然后,我們為運行測試的JVM設置系統屬性bdd.stories

詹金斯

現在,我們可以從IDE和命令行運行BDD方案。 下一步是將它們集成到我們的CI版本中。

我們可以將JBehave報告存檔為工件,但是,老實說,JBehave生成的報告并不是很好。 幸運的是,JBehave團隊還維護了Jenkins CI服務器的插件 。 該插件需要事先安裝xUnit插件 。

將xUnit和JBehave插件安裝到jenkins中之后,我們可以配置Jenkins作業以使用JBehave插件。 首先,添加xUnit構建后操作。 然后,選擇JBehave測試報告。

使用此配置,在我們的BDD故事上運行JBehave的輸出看起來像常規單元測試的輸出:

請注意,圖中的黃色部分表示待處理的步驟。 那些用于BDD場景,但是在Java Steps類中沒有。 等待結果顯示在測試結果的“ Skip列中:

請注意,JBehave Jenkins插件如何將故事轉換為測試,將場景轉換為測試方法。 這樣可以很容易地發現哪些方案需要更多工作。

盡管JBehave插件運行良好,但是有兩點可以改進:

  • 測試的輸出未顯示。 這使得很難弄清楚場景失敗的原因。 因此,我們還存檔了JUnit測試報告
  • 如果將ignoreFailureInStories配置為false ,則JBehave會在失敗時引發異常,該異常會截斷XML輸出。 然后,JBehave Jenkins插件將無法再解析XML(因為它的格式不正確),并且會完全失敗,從而使您沒有測試結果

所有這些都是不便之處,我們對自動化的BDD方案感到非常滿意。

祝您編程愉快,別忘了分享!

參考: 安全軟件開發博客上來自JCG合作伙伴 Remon Sinnema的JBehave,Gradle和Jenkins的行為驅動開發(BDD) 。


翻譯自: https://www.javacodegeeks.com/2012/09/behavior-driven-development-bdd-with.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/371465.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/371465.shtml
英文地址,請注明出處:http://en.pswp.cn/news/371465.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

手型顯示html,css各種手型集合(css禁止手型)

html>css各種手型集合(css禁止手型).auto { cursor: auto; }.deafult { cursor: default; }.none { cursor: none; }.context-menu { cursor: context-menu; }.help { cursor: help; }.pointer { cursor: pointer; }.p…

Maven Fluido Skin和Javadoc類圖

我使用Maven網站已有一段時間了&#xff0c;對此我感到非常滿意。 我不想在Maven 3之后更新我的項目&#xff0c;但是沒關系&#xff0c;Maven 3帶來了許多新奇的東西。 但是&#xff0c;有兩件事使我感到煩惱&#xff1a;缺乏美觀和現代的外觀&#xff0c;以及瀏覽復雜代碼的J…

ZooKeeper安裝,部署

實驗環境 192.168.1.10  Zookeeper1:2181, Zookeeper2:2182 192.168.1.11  ZooKeeper3:2181 依賴環境 JDK1.7 安裝&#xff0c;配置 1、下載解壓 # 192.168.1.10cd /data/server tar -zxv -f zookeeper-3.4.6.tar.gz ln -s zookeeper-3.4.6 zookeeper1ln -s zookeeper-3.4.…

咸寧省2021年模擬高考成績查詢怎么查,2021咸寧市地區高考成績排名查詢,咸寧市高考各高中成績喜報榜單...

距離2018年高考還有不到一個月的時間了&#xff0c;很多人在準備最后沖刺的同時&#xff0c;也在關心高考成績。2018各地區高考成績排名查詢,高考各高中成績喜報榜單尚未公布&#xff0c;下面是往年各地區高考成績排名查詢,高考各高中成績喜報榜單&#xff0c;想要了解同學可以…

保證主題,JMS規范和ActiveMQ的消息傳遞

最近&#xff0c;一個客戶要求我仔細研究ActiveMQ的“持久”消息的實現&#xff0c;它如何應用于主題以及在存在非持久訂閱者的故障轉移方案中會發生什么。 我已經了解到&#xff0c;JMS語義規定&#xff0c;即使面對消息代理提供者失敗&#xff0c;也只能保證主題的持久訂戶以…

java中的除法及求余運算特殊性。

1.如果除法運算符的兩個操作數都是整數類型&#xff0c;則計算結果也是整數&#xff0c;就是將自然除法的結果截斷取整&#xff0c;例如19/4的結果是4&#xff0c;而不是5。并且除數不能0&#xff0c;否則將引起除0異常 2.如果運算符的兩個操作數有1個是浮點數&#xff0c;或兩…

林海峰老師python課件密碼

egon4573轉載于:https://www.cnblogs.com/fengjunhua/p/7395591.html

國際旅游管理專業跨專業考計算機,旅游管理考研我想跨專業考旅游管理專業的研究 – 手機愛問...

2005-12-11我是學旅游管理的大一學生,聽人說這專業就這位兄弟提出的苦惱在大學生中很典型呀!其實你說的不盡然!旅游管理專業,是個很有前景的專業呀!怎么會沒有前途呀?你對自己的人生也太悲觀了吧?就是你說,學校不太好,這可能對自身在大學四年的發展有所限制,但這主要還是看自…

Java注釋:探究和解釋

Java 5 SE的許多出色功能之一是Annotations構造的引入。 注釋是一些標簽&#xff0c;我們可以將其插入程序源代碼中&#xff0c;以使用某種工具對其進行處理并使其變得有意義。 注釋處理工具通常使用&#xff08;Java 5 SE的&#xff09;Reflection API在Java代碼或字節碼級別的…

C# 類

一 string 類型 變量.Length - 字符串長度&#xff0c;返回int類型 string s "abcdefg"; int a s . Length; Console.WriteLine(a); // 輸出結果為&#xff1a;7&#xff08;此字符串有7個字符&#xff09; // Length返回有多少個字符&am…

node+mongodb+win7

一、安裝mongodb&#xff0c;參照教程&#xff0c;注意要先啟動mongod.exe&#xff0c;再啟動mongd.exe。 轉載于:https://www.cnblogs.com/iloveyou-sky/p/7396997.html

cdrom是多媒體微型計算機,全國計算機二級題庫第三章

同時按下CTRLALTDEL組合鍵的作用是(使用任務管理器關閉不響應的應用程序下列說法正確的是(在微型機性能指標中&#xff0c;CPU的主頻越離&#xff0c;其運算速度越快)微型計算機鍵盤上的Tab鍵是(交替換檔鍵)微型計算機鍵盤上的Enter鍵是(回車鍵)微型計算機的運行速度的單位是mi…

Spring MVC控制器JUnit測試

JUnit測試Spring MVC控制器并非易事 。 但是最近&#xff0c;一個新項目 &#xff08;即將在Spring推出&#xff09;提供了新工具來簡化此工作。 這篇文章說明了如何通過JUnit測試來測試一個簡單的控制器。 該代碼是JUnit Testing Spring Service和DAO&#xff08;帶有內存數據…

java基礎03變量和基本數據類型

package cn.bdqn.test;/*** * author 小豆腐* * 變量&#xff1a;會變化的量&#xff1f;&#xff1f;* 一個數據在內存中存儲空間的表示&#xff01;在運行期間可以動態改變&#xff01;* * 關鍵字:在java中已經被使用或者定義的單詞&#xff01;不能作為變量名&#xff01…

5.set集合

list_1 [1,2,3,4,5]list_2 [1,3,5,7,9]#列表轉成set集合set_1 set(list_1)set_2 set(list_2)#交集print(set_1.intersection(set_2))print(set_1 & set_2)#判斷沒有交集print(set(["a","b"]).isdisjoint(set_1))#并集print(set_1.union(set_2))pri…

JavaFX中基于表達式的PathTransitions

在JavaFX中&#xff0c;您可以使用PathTransition對象為路徑上的節點設置動畫。 PathTransitions使用Shape對象描述它們需要沿其動畫的路徑。 JavaFX提供了各種類型的形狀&#xff08;例如&#xff0c;多邊形&#xff0c;圓形&#xff0c;多邊形&#xff0c;路徑&#xff09;。…

html 顯示視頻列表,dvd光碟制作節目軌菜單布局,不要視頻縮略圖,只顯示文件列表...

“如何在刻錄視頻光盤時自定義制作菜單&#xff1f;實現的效果就是當光盤插入DVD影碟機播放時&#xff0c;首先會出現一個所有視頻文件列表的菜單(節目軌菜單)&#xff0c;就相似于音樂CD曲目表一樣&#xff0c;不需要有視頻縮略圖&#xff0c;可通過遙控器選擇性播放列表中某一…

v3學院教你學習-task和function的異同

v3學院教你學習-task和function的異同 task&#xff08;任務&#xff09;與function&#xff08;函數&#xff09;的不同 任務與函數主要有以下四點不同&#xff1a; l 函數只能與主模塊共用一個仿真時間單位&#xff0c;而任務定義自己的仿真時間單位。 l 函數不能啟動任務&am…

Spring事件的觀察者模式

介紹 觀察者模式的本質是“定義對象之間的一對多依賴關系&#xff0c;以便當一個對象改變狀態時&#xff0c;其所有依賴關系都會得到通知并自動更新。” GoF。 觀察者模式是發布/訂閱模式的子集&#xff0c;它允許許多觀察者對象查看事件。 可以在不同的情況下使用此模式&#…

jQuery選擇什么版本 1.x? 2.x? 3.x?

目前jQuery有三個大版本&#xff1a; 1.x&#xff1a;兼容ie678,使用最為廣泛的&#xff0c;官方只做BUG維護&#xff0c;功能不再新增。因此一般項目來說&#xff0c;使用1.x版本就可以了&#xff0c;最終版本&#xff1a;1.12.4 (2016年5月20日)2.x&#xff1a;不兼容ie678&a…