Pytest官方教程-19-插件編寫

目錄:

  1. 安裝及入門
  2. 使用和調(diào)用方法
  3. 原有TestSuite使用方法
  4. 斷言的編寫和報告
  5. Pytest fixtures:清晰 模塊化 易擴展
  6. 使用Marks標(biāo)記測試用例
  7. Monkeypatching/對模塊和環(huán)境進行Mock
  8. 使用tmp目錄和文件
  9. 捕獲stdout及stderr輸出
  10. 捕獲警告信息
  11. 模塊及測試文件中集成doctest測試
  12. skip及xfail: 處理不能成功的測試用例
  13. Fixture方法及測試用例的參數(shù)化
  14. 緩存: 使用跨執(zhí)行狀態(tài)
  15. unittest.TestCase支持
  16. 運行Nose用例
  17. 經(jīng)典xUnit風(fēng)格的setup/teardown
  18. 安裝和使用插件
  19. 插件編寫
  20. 編寫鉤子(hook)方法
  21. 運行日志
  22. API參考
    1. 方法(Functions)
    2. 標(biāo)記(Marks)
    3. 鉤子(Hooks)
    4. 裝置(Fixtures)
    5. 對象(Objects)
    6. 特殊變量(Special Variables)
    7. 環(huán)境變量(Environment Variables)
    8. 配置選項(Configuration Options)
  23. 優(yōu)質(zhì)集成實踐
  24. 片狀測試
  25. Pytest導(dǎo)入機制及sys.path/PYTHONPATH
  26. 配置選項
  27. 示例及自定義技巧
  28. Bash自動補全設(shè)置

插件編寫

很容易為你自己的項目實現(xiàn)本地conftest插件或可以在許多項目中使用的可安裝的插件,包括第三方項目。如果你只想使用但不能編寫插件邑退,請參閱安裝和使用插件。

插件包含一個或多個鉤子(hooks)方法函數(shù)鸠信。編寫鉤子(hooks)方法 解釋了如何自己編寫鉤子(hooks)方法函數(shù)的基礎(chǔ)知識和細節(jié)。pytest通過調(diào)用以下插件的指定掛鉤來實現(xiàn)配置屈暗,收集灸蟆,運行和報告的所有方面:

原則上发皿,每個鉤子(hooks)方法調(diào)用都是一個1:NPython函數(shù)調(diào)用崔慧,其中N是給定規(guī)范的已注冊實現(xiàn)函數(shù)的數(shù)量。所有規(guī)范和實現(xiàn)都遵循pytest_前綴命名約定穴墅,使其易于區(qū)分和查找惶室。

工具啟動時的插件發(fā)現(xiàn)順序

pytest 通過以下方式在工具啟動時加載插件模塊:

  • 通過加載所有內(nèi)置插件

  • 通過加載通過setuptools入口點注冊的所有插件。

  • 通過預(yù)掃描選項的命令行并在實際命令行解析之前加載指定的插件玄货。-p name

  • 通過conftest.py命令行調(diào)用推斷加載所有文件:

    • 如果未指定測試路徑皇钞,則使用當(dāng)前dir作為測試路徑
    • 如果存在,則加載conftest.pytest*/conftest.py相對于第一個測試路徑的目錄部分松捉。

    請注意夹界,pytest conftest.py在工具啟動時沒有在更深的嵌套子目錄中找到文件。將conftest.py文件保存在頂級測試或項目根目錄中通常是個好主意隘世。

  • 通過遞歸加載文件中pytest_plugins變量指定的所有插件 conftest.py

conftest.py:本地每目錄插件

本地conftest.py插件包含特定于目錄的鉤子(hooks)方法實現(xiàn)可柿。Hook Session和測試運行活動將調(diào)用conftest.py靠近文件系統(tǒng)根目錄的文件中定義的所有掛鉤。實現(xiàn)pytest_runtest_setup鉤子(hooks)方法的示例丙者, 以便在a 子目錄中調(diào)用而不是為其他目錄調(diào)用:

a/conftest.py:
    def pytest_runtest_setup(item):
        # called for running each test in 'a' directory
        print("setting up", item)

a/test_sub.py:
    def test_sub():
        pass

test_flat.py:
    def test_flat():
        pass

以下是運行它的方法:

pytest test_flat.py --capture=no  # will not show "setting up"
pytest a/test_sub.py --capture=no  # will show "setting up"

注意

如果你的conftest.py文件不在python包目錄中(即包含一個__init__.py)复斥,那么“import conftest”可能不明確,因為conftest.pyPYTHONPATH或者也可能有其他 文件sys.path械媒。因此目锭,項目要么放在conftest.py 包范圍內(nèi),要么永遠不從conftest.py文件中導(dǎo)入任何內(nèi)容纷捞, 這是一種很好的做法痢虹。

另請參見:pytest import mechanisms和sys.path / PYTHONPATH

編寫自己的插件

如果你想編寫插件主儡,可以從中復(fù)制許多現(xiàn)實示例:

所有這些插件都實現(xiàn)了鉤子(hooks)方法和/或固定裝置 以擴展和添加功能。

注意

請務(wù)必查看優(yōu)秀 的cookiecutter-pytest-plugin 項目缀辩,該項目是 用于創(chuàng)作插件的cookiecutter模板

該模板提供了一個很好的起點踪央,包括一個工作插件臀玄,使用tox運行的測試,一個全面的README文件以及一個預(yù)先配置的入口點畅蹂。

另外考慮將你的插件貢獻給pytest-dev 一旦它擁有一些非自己的快樂用戶健无。

使你的插件可以被他人安裝

如果你想讓你的插件在外部可用,你可以為你的發(fā)行版定義一個所謂的入口點液斜,以便pytest找到你的插件模塊累贤。入口點是setuptools提供的功能叠穆。pytest查找pytest11入口點以發(fā)現(xiàn)其插件,因此你可以通過在setuptools-invocation中定義插件來使插件可用:

# sample ./setup.py file
from setuptools import setup

setup(
    name="myproject",
    packages=["myproject"],
    # the following makes a plugin available to pytest
    entry_points={"pytest11": ["name_of_plugin = myproject.pluginmodule"]},
    # custom PyPI classifier for pytest plugins
    classifiers=["Framework :: Pytest"],
)

如果以這種方式安裝包臼膏,pytestmyproject.pluginmodule作為可以定義掛鉤的插件 加載 硼被。

注意

確保包含在PyPI分類器列表中, 以便用戶輕松找到你的插件渗磅。Framework :: Pytest

斷言重寫

其中一個主要特性pytest是使用普通的斷言語句以及斷言失敗時表達式的詳細內(nèi)省嚷硫。這是由“斷言重寫”提供的,它在編譯為字節(jié)碼之前修改了解析的AST始鱼。這是通過一個完成的PEP 302導(dǎo)入掛鉤仔掸,在pytest啟動時及早安裝 ,并在導(dǎo)入模塊時執(zhí)行此重寫医清。但是起暮,由于我們不想測試不同的字節(jié)碼,因此你將在生產(chǎn)中運行此掛鉤僅重寫測試模塊本身以及作為插件一部分的任何模塊会烙。任何其他導(dǎo)入的模塊都不會被重寫负懦,并且會發(fā)生正常的斷言行為。

如果你在其他模塊中有斷言助手持搜,你需要啟用斷言重寫密似,你需要pytest 在導(dǎo)入之前明確要求重寫這個模塊。

注冊一個或多個要在導(dǎo)入時重寫的模塊名稱葫盼。

此函數(shù)將確保此模塊或程序包內(nèi)的所有模塊將重寫其assert語句残腌。因此,你應(yīng)確保在實際導(dǎo)入模塊之前調(diào)用此方法贫导,如果你是使用包的插件抛猫,則通常在init.py中調(diào)用。

<colgroup><col class="field-name" style="hyphens: manual;"><col class="field-body"></colgroup>
| 舉: | TypeError - 如果給定的模塊名稱不是字符串孩灯。 |

當(dāng)你編寫使用包創(chuàng)建的pytest插件時闺金,這一點尤為重要。導(dǎo)入掛鉤僅將入口點conftest.py 中列出的文件和任何模塊pytest11視為插件峰档。作為示例败匹,請考慮以下包:

pytest_foo/__init__.py
pytest_foo/plugin.py
pytest_foo/helper.py

使用以下典型setup.py提取物:

setup(..., entry_points={"pytest11": ["foo = pytest_foo.plugin"]}, ...)

在這種情況下,只會pytest_foo/plugin.py被重寫讥巡。如果輔助模塊還包含需要重寫的斷言語句掀亩,則需要在導(dǎo)入之前將其標(biāo)記為這樣。通過將其標(biāo)記為在__init__.py模塊內(nèi)部進行重寫欢顷,這是最簡單的槽棍,當(dāng)導(dǎo)入包中的 模塊時,將始終首先導(dǎo)入該模塊。這種方式plugin.py仍然可以helper.py正常導(dǎo)入炼七。然后缆巧,內(nèi)容 pytest_foo/__init__.py將需要如下所示:

import pytest

pytest.register_assert_rewrite("pytest_foo.helper")

在測試模塊或conftest文件中要求/加載插件

你可以在測試模塊或這樣的conftest.py文件中要求插件:

pytest_plugins = ["name1", "name2"]

加載測試模塊或conftest插件時,也會加載指定的插件豌拙。任何模塊都可以作為插件祝福陕悬,包括內(nèi)部應(yīng)用程序模塊:

pytest_plugins = "myapp.testsupport.myplugin"

pytest_plugins變量是遞歸處理的,所以請注意姆蘸,在上面的示例中墩莫,如果myapp.testsupport.myplugin也聲明pytest_plugins,變量的內(nèi)容也將作為插件加載逞敷,依此類推狂秦。

注意

pytest_plugins不建議使用非根conftest.py文件中使用變量的 插件劫笙。

這很重要罐监,因為conftest.py文件實現(xiàn)了每個目錄的鉤子(hooks)方法實現(xiàn),但是一旦導(dǎo)入了插件张峰,它就會影響整個目錄樹牛柒。為了避免混淆堪簿,不推薦pytest_plugins在任何conftest.py不在測試根目錄中的文件中進行定義 ,并將發(fā)出警告皮壁。

這種機制使得在應(yīng)用程序甚至外部應(yīng)用程序中共享裝置變得容易椭更,而無需使用setuptools入口點技術(shù)創(chuàng)建外部插件。

導(dǎo)入的插件pytest_plugins也會自動標(biāo)記為斷言重寫(請參閱參考資料pytest.register_assert_rewrite())蛾魄。但是虑瀑,為了使其具有任何效果,必須不必導(dǎo)入模塊; 如果在pytest_plugins處理語句時已經(jīng)導(dǎo)入它 滴须,則會產(chǎn)生警告舌狗,并且不會重寫插件內(nèi)的斷言。要解決此問題扔水,你可以pytest.register_assert_rewrite()在導(dǎo)入模塊之前自行調(diào)用痛侍,也可以安排代碼以延遲導(dǎo)入,直到注冊插件為止魔市。

按名稱訪問另一個插件

如果一個插件想要與另一個插件的代碼協(xié)作主届,它可以通過插件管理器獲得一個引用,如下所示:

plugin = config.pluginmanager.get_plugin("name_of_plugin")

如果要查看現(xiàn)有插件的名稱待德,請使用該--trace-config選項岂膳。

測試插件

pytest附帶一個名為的插件pytester,可幫助你為插件代碼編寫測試磅网。默認情況下,該插件處于禁用狀態(tài)筷屡,因此你必須先啟用它涧偷,然后才能使用它簸喂。

你可以通過conftest.py將以下行添加到測試目錄中的文件來執(zhí)行此操作:

# content of conftest.py

pytest_plugins = ["pytester"]

或者,你可以使用命令行選項調(diào)用pytest 燎潮。-p pytester

這將允許你使用testdir fixture來測試你的插件代碼喻鳄。

讓我們用一個例子演示你可以用插件做什么。想象一下确封,我們開發(fā)了一個插件除呵,它提供了一個hello產(chǎn)生函數(shù)的fixture ,我們可以用一個可選參數(shù)調(diào)用這個函數(shù)爪喘。如果我們不提供值或者我們提供字符串值颜曾,它將返回字符串值。Hello World!``Hello {value}!

# -*- coding: utf-8 -*-

import pytest

def pytest_addoption(parser):
    group = parser.getgroup("helloworld")
    group.addoption(
        "--name",
        action="store",
        dest="name",
        default="World",
        help='Default "name" for hello().',
    )

@pytest.fixture
def hello(request):
    name = request.config.getoption("name")

    def _hello(name=None):
        if not name:
            name = request.config.getoption("name")
        return "Hello {name}!".format(name=name)

    return _hello

現(xiàn)在秉剑,testdirfixture提供了一個方便的API來創(chuàng)建臨時 conftest.py文件和測試文件泛豪。它還允許我們運行測試并返回一個結(jié)果對象,通過它我們可以斷言測試的結(jié)果侦鹏。

def test_hello(testdir):
    """Make sure that our plugin works."""

    # create a temporary conftest.py file
    testdir.makeconftest(
        """
 import pytest

 @pytest.fixture(params=[
 "Brianna",
 "Andreas",
 "Floris",
 ])
 def name(request):
 return request.param
 """
    )

    # create a temporary pytest test file
    testdir.makepyfile(
        """
 def test_hello_default(hello):
 assert hello() == "Hello World!"

 def test_hello_name(hello, name):
 assert hello(name) == "Hello {0}!".format(name)
 """
    )

    # run all tests with pytest
    result = testdir.runpytest()

    # check that all 4 tests passed
    result.assert_outcomes(passed=4)

另外诡曙,可以在運行pytest之前復(fù)制示例文件夾的示例

# content of pytest.ini
[pytest]
pytester_example_dir = .
# content of test_example.py

def test_plugin(testdir):
    testdir.copy_example("test_example.py")
    testdir.runpytest("-k", "test_example")

def test_example():
    pass
$ pytest
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
cachedir: $PYTHON_PREFIX/.pytest_cache
rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini
collected 2 items

test_example.py ..                                                   [100%]

============================= warnings summary =============================
test_example.py::test_plugin
  $REGENDOC_TMPDIR/test_example.py:4: PytestExperimentalApiWarning: testdir.copy_example is an experimental api that may change over time
    testdir.copy_example("test_example.py")

-- Docs: https://docs.pytest.org/en/latest/warnings.html
=================== 2 passed, 1 warnings in 0.12 seconds ===================

有關(guān)runpytest()返回的結(jié)果對象及其提供的方法的更多信息,請查看RunResult文檔略水。

編寫鉤子(hooks)方法函數(shù)

鉤子(hooks)方法函數(shù)驗證和執(zhí)行

pytest為任何給定的鉤子(hooks)方法規(guī)范調(diào)用已注冊插件的鉤子(hooks)方法函數(shù)价卤。讓我們看一下鉤子(hooks)方法的典型鉤子(hooks)方法函數(shù),pytest在收集完所有測試項目后調(diào)用渊涝。pytest_collection_modifyitems(session, config,items)

當(dāng)我們pytest_collection_modifyitems在插件中實現(xiàn)一個函數(shù)時慎璧,pytest將在注冊期間驗證你是否使用了與規(guī)范匹配的參數(shù)名稱,如果沒有則拯救驶赏。

讓我們看一下可能的實現(xiàn):

def pytest_collection_modifyitems(config, items):
    # called after collection is completed
    # you can modify the ``items`` list
    ...

這里炸卑,pytest將傳入config(pytest配置對象)和items(收集的測試項列表),但不會傳入session參數(shù)煤傍,因為我們沒有在函數(shù)簽名中列出它盖文。這種動態(tài)的“修剪”參數(shù)允許pytest“未來兼容”:我們可以引入新的鉤子(hooks)方法命名參數(shù)而不破壞現(xiàn)有鉤子(hooks)方法實現(xiàn)的簽名。這是pytest插件的一般長期兼容性的原因之一蚯姆。

請注意五续,除了pytest_runtest_*不允許引發(fā)異常之外的鉤子(hooks)方法函數(shù)。這樣做會打破pytest運行龄恋。

firstresult:首先停止非無結(jié)果

大多數(shù)對pytest鉤子(hooks)方法的調(diào)用都會產(chǎn)生一個結(jié)果列表疙驾,其中包含被調(diào)用鉤子(hooks)方法函數(shù)的所有非None結(jié)果。

一些鉤子(hooks)方法規(guī)范使用該firstresult=True選項郭毕,以便鉤子(hooks)方法調(diào)用僅執(zhí)行它碎,直到N個注冊函數(shù)中的第一個返回非None結(jié)果,然后將其作為整個鉤子(hooks)方法調(diào)用的結(jié)果。在這種情況下扳肛,不會調(diào)用其余的鉤子(hooks)方法函數(shù)傻挂。

hookwrapper:在其他鉤子(hooks)方法周圍執(zhí)行

版本2.7中的新功能。

pytest插件可以實現(xiàn)鉤子(hooks)方法包裝器挖息,它包裝其他鉤子(hooks)方法實現(xiàn)的執(zhí)行金拒。鉤子(hooks)方法包裝器是一個生成器函數(shù),它只產(chǎn)生一次套腹。當(dāng)pytest調(diào)用鉤子(hooks)方法時绪抛,它首先執(zhí)行鉤子(hooks)方法包裝器并傳遞與常規(guī)鉤子(hooks)方法相同的參數(shù)。

在鉤子(hooks)方法包裝器的屈服點电禀,pytest將執(zhí)行下一個鉤子(hooks)方法實現(xiàn)幢码,并以Result封裝結(jié)果或異常信息的實例的形式將其結(jié)果返回到屈服點。因此鞭呕,屈服點本身通常不會引發(fā)異常(除非存在錯誤)蛤育。

以下是鉤子(hooks)方法包裝器的示例定義:

import pytest

@pytest.hookimpl(hookwrapper=True)
def pytest_pyfunc_call(pyfuncitem):
    do_something_before_next_hook_executes()

    outcome = yield
    # outcome.excinfo may be None or a (cls, val, tb) tuple

    res = outcome.get_result()  # will raise if outcome was exception

    post_process_result(res)

    outcome.force_result(new_res)  # to override the return value to the plugin system

請注意,鉤子(hooks)方法包裝器本身不返回結(jié)果葫松,它們只是圍繞實際的鉤子(hooks)方法實現(xiàn)執(zhí)行跟蹤或其他副作用瓦糕。如果底層鉤子(hooks)方法的結(jié)果是一個可變對象,它們可能會修改該結(jié)果腋么,但最好避免它咕娄。

有關(guān)更多信息,請參閱插件文檔珊擂。

鉤子(hooks)方法函數(shù)排序/調(diào)用示例

對于任何給定的鉤子(hooks)方法規(guī)范圣勒,可能存在多個實現(xiàn),因此我們通常將hook執(zhí)行視為 1:N函數(shù)調(diào)用摧扇,其中N是已注冊函數(shù)的數(shù)量圣贸。有一些方法可以影響鉤子(hooks)方法實現(xiàn)是在其他人之前還是之后,即在N-sized函數(shù)列表中的位置:

# Plugin 1
@pytest.hookimpl(tryfirst=True)
def pytest_collection_modifyitems(items):
    # will execute as early as possible
    ...

# Plugin 2
@pytest.hookimpl(trylast=True)
def pytest_collection_modifyitems(items):
    # will execute as late as possible
    ...

# Plugin 3
@pytest.hookimpl(hookwrapper=True)
def pytest_collection_modifyitems(items):
    # will execute even before the tryfirst one above!
    outcome = yield
    # will execute after all non-hookwrappers executed

這是執(zhí)行的順序:

  1. Plugin3的pytest_collection_modifyitems被調(diào)用直到屈服點扛稽,因為它是一個鉤子(hooks)方法包裝器吁峻。
  2. 調(diào)用Plugin1的pytest_collection_modifyitems是因為它標(biāo)有tryfirst=True
  3. 調(diào)用Plugin2的pytest_collection_modifyitems因為它被標(biāo)記trylast=True(但即使沒有這個標(biāo)記在张,它也會在Plugin1之后出現(xiàn))用含。
  4. 插件3的pytest_collection_modifyitems然后在屈服點之后執(zhí)行代碼。yield接收一個Result實例帮匾,該實例封裝了調(diào)用非包裝器的結(jié)果啄骇。包裝不得修改結(jié)果。

這是可能的使用tryfirst瘟斜,并trylast結(jié)合還 hookwrapper=True處于這種情況下缸夹,它會影響彼此之間hookwrappers的排序痪寻。

聲明新鉤子(hooks)方法

插件和conftest.py文件可以聲明新鉤子(hooks)方法,然后可以由其他插件實現(xiàn)明未,以便改變行為或與新插件交互:

在插件注冊時調(diào)用槽华,允許通過調(diào)用添加新的掛鉤 。pluginmanager.add_hookspecs(module_or_class, prefix)
參數(shù): | pluginmanager_pytest.config.PytestPluginManager) - pytest插件管理器

注意:
這個鉤子(hooks)方法與之不相容hookwrapper=True趟妥。

鉤子(hooks)方法通常被聲明為do-nothing函數(shù),它們只包含描述何時調(diào)用鉤子(hooks)方法以及期望返回值的文檔佣蓉。

有關(guān)示例披摄,請參閱xdist中newhooks.py

可選擇使用第三方插件的鉤子(hooks)方法

由于標(biāo)準(zhǔn)的驗證機制勇凭,如上所述使用插件中的新鉤子(hooks)方法可能有點棘手:如果你依賴未安裝的插件疚膊,驗證將失敗并且錯誤消息對你的用戶沒有多大意義。

一種方法是將鉤子(hooks)方法實現(xiàn)推遲到新的插件虾标,而不是直接在插件模塊中聲明鉤子(hooks)方法函數(shù)寓盗,例如:

# contents of myplugin.py

class DeferPlugin(object):
    """Simple plugin to defer pytest-xdist hook functions."""

    def pytest_testnodedown(self, node, error):
        """standard xdist hook function.
 """

def pytest_configure(config):
    if config.pluginmanager.hasplugin("xdist"):
        config.pluginmanager.register(DeferPlugin())

這具有額外的好處,允許你根據(jù)安裝的插件有條件地安裝掛鉤璧函。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末傀蚌,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蘸吓,更是在濱河造成了極大的恐慌善炫,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件库继,死亡現(xiàn)場離奇詭異箩艺,居然都是意外死亡,警方通過查閱死者的電腦和手機宪萄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門艺谆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人拜英,你說我怎么就攤上這事静汤。” “怎么了聊记?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵撒妈,是天一觀的道長。 經(jīng)常有香客問我排监,道長狰右,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任舆床,我火速辦了婚禮棋蚌,結(jié)果婚禮上嫁佳,老公的妹妹穿的比我還像新娘。我一直安慰自己谷暮,他們只是感情好蒿往,可當(dāng)我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著湿弦,像睡著了一般瓤漏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上颊埃,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天蔬充,我揣著相機與錄音,去河邊找鬼班利。 笑死饥漫,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的罗标。 我是一名探鬼主播庸队,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼闯割!你這毒婦竟也來了彻消?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤纽谒,失蹤者是張志新(化名)和其女友劉穎证膨,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鼓黔,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡央勒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了澳化。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片崔步。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖缎谷,靈堂內(nèi)的尸體忽然破棺而出井濒,到底是詐尸還是另有隱情,我是刑警寧澤列林,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布瑞你,位于F島的核電站,受9級特大地震影響希痴,放射性物質(zhì)發(fā)生泄漏者甲。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一砌创、第九天 我趴在偏房一處隱蔽的房頂上張望虏缸。 院中可真熱鬧鲫懒,春花似錦、人聲如沸刽辙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽宰缤。三九已至颂翼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間慨灭,已是汗流浹背疚鲤。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留缘挑,地道東北人。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓桶略,卻偏偏與公主長得像语淘,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子际歼,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,802評論 2 345

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