iOS自動(dòng)化測(cè)試之KIF使用分享

KIF的全稱(chēng)是Keep it functional状飞。它是一個(gè)建立在XCTest的UI測(cè)試框架毫胜,通過(guò)accessibility來(lái)定位具體的控件,再利用私有的API來(lái)操作UI诬辈。由于是建立在XCTest上的酵使,所以你可以完美的借助XCode的測(cè)試相關(guān)工具(包括命令行腳本)。

特點(diǎn):

  • 最小化迂回時(shí)間
    繼承KIFTestCase焙糟,測(cè)試代碼都是使用OC編寫(xiě)口渔,最大程度減少了中間層。
  • 配置簡(jiǎn)單
    直接集成到XCode上穿撮,不需要安裝多余的包缺脉。
  • 像用戶(hù)一樣測(cè)試
    測(cè)試代碼模仿用戶(hù)操作,代碼很簡(jiǎn)單
  • 自動(dòng)集成XCode 5以上的測(cè)試工具
    在XCode上使用就像使用蘋(píng)果原生的測(cè)試框架一樣悦穿,支持XCode的各種測(cè)試工具攻礼。

按照KIF的的官方文檔進(jìn)行導(dǎo)入KIF,接下來(lái)以官方的demo為例,進(jìn)行KIF的相關(guān)操作的講解咧党。

目錄

  • 使用描述
  • Tapping
  • Show/Hide
  • Gesture
  • TableView
  • Picker
  • ModalView
  • CollectionView
  • ScrollView
  • Landscape
  • WebView
  • Background
  • PullToRefesh
  • CascadingFailure
  • 補(bǔ)充Tips

使用描述

使用KIF主要有兩個(gè)核心類(lèi):

  • KIFTestCase XCTestCase的子類(lèi)
  • KIFUITestActor 控制UI秘蛔,常見(jiàn)的三種是:點(diǎn)擊一個(gè)View,向一個(gè)View輸入內(nèi)容,等待一個(gè)View的出現(xiàn)

KIF利用Accessibility來(lái)找元素.tapViewWithAccessibilityLabel 這也許是最常被用到的測(cè)試動(dòng)作方法深员。正如其名稱(chēng)所顯示的负蠕,它可以在給定的輔助標(biāo)簽?zāi)M在視圖上的觸擊。在大多數(shù)情況下倦畅,輔助標(biāo)簽和可視的文本標(biāo)簽(例如按鈕組件)是配套的遮糖。否則你就需要手動(dòng)設(shè)置輔助標(biāo)簽.
一些控件,諸如 UISwitch叠赐,更加復(fù)雜欲账,需要比簡(jiǎn)單的觸擊更復(fù)雜的步驟來(lái)觸發(fā)。KIF 提供了一個(gè)特殊的 setOn:forSwitchWithAccessibilityLabel: 方法來(lái)改變一個(gè)切換的狀態(tài).

導(dǎo)入KIF框架后芭概,在項(xiàng)目的Tests(如果還沒(méi)有Tests文件夾,可以先創(chuàng)建Tests)聲明一個(gè)測(cè)試類(lèi)赛不,必須以Tests結(jié)尾(如LoginTests),繼承自KIFTestCase罢洲。為了讓程序在運(yùn)行每個(gè)測(cè)試用例時(shí)能保證連貫性踢故,在每個(gè)類(lèi)中都聲明兩個(gè)方法beforeEachafterEach 保證測(cè)試過(guò)程中可以進(jìn)入想要執(zhí)行的測(cè)試頁(yè)面與退出測(cè)試頁(yè)面。

///進(jìn)入指定頁(yè)面
- (void)beforeEach{
    [tester tapViewWithAccessibilityLabel:@"Tapping"];
}
///退出指定頁(yè)面
- (void)afterEach{
    [tester tapViewWithAccessibilityLabel:@"Test Suite" traits:UIAccessibilityTraitButton];
}

Tapping

點(diǎn)擊控制器上標(biāo)記為T(mén)apViewController Inner ScrollView的視圖上的元素

- (void)testTappingViewFromSpecificView{
    UIView *scrollView = [tester waitForViewWithAccessibilityIdentifier:@"TapViewController Inner ScrollView"];
    UIView *buttonView;
    UIAccessibilityElement *element;
    [tester waitForAccessibilityElement:&element view:&buttonView withIdentifier:@"Inner Button" fromRootView:scrollView tappable:YES];
    
    if (buttonView != NULL) {
        [tester tapAccessibilityElement:element inView:buttonView];
    }
}

長(zhǎng)按操作

- (void)testLongPressingViewViewWithTraits{
    [tester longPressViewWithAccessibilityLabel:@"Greeting" value:@"Hello" duration:2];
    [tester tapViewWithAccessibilityLabel:@"Select All"];
}

切換按鈕狀態(tài)

- (void)testTogglingASwitch
{
    [tester waitForViewWithAccessibilityLabel:@"Happy" value:@"1" traits:UIAccessibilityTraitNone];
    [tester setOn:NO forSwitchWithAccessibilityLabel:@"Happy"];
    [tester waitForViewWithAccessibilityLabel:@"Happy" value:@"0" traits:UIAccessibilityTraitNone];
    [tester setOn:YES forSwitchWithAccessibilityLabel:@"Happy"];
    [tester waitForViewWithAccessibilityLabel:@"Happy" value:@"1" traits:UIAccessibilityTraitNone];
}

滑動(dòng)狀態(tài)條

- (void)testMovingASlider{
    [tester waitForTimeInterval:1];
    [tester setValue:3 forSliderWithAccessibilityLabel:@"Slider"];
    [tester waitForViewWithAccessibilityLabel:@"Slider" value:@"3" traits:UIAccessibilityTraitNone];
    [tester setValue:0 forSliderWithAccessibilityLabel:@"Slider"];
    [tester waitForViewWithAccessibilityLabel:@"Slider" value:@"0" traits:UIAccessibilityTraitNone];
    [tester setValue:5 forSliderWithAccessibilityLabel:@"Slider"];
    [tester waitForViewWithAccessibilityLabel:@"Slider" value:@"5" traits:UIAccessibilityTraitNone];
}

選取系統(tǒng)的圖片

- (void)testPickingAPhoto{
    [tester tapViewWithAccessibilityLabel:@"Photos"];
    [tester acknowledgeSystemAlert];
    [tester waitForTimeInterval:0.5f]; // Wait for view to stabilize
    [tester choosePhotoInAlbum:@"Camera Roll" atRow:1 column:2];
    [tester waitForViewWithAccessibilityLabel:@"UIImage"];
}

Show/Hide

一直尋找區(qū)域內(nèi)標(biāo)記為B的值為BB的可點(diǎn)擊的按鈕

- (void)testWaitingForViewWithValue{
    NSLog(@"testWaitingForViewWithValue");
    [tester waitForTappableViewWithAccessibilityLabel:@"B" value:@"BB" traits:UIAccessibilityTraitButton];
}

選擇視圖內(nèi)可點(diǎn)擊切換狀態(tài)的按鈕

- (void)testTappingOnlyIfNotSelected{
    [tester tapViewIfNotSelected:@"A"];
    [tester waitForViewWithAccessibilityLabel:@"A" traits:UIAccessibilityTraitSelected];
    
    // This should not deselect the element.
    [tester tapViewIfNotSelected:@"A"];
    [tester waitForViewWithAccessibilityLabel:@"A" traits:UIAccessibilityTraitSelected];
}
- (void)tapViewIfNotSelected:(NSString *)label{
    UIAccessibilityElement *element;
    UIView *view;
    [self waitForAccessibilityElement:&element view:&view withLabel:label value:nil traits:UIAccessibilityTraitNone tappable:YES];
    if ((element.accessibilityTraits & UIAccessibilityTraitSelected) == UIAccessibilityTraitNone) {
        [self tapAccessibilityElement:element inView:view];
    }
}

Gesture


手勢(shì)操作

滑動(dòng)

四個(gè)方向都可操作

typedef NS_ENUM(NSUInteger, KIFSwipeDirection) {
    KIFSwipeDirectionRight,
    KIFSwipeDirectionLeft,
    KIFSwipeDirectionUp,
    KIFSwipeDirectionDown
};

示例

- (void)testSwipingRight{
    [tester swipeViewWithAccessibilityLabel:@"Swipe Me" inDirection:KIFSwipeDirectionRight];
    [tester waitForViewWithAccessibilityLabel:@"Right"];
}

點(diǎn)擊

- (void)testPanningRight{
    NSString* regexPattern = kPanRightRegex;
    NSPredicate *resultTestPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regexPattern];
    NSPredicate *noVelocityPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", KPanNoVelocityValue];
    
    UIView* velocityResultView = [tester waitForViewWithAccessibilityLabel:kVelocityValueLabelAccessibilityString];
    XCTAssertTrue([velocityResultView isKindOfClass:[UILabel class]], @"Found view is not a UILabel instance!");
    UILabel* velocityLabel = (UILabel*)velocityResultView;
    
    UIView* panLabel = [tester waitForTappableViewWithAccessibilityLabel:kPanMeAccessibilityString];
    CGPoint centerInView = CGPointMake(panLabel.frame.size.width / 2.0, panLabel.frame.size.height / 2.0);
    
    [panLabel dragFromPoint:centerInView toPoint:CGPointMake(centerInView.x + 30, centerInView.y)];
    XCTAssertFalse([noVelocityPredicate evaluateWithObject:velocityLabel.text], @"No valocity value found!");
    XCTAssertTrue([resultTestPredicate evaluateWithObject:velocityLabel.text], @"The result doesn`t match the %@ regex pattern", regexPattern);
}

拖拽

- (void)testScrolling{
    // Needs to be offset from the edge to prevent the navigation controller's interactivePopGestureRecognizer from triggering
    [tester scrollViewWithAccessibilityIdentifier:@"Scroll View" byFractionOfSizeHorizontal:-0.80 vertical:-0.80];
    [tester waitForTappableViewWithAccessibilityLabel:@"Bottom Right"];
    [tester scrollViewWithAccessibilityIdentifier:@"Scroll View" byFractionOfSizeHorizontal:0.80 vertical:0.80];
    [tester waitForTappableViewWithAccessibilityLabel:@"Top Left"];
}

TableView

tableView的手勢(shì)滑動(dòng)

 [tester swipeRowAtIndexPath:firstCellPath inTableView:tableView inDirection:KIFSwipeDirectionLeft];

點(diǎn)擊tableview上指定的某個(gè)cell

- (void)testTappingRows{
    [tester tapRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:2] inTableViewWithAccessibilityIdentifier:@"TableView Tests Table"];
    [tester waitForViewWithAccessibilityLabel:@"Last Cell" traits:UIAccessibilityTraitSelected];
    [tester tapRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] inTableViewWithAccessibilityIdentifier:@"TableView Tests Table"];
    [tester waitForViewWithAccessibilityLabel:@"First Cell" traits:UIAccessibilityTraitSelected];
}

移動(dòng)

- (void)testMoveRowUpUsingNegativeRowIndexes{
    [tester moveRowAtIndexPath:[NSIndexPath indexPathForRow:-1 inSection:1]
 toIndexPath:[NSIndexPath indexPathForRow:-3 inSection:1] inTableViewWithAccessibilityIdentifier:@"TableView Tests Table"];
}

刪除

///刪除第一個(gè)cell
- (void)testSwipingRows {
    
    UITableView *tableView;
    [tester waitForAccessibilityElement:NULL view:&tableView withIdentifier:@"TableView Tests Table" tappable:NO];
    [tester waitForAnimationsToFinish];
    // First row
    NSIndexPath *firstCellPath = [NSIndexPath indexPathForRow:0 inSection:0];
    [tester swipeRowAtIndexPath:firstCellPath inTableView:tableView inDirection:KIFSwipeDirectionLeft];
    [tester waitForDeleteStateForCellAtIndexPath:firstCellPath inTableView:tableView];
    [tester tapViewWithAccessibilityLabel:@"Delete"];
    
    __KIFAssertEqualObjects([tester waitForCellAtIndexPath:firstCellPath inTableViewWithAccessibilityIdentifier:@"TableView Tests Table"].textLabel.text, @"Deleted", @"");
}

設(shè)置Button狀態(tài)

- (void)testTogglingSwitch{
    [tester setOn:NO forSwitchWithAccessibilityLabel:@"Table View Switch"];
    [tester setOn:YES forSwitchWithAccessibilityLabel:@"Table View Switch"];
}

檢查元素是否在視圖上 當(dāng)元素在視圖上消失時(shí) 執(zhí)行操作

- (void)testButtonAbsentAfterRemoveFromSuperview{
    UIView *view = [tester waitForViewWithAccessibilityLabel:@"Button"];
    [view removeFromSuperview];
    [tester waitForAbsenceOfViewWithAccessibilityLabel:@"Button"];
}

Picker

時(shí)間選擇器

- (void)testSelectingDateInPast{
    [tester tapViewWithAccessibilityLabel:@"Date Selection"];
    NSArray *date = @[@"June", @"17", @"1965"];
    // If the UIDatePicker LocaleIdentifier would be de_DE then the date to set
    // would look like this: NSArray *date = @[@"17.", @"Juni", @"1965"
    [tester selectDatePickerValue:date];
    [tester waitForViewWithAccessibilityLabel:@"Date Selection" value:@"Jun 17, 1965" traits:UIAccessibilityTraitNone];
}

選擇器

- (void)testSelectingAPickerRow{
    [tester selectPickerViewRowWithTitle:@"Charlie"];
    NSOperatingSystemVersion iOS8 = {8, 0, 0};
   [tester waitForViewWithAccessibilityLabel:@"Call Sign" value:@"Charlie" traits:UIAccessibilityTraitNone];
}

ModalView

點(diǎn)擊alertView上的選項(xiàng) 取消

- (void)testInteractionWithAnAlertView{
    [tester tapViewWithAccessibilityLabel:@"UIAlertView"];
    [tester waitForViewWithAccessibilityLabel:@"Alert View"];
    [tester waitForViewWithAccessibilityLabel:@"Message"];
    [tester waitForTappableViewWithAccessibilityLabel:@"Cancel"];
    [tester waitForTappableViewWithAccessibilityLabel:@"Continue"];
    [tester tapViewWithAccessibilityLabel:@"Continue"];
    [tester waitForAbsenceOfViewWithAccessibilityLabel:@"Message"];
}

點(diǎn)擊底部彈窗

- (void)testInteractionWithAnActionSheet{
    [tester tapViewWithAccessibilityLabel:@"UIActionSheet"];
    [tester waitForViewWithAccessibilityLabel:@"Action Sheet"];
    [tester waitForTappableViewWithAccessibilityLabel:@"Destroy"];
    [tester waitForTappableViewWithAccessibilityLabel:@"A"];
    [tester waitForTappableViewWithAccessibilityLabel:@"B"];
}

點(diǎn)擊獲取系統(tǒng)的activity

- (void)testInteractionWithAnActivityViewController{
    if (!NSClassFromString(@"UIActivityViewController")) {
        return;
    }
    [tester tapViewWithAccessibilityLabel:@"UIActivityViewController"];
    [tester waitForTappableViewWithAccessibilityLabel:@"Copy"];
    [tester waitForTappableViewWithAccessibilityLabel:@"Mail"];
}

CollectionView

點(diǎn)擊Item

- (void)testTappingItems{
    [tester tapItemAtIndexPath:[NSIndexPath indexPathForItem:199 inSection:0] inCollectionViewWithAccessibilityIdentifier:@"CollectionView Tests CollectionView"];
    [tester waitForViewWithAccessibilityLabel:@"Last Cell" traits:UIAccessibilityTraitSelected];
    [tester tapItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0] inCollectionViewWithAccessibilityIdentifier:@"CollectionView Tests CollectionView"];
    [tester waitForViewWithAccessibilityLabel:@"First Cell" traits:UIAccessibilityTraitSelected];
}

ScrollView

滑動(dòng)

///down up right left 為ScrollView上的控件
- (void)testScrollingToTapOffscreenViews{
    [tester tapViewWithAccessibilityLabel:@"Down"];
    [tester tapViewWithAccessibilityLabel:@"Up"];
    [tester tapViewWithAccessibilityLabel:@"Right"];
    [tester tapViewWithAccessibilityLabel:@"Left"];
}

Landscape

切換橫屏

- (void)beforeAll{
    [system simulateDeviceRotationToOrientation:UIDeviceOrientationLandscapeLeft];
    [tester scrollViewWithAccessibilityIdentifier:@"Test Suite TableView" byFractionOfSizeHorizontal:0 vertical:-0.2];
}
- (void)afterAll{
    [system simulateDeviceRotationToOrientation:UIDeviceOrientationPortrait];
    [tester waitForTimeInterval:0.5];
}

TextField

textField輸入文字

登錄注冊(cè)時(shí)常常使用這種方式進(jìn)行行為描述

- (void)testWaitingForSearchFieldToBecomeFirstResponder{
    [tester tapViewWithAccessibilityLabel:nil traits:UIAccessibilityTraitSearchField];
    [tester waitForFirstResponderWithAccessibilityLabel:nil traits:UIAccessibilityTraitSearchField];
    [tester enterTextIntoCurrentFirstResponder:@"text"];
    [tester waitForViewWithAccessibilityLabel:nil value:@"text" traits:UIAccessibilityTraitSearchField];
}

WebView

點(diǎn)擊鏈接

- (void)testTappingLinks {
    [tester tapViewWithAccessibilityLabel:@"A link"];
    [tester waitForViewWithAccessibilityLabel:@"Page 2"];
}

輸入文本

- (void)testEnteringText {
    [tester tapViewWithAccessibilityLabel:@"Input Label"];
    [tester enterTextIntoCurrentFirstResponder:@"Keyboard text"];
}

滾動(dòng)Scroll

- (void)testScrolling {
    // Off screen, the web view will need to be scrolled down
    [tester waitForViewWithAccessibilityLabel:@"Footer"];
}

Background

進(jìn)入后臺(tái)操作

- (void)testBackgroundApp {
    [tester waitForViewWithAccessibilityLabel:@"Start"];
    [system deactivateAppForDuration:5];
    [tester waitForViewWithAccessibilityLabel:@"Back"];
}

PullToRefesh

下拉刷新

-(void) testPullToRefreshByAccessibilityLabelWithDuration{
    UITableView *tableView;
    [tester waitForAccessibilityElement:NULL view:&tableView withIdentifier:@"Test Suite TableView" tappable:NO];

    [tester pullToRefreshViewWithAccessibilityLabel:@"Table View" pullDownDuration:KIFPullToRefreshInAboutThreeSeconds];
    [tester waitForViewWithAccessibilityLabel:@"Bingo!"];
    [tester waitForAbsenceOfViewWithAccessibilityLabel:@"Bingo!"];

    [tester waitForTimeInterval:5.0f]; //make sure the PTR is finished.
}

Typing

復(fù)制粘貼

- (void)testEnteringTextIntoViewWithAccessibilityLabel{
    [tester longPressViewWithAccessibilityLabel:@"Greeting" value:@"Hello" duration:2];
    [tester tapViewWithAccessibilityLabel:@"Select All"];
    [tester tapViewWithAccessibilityLabel:@"Cut"];
    [tester enterText:@"Yo" intoViewWithAccessibilityLabel:@"Greeting"];
    [tester waitForViewWithAccessibilityLabel:@"Greeting" value:@"Yo" traits:UIAccessibilityTraitNone];
}

清除

- (void)testClearingAndEnteringTextIntoViewWithAccessibilityLabel
{
    [tester clearTextFromAndThenEnterText:@"Yo" intoViewWithAccessibilityLabel:@"Greeting"];
}

兩個(gè)textField聯(lián)動(dòng)

- (void)testEnteringReturnCharacterIntoViewWithAccessibilityLabel
{
    [tester enterText:@"Hello\n" intoViewWithAccessibilityLabel:@"Other Text"];
    [tester waitForFirstResponderWithAccessibilityLabel:@"Greeting"];
    [tester enterText:@", world\n" intoViewWithAccessibilityLabel:@"Greeting" traits:UIAccessibilityTraitNone expectedResult:@"Hello, world"];
}

輸入Emoj表情

- (void)testEnteringEmojiCharactersIntoViewWithAccessibilityLabel{
    NSString *text = @" ??He??ll??o";
    [tester clearTextFromAndThenEnterText:text intoViewWithAccessibilityLabel:@"Greeting"];
    UITextField * tf = (UITextField*)[tester waitForViewWithAccessibilityLabel:@"Greeting"];
    XCTAssertTrue([tf.text isEqualToString:text]);
}

預(yù)期TextField的輸入

- (void)testThatBackspaceDeletesOneCharacter{
    [tester enterText:@"hi\bello" intoViewWithAccessibilityLabel:@"Other Text" traits:UIAccessibilityTraitNone expectedResult:@"hello"];
    [tester waitForViewWithAccessibilityLabel:@"Greeting" value:@"Deleted something." traits:UIAccessibilityTraitNone];
    UIView *textView = [tester waitForViewWithAccessibilityLabel:@"Other Text"];
    XCTAssertEqualObjects([tester textFromView:textView], @"hello");
}

CascadingFailure

失敗用例測(cè)試

- (void)testCascadingFailure{
    KIFExpectFailure([system failA]);
    KIFExpectFailureWithCount([system failA], 4);
}

補(bǔ)充Tips

按鈕的title惹苗、類(lèi)的title殿较,可以直接做為訪(fǎng)問(wèn)標(biāo)簽
如果UI組件被鍵盤(pán)擋住了,需要先退掉鍵盤(pán)
如果UI組件不在屏幕范圍內(nèi)桩蓉,不可以訪(fǎng)問(wèn)淋纲,但是滾動(dòng)視圖,可以訪(fǎng)問(wèn)院究,且會(huì)出現(xiàn)在可視范圍洽瞬。
無(wú)法訪(fǎng)問(wèn)系統(tǒng)自己的彈窗。例如app想定位用戶(hù)业汰,不能自動(dòng)點(diǎn)擊允許片任;但是app自己的彈窗,可以操作的
類(lèi)內(nèi)部的多個(gè)測(cè)試方法的測(cè)試順序蔬胯,是無(wú)序的
類(lèi)與類(lèi)的測(cè)試順序对供,是無(wú)序的
可以將某個(gè)測(cè)試類(lèi)或者測(cè)試方法給disable掉

最后

到目前為止,我們應(yīng)該對(duì)KIF的使用性有很好的了解氛濒,腦子里也應(yīng)該有不少主意产场,大概了解如何利用這個(gè)高效的功能測(cè)試工具來(lái)測(cè)試你自己的應(yīng)用程序。由于KIF測(cè)試用例是OCUnit的子類(lèi)舞竿,并在標(biāo)準(zhǔn)的Xcode5測(cè)試框架下運(yùn)行京景,你可以使用持續(xù)集成來(lái)跑這些測(cè)試。當(dāng)你干別的事情的時(shí)候骗奖,你擁有了一個(gè)能夠像人的手指一樣觸控的機(jī)器人去測(cè)試你的應(yīng)用程序确徙。

參考文獻(xiàn):

推薦閱讀

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末醒串,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子鄙皇,更是在濱河造成了極大的恐慌芜赌,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,591評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件伴逸,死亡現(xiàn)場(chǎng)離奇詭異缠沈,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)错蝴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)洲愤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人顷锰,你說(shuō)我怎么就攤上這事柬赐。” “怎么了官紫?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,823評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵躺率,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我万矾,道長(zhǎng),這世上最難降的妖魔是什么慎框? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,204評(píng)論 1 292
  • 正文 為了忘掉前任良狈,我火速辦了婚禮,結(jié)果婚禮上笨枯,老公的妹妹穿的比我還像新娘薪丁。我一直安慰自己,他們只是感情好馅精,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布严嗜。 她就那樣靜靜地躺著,像睡著了一般洲敢。 火紅的嫁衣襯著肌膚如雪漫玄。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,190評(píng)論 1 299
  • 那天压彭,我揣著相機(jī)與錄音睦优,去河邊找鬼。 笑死壮不,一個(gè)胖子當(dāng)著我的面吹牛汗盘,可吹牛的內(nèi)容都是我干的改执。 我是一名探鬼主播磁浇,決...
    沈念sama閱讀 40,078評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼肚菠!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起菱阵,我...
    開(kāi)封第一講書(shū)人閱讀 38,923評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤踢俄,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后送粱,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體褪贵,經(jīng)...
    沈念sama閱讀 45,334評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評(píng)論 2 333
  • 正文 我和宋清朗相戀三年抗俄,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了脆丁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,727評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡动雹,死狀恐怖槽卫,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情胰蝠,我是刑警寧澤歼培,帶...
    沈念sama閱讀 35,428評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站茸塞,受9級(jí)特大地震影響躲庄,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜钾虐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評(píng)論 3 326
  • 文/蒙蒙 一噪窘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧效扫,春花似錦倔监、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,672評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至济丘,卻和暖如春谱秽,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背摹迷。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,826評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工弯院, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人泪掀。 一個(gè)月前我還...
    沈念sama閱讀 47,734評(píng)論 2 368
  • 正文 我出身青樓听绳,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親异赫。 傳聞我的和親對(duì)象是個(gè)殘疾皇子椅挣,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評(píng)論 2 354

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

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)头岔、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,094評(píng)論 4 62
  • 前言 如果有測(cè)試大佬發(fā)現(xiàn)內(nèi)容不對(duì)鼠证,歡迎指正峡竣,我會(huì)及時(shí)修改。 大多數(shù)的iOS App(沒(méi)有持續(xù)集成)迭代流程是這樣的...
    默默_David閱讀 1,669評(píng)論 0 4
  • 在蘋(píng)果電腦的屏幕下方量九,有一個(gè)功能類(lèi)似Windows任務(wù)欄的東西适掰。可以顯示荠列、切換正在運(yùn)行的程序类浪,也可以點(diǎn)擊上面程序的...
    大魚(yú)小賤閱讀 2,017評(píng)論 1 0
  • 天啊,天啊固额,我真的是白癡懊呗臁!居然敢這樣跟上司講話(huà)斗躏,你說(shuō)我會(huì)不會(huì)被炒魷魚(yú)笆呕邸!我回過(guò)頭來(lái)對(duì)著老板笑了一下瑟捣。老板忽然...
    祺藝果閱讀 182評(píng)論 0 0
  • 成功學(xué)就是打雞血迈套。成功學(xué)就是興奮不已的表情、慷慨激昂的演講碱鳞、整齊劃一的動(dòng)作桑李。成功學(xué)就是我一定要!我一定行窿给!我是最棒...
    開(kāi)啟2017閱讀 198評(píng)論 2 6