unittest 單元測試框架

我在講解 Appium 的時候有一篇文章使用到了unittest單元測試框架,從那篇文章就可以看出來這個框架給測試帶來的便利沈矿。今天做一次比較全面系統(tǒng)的介紹。配以大量的腳本示例馍佑,希望可以幫助到更多的朋友。

單元測試就是用一個函數(shù)(方法)去驗(yàn)證另一個函數(shù)(方法)是否正確毛肋。

unittest單元測試框架主要完成以下三件事:

提供用例組織與執(zhí)行:當(dāng)測試用例只有幾條的時候可以不考慮用例的組織,但是當(dāng)測試用例數(shù)量較多時屋剑,此時就需要考慮用例的規(guī)范與組織問題了润匙。unittest單元測試框架就是用來解決這個問題的。

提供豐富的比較方法:既然是測試唉匾,就有一個預(yù)期結(jié)果和實(shí)際結(jié)果的比較問題孕讳。比較就是通過斷言來實(shí)現(xiàn),unittest單元測試框架提供了豐富的斷言方法巍膘。

提供豐富的日志:每一個失敗用例我們都希望知道失敗的原因厂财,所有用例執(zhí)行結(jié)束我們有希望知道整體執(zhí)行情況,比如總體執(zhí)行時間峡懈,失敗用例數(shù)璃饱,成功用例數(shù)。unittest單元測試框架為我們提供了這些數(shù)據(jù)肪康。

比如我們有一個方法是計算兩數(shù)之和荚恶,我們輸入幾組數(shù)值求和,如果結(jié)果與預(yù)期結(jié)果5相同磷支,那我們就認(rèn)為這個結(jié)果是我們想要的:


import unittest


class Count(object):
    def __init__(self,a,b):
        self.a = a
        self.b = b


# 計算加法
    def add(self):
        return self.a + self.b


# 單元測試谒撼,測試 add()方法
class TestCount(unittest.TestCase):

    def setUp(self):
        print("Test Start")

    def test_add(self):
        # 這里參數(shù)3,4是我們寫死的齐唆,實(shí)際是可能變化不固定的嗤栓。比如將讀取到的表格內(nèi)的數(shù)據(jù)當(dāng)做這兩個參數(shù)。
        s = Count(3,4)
        # 這里的比較對象5就是我們的預(yù)期結(jié)果箍邮,與之不同即為 Fail茉帅。
        self.assertEqual(s.add(),5)

    def tearDown(self):
        print("Test end")

    if __name__ == '__main__':
        unittest.main()

這里我們將待測方法和單元測試寫在了一個.py文件里,這樣對于日后想要修改帶來一定的不便,所以我們常把待測方法和單元測試分開寫锭弊。

待測試方法:

calculator.py

import unittest

class Count(object):
    def __init__(self,a,b):
        self.a = a
        self.b = b


# 計算加法
    def add(self):
        return self.a + self.b

單元測試:
test.py

from calculator import Count
# 單元測試必須要引入unittest模塊
import unittest
# 測試方法必須要繼承自unittest.TestCase
class TestCount(unittest.TestCase):

    def setUp(self):
        print("Test Start測試開始")

    def test_add(self):
        s = Count(3,4)
        self.assertEqual(s.add(),5)

    def tearDown(self):
        print("Test end測試結(jié)束")

    if __name__ == '__main__':
        unittest.main()

注意:count.py 和 test.py 要在同一路徑下才能 import堪澎。

腳本執(zhí)行結(jié)果報告

這里要特別說明一點(diǎn),測試方法必須要以“test_”開頭味滞,否則unittest.TestCase不識別樱蛤,無法進(jìn)行驗(yàn)證。如果測試方法沒有以“test_”開頭剑鞍,則會報錯昨凡,比如我們將方法名 test_add改為 testadd,執(zhí)行結(jié)果如下:


錯誤的測試方法命名

補(bǔ)充說明:一個.py文件有兩種使用方式:直接使用和模塊調(diào)用蚁署。上面的calculator.py文件就是被模塊調(diào)用便脊,test.py 就是直接使用。腳本最后的 if 語句

     if __name__ == '__main__':
         unittest.main()

表示當(dāng)前文件只能直接使用光戈,不能模塊調(diào)用哪痰。在這里把這兩行代碼去掉也不會影響運(yùn)行結(jié)果遂赠。

單元測試的重要概念

1. TestCase
一個TestCase的實(shí)例就是一個測試用例。一個測試用例要包括測試前準(zhǔn)備環(huán)境的搭建(setUp)晌杰,執(zhí)行測試代碼(run)跷睦,以及測試后環(huán)境的還原(tearDown)。一個測試用例是一個完整的測試單元肋演,通過運(yùn)行這個測試單元抑诸,可以對某一個功能進(jìn)行驗(yàn)證。

2. TestSuite

對于某一個功能模塊的驗(yàn)證可能需要多個測試用例爹殊,多個測試用例集合在一起執(zhí)行驗(yàn)證某一個功能哼鬓,這樣就是一個TestSuite。通過addTest()方法將 TestCase 加載到 TestSuite()中边灭。

3. TestRunner
TestRunner可以使用圖形界面异希、文本界面,或返回一個特殊的值等方式來表示測試執(zhí)行的結(jié)果绒瘦。TextTestRunner提供的 run()方法來執(zhí)行 test suite/test case称簿。

4.TestFixture
一個測試用例環(huán)境的搭建和銷毀就是一個 fixture。

下面我們舉例說明惰帽,對上面的 test.py 文件進(jìn)行修改:

在實(shí)際操作這個示例的時候遇到一些問題憨降,晚些時候補(bǔ)充!
斷言方法
方法 檢查
assertEqual(a,b) a==b
assertNotEqual(a,b) a!=b
assertTrue(x) bool(x) is True
assertFalse(x) bool(x) is False
assertIs(a,b) a is b
assertIsNot(a,b) a is not b
assertIn(a,b) a in b
assertNotIn(a,b) a not in b

舉例說明斷言的用法:
count.py

def is_prime(n):
    if n <= 1:
        return False
    for i in range(2, n):
        if n % i == 0:

            print("i ====哈啊哈哈哈=== %s,%s" % (i, n))
            print(len(range(2, n)))

            return False
        print("i ====哈啊哈哈wo哈=== %s,%s" % (i, n))
        print(len(range(2, n)))
        return True

test2.py

from count import is_prime
import unittest


class Test(unittest.TestCase):
    def setUp(self):
        print("測試開始")

    def tearDown(self):
        print("測試結(jié)束")

    def test_case(self):
        self.assertTrue(is_prime(9),msg="is Not Prime")
        


if __name__ == "__main__":
    unittest.main()
組織單元測試用例

當(dāng)我們新增被測功能和相應(yīng)的測試用例后该酗,再來看看 unittest 是如何擴(kuò)展和組織新增的測試用例的授药。
我們現(xiàn)在對calculator.py文件新增一個函數(shù):
calculator.py

import unittest


class Count(object):
    def __init__(self,a,b):
        self.a = a
        self.b = b


# 計算加法
    def add(self):
        return self.a + self.b

# 計算減法
    def sub(self):
        return self.a - self.b

接下來再修改test.py文件:

from calculator import Count
import unittest


class TestCount(unittest.TestCase):

    def setUp(self):
        print("測試開始")

    def tearDown(self):
        print("測試結(jié)束")

    def test_add(self):
        s = Count(2,1)
        self.assertEqual(s.add(), 3)
    print("用例1")

    def test_add2(self):
        s = Count(2,3)
        self.assertEqual(s.add(), 5)
    print("用例2")


class TestSub(unittest.TestCase):
    def setUp(self):
        print("測試減法開始")

    def tearDown(self):
        print("測試減法結(jié)束")

    def test_sub(self):
        s = Count(4, 1)
        self.assertEqual(s.sub(), 3, msg="4 - 1 != 2")

    def test_sub2(self):
        s = Count(3, 1)
        self.assertEqual(s.sub(), 2)


if __name__ == '__main__':
        print("到這了")
        #  構(gòu)造測試集
        suite = unittest.TestSuite()
        suite.addTest(TestCount.test_add())
        suite.addTest(TestCount.test_add2())
        suite.addTest(TestSub.test_sub())
        suite.addTest(TestSub.test_sub2())
        # 執(zhí)行測試
        runner = unittest.TextTestRunner()
        runner.run(suite)

這個腳本執(zhí)行的結(jié)果是四個函數(shù)全都 pass:


76716464-E157-405B-B3F7-739E8EBDF56F.png

現(xiàn)在我們對測試腳本稍加修改,使得結(jié)果有成功有失斘仄恰:
test.py

from calculator import Count
import unittest


class TestCount(unittest.TestCase):

    def setUp(self):
        print("測試開始")

    def tearDown(self):
        print("測試結(jié)束")

    def test_add(self):
        s = Count(2,1)
        self.assertEqual(s.add(), 3)
    print("用例1")

    def test_add2(self):
        s = Count(2,3)
        self.assertEqual(s.add(), 15)
    print("用例2")


class TestSub(unittest.TestCase):
    def setUp(self):
        print("測試減法開始")

    def tearDown(self):
        print("測試減法結(jié)束")

    def test_sub(self):
        s = Count(4, 1)
        self.assertEqual(s.sub(), 2, msg="錯誤原因:4 - 1 != 2")

    def test_sub2(self):
        s = Count(3, 1)
        self.assertEqual(s.sub(), 2)


if __name__ == '__main__':
        print("到這了")
        #  構(gòu)造測試集
        suite = unittest.TestSuite()
        suite.addTest(TestCount.test_add())
        suite.addTest(TestCount.test_add2())
        suite.addTest(TestSub.test_sub())
        suite.addTest(TestSub.test_sub2())
        # 執(zhí)行測試
        runner = unittest.TextTestRunner()
        runner.run(suite)

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


B6EC4B4D-198A-4B29-8379-DF20688C7BDA.png

從結(jié)果我們能夠看出來悔叽,一共4個用例,其中2個測試通過爵嗅,2個未能通過娇澎,未通過的函數(shù)和原因都已經(jīng)列出。
通過觀察上面的腳本還是有重復(fù)代碼睹晒,我們可以繼續(xù)修改:

from calculator import Count
import unittest


class MyTest(unittest.TestCase):

    def setUp(self):
        print("測試開始")

    def tearDown(self):
        print("測試結(jié)束")


class TestCount(MyTest):

    def test_add(self):
        s = Count(2,1)
        self.assertEqual(s.add(), 3)
    print("用例1")

    def test_add2(self):
        s = Count(2,3)
        self.assertEqual(s.add(), 5)
    print("用例2")


class TestSub(MyTest):
    def setUp(self):
        print("測試減法開始")

    def test_sub(self):
        s = Count(4, 1)
        self.assertEqual(s.sub(), 3, msg="錯誤原因:4 - 1 != 2")

    def test_sub2(self):
        s = Count(3, 1)
        self.assertEqual(s.sub(), 2)


if __name__ == '__main__':
        print("到這了")
        #  構(gòu)造測試集
        suite = unittest.TestSuite()
        suite.addTest(TestCount.test_add())
        suite.addTest(TestCount.test_add2())
        suite.addTest(TestSub.test_sub())
        suite.addTest(TestSub.test_sub2())
        # 執(zhí)行測試
        runner = unittest.TextTestRunner()
        runner.run(suite)

上面腳本類test_add和TestSub都繼承 MyTest趟庄,而 MyTest 又繼承unittest.TestCase,所以這兩個類也就繼承了unittest.TestCase伪很。這樣封裝的前提是戚啥,這兩個類都必須在 setUp 和 tearDown 中干的事情是一樣的。

我在寫這些腳本的時候曾思考過一個問題锉试。就拿我們公司目前已有的測試用例(已經(jīng)有接近400個)來說猫十,如果都寫在 test.py 一個文件里,那這個文件該有多冗余,日后維護(hù)起來該何等麻煩炫彩,有沒有一個更好的辦法來組織這些測試用例呢?別說絮短,還真有江兢!其實(shí)接下來要介紹的內(nèi)容在我介紹 Appium 的時候已經(jīng)使用該方法組織用例了。
首先我們分析一下上面的 test.py 文件不好在哪里丁频。add()和 sub()兩個方法分別實(shí)現(xiàn)兩個不同的功能杉允,為了驗(yàn)證這兩個方法,那就需要兩個類來實(shí)現(xiàn)席里,如果有更多的功能需要驗(yàn)證叔磷,那就需要更多的類,所以我們把這些類都拆分開奖磁。每一個函數(shù)(方法)作為一個單元測試文件改基。

testadd.py

from calculator import Count
import unittest


class TestAdd(unittest.TestCase):

   def setUp(self):
       print()

   def tearDown(self):
       print()

   def test_add(self):
       # Count類有兩個參數(shù),創(chuàng)建對象的時候要有兩個參數(shù)咖为。
       s = Count(2,4)
       self.assertEqual(s.add(), 6, msg="實(shí)際結(jié)果和預(yù)期不符")

   def test_add2(self):
       s = Count(1, 4)
       self.assertEqual(s.add(), 5)

   if __name__ == '_main__':
       unittest.main()

testsub.py

from calculator import Count
import unittest


class TestSub(unittest.TestCase):

    def setUp(self):
        print()

    def tearDown(self):
        print()

    def test_sub(self):
        # Count類有兩個參數(shù)秕狰,創(chuàng)建對象的時候要有兩個參數(shù)。
        s = Count(10,4)
        self.assertEqual(s.sub(), 5, msg="實(shí)際結(jié)果和預(yù)期不符")

    def test_sub2(self):
        s = Count(19, 14)
        self.assertEqual(s.sub(), 5)

    if __name__ == '_main__':
        unittest.main()

如果只是這樣做改變躁染,那么我們驗(yàn)證如果需要驗(yàn)證 add()和 sub()兩個方法鸣哀,就需要分兩次執(zhí)行 testadd.py和 testsub.py 兩個文件。現(xiàn)在我們繼續(xù)組織這兩個腳本吞彤,使得可以一次執(zhí)行這兩個文件我衬。

test.py

import unittest
# 導(dǎo)入測試文件
import testadd, testsub

# 構(gòu)造測試集
suite = unittest.TestSuite()

suite.addTest(testadd.TestAdd("test_add"))
suite.addTest(testadd.TestAdd("test_add2"))

suite.addTest(testsub.TestSub("test_sub"))
suite.addTest(testsub.TestSub("test_sub2"))

if __name__ == '__main__':
    # 執(zhí)行測試
    runner = unittest.TextTestRunner()
    runner.run(suite)

上面這種組織用例的方法要比之前簡潔一些,但是當(dāng)用例更多的時候饰恕,我們還需要通過 addTest()方法將新增的用例添加到 test.py 文件中挠羔。我們講解一個可以自動添加的方法。這就是 TestLoader 類中提供的一個 discover()方法埋嵌。

TestLoader 負(fù)責(zé)根據(jù)各種標(biāo)準(zhǔn)加載測試用例褥赊,并將他們返回給測試套件。正常情況下莉恼,不需要創(chuàng)建這個類的實(shí)例拌喉。unittest 提供了可以共享的 defaultTestLoader 類,可以使用其子類和方法創(chuàng)建實(shí)例俐银,discover()方法就是這個類中的一個方法之一尿背。

test.py

import unittest

test_dir = './'
discover = unittest.defaultTestLoader.discover(test_dir,pattern='test*.py')

if __name__ == '__main__':
    # 執(zhí)行測試
    runner = unittest.TextTestRunner()
    runner.run(discover)

這次的test.py可能就是 終極組織用例的方法了。現(xiàn)在我們介紹一下 discover()方法中參數(shù)的意思:

  • test_dir:需要加載的單元測試文件的路徑捶惜。因?yàn)槲疫@里 test.py文件和和各個測試用例在同一路徑下田藐,所以test_dir = './'。如果不是在同一路徑下,就填寫絕對路徑汽久,比如我的路徑就應(yīng)該是test_dir = /Users/guxuecheng/Desktop/unittest腳本

  • patten 是一個正則表達(dá)式鹤竭,pattern='test*.py'是指加載所有 test 開頭的.py 文件,*表示任意多個字符景醇。

discover()方法會自動的根據(jù)測試目錄(test_dir)匹配查找測試用例文件(test*.py)臀稚,并將查找到的測試用例組裝到測試套件 suite 中,因此可以通過run()方法執(zhí)行 discover三痰。

粗暴的解釋一下最后一段代碼的意思:

通俗的理解name == 'main':假如你叫小明.py吧寺,在朋友眼中,你是小明(name == '小明')散劫;在你自己眼中稚机,你是你自己(name == 'main')。

if name == 'main'的意思是:當(dāng).py文件被直接運(yùn)行時获搏,if name == 'main'之下的代碼塊將被運(yùn)行赖条;當(dāng).py文件以模塊形式被導(dǎo)入時,if name == 'main'之下的代碼塊不被運(yùn)行常熙。

??




在網(wǎng)上看到了一個博主的文章谋币,給我提供了一個新的思路,感覺很不錯症概,在此感謝博主灰藍(lán)蕾额,將文章搬到這篇文章里,方便日后翻閱:
先準(zhǔn)備一些待測方法彼城,這些方法沒有組織到一個類里诅蝶,也沒有初始化參數(shù),很簡練:
mathfunc.py

def add(a, b):
    return a+b

def minus(a, b):
    return a-b

def multi(a, b):
    return a*b

def divide(a, b):
    return a/b

接下來測試這些方法:
test_mathfunc.py

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

import unittest
from mathfunc import *


class TestMathFunc(unittest.TestCase):
    """Test mathfuc.py"""

    def test_add(self):
        """Test method add(a, b)"""
        self.assertEqual(3, add(1, 2))
        self.assertNotEqual(3, add(2, 2))

    def test_minus(self):
        """Test method minus(a, b)"""
        self.assertEqual(1, minus(3, 2))

    def test_multi(self):
        """Test method multi(a, b)"""
        self.assertEqual(6, multi(2, 3))

    def test_divide(self):
        """Test method divide(a, b)"""
        self.assertEqual(2, divide(6, 3))
        self.assertEqual(2.5, divide(5, 2))

if __name__ == '__main__':
    unittest.main()

組織 TestSuite


上面的代碼示例了如何編寫一個簡單的測試募壕,但有兩個問題调炬,我們怎么控制用例執(zhí)行的順序呢?(這里的示例中的幾個測試方法并沒有一定關(guān)系舱馅,但之后你寫的用例可能會有先后關(guān)系缰泡,需要先執(zhí)行方法A,再執(zhí)行方法B)代嗤,我們就要用到TestSuite了棘钞。我們添加到TestSuite中的case是會按照添加的順序執(zhí)行的。

問題二是我們現(xiàn)在只有一個測試文件干毅,我們直接執(zhí)行該文件即可宜猜,但如果有多個測試文件,怎么進(jìn)行組織硝逢,總不能一個個文件執(zhí)行吧姨拥,答案也在TestSuite中绅喉。

下面來個例子:

在文件夾中我們再新建一個文件,test_suite.py:

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

import unittest
from test_mathfunc import TestMathFunc

if __name__ == '__main__':
    suite = unittest.TestSuite()

    tests = [TestMathFunc("test_add"), TestMathFunc("test_minus"), TestMathFunc("test_divide")]
    suite.addTests(tests)

    runner = unittest.TextTestRunner(verbosity=2)
    runner.run(suite)

將結(jié)果輸出到文件中


用例組織好了叫乌,但結(jié)果只能輸出到控制臺柴罐,這樣沒有辦法查看之前的執(zhí)行記錄,我們想將結(jié)果輸出到文件憨奸。很簡單革屠,看示例:

修改test_suite.py:

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

import unittest
from test_mathfunc import TestMathFunc

if __name__ == '__main__':
    suite = unittest.TestSuite()
    suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestMathFunc))

    with open('UnittestTextReport.txt', 'a') as f:
        runner = unittest.TextTestRunner(stream=f, verbosity=2)
        runner.run(suite)

執(zhí)行此文件,可以看到膀藐,在同目錄下生成了UnittestTextReport.txt,所有的執(zhí)行報告均輸出到了此文件中红省,這下我們便有了txt格式的測試報告了额各。

進(jìn)階——用HTMLTestRunner輸出漂亮的HTML報告


我們能夠輸出txt格式的文本執(zhí)行報告了,但是文本報告太過簡陋吧恃,是不是想要更加高大上的HTML報告虾啦?但unittest自己可沒有帶HTML報告,我們只能求助于外部的庫了痕寓。

官方原版:http://tungwaiyip.info/software/HTMLTestRunner.html
我修改后的: https://pan.baidu.com/s/1kV64YZ9

修改我們的 test_suite.py:

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

import unittest
from test_mathfunc import TestMathFunc
from HtmlTestRunner import HTMLTestRunner

if __name__ == '__main__':
    suite = unittest.TestSuite()
    suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestMathFunc))

    with open('HTMLReport.html','w') as f:
        runner = HTMLTestRunner(stream=f,
                                report_title='Test Report',
                                descriptions='Report Details',
                                verbosity=2,
                                output='report',

                                )
        runner.run(suite)
HTML 測試報告

總結(jié)一下:


  1. unittest是Python自帶的單元測試框架傲醉,我們可以用其來作為我們自動化測試框架的用例組織執(zhí)行框架。
  2. unittest的流程:寫好TestCase呻率,然后由TestLoader加載TestCase到TestSuite硬毕,然后由TextTestRunner來運(yùn)行TestSuite,運(yùn)行的結(jié)果保存在TextTestResult中礼仗,我們通過命令行或者unittest.main()執(zhí)行時吐咳,main會調(diào)用TextTestRunner中的run來執(zhí)行,或者我們可以直接通過TextTestRunner來執(zhí)行用例元践。
  3. 一個class繼承unittest.TestCase即是一個TestCase韭脊,其中以 test 開頭的方法在load時被加載為一個真正的TestCase。
  4. verbosity參數(shù)可以控制執(zhí)行結(jié)果的輸出单旁,0 是簡單報告沪羔、1 是一般報告、2 是詳細(xì)報告象浑。
  5. 可以通過addTest和addTests向suite中添加case或suite蔫饰,可以用TestLoader的loadTestsFrom__()方法。
  6. 用 setUp()愉豺、tearDown()死嗦、setUpClass()以及 tearDownClass()可以在用例執(zhí)行前布置環(huán)境,以及在用例執(zhí)行后清理環(huán)境
  7. 我們可以通過skip粒氧,skipIf越除,skipUnless裝飾器跳過某個case,或者用TestCase.skipTest方法。
  8. 參數(shù)中加stream摘盆,可以將報告輸出到文件:可以用TextTestRunner輸出txt報告翼雀,以及可以用HTMLTestRunner輸出html報告。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末孩擂,一起剝皮案震驚了整個濱河市狼渊,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌类垦,老刑警劉巖狈邑,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異蚤认,居然都是意外死亡米苹,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進(jìn)店門砰琢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蘸嘶,“玉大人,你說我怎么就攤上這事陪汽⊙党” “怎么了?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵挚冤,是天一觀的道長况增。 經(jīng)常有香客問我,道長训挡,這世上最難降的妖魔是什么巡通? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮舍哄,結(jié)果婚禮上宴凉,老公的妹妹穿的比我還像新娘。我一直安慰自己表悬,他們只是感情好弥锄,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蟆沫,像睡著了一般籽暇。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上饭庞,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天戒悠,我揣著相機(jī)與錄音,去河邊找鬼舟山。 笑死绸狐,一個胖子當(dāng)著我的面吹牛卤恳,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播寒矿,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼突琳,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了符相?” 一聲冷哼從身側(cè)響起拆融,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎啊终,沒想到半個月后镜豹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蓝牲,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年趟脂,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片搞旭。...
    茶點(diǎn)故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡散怖,死狀恐怖菇绵,靈堂內(nèi)的尸體忽然破棺而出肄渗,到底是詐尸還是另有隱情,我是刑警寧澤咬最,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布翎嫡,位于F島的核電站,受9級特大地震影響永乌,放射性物質(zhì)發(fā)生泄漏惑申。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一翅雏、第九天 我趴在偏房一處隱蔽的房頂上張望圈驼。 院中可真熱鬧,春花似錦望几、人聲如沸绩脆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽靴迫。三九已至,卻和暖如春楼誓,著一層夾襖步出監(jiān)牢的瞬間玉锌,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工疟羹, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留主守,地道東北人禀倔。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像丸逸,于是被迫代替她去往敵國和親蹋艺。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評論 2 344

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