iOS自動(dòng)化測試 ==>針對XCODE自帶的XCTest

啟示

? ?iOS的自動(dòng)化測試相對安卓的成熟度底很多.而自動(dòng)化測試的目的是減輕人工測試的壓力.剛剛看一文章提到“沒有兩片相同的葉子”魂拦,也沒有兩次相同的手工測試.測試比搭,給人的一個(gè)錯(cuò)覺就是重復(fù)性瓦堵,包括有些公司在招測試人員的時(shí)候會(huì)有一條叫“能夠勝任重復(fù)性工作”菲嘴。但試問叭首,誰會(huì)手工運(yùn)行N次相同的測試呢谋梭?一個(gè)測試人員,他在執(zhí)行什么測試不重要哑姚,他為什么要執(zhí)行這個(gè)測試——背后的分析思考才重要祭饭。自動(dòng)化的測試,能夠替代的是相同的執(zhí)行叙量,卻無法替代人的分析與思考倡蝙。而軟件產(chǎn)品在研發(fā)迭代的過程,是團(tuán)隊(duì)不斷地把新的分析思考注入其中的過程绞佩。測試工作面對的是始終在不斷變化的測試需求寺鸥。所以測試的分析思考,包括手工和自動(dòng)化的測試也需要不斷地迭代改善品山。

我16年底接到老大的要求讓我探索自動(dòng)化測試.下面就是我研究了一個(gè)月的成果希望可以幫到剛剛踏入自動(dòng)化測試的童靴.

對于iOS的自動(dòng)化測試有很多種.其他的很多種都是需要比較多的時(shí)間來學(xué)習(xí)寫腳本的能力.而XCTest是Xcode自帶.本身的腳本學(xué)法可以用OC或者是Swift.個(gè)人推薦使用Xcode8的Swift語句.

實(shí)現(xiàn)

自從Xcode7的開始XCTest的UI測試就開始出現(xiàn).到Xcode8去掉UIAutoumator了.那說明XCTest在不久的將來會(huì)提供更多的接口或者被優(yōu)化.(-_-當(dāng)然也有可能會(huì)出更好的新插件).

上圖

單元測試和UI測試

上面的可以進(jìn)行單元測試和接口測試.而下面的則進(jìn)行UI測試.今天只對UI測試做詳細(xì)的介紹.對于單元測試各位上網(wǎng)查找一下對著用就行了.

在我們從xcode7開始都是默認(rèn)創(chuàng)建


創(chuàng)建工程

如果說我們的工程吧這兩個(gè)文件刪了或者一開始沒有加進(jìn)去我們可以

添加UITest (1)
添加UITest (2)

得到了我們所要的頁面了

UITest的代碼

那我們要怎么去用其實(shí)很簡單.我們就點(diǎn)下面那個(gè)紅點(diǎn).那個(gè)就是錄制功能.進(jìn)入錄制的時(shí)候,我們點(diǎn)擊我們的模擬器或者真機(jī),它就會(huì)把我們的操作用代碼記錄下來.

生成代碼

如上圖的第四塊就是我們錄制生成的代碼.那我們又怎么運(yùn)行這些代碼呢.你可以使用快捷鍵CMD+U 或者你可以點(diǎn)擊第一塊的的藍(lán)色方塊.然后可以在第二塊或者第三塊的綠色打鉤的地方點(diǎn)擊.鼠標(biāo)指向這個(gè)地方會(huì)一個(gè)灰色的播放按鈕.就可以運(yùn)行腳本了.

運(yùn)行的效果

XCTest的API

現(xiàn)在就是來學(xué)習(xí)XCTest的API.

第一 XCUIApplication

XCTest新加的類胆建,用于做UI測試,代表被測應(yīng)用肘交,父類為XCUIElement

主要的兩個(gè)方法

launch

啟動(dòng)應(yīng)用笆载。如果目標(biāo)應(yīng)用已運(yùn)行,首先終止應(yīng)用,然后再次啟動(dòng)應(yīng)用宰译。

terminate

關(guān)閉應(yīng)用。

兩個(gè)屬性

launchArguments

數(shù)組對象魄懂,保存啟動(dòng)參數(shù)沿侈。

launchEnvironment

字典對象,保存啟動(dòng)環(huán)境變量

實(shí)例

Swift版本

func testXCUIApplicationAPI(){

let app = XCUIApplication()

//關(guān)閉應(yīng)用

app.terminate()

//啟動(dòng)應(yīng)用(如果應(yīng)用已啟動(dòng),該方法會(huì)先關(guān)閉應(yīng)用市栗,再啟動(dòng)應(yīng)用)

app.launch()

//獲取啟動(dòng)參數(shù)

let args = app.launchArguments;

for arg in args {

print(arg);

}

//獲取啟動(dòng)環(huán)境變量

let envs = app.launchEnvironment;

for env in envs {

print(env);

}

}

OC版本

- (void)testXCUIApplicationAPI {

XCUIApplication *app = [[XCUIApplication alloc] init];

//關(guān)閉應(yīng)用

[app terminate];

//重新啟動(dòng)引用

[app launch];

//啟動(dòng)參數(shù)

NSArray *args = [app launchArguments];

for(int i=0;i<[args count];i++){

NSLog(@"arg :? %@",[args objectAtIndex:i]);

}

//啟動(dòng)環(huán)境

NSDictionary *env = [app launchEnvironment];

for (id key in env) {

NSString *object=[env objectForKey:key];

NSLog(@"env : %@",object);

}

}

第二 XCUIElement

XCUIElement 繼承自

NSObject缀拭,XCUIElementAttributes(定義了一些控件元素屬性,比如value,title等)填帽,XCUIElementTypeQueryProvider(一些元素集合的抽象蛛淋,比如代表按鈕的buttons),代表控件對象

方法

descendantsMatchingType

從該控件的后代控件中找到符合指定類型的控件(子子孫孫都認(rèn))篡腌,需要傳入XCUIElementType類型的參數(shù)褐荷,返回XCUIElementType類型的對象。

childrenMatchingType

只從該控件的孩子節(jié)點(diǎn)中找到符合指定類型的控件(只認(rèn)兒子)嘹悼,需要傳入XCUIElementType類型的參數(shù)叛甫,返回XCUIElementType類型的對象。

屬性

exists

判斷控件對象是否存在杨伙。BOOL類型其监。

debugDescription

保存某控件的debug信息,這些信息只能用于case的調(diào)試限匣,方便我們寫case抖苦,不能作為測試的數(shù)據(jù)。NSString類型米死。

擴(kuò)展XCUIElement

無論OC和Swift都是在XCUIElement的基礎(chǔ)上擴(kuò)展如下方法

tap

單擊

doubleTap

雙擊

twoFingerTap

雙指單擊

pressForDuration(duration: NSTimeInterval)

長按(Swift寫法)锌历,時(shí)間由傳入的參數(shù)定義,單位為秒

pressForDuration(duration: NSTimeInterval, thenDragToElement otherElement: XCUIElement)

長按拖拽(Swift寫法)峦筒。在控件上長按后辩涝,拖拽到另外一個(gè)控件。傳入2個(gè)參數(shù):長按時(shí)間和拖拽到目標(biāo)控件勘天。

swipeUp

控件上滑動(dòng)怔揩。從下劃到上

swipeDown

控件上滑動(dòng)。從上滑到上

swipeLeft

控件上滑動(dòng)脯丝。從右滑到左

swipeRight

控件上滑動(dòng)商膊。從左滑到右

typeText

輸入字符。需要一個(gè)參數(shù):NSString

實(shí)例

Swift版本

func testXCUIElementAPI() {

// Use recording to get started writing UI tests.

// Use XCTAssert and related functions to verify your tests produce the correct results.

let app = XCUIApplication()

//向上滑動(dòng)

app.swipeUp()

//向下滑動(dòng)

app.swipeDown()

//點(diǎn)擊“Groceries”列進(jìn)入子目錄

app.tables.staticTexts["Groceries"].tap()

//獲取當(dāng)前界面的表格對象

let tables = app.tables

//定位到編輯框"Add Item"

let addItemTextField = tables.textFields["Add Item"]

//點(diǎn)擊,焦點(diǎn)定位到編輯框

addItemTextField.tap()

//輸入Hello

addItemTextField.typeText("Hello")

//回車鍵

app.typeText("\r")

//獲取表格中的Cell對象宠进,每一個(gè)表格單元都是一個(gè)Cell對象

let cells = tables.childrenMatchingType(.Cell)

//獲取第二個(gè)單元晕拆,跳過了輸入框所在的行,XCUIElement對象

let cell = cells.elementAtIndex(1)

cell.swipeLeft()

cell.swipeRight()

//從第一個(gè)單元中找到文本框控件集合,XCUIElementQuery對象

let textFields = cell.childrenMatchingType(.TextField)

//let textFields = cell.descendantsMatchingType(.TextField)

//獲取第一個(gè)文本框控件实幕,XCUIElement對象

let textField = textFields.elementAtIndex(0)

if textField.exists{

//左滑然后右滑

textField.swipeLeft()

textField.swipeRight()

}

//長按5.5秒

textField.pressForDuration(5.5)

//打印debug的描述信息吝镣,也就是case執(zhí)行過程中的查找過程

print(textFields.debugDescription)

}

OC版本

-(void)testXCUIElementAPI {

XCUIApplication *app = [[XCUIApplication alloc] init];

//向上滑動(dòng)

[app swipeUp];

//向下滑動(dòng)

[app swipeDown];

//點(diǎn)擊“Groceries”列進(jìn)入子目錄

[app.tables.staticTexts[@"Groceries"] tap];

//獲取當(dāng)前界面的表格對象

XCUIElementQuery *tables = app.tables;

//定位到編輯框"Add Item"

XCUIElement *addItemTextField = tables.textFields[@"Add Item"];

//點(diǎn)擊,焦點(diǎn)定位到編輯框

[addItemTextField tap];

//輸入Hello

[addItemTextField typeText:@"Hello"];

//回車鍵

[app typeText:@"\r"];

//獲取表格中的Cell對象,每一個(gè)表格單元都是一個(gè)Cell對象

XCUIElementQuery *cells = [tables childrenMatchingType:XCUIElementTypeCell];

//獲取第二個(gè)單元昆庇,跳過了輸入框所在的行末贾,XCUIElement對象

XCUIElement *cell = [cells elementAtIndex:1];

[cell swipeLeft];

[cell swipeRight];

//從第一個(gè)單元中找到文本框控件集合,XCUIElementQuery對象

XCUIElementQuery *textFields = [cell childrenMatchingType:XCUIElementTypeTextField];

//XCUIElementQuery *textFields = [cell descendantsMatchingType:XCUIElementTypeTextField];

//獲取第一個(gè)文本框控件整吆,XCUIElement對象

XCUIElement *textField = [textFields elementAtIndex:0];

if ([textField exists]) {

//左滑然后右滑

[textField swipeLeft];

[textField swipeRight];

}

//長按5.5秒

[textField pressForDuration:5.5];

//打印debug的描述信息拱撵,也就是case執(zhí)行過程中的查找過程

NSLog(@" %@ ",[textField debugDescription]);

}

第三 XCUIElementQuery

定位元素的對象,可以理解為存放控件的容器,具有容器的特性.但是無法像數(shù)組和字典一樣打印里面的對象.

方法

elementAtIndex

獲得傳入的索引值所在的元素,返回XCUIElement對象。只能從當(dāng)前對象的查找表蝙。更深層次的元素不在查找范圍內(nèi)

elementMatchingPredicate

根據(jù)NSPredicate定義的匹配條件查找元素拴测。返回XCUIElement對象。只能從當(dāng)前對象中查找府蛇。更深層次的元素不在查找范圍內(nèi)

elementMatchingType

根據(jù)元素類型(XCUIElementType)和id號來匹配查找元素集索。返回XCUIElement對象。只能從當(dāng)前對象中查找汇跨。更深層次的元素不在查找范圍內(nèi)

descendantsMatchingType

傳入XCUIElementType作為匹配條件抄谐,得到匹配的XCUIElementQuery對象,查找對象為當(dāng)前控件的子子孫孫控件扰法。返回XCUIElementQuery對象

childrenMatchingType

傳入XCUIElementType作為匹配條件蛹含,得到匹配的XCUIElementQuery對象,查找對象為當(dāng)前控件的兒子控件塞颁。返回XCUIElementQuery對象

matchingPredicate

傳入NSPredicate作為過濾器浦箱,得到XCUIElementQuery對象。返回XCUIElementQuery對象

matchingType

傳入XCUIElementType和id號作為匹配條件祠锣,得到XCUIElementQuery酷窥。返回XCUIElementQuery對象

matchingIdentifier

傳入id號作為匹配條件,得到XCUIElementQuery伴网。返回XCUIElementQuery對象

containingPredicate

傳入NSPredicate過濾器作為匹配條件蓬推。從子節(jié)點(diǎn)中找到包含該條件的XCUIElementQuery對象

containingType

傳入XCUIElementType和id作為匹配條件。從子節(jié)點(diǎn)中找到包含該條件的XCUIElementQuery對象澡腾。

屬性

element

query用element表示形式沸伏,如果query中只有一個(gè)元素,可以講element當(dāng)成真正的element动分,執(zhí)行點(diǎn)擊等操作毅糟,從這一方面來講XCUIElementQuery其實(shí)也是一種XCUIElement對象,只是是用來存放0~N個(gè)XCUIElement的容器澜公。得到XCUIElement對象姆另。

count

query中找到的元素?cái)?shù)量,得到整數(shù)。

allElementsBoundByAccessibilityElement

query中根據(jù)accessibility element得到的元素?cái)?shù)組。得到XCUIElement數(shù)組

allElementsBoundByIndex

query中根據(jù)索引值得到的元素?cái)?shù)組迹辐。得到XCUIElement數(shù)組

debugDescription

調(diào)試信息

下標(biāo)

subscript (key: String) -> XCUIElement { get } 使得我們下面通過下標(biāo)定位成為了可能蝶防。返回XCUIElement對象

app.tables.staticTexts["Groceries"]

實(shí)例

使用element開頭的三個(gè)方法查找

func testXCUIElementQueryByElement() {

// Use recording to get started writing UI tests.

// Use XCTAssert and related functions to verify your tests produce the correct results.

let app = XCUIApplication()

//獲取所有textField的query對象

let query = app.windows.textFields

let element = query.element

//創(chuàng)建匹配器,匹配placeholderValue的值為Type in number的控件

let predicate = NSPredicate(format: "placeholderValue == %@", "Type in number")

let button = query.elementMatchingPredicate(predicate);

let button2 = query.elementAtIndex(0)

if(button.exists){

button.tap()

button.typeText("button")

}

if(button2.exists){

button2.tap()

button2.typeText("button2")

}

//創(chuàng)建匹配器明吩,匹配placeholderValue的值為Type in number且value值為Hello的控件

let predicate1 = NSPredicate(format: "value == %@ AND placeholderValue == %@", "button","Type in number")

let button3 = query.elementMatchingPredicate(predicate1);

if(button3.exists){

button3.tap()

button3.typeText("button3")

}

//根據(jù)elementMatchingType方法查找元素

let button4 = query.elementMatchingType(.TextField, identifier: "")

if(button4.exists){

button4.tap()

button4.typeText("button4")

}

}

第四 XCUIElementTypeQueryProvider

協(xié)議類间学,XCUIElement遵守的協(xié)議

變量

該協(xié)議中定義了76個(gè)變量,與XCUIElementType定義的枚舉元素相比少了3個(gè):Any,Unknown,Application.原因也很明顯贺喝,因?yàn)閄CUIApplication也遵循該協(xié)議,所以Application對象包含XCUIElementTypeQueryProvider定義的所有屬性宗兼,所以要過濾掉以上三個(gè)大于Application的類型躏鱼。

源碼

@property (readonly, copy) XCUIElementQuery *touchBars;

@property (readonly, copy) XCUIElementQuery *groups;

@property (readonly, copy) XCUIElementQuery *windows;

@property (readonly, copy) XCUIElementQuery *sheets;

@property (readonly, copy) XCUIElementQuery *drawers;

@property (readonly, copy) XCUIElementQuery *alerts;

@property (readonly, copy) XCUIElementQuery *dialogs;

@property (readonly, copy) XCUIElementQuery *buttons;

@property (readonly, copy) XCUIElementQuery *radioButtons;

@property (readonly, copy) XCUIElementQuery *radioGroups;

@property (readonly, copy) XCUIElementQuery *checkBoxes;

@property (readonly, copy) XCUIElementQuery *disclosureTriangles;

@property (readonly, copy) XCUIElementQuery *popUpButtons;

@property (readonly, copy) XCUIElementQuery *comboBoxes;

@property (readonly, copy) XCUIElementQuery *menuButtons;

@property (readonly, copy) XCUIElementQuery *toolbarButtons;

@property (readonly, copy) XCUIElementQuery *popovers;

@property (readonly, copy) XCUIElementQuery *keyboards;

@property (readonly, copy) XCUIElementQuery *keys;

@property (readonly, copy) XCUIElementQuery *navigationBars;

@property (readonly, copy) XCUIElementQuery *tabBars;

@property (readonly, copy) XCUIElementQuery *tabGroups;

@property (readonly, copy) XCUIElementQuery *toolbars;

@property (readonly, copy) XCUIElementQuery *statusBars;

@property (readonly, copy) XCUIElementQuery *tables;

@property (readonly, copy) XCUIElementQuery *tableRows;

@property (readonly, copy) XCUIElementQuery *tableColumns;

@property (readonly, copy) XCUIElementQuery *outlines;

@property (readonly, copy) XCUIElementQuery *outlineRows;

@property (readonly, copy) XCUIElementQuery *browsers;

@property (readonly, copy) XCUIElementQuery *collectionViews;

@property (readonly, copy) XCUIElementQuery *sliders;

@property (readonly, copy) XCUIElementQuery *pageIndicators;

@property (readonly, copy) XCUIElementQuery *progressIndicators;

@property (readonly, copy) XCUIElementQuery *activityIndicators;

@property (readonly, copy) XCUIElementQuery *segmentedControls;

@property (readonly, copy) XCUIElementQuery *pickers;

@property (readonly, copy) XCUIElementQuery *pickerWheels;

@property (readonly, copy) XCUIElementQuery *switches;

@property (readonly, copy) XCUIElementQuery *toggles;

@property (readonly, copy) XCUIElementQuery *links;

@property (readonly, copy) XCUIElementQuery *images;

@property (readonly, copy) XCUIElementQuery *icons;

@property (readonly, copy) XCUIElementQuery *searchFields;

@property (readonly, copy) XCUIElementQuery *scrollViews;

@property (readonly, copy) XCUIElementQuery *scrollBars;

@property (readonly, copy) XCUIElementQuery *staticTexts;

@property (readonly, copy) XCUIElementQuery *textFields;

@property (readonly, copy) XCUIElementQuery *secureTextFields;

@property (readonly, copy) XCUIElementQuery *datePickers;

@property (readonly, copy) XCUIElementQuery *textViews;

@property (readonly, copy) XCUIElementQuery *menus;

@property (readonly, copy) XCUIElementQuery *menuItems;

@property (readonly, copy) XCUIElementQuery *menuBars;

@property (readonly, copy) XCUIElementQuery *menuBarItems;

@property (readonly, copy) XCUIElementQuery *maps;

@property (readonly, copy) XCUIElementQuery *webViews;

@property (readonly, copy) XCUIElementQuery *steppers;

@property (readonly, copy) XCUIElementQuery *incrementArrows;

@property (readonly, copy) XCUIElementQuery *decrementArrows;

@property (readonly, copy) XCUIElementQuery *tabs;

@property (readonly, copy) XCUIElementQuery *timelines;

@property (readonly, copy) XCUIElementQuery *ratingIndicators;

@property (readonly, copy) XCUIElementQuery *valueIndicators;

@property (readonly, copy) XCUIElementQuery *splitGroups;

@property (readonly, copy) XCUIElementQuery *splitters;

@property (readonly, copy) XCUIElementQuery *relevanceIndicators;

@property (readonly, copy) XCUIElementQuery *colorWells;

@property (readonly, copy) XCUIElementQuery *helpTags;

@property (readonly, copy) XCUIElementQuery *mattes;

@property (readonly, copy) XCUIElementQuery *dockItems;

@property (readonly, copy) XCUIElementQuery *rulers;

@property (readonly, copy) XCUIElementQuery *rulerMarkers;

@property (readonly, copy) XCUIElementQuery *grids;

@property (readonly, copy) XCUIElementQuery *levelIndicators;

@property (readonly, copy) XCUIElementQuery *cells;

@property (readonly, copy) XCUIElementQuery *layoutAreas;

@property (readonly, copy) XCUIElementQuery *layoutItems;

@property (readonly, copy) XCUIElementQuery *handles;

@property (readonly, copy) XCUIElementQuery *otherElements;

第五 XCUIElementAttributes

協(xié)議類,XCUIElement遵守的協(xié)議

屬性

identifier

字符串類型

frame

控件的矩形區(qū)域

value

title

標(biāo)題殷绍,String類型

label

標(biāo)簽值染苛,String類型

elementType

控件類型

enabled

是否可見,BOOL類型

horizontalSizeClass

verticalSizeClass

實(shí)例

Swift

func testXCUIElementAttributes(){

let app = XCUIApplication()

//id

let id = app.identifier

print(id)

//frame

let frame = app.frame

//value

let value = app.value

//title

let title = app.title

//label

let label = app.label

//elementType

let elementType = app.elementType

//enabled

let enabled = app.enabled

//horizontalSizeClass

let horizontalSizeClass = app.horizontalSizeClass

//verticalSizeClass

let verticalSizeClass = app.verticalSizeClass

}

http://blog.csdn.net/itfootball/article/details/46621615

第六 NSPredicate

該API 在UITesting中用到了,所以有必要學(xué)習(xí)一下

實(shí)例

func testXCUIElementQueryByElement() {

// Use recording to get started writing UI tests.

// Use XCTAssert and related functions to verify your tests produce the correct results.

let app = XCUIApplication()

//獲取所有textField的query對象

let query = app.windows.textFields

let element = query.element

//創(chuàng)建匹配器主到,匹配placeholderValue的值為Type in number的控件

let predicate = NSPredicate(format: "placeholderValue == %@", "Type in number")

let button = query.elementMatchingPredicate(predicate);

let button2 = query.elementAtIndex(0)

if(button.exists){

button.tap()

button.typeText("button")

}

if(button2.exists){

button2.tap()

button2.typeText("button2")

}

//創(chuàng)建匹配器茶行,匹配placeholderValue的值為Type in number且value值為Hello的控件

let predicate1 = NSPredicate(format: "value == %@ AND placeholderValue == %@", "button","Type in number")

let button3 = query.elementMatchingPredicate(predicate1);

if(button3.exists){

button3.tap()

button3.typeText("button3")

}

//根據(jù)elementMatchingType方法查找元素

let button4 = query.elementMatchingType(.TextField, identifier: "")

if(button4.exists){

button4.tap()

button4.typeText("button4")

}

}

以上就是XCTest的API只要你學(xué)會(huì)這些就可以創(chuàng)建你想要的腳本了.

總結(jié)和反思

雖然上面的內(nèi)容并不多,我用了這么多時(shí)間主要是希望可以用這個(gè)實(shí)現(xiàn)一套人性的框架來測試app.但是至我發(fā)稿我都沒有實(shí)現(xiàn)了一個(gè)完善的框架.該框架我的想法是我們把所以的控件都放入數(shù)組.然后在for循環(huán)實(shí)現(xiàn)每個(gè)按鈕的點(diǎn)擊.但是我只能做到在獲取到這些控件之后,都點(diǎn)擊了然后重啟app就是使用launch()方法,在點(diǎn)擊下個(gè)控件.但是耗時(shí)太久.不是個(gè)好方法,而且我for循環(huán)獲取的所有控件并不代表我獲取了這個(gè)頁面的所有控件,很多復(fù)雜的控件是相互嵌套的.造成控件獲取不全,而在實(shí)現(xiàn)點(diǎn)擊的時(shí)候會(huì)造成各種莫名的奔潰.只要是我們腳本的奔潰,我們又只能重來運(yùn)行腳本.而獲取一個(gè)頁面的所有控件就耗時(shí)5,6分鐘了.效率很低.造成該框架一直無法實(shí)現(xiàn).

再次我希望該文章對你們有用的人可以往這方面想想,給我一些思路!謝謝

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市登钥,隨后出現(xiàn)的幾起案子畔师,更是在濱河造成了極大的恐慌,老刑警劉巖牧牢,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件看锉,死亡現(xiàn)場離奇詭異,居然都是意外死亡塔鳍,警方通過查閱死者的電腦和手機(jī)伯铣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來轮纫,“玉大人腔寡,你說我怎么就攤上這事≌仆伲” “怎么了放前?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長糯彬。 經(jīng)常有香客問我犀斋,道長,這世上最難降的妖魔是什么情连? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任叽粹,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘虫几。我一直安慰自己锤灿,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布辆脸。 她就那樣靜靜地躺著但校,像睡著了一般。 火紅的嫁衣襯著肌膚如雪啡氢。 梳的紋絲不亂的頭發(fā)上状囱,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天,我揣著相機(jī)與錄音倘是,去河邊找鬼亭枷。 笑死,一個(gè)胖子當(dāng)著我的面吹牛搀崭,可吹牛的內(nèi)容都是我干的叨粘。 我是一名探鬼主播,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼瘤睹,長吁一口氣:“原來是場噩夢啊……” “哼升敲!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起轰传,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤驴党,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后获茬,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鼻弧,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年锦茁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了攘轩。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,926評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡码俩,死狀恐怖度帮,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情稿存,我是刑警寧澤笨篷,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站瓣履,受9級特大地震影響率翅,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜袖迎,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一冕臭、第九天 我趴在偏房一處隱蔽的房頂上張望腺晾。 院中可真熱鬧,春花似錦辜贵、人聲如沸悯蝉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鼻由。三九已至,卻和暖如春厚棵,著一層夾襖步出監(jiān)牢的瞬間蕉世,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工婆硬, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留狠轻,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓柿祈,卻偏偏與公主長得像哈误,于是被迫代替她去往敵國和親哩至。 傳聞我的和親對象是個(gè)殘疾皇子躏嚎,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評論 2 354

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

  • 1: 在podfile中添加單元測試依賴庫 1:在pod file添加依賴庫 不添加單元測試會(huì)報(bào)file not ...
    CoderHw閱讀 4,452評論 1 12
  • 前言 如果有測試大佬發(fā)現(xiàn)內(nèi)容不對,歡迎指正菩貌,我會(huì)及時(shí)修改卢佣。 大多數(shù)的iOS App(沒有持續(xù)集成)迭代流程是這樣的...
    默默_David閱讀 1,671評論 0 4
  • 關(guān)于iOS的UI自動(dòng)化測試,是從Xcode7之后才支持的比較好箭阶,使用XCTest.framework,Xcode可...
    房小房MT閱讀 5,237評論 4 13
  • 天下風(fēng)云出我輩,一入江湖歲月催帚称。 本欲狂歌空度日嫩絮,寶劍十年不著灰。 來何洶涌何堪醉诈乒?往事隨風(fēng)不須追罩扇。 萬丈豪情都作...
    何足道_0f11閱讀 278評論 1 2
  • 農(nóng)歷八月十五,中秋節(jié)怕磨。這是人們一直都喻為最有人情味喂饥、最詩情畫意的一個(gè)節(jié)日。有說肠鲫,每逢佳節(jié)倍思親员帮。中秋節(jié)這一份思念當(dāng)...
    運(yùn)安閣閣主閱讀 214評論 0 0