日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Spock Primer 翻译

發(fā)布時間:2023/12/10 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spock Primer 翻译 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

起因

最近要搞groovy介紹,準(zhǔn)備做成一系列的東西,參考github上的計劃。
https://github.com/javahub/groovy_hello

spock沒有找到翻譯文檔,動手把最重要的一章primer翻譯下,想起了c++ primer。
就當(dāng)作翻譯練習(xí)了。

目前項目大使用spock做測試,也是比較推薦的方式。簡潔清爽

Spock Primer

這一章假設(shè)你有關(guān)于groovy與單元測試基本知識。如果你是java開發(fā)者,但沒聽說過groovy,別擔(dān)心,groovy對java開發(fā)者來說非常友好。事實上,groovy相關(guān)抓喲設(shè)計目標(biāo)是與java共存腳本語言。因此只需要繼續(xù)并查看groovy doc

這一章目標(biāo)是教會你足夠?qū)懻鎸峴pec的spock,并且激起你的食欲

學(xué)習(xí)更多關(guān)于groovy,點http://groovy-lang.org/.

學(xué)些更多關(guān)于單元測試,點 http://en.wikipedia.org/wiki/Unit_testing.

術(shù)語

讓我們開始一些定義:spock 讓你寫描述期望特性展示spec作為系統(tǒng)關(guān)注點,系統(tǒng)感興趣關(guān)注點可以是一個簡單的類和整個系統(tǒng)中的任何事,并且被稱為spec下的系統(tǒng)(sus)。一個特性描述開始于spec sus的臨時快照并且作為一個合作者。快照被稱作特性fixture

接下來的部分沿著在spock的spec可能組合構(gòu)建blocks。一個常規(guī)spec能使用它們的中一部分。

Specification

一個spec表現(xiàn)為繼承spock.lang.Specification的一個groovy 類。spec名字通常描述系統(tǒng)或系統(tǒng)操作。例如: CustomerSpec, H264VideoPlayback, and ASpaceshipAttackedFromTwoSides是一個規(guī)范合理的名稱

spec類包含一系統(tǒng)有用的方法,此處它含義為spec用Sputnik在junit中運行,spock的junit runner,感謝Sputnik,spock spec能運行在大多數(shù)的ides和構(gòu)建工具

Fields

def obj = new ClassUnderSpecification() def coll = new Collaborator()

對象實例字段是一個好的地方去存儲屬于spec fixture 。它是一個好的實踐在正確初始化他們在定義時候。(語義上它等價于初始化他們在setup()方法).存儲這些實例字段的對象不應(yīng)該分享在feature方法之間。取而代之,每個特性方法得到他們自己的初始化對象。這個幫助在相互間獨立隔離特性方法,提供一個好的目標(biāo)。

@Shared res = new VeryExpensiveResource()

一些時候你需要分享一個對象在特性方法之間。例如對象可能創(chuàng)建很昂貴,或者你可能想在不同特性方法指南交互。為了實現(xiàn)這一點,定義@Shared 字段,它最好事初始化正確字段在一個定義點(語義上等價等價與setupSpec)

static final PI = 3.141592654

靜態(tài)字段應(yīng)該是常量,寧一方面shared字段是完美的,因為他的語義表現(xiàn)了更好的定義。

Fixture Methods

Fixture Methods def setup() {} // run before every feature method def cleanup() {} // run after every feature method def setupSpec() {} // run before the first feature method def cleanupSpec() {} // run after the last feature method

fixture方法負(fù)責(zé)在環(huán)境設(shè)置清理在每個特性方法運行。通常它是一個好的idea使用刷新fixture 方法在為每個fixture方法,在setup() and cleanup() 做這個。偶爾對特性方法分享是由意義的。他實現(xiàn)了分享使用shared字段與setupSpec() and cleanupSpec() methods。
所有fixture方法都是可選擇的。

說明:setupSpec cleanupSpec 方法不能飲用實例字段

Feature Methods

def "pushing an element on the stack"() { // blocks go here }

Feature 方法是一個spec核心,他描述了你期待系統(tǒng)的在sus下的特性集。根據(jù)約定,特性方法唄命名字符串常量。試著為你的特性方法選擇一個好的方法。并且隨心使用你喜歡的特性。

概念,一個特性方法包括四個語義段:
設(shè)置特性的fixture
提供sus的刺激
描述系統(tǒng)期待的結(jié)果
清理fixture

Blocks

spock實現(xiàn)支持每個feature方法概念語法階段作為一個特性方法。對結(jié)束來說,特性方法被構(gòu)建為一個叫做blocks。blocks開始于一個label并且擴(kuò)展開始下一個label或者方法結(jié)束。這個有六個blocks:setup, when, then, expect, cleanup, and where blocks.。任何語句在方法開始與第一次
隱含的setup block之間。

一個特性方法必須至少一個清晰的label,實際上,一個直接的block表現(xiàn)。Blocks 決定一個方法不同部分并且不能嵌套。

Blocks2Phases
這個右側(cè)圖片展示block如何匹配一個特性方法語法概念。那里的block有一個特殊的角色,被簡單的展現(xiàn)出來,但首先讓我們有一個近距離查看這個block

Setup Blocks

setup: def stack = new Stack() def elem = "push me"

這個setup block 你能做任何你想setpup工作為你想描述的特性。他可能不能被前面其他block處理,并且不能重復(fù)。一個setup block 沒有任何特殊的語義。setup: label時可選的并被提交。結(jié)果在一個直接設(shè)置的block。given: label是一個setup的別名,并且一些時候?qū)е赂嗟目痰奶匦苑椒枋觥?/p>

When and Then Blocks

when與then blocks when: //刺激 then://響應(yīng)

when與then blocks 一直一起出現(xiàn)。他們描述一個刺激發(fā)生并響應(yīng)期待。
when blocks能包含任意代碼;
then blocks被禁止使用在條件,異常條件,交互與變量定義。
一個特性方法可能匹配多個when-then 塊

Conditions

Conditions被描述為一個期待的狀態(tài),必須像junit的assertions。然而,conditions被寫做一個描述布爾表達(dá)式,消除為必需的assertion API(恰恰更多的是一個條件唄處理為一個非布爾表達(dá)式,將會被作為處理根據(jù)groovy truth)讓我們來看一些場景在以下

stack.size() == 2 | | | | 1 false

盡可能保持在每個小特性方法里的條件數(shù)量。一到五個是一個好的指導(dǎo)。如果你有更多,你得問自己,如果在一個場景下有多個不相關(guān)的特性被提及。答案如果是yes,在幾個小的特性方法重構(gòu)。如果你的場景時只有不同的值,考慮使用數(shù)據(jù)表驅(qū)動(spock帶有這個特性)

如果一個條件沒通過,spock提供什么樣的反饋。讓我們試并改變第二個場景

如你所見,spock在一個場景執(zhí)行期間,捕獲所有值處理在,并在一個容易理解的形式表現(xiàn)他們。干得漂亮,不是么?

Implicit and explicit conditions

場景必須有一個 then blocks and expect blocks其中之一。出了調(diào)用空方法雨歸類表達(dá)式作為交互,所有頂級表達(dá)式在這些塊里面是隱含作為場景對待。在別的地方使用題哦安,你需要設(shè)計他們使用groovy的assert關(guān)鍵字。

def setup() { stack = new Stack() assert stack.empty }

如果顯試條件被觸發(fā),他將處理一些相同的診斷信息作為隱含條件。

Exception Conditions

異常場景唄使用描述作為一個when 語句塊應(yīng)該拋出一個異常。他們被定義使用 thrown()方法,被傳遞期待的異常類型。例如,描述被彈出一個空stack 應(yīng)該拋出EmptyStackException,你能像下面這樣寫

when: stack.pop()then: thrown(EmptyStackException) stack.empty

如你所見,異常場景可能是跟別的場景相關(guān)。這個特別有用為對詳細(xì)說明期待內(nèi)容作為異常,訪問這個異常,首先綁定一個變量。

when: stack.pop()then: def e = thrown(EmptyStackException) e.cause == null

寧外,你也可以使用上面語法作為一個輕微有變化

when: stack.pop()then: EmptyStackException e = thrown() e.cause == null

這個語法有兩個小優(yōu)勢,首先,異常變量時強類型,讓它非常容易被ide補全。其次,場景讀起來有一點更像句子。注意,如果沒有異常類型被傳遞在thrown方法,它從左邊的變量類型被推斷

一些時候我們需要表達(dá)一個異常不應(yīng)該被拋出。例如,讓我們嘗試表達(dá)hashmap不應(yīng)該接受null key。

def "HashMap accepts null key"() {setup:def map = new HashMap()map.put(null, "elem") }

一些時候我們需要表達(dá)一個異常不應(yīng)該被拋出。例如,讓我們嘗試表達(dá)hashmap不應(yīng)該接受null key。

這個表示不能揭示代碼的含義。 是否有人離開構(gòu)建之前就完成實現(xiàn)了這個方法。畢竟,場景在哪里? 幸運是我們能做更好。

def "HashMap accepts null key"() {setup: def map = new HashMap()when:map.put(null, "elem")then:notThrown(NullPointerException) }

通過使用notThrown。我們能使清晰在一個特殊的NullPointerException 不應(yīng)該被拋出。(按照Map.put()方法的約定,它是正確的事情不支持null keys在map上使用。)然而,方法將會失敗如果有任何逼的異常拋出。

Interactions

盡管條件描述了一個對象的狀態(tài),交互描述了對象互相間關(guān)系。交互被轉(zhuǎn)用于一章。所以我們只快速給一個例子在這。假設(shè)我們想描述從一個發(fā)布者到訂閱者的事件流。代碼如下

def "events are published to all subscribers"() {def subscriber1 = Mock(Subscriber)def subscriber2 = Mock(Subscriber)def publisher = new Publisher()publisher.add(subscriber1)publisher.add(subscriber2)when: publisher.fire("event")then: 1 * subscriber1.receive("event") 1 * subscriber2.receive("event")

Expect Blocks

一個expect block 比then block有更多的限制。他可能包含場景與變量定義。它是有用的情形當(dāng)他更加自然描述刺激與期待結(jié)果響應(yīng)在一個簡單的表達(dá)式里。例如,比較下面兩個描述 Math.max()方法。

when:def x = Math.max(1, 2)then:x == 2expect:Math.max(1, 2) == 2

盡管兩個片段時語義等價。第二個是更清晰選擇。作為一個指引,使用when-then 去描述帶有副作用。并且期待描述純碎的函數(shù)方法。

TIP

利用groovy jdk方法像any() every()去創(chuàng)建更多表現(xiàn)力與簡潔的條件。

Cleanup Blocks

setup: def file = new File("/some/path") file.createNewFile() // ... cleanup: file.delete()

cleanup block

只能跟著where block后面。并且不能重復(fù)。像一個cleanup 方法,它作為釋放資源使用作為一個特性方法使用,運行即使特性方法拋出異常。因此,cleanup block 必須防御編程。在最糟糕的情況下,它必須優(yōu)雅的處理在特性方法里拋出異常的第一個語句。并且所有本地變量有默認(rèn)值。

TIPS

groovy的安全引用操作精簡寫防御是代碼
對象級別的spec 通常不用cleanup方法。作為唯一資源他們消費內(nèi)存,自動被回收通過垃圾收集齊。更多粗力度spec,但是,可能使用clean 塊 清理文件系統(tǒng)關(guān)閉數(shù)據(jù)庫連接,關(guān)閉網(wǎng)絡(luò)服務(wù)

def "computing the maximum of two numbers"() { expect: Math.max(a, b) == cwhere: a << [5, 3] b << [1, 9] c << [5, 9]

}
This where block effectively creates two "versions" of the feature method: One where a is 5, b is 1, and c is 5, and another one where a is 3, b is 9, and c is 9.

這個where 塊創(chuàng)建兩個版本特性方法非常有效:One where a is 5, b is 1, and c is 5, and another one where a is 3, b is 9, and c is 9.

where block 將會在數(shù)據(jù)驅(qū)動測試章節(jié)解釋

Helper Methods

一些時候特性方法增長巨大在 and/or包含重復(fù)代碼。在這種情形下引入一個多個幫助方法會有意義。兩個好的候選者為幫助方法是setup/cleanup 邏輯與復(fù)雜場景。分解出前者是直接的,讓我們看下場景

def "offered PC matches preferred configuration"() { when: def pc = shop.buyPc()then: pc.vendor == "Sunny" pc.clockRate >= 2333 pc.ram >= 4096 pc.os == "Linux"

}
如果碰巧你也是電腦極客,你更愿意pc配置是詳細(xì)的,或者你可能想比較供應(yīng)從同的商店。因此,讓我們分解條件

def "offered PC matches preferred configuration"() { when: def pc = shop.buyPc()then: matchesPreferredConfiguration(pc)

}

def matchesPreferredConfiguration(pc) { pc.vendor == "Sunny" && pc.clockRate >= 2333 && pc.ram >= 4096 && pc.os == "Linux"

}
新的幫助方法matchesPreferredConfiguration 由簡單的布爾表達(dá)式組成作為結(jié)果返回。
這是好的除了那些一個不充分的供應(yīng)被描述。

Condition not satisfied:matchesPreferredConfiguration(pc) | | false ... Not very helpful. Fortunately, we can do better:void matchesPreferredConfiguration(pc) {assert pc.vendor == "Sunny"assert pc.clockRate >= 2333assert pc.ram >= 4096assert pc.os == "Linux" }

不是很有什么幫助。幸運的事,我們可以做更好
當(dāng)在一個幫助方法分解場景時,必須思考兩個點:首先,隱含條件必須轉(zhuǎn)換為顯性條件使用assert關(guān)鍵字。其次,幫助方法必須返回空類型。否則,spock會解釋返回值為失敗條件,這并不是我們想要的。

作為猜想,改進(jìn)的幫助方法告訴我們確切什么是錯的。

Condition not satisfied:assert pc.clockRate >= 2333| | || 1666 false...

條件不是滿意:

最后一個建議:盡管重用代碼是一個好事情,但不要是他太遠(yuǎn)。更聰明使用fixture 和幫助方法能增加耦合在特性方法間。如果你重用太多或者有錯誤代碼,你將以脆弱和艱難改進(jìn)的spec結(jié)束。

Specifications as Documentation

寫得好的spec作為一個源碼信息價值點。尤其是對高級別spec目標(biāo)是更廣泛的受眾不知是開發(fā)者(架構(gòu)師 領(lǐng)域?qū)<?客戶等)它是有道理的提供更多信息使用自然語言比只是使用規(guī)格與特性的名稱。因此,spock提供了一種方式附屬文本話的描述使用塊。

setup: "open a database connection"// code goes hereIndividual parts of a block can be described with and::setup: "open a database connection"// code goes hereand: "seed the customer table"// code goes hereand: "seed the product table"

一個and 標(biāo)簽 跟著描述能插入到特性方法的任何位置,沒有改變方法語義。

在行為驅(qū)動測試,面向客戶的特性被描述在一個given-when-then 格式。spock直接支持這個風(fēng)格的spec使用given標(biāo)簽

given: "an empty bank account"// ...when: "the account is credited $10"// ...then: "the account's balance is $10"// ...As noted before, given: is just an alias for setup:.

作為之前的提示,given知識setup的一個別名

塊描述不應(yīng)該出現(xiàn)在源碼里。但應(yīng)該在運行時可用對spock運行時。塊描述用法的計劃被增強診斷信息并且文本化的報告被所有利益相關(guān)者同樣理解。

擴(kuò)展
如所見,spock提供許多寫spec功能。然而總是有這種時候,當(dāng)一些別的東西被需要。因此,spock提供了一個基于攔截的擴(kuò)展機(jī)制。擴(kuò)展通過注解被直接激活。當(dāng)前,spock附帶一下指令

@Timeout Sets a timeout for execution of a feature or fixture method.設(shè)置超時時間為特性方法或者fixture方法@Ignore Ignores a feature method.忽略特性方法@IgnoreRest Ignores all feature methods not carrying this annotation. Useful for quickly running just a single method. 不移除這個注釋,忽略所有特性方法不去。對快速運行單個方法非常有用。

期待一個特性方法去完成打斷。@FailsWith有兩個用例:首先,文檔化我們知道的bug不需要立刻解釋。其次,替換異常條件在一個確定的角落用例在后面不能使用。在所有的用例,異常條件不是優(yōu)選。

學(xué)習(xí)怎樣實現(xiàn)你自己的指令與擴(kuò)展,去看擴(kuò)展章節(jié)

Comparison to JUnit

盡管spock使用不同的技術(shù),大部分概念和特性唄激活從junit。這有一個粗的比較
comparison

|Spock|JUnit|
|--|--|
|Specification|Test class|
|setup()|@Before|
|cleanup()|@After|
|setupSpec()|@BeforeClass|
|cleanupSpec()|@AfterClass|
|Feature|Test|
|Feature method|Test method|
|Data-driven feature|Theory|
|Condition|Assertion|
|Exception condition|@Test(expected=…?)|
|Interaction|Mock expectation (e.g. in Mockito)|

總結(jié)

以上是生活随笔為你收集整理的Spock Primer 翻译的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。