單元測(cè)試與Junit4測(cè)試框架 2018-05-15

1 單元測(cè)試與Junit4測(cè)試框架:

單元測(cè)試:是指對(duì)軟件中的最小可測(cè)試單元進(jìn)行檢查和驗(yàn)證巡雨。在java應(yīng)用程序中常常指的是一個(gè)方法(但并不總是如此)谆沃。

Junit4測(cè)試框架:框架是一個(gè)應(yīng)用程序的半成品。框架提供了可在應(yīng)用程序之間共享的課服用的公共結(jié)構(gòu)。例如下面在Eclipse中運(yùn)行Junit4生成的框架:

package com.huawei.osm.incident.utils;

import static org.junit.Assert.*;

import org.junit.After;

import org.junit.AfterClass;

import org.junit.Before;

import org.junit.BeforeClass;

import org.junit.Test;

public class MybatisUtilsTest

{? ?

? ? @BeforeClass

? ? public static void setUpBeforeClass() throws Exception

? ? {

? ? }? ?

? ? @AfterClass

? ? public static void tearDownAfterClass() throws Exception

? ? {

? ? }? ?

? ? @Before

? ? public void setUp() throws Exception

? ? {

? ? }? ?

? ? @After

? ? public void tearDown() throws Exception

? ? {

? ? }? ?

? ? @Test

? ? public void testGetSqlSession()

? ? {

? ? ? ? fail("Not yet implemented");

? ? }? ?

? ? @Test

? ? public void testCloseSqlSession()

? ? {

? ? ? ? fail("Not yet implemented");

? ? }? ?

}

2 了解Junit4新特性:

2.1 Junit4新特性

1. 必須引入的Test類:import org.junit.Test扎运。舊的Junit3是需要繼承Test。以及新的類:org.junit.Assert.*饮戳。

2. 采用@Befor和@After加載或者清除資源豪治。相當(dāng)于許多方法類中的init()和destroy();

3. 屬于類范圍的 setUp()方法 和 tearDown() 方法,任何用 @BeforeClass 注釋的方法都將在該類中的測(cè)試方法運(yùn)行之前運(yùn)行一次,而任何用 @AfterClass 注釋的方法都將在該類中的所有測(cè)試都運(yùn)行之后運(yùn)行一次扯罐;

4. 提供@Test(expected=“可能拋出的異掣耗猓”)對(duì)異常測(cè)試的注解

5. 提供@lgnore注解,意即被@Ignore標(biāo)記的方法會(huì)在運(yùn)行測(cè)試時(shí)跳過篮赢,或者說被改元素標(biāo)記的方法在測(cè)試中會(huì)被忽略齿椅。當(dāng)測(cè)試的方法還沒有實(shí)現(xiàn),或者測(cè)試的方法已經(jīng)過時(shí)启泣,或者在某種條件下才能測(cè)試該方法(比如需要一個(gè)數(shù)據(jù)庫聯(lián)接涣脚,而在本地測(cè)試的時(shí)候,數(shù)據(jù)庫并沒有連接)寥茫,那么使用該標(biāo)簽來標(biāo)示這個(gè)方法遣蚀。同時(shí),你可以為該標(biāo)簽傳遞一個(gè)String的參數(shù)纱耻,來表明為什么會(huì)忽略這個(gè)測(cè)試方法芭梯。比如:@lgnore(“該方法還沒有實(shí)現(xiàn)”),在執(zhí)行的時(shí)候弄喘,僅會(huì)報(bào)告該方法沒有實(shí)現(xiàn)玖喘,而不會(huì)運(yùn)行測(cè)試方法。

6. 提供測(cè)試響應(yīng)時(shí)間@Test(timeout=1000)(單位:毫秒)蘑志,如果測(cè)試的運(yùn)行時(shí)間超過指定的毫秒數(shù)累奈,即認(rèn)為測(cè)試失敗贬派。

7. 增加兩個(gè)斷言方法:

(1)public static void assertEquals(Object[] expected, Object[] actual)

(2)public static void assertEquals(String message, Object[] expected, Object[] actual) 這兩用來比較數(shù)組:如果數(shù)組的長度和對(duì)應(yīng)的元素相同,測(cè)這兩個(gè)數(shù)組相等澎媒,否則不等搞乏,也考慮了數(shù)組為空的情況。

2.2 Junit4中常見的幾個(gè)annotation釋義

@Test:測(cè)試方法戒努,可以測(cè)試期望異常和超市時(shí)間

@Before:初始化方法请敦,每次執(zhí)行@Test之前都會(huì)運(yùn)行一次。

@After:資源釋放储玫,每次執(zhí)行@Test之后都會(huì)運(yùn)行一次侍筛。

@Ignore:忽略的測(cè)試方法

@BeforeClass、@AfterClass:注意區(qū)分@Before缘缚,它是針對(duì)所有的測(cè)試勾笆,在所在類中只會(huì)執(zhí)行一次敌蚜,只能定義為static void桥滨。同理可以接@AfterClass。

2.3 Junit4的單元測(cè)試用例執(zhí)行順序?yàn)?/p>

@BeforeClass>>@Before>>@Test>>@After>>@AfterClass.

3 Junit4測(cè)試案例

3.1 Eclipse中使用Junit4

下面是我們?cè)贓clipse中新建的一個(gè)用來做測(cè)試的一個(gè)計(jì)算器類Claculator

package com.huawei.demo;

public class Calculator

{

? ? private static int result;

? ? public void add(int n)

? ? {

? ? ? ? result = result + n;? ? ? ?

? ? }

? ? public void subs(int n)

? ? {?

? ? ? ? result = result - n;? ? ? ?

? ? }

? ? // 此方法尚未寫好

public void multiply(int n)

{? ?

// 此方法尚未寫好? ?

? ? }? ?

? ? public void divide(int n)

? ? {

? ? ? ? result = result / n;

? ? }

? ? public void square(int n)

? ? {

? ? ? ? result = n * n;

? ? }

? ? //Bug : 死循環(huán)

? ? public void squareRoot(int n)

? ? {

? ? ? ? for (; ;) ;?

? ? }

? ? // 將結(jié)果清零

? ? public void clear()

? ? {

? ? ? ? result = 0;

? ? }

? ? public int getResult()

? ? {

? ? ? ? return result;

}

}

第二步弛车,在我們的項(xiàng)目中引入JUnit4的jar包(略)

第三步齐媒,右鍵點(diǎn)擊我們剛才新建的Claculator類,選擇“New”新建一個(gè)“JUnit Test Case”,如圖:

點(diǎn)擊“下一步”,進(jìn)入勾選測(cè)試方法的頁面纷跛,根據(jù)情況選擇需要做測(cè)試的單元喻括,如圖:

點(diǎn)擊“完成”。Eclipse會(huì)自動(dòng)幫我們生成Junit4的測(cè)試框架贫奠,如下:

package com.huawei.demoTest;

import static org.junit.Assert.*;

import org.junit.Before;

import org.junit.Test;

public class CalculatorTest

{? ?

? ? @Before

? ? public void setUp() throws Exception

? ? {

? ? }? ?

? ? @Test

? ? public void testAdd()

? ? {

? ? ? ? fail("Not yet implemented");

? ? }? ?

? ? @Test

? ? public void testSubs()

? ? {

? ? ? ? fail("Not yet implemented");

? ? }? ?

? ? @Test

? ? public void testMultiply()

? ? {

? ? ? ? fail("Not yet implemented");

? ? }? ?

? ? @Test

? ? public void testDivide()

? ? {

? ? ? ? fail("Not yet implemented");

? ? }? ?

? ? @Test

? ? public void testSquare()

? ? {

? ? ? ? fail("Not yet implemented");

? ? }? ?

? ? @Test

? ? public void testSquareRoot()

? ? {

? ? ? ? fail("Not yet implemented");

? ? }

}

第四步:編寫我們的測(cè)試內(nèi)容唬血。(在Calculator類中預(yù)留的bug和exception都得處理好。)修改后如下:

package com.huawei.demoTest;

import static org.junit.Assert.*;

import org.junit.Before;

import org.junit.Ignore;

import org.junit.Test;

import com.huawei.demo.Calculator;

public class CalculatorTest

{? ?

? ? private static Calculator calculator = new Calculator();

? ? @Before

? ? public void setUp() throws Exception

? ? {

? ? ? ? calculator.clear();

? ? }? ?

? ? @Test

? ? public void testAdd()

? ? {

? ? ? ? calculator.add(2);

? ? ? ? calculator.add(3);

calculator.add(-5);

? ? ? ? assertEquals(0, calculator.getResult());

? ? }? ?

? ? @Test

? ? public void testSubs()

? ? {

? ? ? ? calculator.add(10);

? ? ? ? calculator.subs(2);

? ? ? ? assertEquals(8, calculator.getResult());

? ? }

? ? @Ignore("Multiply() Not yet implemented")

? ? @Test

? ? public void testMultiply()

? ? {

? ? }? ?

? ? @Test

? ? public void testDivide()

? ? {

? ? ? ? calculator.add(16);

? ? ? ? calculator.divide(-2);

calculator.divide(-2);

? ? ? ? assertEquals(4, calculator.getResult());

? ? }

? ? @Test(expected = ArithmeticException.class)

? ? public void divideByZero()

? ? {

? ? ? ? calculator.divide(0);

? ? }

? ? @Test

? ? public void testSquare()

{

calculator.square(-2);

? ? ? ? calculator.square(4);

? ? ? ? assertEquals(16, calculator.getResult());

? ? }? ?

? ? @Test(timeout = 1000)

? ? public void testSquareRoot()

? ? {

? ? ? ? calculator.squareRoot(4);

? ? ? ? assertEquals(2, calculator.getResult());

}

}

如下:運(yùn)行改單元測(cè)試案例唤崭,可以查看測(cè)試結(jié)果:

3.2 Gradle中集成Junit4單元測(cè)試

第一步:按照gradle項(xiàng)目目錄結(jié)構(gòu)新建一個(gè)“gradle-junit”的項(xiàng)目工程拷恨,該工程下包含標(biāo)示gradle項(xiàng)目的build.gradle文件。并將我們剛才編寫的Calculator類和它的單元測(cè)試案例類CalculatorTest放在對(duì)應(yīng)的目錄中谢肾。

第二步:編寫我們的build.gradle文件腕侄,如下

第三步:執(zhí)行g(shù)radle命令。命令行模式下芦疏,進(jìn)入我們剛才仙劍的“gradle-junit”工程所在的目錄冕杠,執(zhí)行g(shù)radle test命令。等待gradle構(gòu)建完畢酸茴,從窗口可以看到本次執(zhí)行的結(jié)果分预,如下:

結(jié)果分析解讀:

1. 執(zhí)行testSquareRoot(死循環(huán))測(cè)試失敗,并報(bào)TestTimedOutException異常薪捍;

2. 總共測(cè)試了7個(gè)tests笼痹,1個(gè)失敗了(failed)魁淳,1個(gè)跳過了(skipped);

3. 最后最大的亮點(diǎn)在,gradle為我們生成了本次測(cè)試的html頁面報(bào)告文件(…/build/reports/tests/test/index.html)与倡,可以非常直觀的顯示本次構(gòu)建結(jié)果界逛,并且還支持鏈接查看類和我們剛才編寫的單元測(cè)試案例。

4. 點(diǎn)擊紅色標(biāo)記的包或者類可以進(jìn)入相應(yīng)的鏈接頁面纺座,查看更詳細(xì)的結(jié)果息拜。例如點(diǎn)擊下面的CalculatorTest鏈接可以查看測(cè)試失敗單元測(cè)試案例原因:

TestTimedOutException:test timed out after 1000 milliseconds

以及測(cè)試類的一個(gè)測(cè)試結(jié)果類的小結(jié),如下圖:

(可以看見執(zhí)行testSquareRoot測(cè)試任務(wù)花費(fèi)1.010s净响,超過我們?cè)O(shè)定的閥值1s少欺;

并且testMultiply測(cè)試任務(wù)變色。)

4 單元測(cè)試代碼覆蓋率

在做單元測(cè)試時(shí)馋贤,代碼覆蓋率常常被拿來作為衡量測(cè)試好壞的指標(biāo)赞别,甚至,有用代碼覆蓋率來考核測(cè)試任務(wù)完成情況配乓,比如代碼覆蓋率必須達(dá)到80%或90%仿滔。正確理解代碼覆蓋率,對(duì)我們?cè)O(shè)計(jì)案例覆蓋代碼很有必要犹芹,因?yàn)閮H僅使用代碼覆蓋率來衡量崎页,有利也有弊。

4.1 語句覆蓋

語句覆蓋就是度量被測(cè)試代碼中每個(gè)可執(zhí)行語句是否被執(zhí)行到了腰埂,簡單的說就是只統(tǒng)計(jì)能夠執(zhí)行的代碼被執(zhí)行了多少行飒焦。語句覆蓋常常被人指責(zé)為“最弱的覆蓋”,它只管覆蓋代碼中執(zhí)行語句屿笼,卻不考慮各種分支的組合等等牺荠。例如:

測(cè)試代碼如下:

int foo (int a,int b)

{

return a/b;

}

假如我們?cè)O(shè)計(jì)如下的測(cè)試案例:

TeseCase:a = 10,b = 5

雖然代碼覆蓋率到達(dá)了100%,并且所有的測(cè)試案例都通過了驴一。然而遺憾的是休雌,我們的語句覆蓋率到達(dá)了所謂的100%,但是卻沒有發(fā)現(xiàn)最賤的bug蛔趴,比如當(dāng)我們?nèi)=0時(shí)挑辆,會(huì)拋出異常。再如下面的例子:

int foo (int a, int b)

{

int result = 0

if (a < 10) {

result += 1;

}

if (b < 10) {

result += 10;

}

return resule;

}

設(shè)計(jì)的測(cè)試案例如下:

TeseCase:a = 5, b = 5

該案例保證了測(cè)試案例的語句都執(zhí)行了孝情,包括分支中執(zhí)行的語句鱼蝉,因此語句覆蓋率也達(dá)到了100%,但是從分支邏輯上明顯覆蓋不全。

4.2 判定覆蓋和條件覆蓋

判定覆蓋又稱分支覆蓋箫荡,它是度量程序中沒一個(gè)判定的分支是否都被測(cè)試到了魁亦。這句話需要進(jìn)一步理解,很容易和條件覆蓋混淆羔挡。我們看例子:

int foo (int a, int b)

{

if (a < 10 || b < 10)

{

return 0; //分支一

}else {

return 1;//分支二

}

}

設(shè)計(jì)判定覆蓋案例時(shí)洁奈,我們只需考慮判定結(jié)果為true和false兩種情況间唉,我們?cè)O(shè)計(jì)如下的案例就能達(dá)到判定覆蓋率為100%:

TeseCase1:a = 5, b = 任意數(shù) 覆蓋了分支一

TeseCase2:a = 15, b = 15 覆蓋了分支二

從設(shè)計(jì)條件的邏輯上出發(fā),TeseCase2的設(shè)計(jì)與TeseCase1的在邏輯上完全的互斥互逆的利术,簡單理解為除了分支一的情況呈野,就只剩下分支二了。

設(shè)計(jì)條件覆蓋案例時(shí),我們需要考慮判定中的每個(gè)條件表達(dá)結(jié)果,為了覆蓋率達(dá)到100%虹曙,我們?cè)O(shè)計(jì)如下的案例:

TeseCase1:a = 5, b = 5 true, true

TeseCase2:a = 15娇钱,b = 15 false, false

由此可見橘券,條件覆蓋不是講判定中的每一個(gè)田間表達(dá)式的結(jié)果進(jìn)行排列組合,而只要每個(gè)條件表達(dá)式的結(jié)果為true和false測(cè)試到了就OK了。說白了,條件覆蓋就是不考慮邏輯分支僅覆蓋條件分支率触,執(zhí)行條件分支語句的覆蓋。因此汇竭,我們得出這樣的推論:完全的條件覆蓋并不能覆蓋保證完全的判定覆蓋葱蝗。

4.3 路徑覆蓋

對(duì)于路徑覆蓋的理解,我們?cè)O(shè)計(jì)如下的案例:

int foo (int a, int b)

{

int result = 0

if (a < 10) {

result += 1;

}

if (b < 10) {

result += 10;

}

return resule;

}

測(cè)試案例:

TsseCase1:a = 5, b = 5

TeseCase2:a = 5, b = 15

TeseCase3:a = 15, b = 5

TeseCase4:a = 15, b = 15

路徑覆蓋又稱斷言覆蓋韩玩。它度量了是否函數(shù)的每一個(gè)分支都被執(zhí)行了垒玲。這句話也非常好理解,就是所有的可能分支都執(zhí)行一遍找颓,有多個(gè)分支嵌套時(shí),需要對(duì)多個(gè)分支進(jìn)行排列組合叮贩,可想而知击狮,測(cè)試的路徑隨著分支的數(shù)量呈2?指數(shù)級(jí)別的增加。

5 Jacoco單元測(cè)試覆蓋率

Jacoco專門用于統(tǒng)計(jì)單元測(cè)試覆蓋率的益老,在gradle中和‘java’插件一樣使用時(shí)直接引用彪蓬,并添加版本即可:

apply plugin: 'jacoco'

jacoco{? toolVersion = "0.7.1.201405082137"? }

運(yùn)行jacoco也非常簡單,因?yàn)樗蕾囉趩卧獪y(cè)試的完成捺萌,所以執(zhí)行完test任務(wù)后档冬,可以緊接著執(zhí)行g(shù)radle jacoco命令,執(zhí)行成功桃纯,也會(huì)生成一個(gè)類似單元測(cè)試的html結(jié)果報(bào)告酷誓,非常直觀的可以看到統(tǒng)計(jì)數(shù)據(jù)的結(jié)果。

5.1 Jacoco案例分析(一):語句覆蓋與判定覆蓋

源碼如下:

package com.huawei.demo;

public class CoverJudge

{

? ? public int foot(int a, int b)

? ? {

? ? ? ? int result = 0;

? ? ? ? if (a < 10)

? ? ? ? {

? ? ? ? ? ? result += 1;

? ? ? ? }

? ? ? ? if (b < 10)

? ? ? ? {

? ? ? ? ? ? result += 10;

? ? ? ? }

? ? ? ? return result;

? ? }? ?

}

下面是設(shè)計(jì)的單元測(cè)試案例:

package com.huawei.demoTest;

import static org.junit.Assert.*;

import org.junit.Test;

import com.huawei.demo.CoverJudge;

public class CoverJudgeTest

{

? ? private static CoverJudge coverJudge = new CoverJudge();

//簡單的語句覆蓋

@Test

? ? public void testFoot()

? ? {

? ? ? ? int a = 5;

? ? ? ? int b = 5;

? ? ? ? assertEquals(11, coverJudge.foot(a, b));

? ? }

? ? /*@Test

? ? public void testFoot()

? ? {

? ? ? ? int a = 5;

? ? ? ? int b = 15;

? ? ? ? assertEquals(1, coverJudge.foot(a, b));

? ? }

@Test

? ? public void testFoot1()

? ? {

? ? ? ? int a = 15;

? ? ? ? int b = 5;

? ? ? ? assertEquals(10, coverJudge.foot(a, b));

? ? }*/? ?

}

運(yùn)行g(shù)radle test jacoco,構(gòu)建完成后可以查看覆蓋率報(bào)告态坦,如下:

顯示分支覆蓋率(Missed Branches)僅為50%盐数。

5.2 Jacoco案例分析(二):多分支覆蓋

源碼如下:

package com.huawei.demo;

public class MathUtil

{

? ? public int max(int a, int b, int c)

? ? {

? ? ? ? if (a > b)

? ? ? ? {

? ? ? ? ? ? if (a > c)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? return a;

? ? ? ? ? ? }

? ? ? ? ? ? else

? ? ? ? ? ? {

? ? ? ? ? ? ? ? return c;

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? else

? ? ? ? {

? ? ? ? ? ? if (b > c)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? return b;

? ? ? ? ? ? }

? ? ? ? ? ? else

? ? ? ? ? ? {

? ? ? ? ? ? ? ? return c;

? ? ? ? ? ? }

? ? ? ? }

? ? }

}

下面是設(shè)計(jì)的單元測(cè)試案例:

TeseCase1:

package com.huawei.demoTest;

import static org.junit.Assert.*;

import org.junit.Test;

import com.huawei.demo.MathUtil;

public class MathUtilTest

{

? ? private static MathUtil mathUtil = new MathUtil();

? ? @Test

? ? public void testMax1_2_3()

? ? {

? ? ? ? assertEquals(3, mathUtil.max(1, 2, 3));

? ? }? ?

}

執(zhí)行后結(jié)果如下,還可以進(jìn)入鏈接查看詳情

TestCase2:

package com.huawei.demoTest;

import static org.junit.Assert.*;

import org.junit.Test;

import com.huawei.demo.MathUtil;

public class MathUtilTest2

{

? ? private static MathUtil mathUtil = new MathUtil();

? ? @Test

? ? public void testMax1_2_3()

? ? {

? ? ? ? assertEquals(3, mathUtil.max(1, 2, 3));

? ? }

@Test

public void test_max_1_3_2() {

assertEquals(3, mathUtil.max(1, 3, 2));

}

@Test

public void test_max_3_2_1() {

assertEquals(3, mathUtil.max(3, 2, 1));

}

@Test

public void test_max_0_0_0(){

assertEquals(0, mathUtil.max(0, 0, 0));

}

@Test

public void test_max_0_1_0(){

assertEquals(1, mathUtil.max(0, 1, 0));

}? ?

}

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

點(diǎn)擊鏈接還可以查詢沒有覆蓋到的分支:

紅色表示沒有覆蓋到的分支;分析沒有覆蓋到a > b且a < c的情況伞梯,所以可以設(shè)計(jì)如下Tesecase:a = 2, b = 1, c = 3的情況玫氢。

所以增加如下單元測(cè)試案例:

@Test

public void test_max_2_1_3() {

assertEquals(3, mathUtil.max(2, 1, 3));

}

再次執(zhí)行可以顯示100%的分支代碼覆蓋率帚屉。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市漾峡,隨后出現(xiàn)的幾起案子攻旦,更是在濱河造成了極大的恐慌,老刑警劉巖生逸,帶你破解...
    沈念sama閱讀 216,324評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件敬特,死亡現(xiàn)場離奇詭異,居然都是意外死亡牺陶,警方通過查閱死者的電腦和手機(jī)伟阔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來掰伸,“玉大人皱炉,你說我怎么就攤上這事∈ㄑ迹” “怎么了合搅?”我有些...
    開封第一講書人閱讀 162,328評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長歧蕉。 經(jīng)常有香客問我灾部,道長,這世上最難降的妖魔是什么惯退? 我笑而不...
    開封第一講書人閱讀 58,147評(píng)論 1 292
  • 正文 為了忘掉前任赌髓,我火速辦了婚禮,結(jié)果婚禮上催跪,老公的妹妹穿的比我還像新娘锁蠕。我一直安慰自己,他們只是感情好懊蒸,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,160評(píng)論 6 388
  • 文/花漫 我一把揭開白布荣倾。 她就那樣靜靜地躺著,像睡著了一般骑丸。 火紅的嫁衣襯著肌膚如雪舌仍。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,115評(píng)論 1 296
  • 那天通危,我揣著相機(jī)與錄音铸豁,去河邊找鬼。 笑死黄鳍,一個(gè)胖子當(dāng)著我的面吹牛推姻,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播框沟,決...
    沈念sama閱讀 40,025評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼藏古,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼增炭!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起拧晕,我...
    開封第一講書人閱讀 38,867評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤隙姿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后厂捞,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體输玷,經(jīng)...
    沈念sama閱讀 45,307評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,528評(píng)論 2 332
  • 正文 我和宋清朗相戀三年靡馁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了欲鹏。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,688評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡臭墨,死狀恐怖赔嚎,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情胧弛,我是刑警寧澤尤误,帶...
    沈念sama閱讀 35,409評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站结缚,受9級(jí)特大地震影響损晤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜红竭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,001評(píng)論 3 325
  • 文/蒙蒙 一尤勋、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧德崭,春花似錦斥黑、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽兽狭。三九已至憾股,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間箕慧,已是汗流浹背服球。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評(píng)論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留颠焦,地道東北人斩熊。 一個(gè)月前我還...
    沈念sama閱讀 47,685評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像伐庭,于是被迫代替她去往敵國和親粉渠。 傳聞我的和親對(duì)象是個(gè)殘疾皇子分冈,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,573評(píng)論 2 353

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