測試三明治和雪鸮探索測試

測試金字塔理論被廣泛應(yīng)用于計劃和實施敏捷軟件開發(fā)所倡導(dǎo)的測試自動化努释,并且取得了令人矚目的成就。本文嘗試從產(chǎn)品開發(fā)的角度出發(fā)沪铭,結(jié)合Kent Beck最近提出的3X模型和近年來迅速發(fā)展的自動化測試技術(shù)省古,提出并討論一種新的測試層級動態(tài)平衡觀:三明治模型。同時薯酝,為了應(yīng)對端到端測試在實踐中面臨的種種挑戰(zhàn),設(shè)計并實現(xiàn)了一種面向用戶旅程的端到端自動化測試框架——雪鸮爽柒。實際項目經(jīng)驗表明吴菠,雪鸮能夠顯著提升端到端測試的可維護(hù)性,減少不確定性影響浩村,幫助開發(fā)人員更快定位和修復(fù)問題做葵,對特定時期的產(chǎn)品開發(fā)活動更具吸引力。

背景

測試金字塔

按照自動化測試的層級心墅,從下至上依次為單元測試酿矢、集成測試和端到端測試,盡量保持?jǐn)?shù)量較多的低層單元測試怎燥,以及相對較少的高層端到端測試瘫筐,這就是測試金字塔理論。隨著敏捷軟件開發(fā)的日益普及铐姚,測試金字塔逐漸為人所知策肝,進(jìn)而得到廣泛應(yīng)用。Mike Cohn隐绵、Martin Fowler以及Mike Wacker等先后對測試金字塔進(jìn)行了很好的詮釋和發(fā)展之众,其主要觀點如下:

  • 測試層級越高,運行效率就越低依许,進(jìn)而延緩持續(xù)交付的構(gòu)建-反饋循環(huán)棺禾。
  • 測試層級越高,開發(fā)復(fù)雜度就越高峭跳,如果團(tuán)隊能力受限膘婶,交付進(jìn)度就會受到影響缺前。
  • 端到端測試更容易遇到測試結(jié)果的不確定性問題,按照Martin Fowler的說法竣付,這種結(jié)果不確定性的測試毫無意義诡延。
  • 測試層級越低滞欠,測試的代碼隔離性越強(qiáng)古胆,越能幫助開發(fā)人員快速定位和修復(fù)問題。

3X模型

2016年起筛璧,敏捷和TDD先驅(qū)Kent Beck開始在個人Facebook主頁撰寫系列文章逸绎,闡述產(chǎn)品開發(fā)的三個階段——Explore、Expand和Extract夭谤,以及在不同階段中產(chǎn)品與工程實踐之間的關(guān)系問題棺牧,即3X模型。近二十年軟硬件技術(shù)的飛速發(fā)展朗儒,使得軟件開發(fā)活動面臨敏捷早期從未遇到的市場變革颊乘,而根據(jù)在Facebook工作的經(jīng)歷,Kent Beck把產(chǎn)品開發(fā)總結(jié)為三個階段:

  • 探索(Explore)醉锄,此時的產(chǎn)品開發(fā)仍處于非常初期的階段乏悄,仍然需要花費大量時間尋找產(chǎn)品和市場的適配點,也是收益最低的階段恳不。
  • 擴(kuò)張(Expand)檩小,一旦產(chǎn)品擁有助推器(通常意味著已經(jīng)找到了市場的適配點),市場需求就會呈現(xiàn)指數(shù)級上升烟勋,產(chǎn)品本身也需要具備足夠的伸縮性以滿足這些需求规求,由此收益也會快速上升。
  • 提嚷训搿(Extract)阻肿,當(dāng)位于該階段時,公司通常希望最大化產(chǎn)品收益沮尿。但此時收益的增幅會小于擴(kuò)張階段丛塌。
image

(3X)

Kent Beck認(rèn)為,如果以產(chǎn)品是否成功作為衡量依據(jù)蛹找,那么引入自動化測試在探索階段的作用就不大姨伤,甚至?xí)泳彯a(chǎn)品接受市場反饋循環(huán)的速度,對產(chǎn)品的最終成功毫無用處庸疾,還不如不引入乍楚;當(dāng)位于擴(kuò)張階段時,市場一方面要求產(chǎn)品更高的伸縮性届慈,另一方面也開始要求產(chǎn)品保證一致的行為(例如質(zhì)量需求)徒溪,那么此時就該引入自動化測試來保證產(chǎn)品的行為一致性忿偷;當(dāng)產(chǎn)品最終處于提取階段時,任何改動都應(yīng)以不犧牲現(xiàn)有行為為前提臊泌,否則由此引發(fā)的損失可能遠(yuǎn)高于改動帶來的收益鲤桥,此時自動化測試就扮演了非常重要的角色。

測試工具爆炸式增長和綜合技能學(xué)習(xí)曲線陡升

根據(jù)SoftwareQATest網(wǎng)站的歷史數(shù)據(jù)渠概,2010年記錄的測試工具有440個茶凳,共劃分為12個大類。這個數(shù)字到2017年已經(jīng)變?yōu)?60個播揪,共15個大類贮喧,且其中有340個在2010年之后才出現(xiàn)。也就是說猪狈,平均每年就有50個新的測試工具誕生箱沦。

面對測試工具的爆炸式增長,一方面所支持的測試類型更加完善雇庙,更加有利于在產(chǎn)品開發(fā)過程中保證產(chǎn)品的一致性谓形;另一方面也導(dǎo)致針對多種測試工具組合的綜合技能學(xué)習(xí)曲線不斷上升。在實踐中疆前,團(tuán)隊也往往對如何定義相關(guān)測試的覆蓋范圍感到不知所措寒跳,難以真正發(fā)揮測試工具的效用,也很難對產(chǎn)品最終成功作出應(yīng)有的貢獻(xiàn)峡继。

從金字塔到三明治

作為敏捷在特定時期的產(chǎn)物冯袍,測試金字塔并不失其合理性,甚至還對自動化測試起到了重要推廣作用碾牌。但是康愤,隨著行業(yè)整體技術(shù)能力的不斷提升,市場需求和競爭日趨激烈舶吗,在項目中具體實施測試金字塔時往往遭遇困難征冷,即便借助外力強(qiáng)推,其質(zhì)量和效果也難以度量誓琼。

此外检激,隨著軟件設(shè)計和開發(fā)技術(shù)的不斷發(fā)展,低層單元測試的傳統(tǒng)測試技術(shù)和落地腹侣,因前叔收、后端技術(shù)棧的多樣化而大相徑庭;同時傲隶,在經(jīng)歷過覆蓋率之爭饺律,如何確保單元測試的規(guī)范和有效,也成為工程質(zhì)量管理的一大挑戰(zhàn)跺株;高層的端到端測試則基本不受技術(shù)棧頻繁更替的影響复濒,隨著不同載體上driver類技術(shù)的不斷成熟脖卖,其開發(fā)復(fù)雜度反而逐漸降低。

這里討論一種新的測試層級分配策略巧颈,我們稱之為三明治模型 畦木。如下圖所示,該模型允許對不同測試層級的占比進(jìn)行動態(tài)調(diào)整砸泛,說明了倒金字塔形十籍、沙漏形以及金字塔形分配對特定產(chǎn)品開發(fā)階段的積極作用。

image

(Sandwich)

產(chǎn)品開發(fā)的自動化測試策略

根據(jù)3X模型晾嘶,在探索初期往往選擇避開自動化測試妓雾。一旦進(jìn)入擴(kuò)張期娶吞,產(chǎn)品的可伸縮性和行為一致性就成為共同目標(biāo)垒迂,但此時也常會發(fā)生大的代碼重構(gòu)甚至重寫,如果沿用測試金字塔妒蛇,無論補(bǔ)充缺失的單元測試机断,還是只對新模塊寫單元測試,都既損害了產(chǎn)品的快速伸縮能力绣夺,也無法保證面向用戶的產(chǎn)品行為一致性吏奸。因此,如果在探索后期先引入高層的端到端測試陶耍,覆蓋主要用戶旅程奋蔚,那么擴(kuò)張期內(nèi)所產(chǎn)生的一系列改動都能夠受到端到端測試的保障。

需要注意的是烈钞,用戶旅程在產(chǎn)品即將結(jié)束探索期時通常會趨于穩(wěn)定泊碑,在擴(kuò)張期出現(xiàn)顛覆性變化的概率會逐漸減少,端到端測試的增長率會逐步下降毯欣。

除此以外馒过,隨著擴(kuò)張期內(nèi)不斷產(chǎn)生的模塊重構(gòu)和服務(wù)化,團(tuán)隊還應(yīng)增加單元測試和集成測試的占比酗钞。其中腹忽,單元測試應(yīng)確保覆蓋分支場景(可以在CI中引入基于模塊的覆蓋率檢測);集成測試和某些團(tuán)隊實踐的驗收測試砚作,則需進(jìn)一步覆蓋集成條件和驗收條件(在story sign-off和code review時驗收)窘奏。

許多新興的測試技術(shù)和工具擅長各自場景下的驗收測試,但更重要的仍是識別產(chǎn)品階段和當(dāng)前需求葫录,以滿足收益最大化着裹。

image

(Sandwich-3x)

由此我們認(rèn)為,隨著產(chǎn)品開發(fā)的演進(jìn)压昼,測試層級的分配應(yīng)參考三明治模型求冷,動態(tài)調(diào)整層級占比瘤运,更加重視運營和市場反饋,致力于真正幫助產(chǎn)品走向成功匠题。

端到端測試的機(jī)遇和挑戰(zhàn)

與其他測試層級相比拯坟,端到端測試技術(shù)的發(fā)展程度相對滯后。一方面韭山,作為其基礎(chǔ)的driver工具要在相應(yīng)載體成熟一段時間之后才能趨于穩(wěn)定郁季,web、mobile無不如是钱磅。另一方面梦裂,端到端測試偏向黑盒測試,更加側(cè)重描述用戶交互和業(yè)務(wù)功能盖淡,尋求硬核技術(shù)突破的難度較高年柠,于是較少受開發(fā)人員青睞。但是褪迟,由于端到端測試更接近真實用戶冗恨,其在特定產(chǎn)品開發(fā)活動中的性價比較高,有一定的發(fā)展?jié)摿Α?/p>

然而味赃,當(dāng)前實踐中的端到端測試掀抹,普遍存在如下問題:

  • 低可維護(hù)性。一般實踐并不對測試代碼質(zhì)量作特別要求心俗,而這點在端到端測試就體現(xiàn)得更糟傲武。因為其涉及數(shù)據(jù)、載體城榛、交互揪利、功能、參照(oracle)等遠(yuǎn)比單元測試復(fù)雜的broad stack吠谢。雖然也有Page Object等模式的廣泛應(yīng)用土童,但仍難以應(yīng)對快速變化。
  • 低運行效率工坊。如果拿單次端到端測試與單元測試相比献汗,前者的運行效率肯定更低。因此只一味增加端到端測試肯定會損害構(gòu)建-反饋循環(huán)王污,進(jìn)而影響持續(xù)交付罢吃。
  • 高不確定性。同樣因為broad stack的問題昭齐,端到端測試有更高的幾率產(chǎn)生不確定測試尿招,表現(xiàn)為測試結(jié)果呈隨機(jī)性成功/失敗,進(jìn)一步降低運行效率,使得真正的問題很容易被掩蓋就谜,團(tuán)隊也逐漸喪失對端到端測試的信心怪蔑。
  • 難以定位問題根因。端到端測試結(jié)果很難觸及代碼級別的錯誤丧荐,這就需要額外人工恢復(fù)測試環(huán)境并嘗試進(jìn)行問題重現(xiàn)缆瓣。其中所涉及的數(shù)據(jù)重建、用戶交互等會耗費可觀的成本虹统。

方法

為了解決傳統(tǒng)端到端測試遇到的種種挑戰(zhàn)弓坞,本文設(shè)計了一種面向用戶旅程的端到端自動化測試框架——雪鸮(snowy_owl),通過用戶旅程優(yōu)先车荔、數(shù)據(jù)分離渡冻、業(yè)務(wù)復(fù)用和狀態(tài)持久化等方法,顯著提高了端到端測試的可維護(hù)性忧便,降低不確定性的影響族吻,并且能夠幫助團(tuán)隊成員快速定位問題。

image

用戶旅程驅(qū)動

端到端測試應(yīng)盡量貼近用戶茬腿,從用戶旅程出發(fā)能保證這一點呼奢。在雪鸮中,用戶旅程使用被稱作play books的若干yaml格式的文件進(jìn)行組織切平,例如下列目錄結(jié)構(gòu):

play_books/
  core_journey.yml
  external_integration.yml
  online_payment.yml

其中每個play book由若干plots所組成,plot用于表示用戶旅程中的“情節(jié)”單位辐董,其基本特征如下:

  • 單一plot可以作為端到端測試獨立運行悴品,例如發(fā)送一條tweet的情節(jié):
SnowyOwl::Plots.write 'send a plain text tweet' do
  visit '/login'  
  page.fill_in 'username', with: 'username'
  page.fill_in 'password', with: 'password'
  page.find('a', text: 'Sign In').click
  # verify already login?
  page.find('a', text: 'Home').click
  # verify already on home page?
  page.fill_in 'textarea', with: 'Hello World'
  page.find('a', text: 'Send').click
  # verify already sent?
end
  • 單一plot應(yīng)是緊密關(guān)聯(lián)的一組用戶交互,并且具備體現(xiàn)一個較小業(yè)務(wù)價值的測試參照简烘。

  • plot可以被play book引用任意次從而組成用戶旅程苔严,play book同時定義了所引用plots之間的順序關(guān)系,基本語法如下所示:

---
- plot_name: send a plain text tweet
  digest: 2aae6c35c94fcfb415dbe95f408b9ce91ee846ed
  parent: d6b0d82cea4269b51572b8fab43adcee9fc3cf9a

其中plot_name表示情節(jié)的標(biāo)題孤澎,digest和parent分別表示當(dāng)前情節(jié)引用在整個端到端測試過程中的唯一標(biāo)識和前序情節(jié)標(biāo)識届氢,初期開發(fā)人員可以通過各個情節(jié)的引用順序定義用戶旅程,大多數(shù)情況下digest和parent將由系統(tǒng)自動生成并維護(hù)覆旭。

整個play books集合將是一個以plots為基礎(chǔ)組成的森林結(jié)構(gòu)退子,而端到端測試的執(zhí)行順序則是針對其中每棵樹進(jìn)行深度遍歷。

通用業(yè)務(wù)復(fù)用

由于plot本身必須是一個獨立可運行的端到端測試型将,那么plots之間通常會共享一部分交互操作寂祥,例如用戶登錄。雪鸮允許把高度可復(fù)用的交互代碼進(jìn)行二次抽取七兜,稱作determination:

SnowyOwl::Determinations.determine('user login') do |name, user_profile|
  # return if already login
  visit '/login'  
  page.fill_in 'username', with: user_profile[:username]
  page.fill_in 'password', with: user_profile[:password]
  page.find('a', text: 'Sign In').click
  # verify already login?
end

這樣丸凭,plot的代碼就可以簡化成:

SnowyOwl::Plots.write 'send a plain text tweet' do
  determine_user_login({username: 'username', password: 'password'})
  page.find('a', text: 'Home').click
  # verify already on home page?
  page.fill_in 'textarea', with: 'Hello World'
  page.find('a', text: 'Send').click
  # verify already sent?
end

這里應(yīng)注意Determination和Page Object的區(qū)別。看似使用Page Object可以達(dá)到相同的目的惜犀,但是后者與Page這一概念強(qiáng)綁定铛碑。而Determination更加側(cè)重描述業(yè)務(wù)本身,更符合對用戶旅程的描述虽界,因此比Page Object在plot中更具適用性亚茬。當(dāng)然,在描述更低層的組件交互時浓恳,Page Object仍然是最佳選擇刹缝。

測試數(shù)據(jù)分離

合理的數(shù)據(jù)設(shè)計對描繪用戶旅程非常重要,雪鸮對測試邏輯和數(shù)據(jù)進(jìn)行了進(jìn)一步分離颈将。例如用戶基本數(shù)據(jù)(profile)梢夯,同樣是使用yaml文件進(jìn)行表示:

data/
  tweets/
    plain_text.yml
  users/
    plain_user.yml

那么在plot的實現(xiàn)中,就可以使用同名對象方法替代字面值:

SnowyOwl::Plots.write 'send a plain text tweet' do
  determine_user_login({username: plain_user.username, password: plain_user.password})
  page.find('a', text: 'Home').click
  # verify already on home page?
  page.fill_in 'textarea', with: plain_text.value
  page.find('a', text: 'Send').click
  # verify already sent?
end

情節(jié)狀態(tài)持久化

雪鸮的另一個重要功能是情節(jié)狀態(tài)的持久化和場景復(fù)原晴圾。為了啟用情節(jié)狀態(tài)持久化颂砸,開發(fā)人員需要自己實現(xiàn)一個持久化腳本,例如對當(dāng)前數(shù)據(jù)庫進(jìn)行dump死姚,并按照雪鸮提供的持久化接口把dump文件存儲至指定位置人乓。

當(dāng)端到端測試運行每進(jìn)入一個新的情節(jié)之前,系統(tǒng)會自動執(zhí)行持久化腳本都毒。也就是說色罚,雪鸮支持保存每個情節(jié)的前置運行狀態(tài)。

當(dāng)端到端測試需要從特定的情節(jié)重新開始運行時账劲,雪鸮同樣會提供一個恢復(fù)接口戳护,通過用戶自定義的數(shù)據(jù)恢復(fù)腳本把指定位置的dump文件恢復(fù)至當(dāng)前系統(tǒng)。

該功能有兩處消費場景:

  • 由于broad stack的問題瀑焦,端到端測試不確定性的技術(shù)因素一般較為復(fù)雜腌且。實際經(jīng)驗表明,測試的隨機(jī)失敗率越低榛瓮,就越難以定位和修復(fù)問題铺董,而通過不斷改進(jìn)測試代碼的方式消除這種不確定性的成本較高,效果也不好禀晓。但是精续,可以盡量消除不確定性帶來的影響。例如匆绣,不確定測試導(dǎo)致的測試失敗驻右,通常會導(dǎo)致額外人工驗證時間,完全可以選擇讓系統(tǒng)自動重試失敗的測試崎淳。另一方面堪夭,重試會造成測試運行效率降低,特別是針對端到端測試。當(dāng)一輪端到端測試結(jié)束后森爽,雪鸮只會自動重試失敗的情節(jié)測試恨豁,同時利用該情節(jié)對應(yīng)的數(shù)據(jù)dump文件保證場景一致性,這就減少了重試整個端到端測試帶來的運行效率下降問題爬迟。

  • 當(dāng)團(tuán)隊成員發(fā)現(xiàn)端到端測試失敗橘蜜,通常需要在本地復(fù)現(xiàn)該問題。而借助測試dump文件付呕,可以直接運行指定plot測試计福,從而避免額外的人工設(shè)置數(shù)據(jù)和交互操作,加快問題定位和解決徽职。

實踐

雪鸮在筆者所在的項目有超過6個月的應(yīng)用時間象颖。該項目在產(chǎn)品開發(fā)方面長期陷入困境,例如過程中同時兼具了3X每個階段的特點姆钉,不僅缺少清晰的產(chǎn)品主線说订,還背負(fù)了接棒遺留系統(tǒng)的包袱。這種狀況對工程質(zhì)量管理提出了更大挑戰(zhàn)潮瓶。

項目采用雪鸮對已有端到端測試進(jìn)行了重構(gòu)陶冷,生成了一個核心用戶旅程和三個涉及外部系統(tǒng)集成的重要用戶旅程,包含24個plots毯辅,9個determinations埂伦,使端到端測試實現(xiàn)了長期穩(wěn)定運行。在本地相同軟硬件環(huán)境下悉罕,不確定性導(dǎo)致的隨機(jī)失敗從原有10%降低至1%以內(nèi)赤屋,部署至云環(huán)境并采用headless模式后,連續(xù)15天測試失敗記錄為零壁袄,運行效率的損失可以忽略不計。同時媚媒,當(dāng)用戶旅程產(chǎn)生新分支時嗜逻,可以引入新的情節(jié)測試節(jié)點,并且根據(jù)業(yè)務(wù)需求將其加入現(xiàn)有play book樹缭召,從而實現(xiàn)端到端測試的快速維護(hù)栈顷。

持續(xù)集成與常態(tài)化運行

項目完整的端到端測試的平均運行時間保持在19分鐘左右,為了不影響現(xiàn)有持續(xù)集成節(jié)奏嵌巷,CI每30分鐘自動更新代碼并運行端到端測試萄凤,結(jié)果在dashboard同步顯示,一旦發(fā)生測試失敗搪哪,第一優(yōu)先級查找失敗原因并嘗試在本地復(fù)現(xiàn)和修復(fù)靡努。

常態(tài)化運行端到端測試的另一個好處是,能夠以低成本的方式實現(xiàn)24小時監(jiān)控系統(tǒng)各個組件的功能正確性,有助于更早發(fā)現(xiàn)問題:一次惑朦,產(chǎn)品即將上線的支付功能發(fā)生異常兽泄,查看CI記錄發(fā)現(xiàn)端到端測試在晚上9:15左右出現(xiàn)了首次告警。通過及時溝通漾月,確認(rèn)是海外團(tuán)隊在當(dāng)時擅自改動了支付網(wǎng)關(guān)的一個配置病梢,造成服務(wù)不可用的問題,并迅速解決梁肿。

結(jié)論與展望

Kent Beck的3X模型蜓陌,提出了從不同產(chǎn)品開發(fā)階段看待工程實踐的新視角。而敏捷一貫推崇的TDD等實踐吩蔑,更多體現(xiàn)在個人技術(shù)專長(Expertise)方面钮热,與產(chǎn)品是否成功并無必然聯(lián)系。然而哥纫,程序員的專業(yè)主義(Professionalism)的確同時涵蓋了技術(shù)專長和產(chǎn)品成功兩個方面霉旗,二者相輔相成。因此蛀骇,如何通過平衡眾多因素并最終提高整體專業(yè)性厌秒,這才是軟件工程面臨的經(jīng)典問題。本文給出的測試三明治模型擅憔,目的就是幫助思考產(chǎn)品開發(fā)過程中測試層級間的平衡問題鸵闪。

為了應(yīng)對現(xiàn)有端到端測試面臨的挑戰(zhàn),本文設(shè)計并實現(xiàn)了一種新的面向用戶旅程的端到端測試框架暑诸,通過職責(zé)隔離蚌讼、業(yè)務(wù)復(fù)用和狀態(tài)持久化等手段,構(gòu)建了易于維護(hù)且更加有效的端到端測試个榕。同時篡石,基于上述方法構(gòu)建的測試代碼,更易于和自動化測試的其他研究領(lǐng)域相結(jié)合西采,在諸如測試數(shù)據(jù)構(gòu)建凰萨、用例生成、隨機(jī)測試和測試參照增強(qiáng)等方向有進(jìn)一步的應(yīng)用潛力械馆。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末户辞,一起剝皮案震驚了整個濱河市低飒,隨后出現(xiàn)的幾起案子畔勤,更是在濱河造成了極大的恐慌夯尽,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件尾菇,死亡現(xiàn)場離奇詭異境析,居然都是意外死亡囚枪,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進(jìn)店門簿晓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來眶拉,“玉大人,你說我怎么就攤上這事憔儿∫渲玻” “怎么了?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵谒臼,是天一觀的道長朝刊。 經(jīng)常有香客問我,道長蜈缤,這世上最難降的妖魔是什么拾氓? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮底哥,結(jié)果婚禮上咙鞍,老公的妹妹穿的比我還像新娘。我一直安慰自己趾徽,他們只是感情好续滋,可當(dāng)我...
    茶點故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著孵奶,像睡著了一般疲酌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上了袁,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天朗恳,我揣著相機(jī)與錄音,去河邊找鬼载绿。 笑死粥诫,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的崭庸。 我是一名探鬼主播臀脏,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼冀自!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起秒啦,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤熬粗,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后余境,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體驻呐,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡灌诅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了含末。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片猜拾。...
    茶點故事閱讀 38,654評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖佣盒,靈堂內(nèi)的尸體忽然破棺而出挎袜,到底是詐尸還是另有隱情,我是刑警寧澤肥惭,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布盯仪,位于F島的核電站,受9級特大地震影響蜜葱,放射性物質(zhì)發(fā)生泄漏全景。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一牵囤、第九天 我趴在偏房一處隱蔽的房頂上張望爸黄。 院中可真熱鬧,春花似錦揭鳞、人聲如沸炕贵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鲁驶。三九已至,卻和暖如春舞骆,著一層夾襖步出監(jiān)牢的瞬間钥弯,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工督禽, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留脆霎,地道東北人。 一個月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓狈惫,卻偏偏與公主長得像睛蛛,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子胧谈,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,543評論 2 349

推薦閱讀更多精彩內(nèi)容