敏捷实践 (3) - Appium Ruby Console

appium.png

1. Appium Ruby Console

Appium Ruby Console (ARC) 顾名思义就是Appium控制台(命令行模式)。
https://github.com/appium/ruby_console

2. 安装

如果你在 敏捷实践(1) - 我们是如何自动化App验收标准 中,已经安装了ARC,这个步就可以忽略。

$ gem install appium_lib
$ gem install appium_console

3. 启动

3.1 appium

在打开一个命令行窗口运行 appium 服务
$ appium

run_appium.png

3.2 拉取Sample-Code

`$ git clone https://github.com/appium/sample-code.git

3.3 运行ARC

arc 会自动读取 appium.txt 并通知appium启动appium.txt指定的App

app的位置在sample-code/sample-code/apps/TestApp/build/release-iphonesimulator/TestApp.app

$ cd sample-code/sample-code/examples/ruby
# 运行 bundle 安装依赖包
$ bundle
$ arc

这个一步发生了什么?
** ARC 启动,读取appium.txt的配置发送给 appium **

run_arc.png

** appium 收到请求,启动模拟器,安装WebDriverAgent & TestApp **
下面粘贴的日志信息可以让大家看到许多背后的细节,对理解appium如何工作很有帮助。

EdwarddeMBP:appium_work edwardzhou$ appium
[Appium] Welcome to Appium v1.6.3
[Appium] Appium REST http interface listener started on 0.0.0.0:4723
[HTTP] --> POST /wd/hub/session {"desiredCapabilities":{"browserName":"","version":"","platform":"ANY","javascriptEnabled":true,"cssSelectorsEnabled":true,"takesScreenshot":true,"nativeEvents":false,"rotatable":false,"newCommandTimeout":999999,"platformName":"ios","versionNumber":"10.2","deviceName":"iPhone 6","app":"/Users/edwardzhou/appium_work/sample-code/sample-code/apps/TestApp/build/release-iphonesimulator/TestApp.app","automationName":"XCUITest","language":"zh","locale":"zh_CN","autoAcceptAlerts":true}}
[debug] [MJSONWP] Calling AppiumDriver.createSession() with args: [{"browserName":"","version":"","platform":"ANY","javascriptEnabled":true,"cssSelectorsEnabled":true,"takesScreenshot":true,"nativeEvents":false,"rotatable":false,"newCommandTimeout":999999,"platformName":"ios","versionNumber":"10.2","deviceName":"iPhone 6","app":"/Users/edwardzhou/appium_work/sample-code/sample-code/apps/TestApp/build/release-iphonesimulator/TestApp.app","automationName":"XCUITest","language":"zh","locale":"zh_CN","autoAcceptAlerts":true},null,null,null,null]
[Appium] Creating new XCUITestDriver session
[Appium] Capabilities:
[Appium]   browserName: ''
[Appium]   version: ''
[Appium]   platform: 'ANY'
[Appium]   javascriptEnabled: true
[Appium]   cssSelectorsEnabled: true
[Appium]   takesScreenshot: true
[Appium]   nativeEvents: false
[Appium]   rotatable: false
[Appium]   newCommandTimeout: 999999
[Appium]   platformName: 'ios'
[Appium]   versionNumber: '10.2'
[Appium]   deviceName: 'iPhone 6'
[Appium]   app: '/Users/edwardzhou/appium_work/sample-code/sample-code/apps/TestApp/build/release-iphonesimulator/TestApp.app'
[Appium]   automationName: 'XCUITest'
[Appium]   language: 'zh'
[Appium]   locale: 'zh_CN'
[Appium]   autoAcceptAlerts: true
[debug] [XCUITest] XCUITestDriver version: 2.5.3
[BaseDriver] The following capabilities were provided, but are not recognized by appium: version, platform, javascriptEnabled, cssSelectorsEnabled, takesScreenshot, nativeEvents, rotatable, versionNumber.
[XCUITest] The capabilities 'autoAcceptAlerts' and 'autoDismissAlerts' do not work for XCUITest-based tests. Please adjust your alert handling accordingly.
[BaseDriver] Session created with session id: 136bbab8-78e5-4e5d-9cd1-0b174eeaa835
[debug] [XCUITest] Xcode version set to '8.2.1'
[debug] [XCUITest] iOS SDK Version set to '10.2'
[XCUITest] Simluator udid not provided, using desired caps to create a new simulator
[XCUITest] No platformVersion specified. Using latest version Xcode supports: '10.2' This may cause problems if a simulator does not exist for this platform version.
[iOSSim] Constructing iOS simulator for Xcode version 8.2.1 with udid 'C2E88820-BB65-4D79-923B-15C63D5FA384'
[XCUITest] Created simulator with udid 'C2E88820-BB65-4D79-923B-15C63D5FA384'.
[XCUITest] Determining device to run tests on: udid: 'C2E88820-BB65-4D79-923B-15C63D5FA384', real device: false
[BaseDriver] Using local app '/Users/edwardzhou/appium_work/sample-code/sample-code/apps/TestApp/build/release-iphonesimulator/TestApp.app'
[debug] [XCUITest] Checking whether app '/Users/edwardzhou/appium_work/sample-code/sample-code/apps/TestApp/build/release-iphonesimulator/TestApp.app' is actually present
[debug] [XCUITest] App is present
[debug] [iOS] Getting bundle ID from app '/Users/edwardzhou/appium_work/sample-code/sample-code/apps/TestApp/build/release-iphonesimulator/TestApp.app': 'io.appium.TestApp'
[debug] [iOSLog] Starting iOS 10.2 simulator log capture
[debug] [iOSLog] System log path: /Users/edwardzhou/Library/Logs/CoreSimulator/C2E88820-BB65-4D79-923B-15C63D5FA384/system.log
[XCUITest] Setting up simulator
[debug] [iOSSim] Checking whether simulator has been run before
[debug] [iOSSim] Simulator has not been run before
[debug] [iOS] No simulator directories found.
[debug] [iOSSim] Attempting to launch and quit the simulator, to create directory structure
[debug] [iOSSim] Will launch with Safari? false
[iOSSim] Starting simulator with command: open -Fn /Applications/Xcode.app/Contents/Developer/Applications/Simulator.app --args -CurrentDeviceUDID C2E88820-BB65-4D79-923B-15C63D5FA384
[iOSSim] Simulator log at '/Users/edwardzhou/Library/Logs/CoreSimulator/C2E88820-BB65-4D79-923B-15C63D5FA384/system.log'
[iOSSim] Tailing simulator logs until we encounter the string "com.apple.springboard"
[iOSSim] We will time out after 60000ms
[debug] [iOSSim] Waiting an extra 10000ms for the simulator to really finish booting
[debug] [iOSSim] Done waiting extra time for simulator
[iOSSim] Simulator booted in 11143ms
[debug] [iOSSim] Checking whether simulator has been run before
[debug] [iOSSim] Simulator has been run before
[debug] [iOSSim] Killing all iOS Simulators
[debug] [iOS] Setting locale information
[debug] [iOSSim] New language: zh
[debug] [iOSSim] New locale: zh_CN
[debug] [iOSSim] Writing new locale plist data
[debug] [iOS] Locale was updated. Stopping simulator.
[debug] [iOS] Killing the simulator
[debug] [iOSSim] Killing all iOS Simulators
[debug] [iOS] No iOS / app preferences to set
[XCUITest] Simulator with udid 'C2E88820-BB65-4D79-923B-15C63D5FA384' not booted. Booting up now
[debug] [iOSSim] Killing all iOS Simulators
[iOSSim] Starting simulator with command: open -Fn /Applications/Xcode.app/Contents/Developer/Applications/Simulator.app --args -CurrentDeviceUDID C2E88820-BB65-4D79-923B-15C63D5FA384
[iOSSim] Simulator log at '/Users/edwardzhou/Library/Logs/CoreSimulator/C2E88820-BB65-4D79-923B-15C63D5FA384/system.log'
[iOSSim] Tailing simulator logs until we encounter the string "com.apple.springboard"
[iOSSim] We will time out after 60000ms
[debug] [iOSSim] Waiting an extra 10000ms for the simulator to really finish booting
[debug] [iOSSim] Done waiting extra time for simulator
[iOSSim] Simulator booted in 22072ms
[debug] [XCUITest] Installing app '/Users/edwardzhou/appium_work/sample-code/sample-code/apps/TestApp/build/release-iphonesimulator/TestApp.app' on device
[XCUITest] Using WDA path: '/Users/edwardzhou/servers/node-v7.4.0/lib/node_modules/appium/node_modules/appium-xcuitest-driver/WebDriverAgent'
[XCUITest] Using WDA agent: '/Users/edwardzhou/servers/node-v7.4.0/lib/node_modules/appium/node_modules/appium-xcuitest-driver/WebDriverAgent/WebDriverAgent.xcodeproj'
[XCUITest] Launching WebDriverAgent on the device
[debug] [XCUITest] Carthage found: /usr/local/bin/carthage
[debug] [XCUITest] Killing hanging processes
[debug] [XCUITest] Beginning test with command 'xcodebuild build-for-testing test-without-building -project /Users/edwardzhou/servers/node-v7.4.0/lib/node_modules/appium/node_modules/appium-xcuitest-driver/WebDriverAgent/WebDriverAgent.xcodeproj -scheme WebDriverAgentRunner -destination id=C2E88820-BB65-4D79-923B-15C63D5FA384 -configuration Debug' in directory '/Users/edwardzhou/servers/node-v7.4.0/lib/node_modules/appium/node_modules/appium-xcuitest-driver/WebDriverAgent'
[debug] [XCUITest] Waiting up to 60000ms for WebDriverAgent to start
[debug] [XCUITest] Log file for xcodebuild test: /Users/edwardzhou/Library/Developer/Xcode/DerivedData/WebDriverAgent-ddapapcqxaoabrhjkjsyvzexgoxy/Logs/Test/98A1C0F5-03F0-4A95-9408-FE68E30628B2/Session-WebDriverAgentRunner-2017-02-26_191404-oFrhPq.log
[debug] [XCUITest] WebDriverAgent successfully started after 15361ms
[debug] [XCUITest] Sending createSession command to WDA
[debug] [JSONWP Proxy] Proxying [POST /session] to [POST http://localhost:8100/session] with body: {"desiredCapabilities":{"bundleId":"io.appium.TestApp","arguments":[],"environment":{},"shouldWaitForQuiescence":true}}
[debug] [JSONWP Proxy] Got response with status 200: {"value":{"sessionId":"AC8C1ADF-3E96-4C55-9302-73B4D7AA6B89","capabilities":{"device":"iphone","browserName":" ","sdkVersion":"10.2","CFBundleIdentifier":"local.pid.35906"}},"sessionId":"AC8C1ADF-3E96-4C55-9302-73B4D7AA6B89","status":0}
[debug] [XCUITest] Setting initial orientation to 'PORTRAIT'
[debug] [JSONWP Proxy] Proxying [POST /orientation] to [POST http://localhost:8100/session/AC8C1ADF-3E96-4C55-9302-73B4D7AA6B89/orientation] with body: {"orientation":"PORTRAIT"}
[debug] [JSONWP Proxy] Got response with status 200: {"value":{},"sessionId":"AC8C1ADF-3E96-4C55-9302-73B4D7AA6B89","status":0}
[Appium] New XCUITestDriver session created successfully, session 136bbab8-78e5-4e5d-9cd1-0b174eeaa835 added to master session list
[debug] [MJSONWP] Responding to client with driver.createSession() result: {"webStorageEnabled":false,"locationContextEnabled":false,"browserName":"","platform":"ANY","javascriptEnabled":true,"databaseEnabled":false,"takesScreenshot":true,"networkConnectionEnabled":false,"version":"","cssSelectorsEnabled":true,"nativeEvents":false,"rotatable":false,"newCommandTimeout":999999,"platformName":"ios","versionNumber":"10.2","deviceName":"iPhone 6","app":"/Users/edwardzhou/appium_work/sample-code/sample-code/apps/TestApp/build/release-iphonesimulator/TestApp.app","automationName":"XCUITest","language":"zh","locale":"zh_CN","autoAcceptAlerts":true}
[HTTP] <-- POST /wd/hub/session 200 68905 ms - 645 
[HTTP] --> GET /wd/hub/status {}
[debug] [MJSONWP] Calling AppiumDriver.getStatus() with args: []
[debug] [MJSONWP] Responding to client with driver.getStatus() result: {"build":{"version":"1.6.3","revision":null}}
[HTTP] <-- GET /wd/hub/status 200 11 ms - 83 
[HTTP] --> POST /wd/hub/session/136bbab8-78e5-4e5d-9cd1-0b174eeaa835/timeouts/implicit_wait {"ms":0}
[debug] [MJSONWP] Calling AppiumDriver.implicitWait() with args: [0,"136bbab8-78e5-4e5d-9cd1-0b174eeaa835"]
[debug] [XCUITest] Executing command 'implicitWait'
[debug] [BaseDriver] Set implicit wait to 0ms
[debug] [MJSONWP] Responding to client with driver.implicitWait() result: null
[HTTP] <-- POST /wd/hub/session/136bbab8-78e5-4e5d-9cd1-0b174eeaa835/timeouts/implicit_wait 200 17 ms - 76 

** iOS 模拟器就绪**

ios_01.png

大家看到,app首次运行弹出的alert,就是导致sample-code中的测试用例无法通过的原因。

因为,所有的查询定位,都是在当前视图中处理,这个alert出现后就改变了当前视图。

let me show you~

在 arc 中输入page,回车

[1] pry(main)> page
XCUIElementTypeApplication
   name, label:  
XCUIElementTypeOther
   name, label: 3 格 Wi-Fi 信号(共 3 格)
   value: SSID
XCUIElementTypeOther
   name, label: 下午7:27
XCUIElementTypeOther
   name, label: 电池电量:-100%
XCUIElementTypeAlert
   name, label: “TestApp”可能使 iPhone 变慢
XCUIElementTypeStaticText
   name, label, value: “TestApp”可能使 iPhone 变慢
XCUIElementTypeStaticText
   name, label, value: 应用开发者需要更新此应用以改进其兼容性。
XCUIElementTypeButton
   name, label: 好
nil
[2] pry(main)> 

page 指令背后的细节 (appium log)

[HTTP] --> GET /wd/hub/session/136bbab8-78e5-4e5d-9cd1-0b174eeaa835/context {}
[debug] [MJSONWP] Calling AppiumDriver.getCurrentContext() with args: ["136bbab8-78e5-4e5d-9cd1-0b174eeaa835"]
[debug] [XCUITest] Executing command 'getCurrentContext'
[debug] [MJSONWP] Responding to client with driver.getCurrentContext() result: "NATIVE_APP"
[HTTP] <-- GET /wd/hub/session/136bbab8-78e5-4e5d-9cd1-0b174eeaa835/context 200 7 ms - 84 
[HTTP] --> GET /wd/hub/session/136bbab8-78e5-4e5d-9cd1-0b174eeaa835/context {}
[debug] [MJSONWP] Calling AppiumDriver.getCurrentContext() with args: ["136bbab8-78e5-4e5d-9cd1-0b174eeaa835"]
[debug] [XCUITest] Executing command 'getCurrentContext'
[debug] [MJSONWP] Responding to client with driver.getCurrentContext() result: "NATIVE_APP"
[HTTP] <-- GET /wd/hub/session/136bbab8-78e5-4e5d-9cd1-0b174eeaa835/context 200 4 ms - 84 
[HTTP] --> GET /wd/hub/session/136bbab8-78e5-4e5d-9cd1-0b174eeaa835/source {}
[debug] [MJSONWP] Calling AppiumDriver.getPageSource() with args: ["136bbab8-78e5-4e5d-9cd1-0b174eeaa835"]
[debug] [XCUITest] Executing command 'getPageSource'
[debug] [JSONWP Proxy] Proxying [GET /source/xml] to [GET http://localhost:8100/session/AC8C1ADF-3E96-4C55-9302-73B4D7AA6B89/source/xml] with no body
[debug] [JSONWP Proxy] Got response with status 200: "{\n  \"value\" : {\n    \"tree\" : \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\\n<XCUIElementTypeApplication type=\\\"XCUIElementTypeApplication\\\" name=\\\" \\\" label=\\\" \\\" visible=\\\"true\\\" enabled=\\\"true\\\" x=\\\"0\\\" y=\\\"0\\\" width=\\\"375\\\" height=\\\"667\\\">\\n  <XCUIElementTypeWindow type=\\\"XCUIElementTypeWindow\\\" visible=\\\"false\\\" enabled=\\\"true\\\" x=\\\"0\\\" y=\\\"0\\\" width=\\\"375\\\" height=\\\"667\\\">\\n    <XCUIElementTypeOther type=\\\"XCUIElementTypeOther\\\" visible=\\\"false\\\" enabled=\\\"true\\\" x=\\\"0\\\" y=\\\"0\\\" width=\\\"375\\\" height=\\\"667\\\"\\/>\\n    <XCUIElementTypeOther type=\\\"XCUIElementTypeOther\\\" visible=\\\"false\\\" enabled=\\\"true\\\" x=\\\"0\\\" y=\\\"0\\\" width=\\\"375\\\" height=\\\"667\\\"\\/>\\n  <\\/XCUIElementTypeWindow>\\n  <XCUIElementTypeWindow type=\\\"XCUIElementTypeWindow\\\" visible=\\\"false\\\" enabled=\\\"true\\\" x=\\\"0\\\" y=\\\"0\\\" width=\\\"375\\\" height=\\\"667\\\">\\n    <XCUIElementType...
[debug] [MJSONWP] Responding to client with driver.getPageSource() result: "<?xml version=\"1.0\" encoding=\"UTF-8\"?><AppiumAUT><XCUIElementTypeApplication type=\"XCUIElementTypeApplication\" name=\" \" label=\" \" visible=\"true\" enabled=\"true\" x=\"0\" y=\"0\" width=\"375\" height=\"667\">\n  <XCUIElementTypeWindow type=\"XCUIElementTypeWindow\" visible=\"false\" enabled=\"true\" x=\"0\" y=\"0\" width=\"375\" height=\"667\">\n    <XCUIElementTypeOther type=\"XCUIElementTypeOther\" visible=\"false\" enabled=\"true\" x=\"0\" y=\"0\" width=\"375\" height=\"667\"/>\n    <XCUIElementTypeOther type=\"XCUIElementTypeOther\" visible=\"false\" enabled=\"true\" x=\"0\" y=\"0\" width=\"375\" height=\"667\"/>\n  </XCUIElementTypeWindow>\n  <XCUIElementTypeWindow type=\"XCUIElementTypeWindow\" visible=\"false\" enabled=\"true\" x=\"0\" y=\"0\" width=\"375\" height=\"667\">\n    <XCUIElementTypeOther type=\"XCUIElementTypeOther\" visible=\"false\" enabled=\"true\" x=\"0\" y=\"0\" width=\"375\" height=\"667\"/>\n  </XCUIElementTypeWindow>\n  <XCUIElementTypeWindow type=\"XCUIElementTypeWin...
[HTTP] <-- GET /wd/hub/session/136bbab8-78e5-4e5d-9cd1-0b174eeaa835/source 200 422 ms - 14307 

点击 “好”,或直接在arc中输入 alert_accept 回车,关闭对话框

ios_02.png

4. 测试指令

4.1 page

page 用于查看当前视图中有哪些元素,并以行文本形式输出

[2] pry(main)> alert_accept
{}
[3] pry(main)> page
XCUIElementTypeApplication
   name, label: TestApp
XCUIElementTypeTextField
   name: IntegerA
  label: TextField1
XCUIElementTypeTextField
   name: IntegerB
  label: TextField2
XCUIElementTypeButton
   name: ComputeSumButton
  label: Compute Sum
XCUIElementTypeStaticText
   name: Answer
  label: SumLabel
  value: SumLabel
XCUIElementTypeButton
   name, label: show alert
XCUIElementTypeButton
   name, label: contact alert
XCUIElementTypeButton
   name, label: location alert
XCUIElementTypeStaticText
   name, label, value: AppElem
XCUIElementTypeSlider
   name, label: AppElem
   value: 50%
XCUIElementTypeStaticText
   name: Accessibility
XCUIElementTypeStaticText
   name, label, value: AppElem
XCUIElementTypeButton
   name: DisabledButton
  label: disabled button
XCUIElementTypeSwitch
   name, label: locationStatus
   value: 0
XCUIElementTypeButton
   name, label: Test Gesture
XCUIElementTypeButton
   name, label: Crash
XCUIElementTypeOther
   name, label: 3 of 3 Wi-Fi bars
   value: SSID
XCUIElementTypeOther
   name, label: 下午7:48
XCUIElementTypeOther
   name, label: -100% battery power
nil
[4] pry(main)> 

测试应用为TestApp

XCUIElementTypeApplication
name, label: TestApp

第一个输入框,类型为 XCUIElementTypeTextField,
name (id) 为IntegerA
文本标签TextField1

XCUIElementTypeTextField
name: IntegerA
label: TextField1

....


4.2 source

source 作用同 Page
source 返回个是XML的文档格式。

4.3 查找元素(find_element, find, id, xpath ...)

Ref:
https://github.com/appium/ruby_lib/blob/master/docs/docs.md

Appium Ruby Lib(SeleniumDriver)真正提供的查找元素的方法是

  • find_element - 查找单个元素, 如果有多个满足条件的,返回第一个。如果一个都没有,报错。
  • find_elements - 查找多个元素, 并以数组形式返回。没找到,返回空数组 []。

其他的方法(find, id, xpath ...),都是语法糖。

语法糖 对应find_element(s)
id('comp_id') find_element(:id, 'comp_id')
buttons find_elements(:class, 'XCUIElementTypeButton')
button(index) => buttons[index]
texts find_elements(:class, 'XCUIElementTypeStaticText')
text(index) => texts[index]
textfields find_elements(:class, 'XCUIElementTypeTextField')
textfield[index] => textfields[index]
xpath('xpath_expr') find_element(:xpath, 'xpath_expr')
xpaths('xpath_expr') find_elements(:xpath, 'xpath_expr)
finds('text') find_elements(:xpath, "(//*)[@*[contains(translate(., "Text", "text"), "text")]]"
find('text') => finds('text')[0]

基于性能考虑,建议尽量使用 id 查找元素,find/finds 的性能最差.


4.4 对元素执行动作

拿到一个元素e之后,我们就是直接访问属性或发送动作。

e.name # button, text
e.value # secure, textfield
e.type 'some text' # type text into textfield
e.clear # clear textfield
e.tag_name # calls .type (patch.rb)
e.text
e.size
e.location
e.rel_location
e.click
e.send_keys 'keys to send'
e.set_value 'value to set' # ruby_console specific
e.displayed? # true or false depending if the element is visible
e.selected? # is the tab selected?
e.attribute('checked') # is the checkbox checked?

这些属性和动作的背后,都是发送指令到appium,可以直接在appium运行日志中看到每个请求的具体细节。

有一点需要注意的是,e.click 背后的实现是,先获取 e 的屏幕坐标,然后向该坐标发送触碰事件,并不是说能够直接控制e触发点击事件。因此,如果e被其他控件(如键盘)遮住,则触碰事件实际是其他控件接受了。 这个着实坑了我们一把。


以后有时间再接着第一篇说说我们是如何改进测试用例,把steps模版化。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,099评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,828评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,540评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,848评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,971评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,132评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,193评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,934评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,376评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,687评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,846评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,537评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,175评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,887评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,134评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,674评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,741评论 2 351

推荐阅读更多精彩内容