WireMock詳細(xì)解析(一) —— Xcode中基于WireMock和UI Tests的本地API調(diào)用(一)

版本記錄

版本號(hào) 時(shí)間
V1.0 2019.08.12 星期一

前言

WireMock是基于HTTP的API的模擬器,下面我們就一起來(lái)學(xué)習(xí)和了解御板。

開(kāi)始

首先看下主要內(nèi)容

了解如何使用WireMock,這是一種可以與用戶界面測(cè)試結(jié)合使用的工具,用于提供遠(yuǎn)程API調(diào)用結(jié)果的本地副本。

然后看一下寫(xiě)作環(huán)境

Swift 5, iOS 13, Xcode 11

WireMock是基于HTTP的API的模擬器弓柱。 有些人可能會(huì)認(rèn)為它是服務(wù)虛擬化(service virtualization)工具或模擬服務(wù)器(mock server)〔嗟可以看一下WireMock官網(wǎng)矢空,和 GitHub - WireMock

當(dāng)您依賴的API不存在或不完整時(shí)俊犯,它可以使您保持高效妇多。 它支持測(cè)試真實(shí)API無(wú)法可靠生成的邊緣情況和失敗模式。 而且因?yàn)樗俣瓤煅嘞溃梢詫?gòu)建時(shí)間從幾小時(shí)減少到幾分鐘者祖。

它具有以下幾個(gè)特點(diǎn):

  • Flexible Deployment:從Java應(yīng)用程序立莉,JUnit測(cè)試,Servlet容器或獨(dú)立進(jìn)程中運(yùn)行WireMock七问。
  • Powerful Request Matching:使用各種策略匹配請(qǐng)求URL蜓耻,方法,header械巡,cookie和正文刹淌。 對(duì)JSONXML支持。
  • Record and Playback:通過(guò)捕獲現(xiàn)有API的流量來(lái)快速啟動(dòng)并運(yùn)行讥耗。

WireMock是一個(gè)開(kāi)發(fā)工具有勾,它提供遠(yuǎn)程API調(diào)用結(jié)果的本地副本。 您可以將它與User Interface(UI)測(cè)試結(jié)合使用古程,以呈現(xiàn)不同類型的API響應(yīng)蔼卡。

UI測(cè)試充當(dāng)安全網(wǎng),確保您提供預(yù)期的用戶體驗(yàn)挣磨。 它側(cè)重于您的應(yīng)用程序的端到端體驗(yàn)雇逞。 同樣,UI測(cè)試可以回答不同于單元測(cè)試的問(wèn)題茁裙,例如:

  • 如果我的視圖為空塘砸,在此屏幕上會(huì)發(fā)生什么?
  • 如果我從網(wǎng)絡(luò)請(qǐng)求中收到錯(cuò)誤會(huì)怎么樣晤锥?
  • 我的驗(yàn)證用戶界面是否顯示了不同類型輸入的正確信息掉蔬?
  • 我的table cells是否反映了收到的數(shù)據(jù)?

首先查近,找到入門(mén)項(xiàng)目并打開(kāi)它眉踱。 構(gòu)建并運(yùn)行項(xiàng)目以檢查功能。

星球大戰(zhàn)(Star Wars)信息應(yīng)用程序使用Star Wars API來(lái)檢索星球大戰(zhàn)角色列表霜威。 您可以點(diǎn)擊每個(gè)單元格以導(dǎo)航到該角色的詳細(xì)信息頁(yè)面谈喳。

1. Running the Tests

該應(yīng)用程序已經(jīng)設(shè)置了UI測(cè)試目標(biāo)(UI testing target)和兩個(gè)UI測(cè)試。 UI測(cè)試目標(biāo)已連接到構(gòu)建方案的默認(rèn)Test操作戈泼。

通過(guò)按Command-U或單擊菜單項(xiàng)Product ? Test來(lái)運(yùn)行測(cè)試婿禽。 您將看到應(yīng)用程序啟動(dòng)并從列表視圖導(dǎo)航到詳細(xì)視圖并返回。 在此導(dǎo)航期間大猛,UI測(cè)試驗(yàn)證列表視圖和詳細(xì)信息視圖上的預(yù)期條件扭倾。

要查看測(cè)試報(bào)告,請(qǐng)轉(zhuǎn)到左側(cè)窗格中的Report navigator挽绩,然后查看測(cè)試結(jié)果:

只要您的計(jì)算機(jī)處于聯(lián)機(jī)狀態(tài)并且測(cè)試可以成功點(diǎn)擊Star Wars API膛壹,測(cè)試就會(huì)通過(guò)。

2. UI Test Code

查看StarWarsInfoUITests.swift以查看UI tests。 UI測(cè)試的詳細(xì)信息超出了本文的范圍模聋。

示例項(xiàng)目演示了最佳實(shí)踐肩民,包括:

  • 盡可能使用輔助功能標(biāo)識(shí)符而非輔助功能標(biāo)簽labels來(lái)標(biāo)識(shí)元素。這種方法的好處包括:
    • 用戶無(wú)法以任何方式使用輔助功能標(biāo)識(shí)符链方,因此您可以根據(jù)需要為其命名持痰。
    • 標(biāo)識(shí)符保持不變。例如祟蚀,label可能具有不同的值工窍,但其標(biāo)識(shí)符保持不變。所以你的測(cè)試仍然可以在屏幕上找到元素前酿。
  • XCTestCase上的擴(kuò)展中名為waitForElementToAppear(_:file:line:elementName:timeout :)的便捷方法允許自定義超時(shí)患雏。
  • 將文件和行號(hào)傳遞給便利函數(shù)允許UI測(cè)試系統(tǒng)報(bào)告測(cè)試失敗。

Challenges With the Current Setup

這個(gè)小應(yīng)用程序和相關(guān)的測(cè)試在當(dāng)前配置中表現(xiàn)良好罢维,但隨著代碼庫(kù)的增長(zhǎng)纵苛,應(yīng)用程序?qū)⒁蕾囉诟嗟木W(wǎng)絡(luò)請(qǐng)求。 測(cè)試會(huì)變慢并變得不穩(wěn)定言津。

以下是代碼庫(kù)增長(zhǎng)時(shí)可以預(yù)見(jiàn)的一些問(wèn)題:

  • 如果您依賴的網(wǎng)絡(luò)請(qǐng)求失敗,會(huì)發(fā)生什么取试?
  • 如果網(wǎng)絡(luò)速度變慢悬槽,導(dǎo)致超時(shí)或延長(zhǎng)等待時(shí)間,會(huì)發(fā)生什么瞬浓?
  • 如果列表請(qǐng)求開(kāi)始以不同的排序順序發(fā)回?cái)?shù)據(jù)怎么辦初婆?

在所有三種情況下,您的測(cè)試都會(huì)失敗猿棉。 有一個(gè)共同點(diǎn)磅叛。 這些測(cè)試失敗都不是由編程錯(cuò)誤或邏輯問(wèn)題引起的。 在這些情況下測(cè)試失敗將是誤報(bào)萨赁,因?yàn)槭⒊瞿目刂品秶?/p>

1. Mitigating Network Failures

在本教程中弊琴,您將消除UI測(cè)試中的一個(gè)不確定性來(lái)源。 您將停止制作實(shí)時(shí)網(wǎng)絡(luò)請(qǐng)求并依賴稱為WireMock的網(wǎng)絡(luò)模擬技術(shù)杖爽。 WireMock允許您將網(wǎng)絡(luò)排除為UI測(cè)試中潛在的故障源敲董。

使用WireMock,您將在每次測(cè)試運(yùn)行時(shí)始終獲得與給定請(qǐng)求相同的響應(yīng)慰安。 這使您可以更自信地進(jìn)行測(cè)試腋寨。 如果出現(xiàn)failure,您將花費(fèi)更少的時(shí)間來(lái)確定原因化焕。 網(wǎng)絡(luò)是任何應(yīng)用程序中更易變的組件之一萄窜。 通過(guò)將其從失敗的潛在原因列表中刪除,您將能夠?qū)W⒂谀鷩L試使用每個(gè)屏幕測(cè)試的基本功能。


Overview of WireMock

WireMock是一個(gè)開(kāi)源庫(kù)查刻,允許您運(yùn)行本地Web服務(wù)器進(jìn)行測(cè)試键兜。通過(guò)在運(yùn)行測(cè)試時(shí)更新您從應(yīng)用程序調(diào)用的API端點(diǎn),您可以返回已知的響應(yīng)赖阻。這可以幫助您在開(kāi)發(fā)過(guò)程中更快地進(jìn)行蝶押。在測(cè)試運(yùn)行期間,將應(yīng)用程序指向WireMock實(shí)例允許您從API請(qǐng)求接收預(yù)期的響應(yīng)火欧。

足夠的理論棋电。開(kāi)始的時(shí)候了!


Setting Up WireMock

WireMock至少需要Java 7苇侵,因此請(qǐng)確保您的Mac安裝了更新版本的Java赶盔。從Oracle下載最新的Java Development Kit JDK。您將作為獨(dú)立實(shí)例運(yùn)行WireMock榆浓。轉(zhuǎn)到下載頁(yè)面download page于未,獲取WireMock的最新穩(wěn)定版本。下載將是一個(gè)JAR文件陡鹃。

轉(zhuǎn)到starter項(xiàng)目的基本目錄烘浦,并創(chuàng)建名為Vendor的目錄。將JAR文件移動(dòng)到此目錄中萍鲸。重命名JAR文件WireMock.jar闷叉,以便更容易地從命令行進(jìn)行交互。接下來(lái)脊阴,打開(kāi)終端并導(dǎo)航到您創(chuàng)建的Vendor目錄握侧。

在此目錄中,鍵入以下命令以啟動(dòng)WireMock進(jìn)程:

java -jar wiremock.jar --port 9999 --verbose

此命令在端口9999上啟動(dòng)WireMock并打開(kāi)詳細(xì)模式(verbose mode)嘿期。 打開(kāi)詳細(xì)模式可以讓您在應(yīng)用與WireMock端點(diǎn)交互時(shí)查看所有消息品擎,包括URL匹配和未命中。 在嘗試確定WireMock端點(diǎn)可能無(wú)法正常工作的原因時(shí)备徐,這是一個(gè)很大的幫助萄传。

現(xiàn)在,測(cè)試WireMock是否在您的系統(tǒng)上運(yùn)行坦喘。 打開(kāi)瀏覽器并轉(zhuǎn)到http://localhost:9999/__admin/mappings盲再。

你應(yīng)該看到以下內(nèi)容:

{
  "mappings" : [ ],
  "meta" : {
    "total" : 0
  }
}

很好! 這意味著WireMock已啟動(dòng)并正在運(yùn)行瓣铣。 您還會(huì)注意到WireMockVendor中創(chuàng)建了兩個(gè)目錄:__ filesmappings答朋。

默認(rèn)情況下,WireMock的獨(dú)立實(shí)例會(huì)查找與可執(zhí)行文件位置相關(guān)的這兩個(gè)目錄棠笑。

  • __files目錄包含您要為任何給定的API請(qǐng)求發(fā)回的模擬響應(yīng)梦碗。
  • mappings目錄包含將API請(qǐng)求模式映射到包含所需響應(yīng)的特定文件的文件。

Setting Up a Mock Response

示例應(yīng)用程序使用Star Wars API中的一個(gè)端點(diǎn)來(lái)請(qǐng)求字符列表。 該端點(diǎn)是https://swapi.co/api/people/洪规。

如果您在瀏覽器中訪問(wèn)此端點(diǎn)印屁,Star Wars API頁(yè)面可以很好地向您顯示JSON響應(yīng),包括headers斩例。 您只對(duì)這里的回復(fù)感興趣雄人。

復(fù)制不包括headers的完整response

{
  "count": 87,
  "next": "https://swapi.co/api/people/?page=2",
  "previous": null,
  "results": [
    {
      "name": "Luke Skywalker",
      "height": "172",
      "mass": "77",
      "hair_color": "blond",
      "skin_color": "fair",
      "eye_color": "blue",
      "birth_year": "19BBY",
      "gender": "male",
      // Clipped for brevity here
  ]
}

將此響應(yīng)作為character-list.json保存到__files目錄中。

1. Setting Up Mappings

接下來(lái)念赶,您需要讓WireMock知道如何將people端點(diǎn)映射到此響應(yīng)础钠。 在名為 character-list.json的映射目錄中創(chuàng)建一個(gè)新文件。

使文件的內(nèi)容如下所示:

{
  "request": {
      "method": "GET",
      "url": "/swapi.co/api/people"
  },
  "response": {
      "status": 200,
      "bodyFileName": "character-list.json"
  }
}

這使得Wiremock知道使用/swapi.co/api/people路徑將任何GET請(qǐng)求映射到具有HTTP 200成功狀態(tài)的character-list.json響應(yīng)叉谜。

您的最終Vendor目錄布局應(yīng)如下所示:

2. Verify Functionality

現(xiàn)在旗吁,驗(yàn)證WireMock是否已將您的映射編入索引。 如果您的終端仍然在上一個(gè)會(huì)話中運(yùn)行停局,請(qǐng)按Control-C停止它很钓,然后使用以下命令再次啟動(dòng)WireMock

java -jar wiremock.jar --port 9999 --verbose

WireMock應(yīng)該已經(jīng)拿起你的新映射文件。 要檢查這一點(diǎn)董栽,請(qǐng)轉(zhuǎn)到http://localhost:9999/__admin/mappings码倦。

您應(yīng)該看到以下輸出:

{
  "mappings" : [ {
    "id" : "5804b634-2a15-4fb0-a16e-2c19559f37df",
    "request" : {
      "url" : "/swapi.co/api/people",
      "method" : "GET"
    },
    "response" : {
      "status" : 200,
      "bodyFileName" : "character-list.json"
    },
    "uuid" : "5804b634-2a15-4fb0-a16e-2c19559f37df"
  } ],
  "meta" : {
    "total" : 1
  }
}

此輸出表示WireMock正在拾取您的映射文件。 接下來(lái)锭碳,檢查為端點(diǎn)返回的響應(yīng)叹洲。 轉(zhuǎn)到瀏覽器并輸入http://localhost:9999/swapi.co/api/people

您應(yīng)該看到以下輸出:

很棒工禾!一切都在WireMock方面發(fā)揮作用。現(xiàn)在蝗柔,您將把WireMock集成到UI test中闻葵。


Integrating WireMock

要將WireMock的工作實(shí)例集成到UI測(cè)試中,請(qǐng)按照下列步驟操作:

  • 1) 設(shè)置項(xiàng)目以允許來(lái)自本地運(yùn)行的WireMock實(shí)例的HTTP加載癣丧。
  • 2) 使用啟動(dòng)參數(shù)啟動(dòng)UI測(cè)試以傳遞已定義的參數(shù)槽畔。
  • 3) 創(chuàng)建一種基于啟動(dòng)參數(shù)在代碼中切換URL schemes的方法。

1. Allowing Loads from a Local HTTP Server

首先胁编,配置項(xiàng)目以允許來(lái)自非SSL連接的HTTP請(qǐng)求厢钧。如果您不執(zhí)行此步驟,App Transport Security(ATS)將不允許網(wǎng)絡(luò)請(qǐng)求連接到WireMock嬉橙。

通常不建議允許不安全的負(fù)載早直,但對(duì)于UI測(cè)試,它比配置自簽名證書(shū)更容易從WireMock啟用SSL市框。在更復(fù)雜的設(shè)置中霞扬,您可以將項(xiàng)目配置為僅允許測(cè)試方案中的不安全負(fù)載使用構(gòu)建配置設(shè)置或測(cè)試目標(biāo)的不同Info.plist

按照以下步驟使用WireMock設(shè)置ATS進(jìn)行UI測(cè)試:

  • 1) 在StarWarsInfo group組中打開(kāi)Info.plist
  • 2) 在底部喻圃,單擊最后一行上的+萤彩。
  • 3) 從Key列的下拉列表中選擇App Transport Security Settings
  • 4) 按Tab鍵斧拍。
  • 5) 選擇右側(cè)的顯示三角形使其指向下方雀扶。
  • 6) 現(xiàn)在,在App Transport Security Settings行中單擊+肆汹。
  • 7) 從新行的下拉列表中愚墓,選擇Allow Arbitrary Loads
  • 8) 最后县踢,在此行的Value列中洲劣,將值更改為YES

2. Defining a Launch Argument

接下來(lái)袜刷,您將定義一個(gè)啟動(dòng)參數(shù)横堡,讓?xiě)?yīng)用程序知道何時(shí)切換URL schemes。 從Xcode啟動(dòng)時(shí)谴返,您可以將參數(shù)傳遞給您的應(yīng)用程序煞肾,類似于將參數(shù)傳遞給終端命令的方式。 在Xcode中使用Scheme Editor嗓袱。

您將在該scheme的運(yùn)行操作中定義啟動(dòng)參數(shù)籍救。 通過(guò)這種方式配置,您可以在模擬器中運(yùn)行應(yīng)用程序而無(wú)需運(yùn)行任何測(cè)試渠抹。 一旦確定一切都按照您想要的方式運(yùn)行蝙昙,您將在測(cè)試代碼中定義相同的參數(shù)并使用它們啟動(dòng)應(yīng)用程序。 運(yùn)行UI測(cè)試時(shí)梧却,應(yīng)用程序的行為方式應(yīng)該相同奇颠。

3. Editing the Xcode Scheme

單擊Xcode中的StarWarsInfo方案,然后單擊Edit Scheme放航。

在左側(cè)窗格中選擇Run操作烈拒。 在中間窗格中,選擇Arguments選項(xiàng)卡广鳍。 在Arguments Passed on Launch部分中荆几,單擊+并添加啟動(dòng)參數(shù)-runlocal。 確保選中新啟動(dòng)參數(shù)左側(cè)的復(fù)選框赊时。

單擊Close接受更改并返回到您的代碼吨铸。

4. Updating to Use Launch Arguments

現(xiàn)在,您需要更新代碼庫(kù)以查找此啟動(dòng)參數(shù)并使用適當(dāng)?shù)?code>URL scheme祖秒。

Adding a Utility Function

首先焊傅,創(chuàng)建一個(gè)實(shí)用程序方法來(lái)查找啟動(dòng)參數(shù)剂陡。 按住Control鍵并單擊StarWarsInfo組,然后創(chuàng)建一個(gè)名為Utils的新組狐胎。 然后鸭栖,按住Control鍵并單擊新的Utils組,并創(chuàng)建一個(gè)名為StartupUtils.swift的新Swift文件握巢。 將以下代碼添加到此文件:

struct StartupUtils {
  static func shouldRunLocal() -> Bool {
    return CommandLine.arguments.contains("-runlocal")
  }
}

此代碼檢查CommandLine.arguments晕鹊,它是一個(gè)字符串?dāng)?shù)組。 如果該數(shù)組包含-runlocal參數(shù)暴浦,則該函數(shù)將返回true溅话。

Checking for Local flag in Network Client

接下來(lái),在網(wǎng)絡(luò)客戶端中使用新的便利函數(shù)歌焦。 在Network組內(nèi)飞几,打開(kāi)StarWarsAPINetworkClient.swift。 將baseURLString的屬性更新為計(jì)算屬性独撇,如下所示:

var baseURLString: String {
  if StartupUtils.shouldRunLocal() {
    return "http://localhost:9999/swapi.co/api/"
  } else {
    return "https://swapi.co/api/"
  }
}

如果啟動(dòng)時(shí)存在-runlocal屬性屑墨,則baseURLString將使用local scheme,連接到正在運(yùn)行的WireMock實(shí)例以獲取其數(shù)據(jù)纷铣。 現(xiàn)在卵史,您可以完全控制API的數(shù)據(jù)響應(yīng)。

打開(kāi)終端(如果尚未打開(kāi))并確保WireMock正在運(yùn)行搜立。 導(dǎo)航到包含WireMock可執(zhí)行文件的目錄以躯。 運(yùn)行相同的命令以啟動(dòng)WireMock

java -jar wiremock.jar --port 9999 --verbose

Perform a Run with WireMock

設(shè)置啟動(dòng)參數(shù),按Command-R建立并運(yùn)行啄踊。 加載初始列表時(shí)觀察終端忧设。 當(dāng)應(yīng)用程序請(qǐng)求網(wǎng)絡(luò)數(shù)據(jù)并且WireMock返回時(shí),您應(yīng)該看到控制臺(tái)打印輸出颠通。

5. Testing Against WireMock

現(xiàn)在见转,執(zhí)行最后的步驟,使用正確的啟動(dòng)參數(shù)設(shè)置UI測(cè)試蒜哀。

UI Test Launch Arguments

回到Xcode,展開(kāi)Project導(dǎo)航器中的StarWarsInfoUITests組吏砂。 然后按住Control鍵并單擊Utility組撵儿。 創(chuàng)建一個(gè)名為LaunchArguments.swift的新文件。 請(qǐng)務(wù)必選擇StarWarsInfoUITests并從Save As對(duì)話框的Targets部分中刪除StarWarsInfo的選擇狐血。

添加以下代碼

struct LaunchArguments {
  static var launchLocalArguments: [String] {
    return [
      "-runlocal"
    ]
  }
}

最后淀歇,展開(kāi)項(xiàng)目導(dǎo)航器中的Tests組并打開(kāi)StarWarsInfoUITests.swift。 在兩個(gè)測(cè)試中的每個(gè)測(cè)試中匈织,在創(chuàng)建本地app參數(shù)之后浪默,添加以下行:

app.launchArguments = LaunchArguments.launchLocalArguments

這會(huì)為每個(gè)測(cè)試添加-runlocal啟動(dòng)參數(shù)牡直。

現(xiàn)在,您可以測(cè)試針對(duì)WireMock而不是實(shí)時(shí)網(wǎng)絡(luò)運(yùn)行的UI測(cè)試纳决。

切換回Xcode并按Command-U運(yùn)行UI測(cè)試碰逸。 如果您在測(cè)試運(yùn)行時(shí)觀察終端,您將看到WireMock的輸出作為您的測(cè)試請(qǐng)求數(shù)據(jù)阔加,并且它們是從本地服務(wù)器返回的饵史。

恭喜! 您已消除UI測(cè)試對(duì)網(wǎng)絡(luò)的嚴(yán)重依賴胜榔。

除了模擬您從實(shí)時(shí)網(wǎng)絡(luò)請(qǐng)求獲得的相同響應(yīng)之外胳喷,您現(xiàn)在可以將不同的場(chǎng)景發(fā)送回您的UI并查看應(yīng)用程序的響應(yīng)方式。

例如:

  • 如果收到HTTP 500狀態(tài)夭织,您的應(yīng)用會(huì)顯示正確的錯(cuò)誤消息嗎吭露?
  • 如果UI收到空數(shù)據(jù)集,會(huì)發(fā)生什么尊惰?
  • 如果收到格式錯(cuò)誤的數(shù)據(jù)集讲竿,應(yīng)用程序是否以正確的方式響應(yīng)?
  • 如果收到的某些字符串對(duì)于UI來(lái)說(shuō)太長(zhǎng)择浊,會(huì)發(fā)生什么戴卜? 是否所有內(nèi)容都按預(yù)期包裝或截?cái)啵?/li>

嘗試調(diào)整模擬的響應(yīng)以測(cè)試應(yīng)用內(nèi)的不同流。 WireMock還允許您通過(guò)同一端點(diǎn)的許多不同變量來(lái)改變響應(yīng)琢岩,例如查詢參數(shù)和標(biāo)頭投剥。 查看文檔documentation以了解還有什么可能情況。

后記

本篇主要講述了Xcode中基于WireMock和UI Tests的本地API調(diào)用担孔,感興趣的給個(gè)贊或者關(guān)注~~~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末江锨,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子糕篇,更是在濱河造成了極大的恐慌啄育,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,080評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拌消,死亡現(xiàn)場(chǎng)離奇詭異挑豌,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)墩崩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,422評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)氓英,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人鹦筹,你說(shuō)我怎么就攤上這事铝阐。” “怎么了铐拐?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,630評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵徘键,是天一觀的道長(zhǎng)练对。 經(jīng)常有香客問(wèn)我,道長(zhǎng)吹害,這世上最難降的妖魔是什么螟凭? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,554評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮赠制,結(jié)果婚禮上赂摆,老公的妹妹穿的比我還像新娘。我一直安慰自己钟些,他們只是感情好烟号,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,662評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著政恍,像睡著了一般汪拥。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上篙耗,一...
    開(kāi)封第一講書(shū)人閱讀 49,856評(píng)論 1 290
  • 那天迫筑,我揣著相機(jī)與錄音,去河邊找鬼宗弯。 笑死脯燃,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蒙保。 我是一名探鬼主播辕棚,決...
    沈念sama閱讀 39,014評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼邓厕!你這毒婦竟也來(lái)了逝嚎?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,752評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤详恼,失蹤者是張志新(化名)和其女友劉穎补君,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體昧互,經(jīng)...
    沈念sama閱讀 44,212評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡挽铁,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,541評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了敞掘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片叽掘。...
    茶點(diǎn)故事閱讀 38,687評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖渐逃,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情民褂,我是刑警寧澤茄菊,帶...
    沈念sama閱讀 34,347評(píng)論 4 331
  • 正文 年R本政府宣布疯潭,位于F島的核電站,受9級(jí)特大地震影響面殖,放射性物質(zhì)發(fā)生泄漏竖哩。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,973評(píng)論 3 315
  • 文/蒙蒙 一脊僚、第九天 我趴在偏房一處隱蔽的房頂上張望相叁。 院中可真熱鬧,春花似錦辽幌、人聲如沸增淹。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,777評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)虑润。三九已至,卻和暖如春加酵,著一層夾襖步出監(jiān)牢的瞬間拳喻,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,006評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工猪腕, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留冗澈,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,406評(píng)論 2 360
  • 正文 我出身青樓陋葡,卻偏偏與公主長(zhǎng)得像亚亲,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子脖岛,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,576評(píng)論 2 349

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