干貨 | 一文搞定 pytest 自動化測試框架(二)

干貨 | 一文搞定 pytest 自動化測試框架(二)

本文節(jié)選自霍格沃玆測試學(xué)院內(nèi)部教材,進(jìn)階學(xué)習(xí)冲粤。

上一篇文章中分享了 pytest 的基本用法袜茧,本文進(jìn)一步介紹 pytest 的其他實(shí)用特性和進(jìn)階技巧。

pytest fixtures

pytest 中可以使用 @pytest.fixture 裝飾器來裝飾一個(gè)方法倍踪,被裝飾方法的方法名可以作為一個(gè)參數(shù)傳入到測試方法中系宫。可以使用這種方式來完成測試之前的初始化建车,也可以返回?cái)?shù)據(jù)給測試函數(shù)扩借。

將 fixture 作為函數(shù)參數(shù)

通常使用 setup 和 teardown 來進(jìn)行資源的初始化。如果有這樣一個(gè)場景缤至,測試用例 1 需要依賴登錄功能潮罪,測試用例 2 不需要登錄功能,測試用例 3 需要登錄功能凄杯。這種場景 setup错洁,teardown 無法實(shí)現(xiàn),可以使用 pytest fixture 功能戒突,在方法前面加個(gè) @pytest.fixture 裝飾器屯碴,加了這個(gè)裝飾器的方法可以以參數(shù)的形式傳入到方法里面執(zhí)行。

例如在登錄的方法膊存,加上 @pytest.fixture 這個(gè)裝飾器后导而,將這個(gè)用例方法名以參數(shù)的形式傳到方法里,這個(gè)方法就會先執(zhí)行這個(gè)登錄方法隔崎,再去執(zhí)行自身的用例步驟今艺,如果沒有傳入這個(gè)登錄方法,就不執(zhí)行登錄操作爵卒,直接執(zhí)行已有的步驟虚缎。

創(chuàng)建一個(gè)文件名為“test_fixture.py”,代碼如下:

#!/usr/bin/env python# -*- coding: utf-8 -*-import pytest@pytest.fixture()def login():    print("這是個(gè)登錄方法")    return ('tom','123')@pytest.fixture()def operate():    print("登錄后的操作")def test_case1(login,operate):    print(login)    print("test_case1钓株,需要登錄")def test_case2():    print("test_case2实牡,不需要登錄 ")def test_case3(login):    print(login)    print("test_case3,需要登錄")

在上面的代碼中轴合,測試用例 test_case1 和 test_case3 分別增加了 login 方法名作為參數(shù)创坞,pytest 會發(fā)現(xiàn)并調(diào)用 @pytest.fixture 標(biāo)記的 login 功能,運(yùn)行測試結(jié)果如下:

plugins: html-2.0.1, rerunfailures-8.0, xdist-1.31.0, \ordering-0.6, forked-1.1.3, allure-pytest-2.8.11, metadata-1.8.0collecting ... collected 3 itemstest_fixture.py::test_case1 這是個(gè)登錄方法登錄后的操作PASSED     [ 33%]('tom', '123')test_case1受葛,需要登錄test_fixture.py::test_case2 PASSED \[ 66%]test_case2题涨,不需要登錄 test_fixture.py::test_case3 這是個(gè)登錄方法PASSED      [100%]('tom', '123')test_case3偎谁,需要登錄============================== 3 passed in 0.02s ===============================Process finished with exit code 0

從上面的結(jié)果可以看出,test_case1 和 test_case3 運(yùn)行之前執(zhí)行了 login 方法纲堵,test_case2 沒有執(zhí)行這個(gè)方法巡雨。

指定范圍內(nèi)共享

fixture 里面有一個(gè)參數(shù) scope,通過 scope 可以控制 fixture 的作用范圍婉支,根據(jù)作用范圍大小劃分:session> module> class> function鸯隅,具體作用范圍如下:

  • function 函數(shù)或者方法級別都會被調(diào)用
  • class 類級別調(diào)用一次
  • module 模塊級別調(diào)用一次
  • session 是多個(gè)文件調(diào)用一次(可以跨.py文件調(diào)用,每個(gè).py文件就是module)

例如整個(gè)模塊有多條測試用例向挖,需要在全部用例執(zhí)行之前打開瀏覽器蝌以,全部執(zhí)行完之后去關(guān)閉瀏覽器,打開和關(guān)閉操作只執(zhí)行一次何之,如果每次都重新執(zhí)行打開操作跟畅,會非常占用系統(tǒng)資源。這種場景除了setup_module,teardown_module 可以實(shí)現(xiàn),還可以通過設(shè)置模塊級別的 fixture 裝飾器(@pytest.fixture(scope="module"))來實(shí)現(xiàn)溶推。

scope='module'

fixture 參數(shù) scope='module'徊件,module 作用是整個(gè)模塊都會生效。

創(chuàng)建文件名為 test_fixture_scope.py蒜危,代碼如下:

#!/usr/bin/env python# -*- coding: utf-8 -*-import pytest# 作用域:module是在模塊之前執(zhí)行虱痕, 模塊之后執(zhí)行@pytest.fixture(scope="module")def open():    print("打開瀏覽器")    yield    print("執(zhí)行teardown !")    print("最后關(guān)閉瀏覽器")@pytest.mark.usefixtures("open")def test_search1():    print("test_search1")    raise NameError    passdef test_search2(open):    print("test_search2")    passdef test_search3(open):    print("test_search3")    pass

代碼解析:

@pytest.fixture() 如果不寫參數(shù),參數(shù)默認(rèn) scope='function'辐赞。當(dāng) scope='module' 時(shí)部翘,在當(dāng)前 .py 腳本里面所有的用例開始前只執(zhí)行一次。scope 巧妙與 yield 組合使用响委,相當(dāng)于 setup 和 teardown 方法新思。還可以使用 @pytest.mark.usefixtures 裝飾器,傳入前置函數(shù)名作為參數(shù)赘风。

運(yùn)行結(jié)果如下:

plugins: html-2.0.1, rerunfailures-8.0, \xdist-1.31.0, ordering-0.6, forked-1.1.3,\ allure-pytest-2.8.11, metadata-1.8.0collecting ... collected 3 itemstest_fixture_yield.py::test_search1 打開瀏覽器FAILED  [ 33%]test_search1test_fixture_yield.py:13 (test_search1)open = None    def test_search1(open):        print("test_search1")>       raise NameErrorE       NameErrortest_fixture_yield.py:16: NameErrortest_fixture_yield.py::test_search2 PASSED  \[ 66%]test_search2test_fixture_yield.py::test_search3 PASSED   \[100%]test_search3執(zhí)行teardown !最后關(guān)閉瀏覽器...open = None    def test_search1(open):        print("test_search1")>       raise NameErrorE       NameErrortest_fixture_yield.py:16: NameError------ Captured stdout setup --------打開瀏覽器----- Captured stdout call -----test_search1===== 1 failed, 2 passed in 0.06s =====Process finished with exit code 0

從上面運(yùn)行結(jié)果可以看出夹囚,scope="module" 與 yield 結(jié)合,相當(dāng)于 setup_module 和 teardown_module 方法邀窃。整個(gè)模塊運(yùn)行之前調(diào)用了 open()方法中 yield 前面的打印輸出“打開瀏覽器”荸哟,整個(gè)運(yùn)行之后調(diào)用了 yield 后面的打印語句“執(zhí)行 teardown !”與“關(guān)閉瀏覽器”。yield 來喚醒 teardown 的執(zhí)行瞬捕,如果用例出現(xiàn)異常鞍历,不影響 yield 后面的 teardown 執(zhí)行∩轿觯可以使用 @pytest.mark.usefixtures 裝飾器來進(jìn)行方法的傳入。

conftest.py 文件

fixture scope 為 session 級別是可以跨 .py 模塊調(diào)用的掏父,也就是當(dāng)我們有多個(gè) .py 文件的用例時(shí)笋轨,如果多個(gè)用例只需調(diào)用一次 fixture,可以將 scope='session',并且寫到 conftest.py 文件里爵政。寫到 conftest.py 文件可以全局調(diào)用這里面的方法仅讽。使用的時(shí)候不需要導(dǎo)入 conftest.py 這個(gè)文件。使用 conftest.py 的規(guī)則:

  1. conftest.py 這個(gè)文件名是固定的钾挟,不可以更改洁灵。
  2. conftest.py 與運(yùn)行用例在同一個(gè)包下,并且該包中有 init.py 文件
  3. 使用的時(shí)候不需要導(dǎo)入 conftest.py掺出,pytest 會自動識別到這個(gè)文件
  4. 放到項(xiàng)目的根目錄下可以全局調(diào)用徽千,放到某個(gè) package 下,就在這個(gè) package 內(nèi)有效汤锨。

案例

在運(yùn)行整個(gè)項(xiàng)目下的所有的用例双抽,只執(zhí)行一次打開瀏覽器。執(zhí)行完所有的用例之后再執(zhí)行關(guān)閉瀏覽器闲礼,可以在這個(gè)項(xiàng)目下創(chuàng)建一個(gè) conftest.py 文件牍汹,將打開瀏覽器操作的方法放在這個(gè)文件下,并添加一個(gè)裝飾器 @pytest.fixture(scope="session")柬泽,就能夠?qū)崿F(xiàn)整個(gè)項(xiàng)目所有測試用例的瀏覽器復(fù)用慎菲,案例目錄結(jié)構(gòu)如下:

干貨 | 一文搞定 pytest 自動化測試框架(二)

創(chuàng)建目錄 test_scope,并在目錄下創(chuàng)建三個(gè)文件 conftest.py锨并,test_scope1.py 和 test_scope2.py露该。

conftest.py 文件定義了公共方法,pytest 會自動讀取 conftest.py 定義的方法琳疏,代碼如下:

#!/usr/bin/env python# -*- coding: utf-8 -*-import pytest@pytest.fixture(scope="session")def open():    print("打開瀏覽器")    yield    print("執(zhí)行teardown !")    print("最后關(guān)閉瀏覽器")

創(chuàng)建 test_scope1.py 文件有决,代碼如下:

#!/usr/bin/env python# -*- coding: utf-8 -*-import pytestdef test_search1(open):    print("test_search1")    passdef test_search2(open):    print("test_search2")    passdef test_search3(open):    print("test_search3")    passif __name__ == '__main__':    pytest.main()

創(chuàng)建文件“test_scope2.py”,代碼如下:

#!/usr/bin/env python# -*- coding: utf-8 -*-class TestFunc():    def test_case1(self):        print("test_case1空盼,需要登錄")    def test_case2(self):        print("test_case2书幕,不需要登錄 ")    def test_case3(self):        print("test_case3,需要登錄")

打開 cmd揽趾,進(jìn)入目錄 test_scope/台汇,執(zhí)行如下命令:

pytest -v -s  

或者

pytest -v -s test_scope1.py test_scope2.py

執(zhí)行結(jié)果如下:

省略...collected 6 items                                                                                                   test_scope1.py::test_search1 打開瀏覽器test_search1PASSEDtest_scope1.py::test_search2 test_search2PASSEDtest_scope1.py::test_search3 test_search3PASSEDtest_scope2.py::TestFunc::test_case1 test_case1,需要登錄PASSEDtest_scope2.py::TestFunc::test_case2 test_case2篱瞎,不需要登錄 PASSEDtest_scope2.py::TestFunc::test_case3 test_case3苟呐,需要登錄PASSED執(zhí)行teardown !最后關(guān)閉瀏覽器省略后面打印結(jié)果...

執(zhí)行過程中 pytest 會自動識別當(dāng)前目錄的 conftest.py,不需要導(dǎo)入直接引用里面的方法配置俐筋。應(yīng)用到整個(gè)目錄下的所有調(diào)用這里面的方法中執(zhí)行牵素。conftest.py 與運(yùn)行的用例要在同一個(gè) pakage 下,并且這個(gè)包下有 init.py 文件

自動執(zhí)行 fixture

如果每條測試用例都需要添加 fixture 功能澄者,則需要在每一要用例方法里面?zhèn)魅脒@個(gè)fixture的名字笆呆,這里就可以在裝飾器里面添加一個(gè)參數(shù) autouse='true'请琳,它會自動應(yīng)用到所有的測試方法中,只是這里沒有辦法返回值給測試用例赠幕。

使用方法俄精,在方法前面加上裝飾器,如下:

@pytest.fixture(autouse="true")def myfixture():    print("this is my fixture")

@pytest.fixture 里設(shè)置 autouse 參數(shù)值為 true(默認(rèn) false)榕堰,每個(gè)測試函數(shù)都會自動調(diào)用這個(gè)前置函數(shù)竖慧。

創(chuàng)建文件名為“test_autouse.py”,代碼如下:

# coding=utf-8import pytest@pytest.fixture(autouse="true")def myfixture():    print("this is my fixture")class TestAutoUse:    def test_one(self):        print("執(zhí)行test_one")        assert 1 + 2 == 3    def test_two(self):        print("執(zhí)行test_two")        assert 1 == 1    def test_three(self):        print("執(zhí)行test_three")        assert 1 + 1 == 2

執(zhí)行上面這個(gè)測試文件,結(jié)果如下:

...test_a.py::TestAutoUse::test_one this is my fixture執(zhí)行test_onePASSEDtest_a.py::TestAutoUse::test_two this is my fixture執(zhí)行test_twoPASSEDtest_a.py::TestAutoUse::test_three this is my fixture執(zhí)行test_threePASSED...

從上面的運(yùn)行結(jié)果可以看出逆屡,在方法 myfixture() 上面添加了裝飾器 @pytest.fixture(autouse="true")圾旨,測試用例無須傳入這個(gè) fixture 的名字,它會自動在每條用例之前執(zhí)行這個(gè) fixture康二。

fixture 傳遞參數(shù)

測試過程中需要大量的測試數(shù)據(jù)碳胳,如果每條測試數(shù)據(jù)都編寫一條測試用例,用例數(shù)量將是非常寵大的沫勿。一般我們在測試過程中會將測試用到的數(shù)據(jù)以參數(shù)的形式傳入到測試用例中挨约,并為每條測試數(shù)據(jù)生成一個(gè)測試結(jié)果數(shù)據(jù)。

這時(shí)候可以使用 fixture 的參數(shù)化功能产雹,在 fixture 方法加上裝飾器 @pytest.fixture(params=[1,2,3])诫惭,就會傳入三個(gè)數(shù)據(jù) 1、2蔓挖、3夕土,分別將這三個(gè)數(shù)據(jù)傳入到用例當(dāng)中。這里可以傳入的數(shù)據(jù)是個(gè)列表瘟判。傳入的數(shù)據(jù)需要使用一個(gè)固定的參數(shù)名 request 來接收怨绣。

創(chuàng)建文件名為“test_params.py”,代碼如下:

import pytest@pytest.fixture(params=[1, 2, 3])def data(request):    return request.paramdef test_not_2(data):    print(f"測試數(shù)據(jù):{data}")    assert data < 5

運(yùn)行結(jié)果如下:

...test_params.py::test_not_2[1]PASSED  [ 33%]測試數(shù)據(jù):1test_params.py::test_not_2[2] PASSED [ 66%]測試數(shù)據(jù):2test_params.py::test_not_2[3] PASSED [100%]測試數(shù)據(jù):3...

從運(yùn)行結(jié)果可以看出拷获,對于 params 里面的每個(gè)值篮撑,fixture 都會去調(diào)用執(zhí)行一次,使用 request.param 來接受用例參數(shù)化的數(shù)據(jù)匆瓜,并且為每一個(gè)測試數(shù)據(jù)生成一個(gè)測試結(jié)果赢笨。在測試工作中使用這種參數(shù)化的方式,會減少大量的代碼量驮吱,并且便于閱讀與維護(hù)茧妒。

多線程并行與分布式執(zhí)行

假如項(xiàng)目中有測試用例 1000 條,一條測試用例需要執(zhí)行 1 分鐘左冬,一個(gè)測試人員需要 1000 分鐘才能完成一輪回歸測試桐筏。通常我們會用人力成本換取時(shí)間成本,加幾個(gè)人一起執(zhí)行拇砰,時(shí)間就會縮短梅忌。如果 10 人一起執(zhí)行只需要 100 分鐘绊袋,這就是一種并行測試,分布式的場景铸鹰。

pytest-xdist 是 pytest 分布式執(zhí)行插件,可以多個(gè) CPU 或主機(jī)執(zhí)行皂岔,這款插件允許用戶將測試并發(fā)執(zhí)行(進(jìn)程級并發(fā)),插件是動態(tài)決定測試用例執(zhí)行順序的蹋笼,為了保證各個(gè)測試能在各個(gè)獨(dú)立線程里正確的執(zhí)行,應(yīng)該保證測試用例的獨(dú)立性(這也符合測試用例設(shè)計(jì)的最佳實(shí)踐)躁垛。

安裝

pip install pytest-xdist

多個(gè) CPU 并行執(zhí)行用例剖毯,需要在 pytest 后面添加 -n 參數(shù),如果參數(shù)為 auto教馆,會自動檢測系統(tǒng)的 CPU 數(shù)目逊谋。如果參數(shù)為數(shù)字,則指定運(yùn)行測試的處理器進(jìn)程數(shù)土铺。

pytest -n auto   pytest -n [num]  

案例

某個(gè)項(xiàng)目有 200 條測試用例胶滋,每條測試用例之間沒有關(guān)聯(lián)關(guān)系,互不影響悲敷。這 200 條測試用例需要在 1 小時(shí)之內(nèi)測試完成究恤,可以加個(gè)-n參數(shù),使用多 CPU 并行測試后德。運(yùn)行方法:

pytest -n 4

進(jìn)入到項(xiàng)目目錄下部宿,執(zhí)行 pytest 可以將項(xiàng)目目錄下所有測試用例識別出來并且運(yùn)行,加上 -n 參數(shù)瓢湃,可以指定 4 個(gè) CPU 并發(fā)執(zhí)行理张。大量的測試用例并發(fā)執(zhí)行提速非常明顯。

結(jié)合 pytest-html 生成測試報(bào)告

測試報(bào)告通常在項(xiàng)目中尤為重要绵患,報(bào)告可以體現(xiàn)測試人員的工作量雾叭,開發(fā)人員可以從測試報(bào)告中了解缺陷的情況,因此測試報(bào)告在測試過程中的地位至關(guān)重要藏雏,測試報(bào)告為糾正軟件存在的質(zhì)量問題提供依據(jù)拷况,為軟件驗(yàn)收和交付打下基礎(chǔ)。測試報(bào)告根據(jù)內(nèi)容的側(cè)重點(diǎn)掘殴,可以分為 “版本測試報(bào)告” 和 “總結(jié)測試報(bào)告”赚瘦。執(zhí)行完 pytest 測試用例,可以使用 pytest-HTML 插件生成 HTML 格式的測試報(bào)告奏寨。

安裝

pip install pytest-html

執(zhí)行方法

pytest --html=path/to/html/report.html

結(jié)合 pytest-xdist 使用

pytest -v -s -n 3 --html=report.html --self-contained-html 

生成測試報(bào)告

如下圖:

干貨 | 一文搞定 pytest 自動化測試框架(二)

生成的測試報(bào)告最終是 HTML 格式起意,報(bào)告內(nèi)容包括標(biāo)題、運(yùn)行時(shí)間病瞳、環(huán)境揽咕、匯總結(jié)果以及用例的通過個(gè)數(shù)悲酷、跳過個(gè)數(shù)、失敗個(gè)數(shù)亲善、錯(cuò)誤個(gè)數(shù)设易,期望失敗個(gè)數(shù)、不期望通過個(gè)數(shù)蛹头、重新運(yùn)行個(gè)數(shù)顿肺、以及錯(cuò)誤的詳細(xì)展示信息。報(bào)告會生成在運(yùn)行腳本的同一路徑渣蜗,需要指定路徑添加--html=path/to/html/report.html 這個(gè)參數(shù)配置報(bào)告的路徑屠尊。如果不添加 --self-contained-html 這個(gè)參數(shù),生成報(bào)告的 CSS 文件是獨(dú)立的耕拷,分享的時(shí)候容易千萬數(shù)據(jù)丟失讼昆。

pytest 框架 assert 斷言使用(附)

編寫代碼時(shí),我們經(jīng)常會做出一些假設(shè)骚烧,斷言就是用于在代碼中捕捉這些假設(shè)浸赫。斷言表示為一些布爾表達(dá)式,測試人員通常會加一些斷言來斷定中間過程的正確性赃绊。斷言支持顯示最常見的子表達(dá)式的值掺炭,包括調(diào)用,屬性凭戴,比較以及二元和一元運(yùn)算符涧狮。Python使用 assert(斷言)用于判斷一個(gè)表達(dá)式,在表達(dá)式條件為 false 的時(shí)候觸發(fā)異常么夫。

使用方法:

assert True         #斷言為真assertnot False     #斷言為假

案例如下:

assert "h" in "hello"  #判斷h在hello中assert 5>6             #判斷5>6為真    assert not True        #判斷xx不為真assert {'0', '1', '3', '8'} == {'0', '3', '5', '8'}     #判斷兩個(gè)字典相等

如果沒有斷言者冤,沒有辦法判定用例中每一個(gè)測試步驟結(jié)果的正確性。在項(xiàng)目中適當(dāng)?shù)氖褂脭嘌缘祷荆瑏韺Υa的結(jié)構(gòu)涉枫、屬性、功能腐螟、安全性等場景檢查與驗(yàn)證愿汰。
點(diǎn)擊領(lǐng)取:自動化+側(cè)開+性能+簡歷+面試核心教程資料

http://qrcode.testing-studio.com/f?from=jianshu&url=https://ceshiren.com/t/topic/3595

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末乐纸,一起剝皮案震驚了整個(gè)濱河市衬廷,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌汽绢,老刑警劉巖吗跋,帶你破解...
    沈念sama閱讀 221,888評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡跌宛,警方通過查閱死者的電腦和手機(jī)酗宋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來疆拘,“玉大人蜕猫,你說我怎么就攤上這事“テ” “怎么了丹锹?”我有些...
    開封第一講書人閱讀 168,386評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長芬失。 經(jīng)常有香客問我,道長匾灶,這世上最難降的妖魔是什么棱烂? 我笑而不...
    開封第一講書人閱讀 59,726評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮阶女,結(jié)果婚禮上颊糜,老公的妹妹穿的比我還像新娘。我一直安慰自己秃踩,他們只是感情好衬鱼,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,729評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著憔杨,像睡著了一般鸟赫。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上消别,一...
    開封第一講書人閱讀 52,337評論 1 310
  • 那天抛蚤,我揣著相機(jī)與錄音,去河邊找鬼寻狂。 笑死岁经,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蛇券。 我是一名探鬼主播缀壤,決...
    沈念sama閱讀 40,902評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼纠亚!你這毒婦竟也來了塘慕?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,807評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蒂胞,失蹤者是張志新(化名)和其女友劉穎苍糠,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體啤誊,經(jīng)...
    沈念sama閱讀 46,349評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡岳瞭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,439評論 3 340
  • 正文 我和宋清朗相戀三年拥娄,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瞳筏。...
    茶點(diǎn)故事閱讀 40,567評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡稚瘾,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出姚炕,到底是詐尸還是另有隱情摊欠,我是刑警寧澤,帶...
    沈念sama閱讀 36,242評論 5 350
  • 正文 年R本政府宣布柱宦,位于F島的核電站些椒,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏掸刊。R本人自食惡果不足惜免糕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,933評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望忧侧。 院中可真熱鬧石窑,春花似錦、人聲如沸蚓炬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽肯夏。三九已至经宏,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間驯击,已是汗流浹背烛恤。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留余耽,地道東北人缚柏。 一個(gè)月前我還...
    沈念sama閱讀 48,995評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像碟贾,于是被迫代替她去往敵國和親币喧。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,585評論 2 359