python3+excel+unittest+ddt+BeautifulReport實現接口自動化測試

? ? ? ? ? ? 本問主要介紹用excel表格來管理接口用例,采用python+unittest測試框架踩娘,結合ddt數據驅動橘沥,最后結合BeautifulReport報告插件毅戈,生成最終的測試報告

首先,來3張圖检痰,了解輸入數據包归,輸出結果

?????1、需要測試的接口case:execel表格管理

? ??2铅歼、請求的body:request_data.py文件中字典req_data公壤,用來存放所有case請求的body

? ? 3、利用unittest+ddt+BeautifulReport生成HTML測試報告:

其次椎椰,附上整個項目的結構圖

最后厦幅,分解項目運行的細節(jié)內容

1、項目的主運行文件:run_ddt.py

(1)慨飘、導入我們run_ddt.py文件運行所需要的第三方包

# coding=utf-8

import unittest

import time

import os

from BeautifulReport import BeautifulReport

(2)确憨、生成我們需要的report路徑

curpath = os.path.dirname(os.path.realpath(__file__))

reprot_path = os.path.join(curpath, "report")

(3)、匹配該項目里瓤的,以test開頭的文件休弃,并添加成一個unittest測試集

def add_case(casepath=curpath, rule="test_*.py"):

? ? discover = unittest.defaultTestLoader.discover(casepath, pattern=rule)

? ? return discover

(4)、得到了測試集圈膏,便可以運行整個測試集里面的測試用例

def run_case(all_case, reportpath=reprot_path):

? ? now = time.strftime("%Y%m%d%H%M%S")

? ? print('測試報告生成地址: %s' % reportpath)

? ? BeautifulReport(all_case).report(description='用例執(zhí)行情況', filename='測試報告_' + str(now), report_dir=reportpath)

# 該文件的main函數入口:

if __name__ == '__main__':

? ? cases = add_case()

? ? run_case(cases)

? ? ? ? 寫到上面第3步的時候塔猾,你就會聯想到,我們后續(xù)肯定會編寫一個test_開頭的py文件稽坤,而里面就是我們的測試內容丈甸。

? ? ? ? 是的,我們第2個文件尿褪,就是編寫我們的測試代碼睦擂,也可以說是我們的測試思路或者是測試的步驟。

2茫多、測試思路:test_case_all.py

(1)祈匙、導入該文件所運行的包忽刽,以及從公用模塊導入公用函數

from myrequests import MyRequests

from common.operationExcel import OperationExcel

from common.operationReqData import OperationReqDate

from common.dependentData import DependentData

from ddt import ddt, data, unpack

from common.operationSQL import connectSQL

from config import *

import json

import unittest

(2)天揖、我們是從一個excel的sheet表拿的數據夺欲,要想把這些數據利用ddt來驅動,就需要把整個excel表的數據全部拿出來今膊,然后再利用ddt來分割數據些阅,在用切割的數據進行單個case測試

class GetReqData(object):

# 初始化excel操作模塊類,才能調用該類下的函數方法

? ? def __init__(self):

? ? ? ? self.operation_excel = OperationExcel()

#? 利用excel類里面的方法斑唬,獲取excel表格的所有數據

? ? def get_data(self):

? ? ? ? exe_data_all = []? ? # 定義一個空的列表市埋,存放excel表格的數據

? ? ? ? rows_count = self.operation_excel.get_all_lines()? ? # 獲取表格中有多少行數據

? ? ? ? for i in range(1, rows_count):? ? # 循環(huán)遍歷取excel表格的數據,去除第一行

? ? ? ? ? ? exe_data = self.operation_excel.get_a_row_data(i)? ? # 把每一行的數據都取出

? ? ? ? ? ? exe_data_all.append(tuple(exe_data))? ? # 取出的數據恕刘,都添加到定義空列表中

? ? ? ? return exe_data_all? ? # 取值完成后缤谎,把所有的數據返回出去

# 單獨的把獲取數據函數進行調用一次,這樣ddt數據驅動褐着,才有數據作為參數傳入

get_req_data = GetReqData()

req_data = get_req_data.get_data()

(3)坷澡、ddt來驅動excel表的數據,獲取到的excel數據是一個list類型含蓉,提取每一行的數據就顯示輕松多了频敛。提取完數據,就可以進行request請求測試了馅扣。

# 采用ddt數據驅動斟赚,在運行的類前,就需要先運行ddt的裝飾器函數差油,故需要在Run類前加上@ddt

@ddt

class Run(unittest.TestCase):

? ? #? 集成unittest.TestCase方法拗军,然而需要初始化,在unittest里__init__函數無法使用厌殉,所以我們就用到unittest里的setUp食绿、?tearDown這樣函數來做類函數的初始化,這里初始化只需要運行一次公罕,這里我采用了setUpClass這個函數來實現

? ? @classmethod

? ? def setUpClass(cls):

? ? ? ? print('------執(zhí)行開始------')

? ? ? ? cls.operation_excel = OperationExcel()

? ? ? ? cls.operation_req_data = OperationReqDate()

? ? ? ? cls.dependent_data = DependentData()

? ? ? ? cls.m = MyRequests()

? ? ? ? cls.host = HOST? ? # 從config文件獲取host器紧,這樣切換地址不用改excel表的url內容

? ? ? ? cls.new_data_dict = {}

? ? @classmethod

? ? def tearDownClass(cls):

? ? ? ? print('------執(zhí)行完畢------')


#? ? ?初始化工作已完成,那就進入我們重點楼眷、重點铲汪、重點了

? ? @data(*req_data)? ? # ddt下data可以把數據進行切分返回數據,具體可參照ddt使用

? ? @unpack? ? # ddt下的一個方法罐柳,目的是把每一行數據分開傳參掌腰,具體使用ddt詳解

? ? def test_case(cls,? *exe_data):

? ? ? ??# 這里是判斷需要執(zhí)行SQL語句

? ? ? ? if exe_data[3] == "SQL":? ? ? ?

? ? ? ? ? ? sql = exe_data[5]

? ? ? ? ? ? connectSQL(exe_data[7], sql, cls.new_data_dict)

'''

這里判斷case是都需要執(zhí)行(運行的流程重點就在此)

我們從每一行數據取出來是一個list,根據list的下標张吉,獲取excel表格的值齿梁;

? ? 1、取決于該case是否運行,如果運行勺择,就往下取值创南,反之,則不用管省核;

? ? 2稿辙、獲取該case請求的body值,根據excel的req_data字段气忠,取對應的值

? ? 3邻储、如果該case有依賴,就需要走依賴函數旧噪,進行鍵位值的替換吨娜,實現實時數據變動;

? ? 4淘钟、進行接口的請求(如果沒有依賴萌壳,則可以跳過第3步)

? ? 5、進行預期結果與實際結果的對比

? ? 6日月、最后袱瓮,如果該case需要提取某個字段的值,根據鍵位爱咬,在返回的內容中進行提取

? ? 注意:new_data_dict這個字典尺借,是存放替換的值,格式是key=value精拟,key是我們自定義的名稱燎斩,value則是從返回值提取的值,提取數據必須在替換數據之前就有值蜂绎,不然會報錯栅表,因為提取的數據沒有值,替換的時候就無法找到值進行替換师枣。提取值是用了jsonpath的方法提取怪瓶,替換則是采用了自己定義的,以"."的方式代替層級關系践美。

'''

????elif exe_data[3] == 'YES':? ? ? ?# 第1步洗贰,判斷是否運行

? ? ? ? ? ? req_data = cls.operation_req_data.get_req_data(exe_data[5])? ? # 第2步取body

? ? ? ? ? ? print('執(zhí)行的用例ID: ', exe_data[0])

? ? ? ? ? ? data = json.loads(exe_data[9])? ? # 數據轉換,怕數據格式錯誤陨倡。

? ? ? ? ? ? if exe_data[7] != '':? ? # 判斷請求的body是否有依賴敛滋,此處判斷值為有依賴

? ? ? ? ? ? ? ? req_data = cls.dependent_data.replace_req_data(exe_data[7], req_data, cls.new_data_dict)? ? # 第3步,有依賴兴革,從提取值獲取進行替換(注:提取值必須有值)

? ? ? ? ? ? ? ? res = cls.m.myrequests(cls.host + exe_data[2], req_data, exe_data[4], exe_data[6])? ????? # 第4步绎晃,進行數據請求

? ? ? ? ? ? ? ? for key, value in data.items():? ? ? ? # 第5步蜜唾,預期結果與實際結果的對比

? ? ? ? ? ? ? ? ? ? res_value = cls.dependent_data.replace_data(key, res)

? ? ? ? ? ? ? ? ? ? cls.assertEqual(value, res_value)

? ? ? ? ? ? ? ? if exe_data[8] != '':? ? ? ? # 判斷是否需要提取

? ? ? ? ? ? ? ? ? ? cls.new_data_dict = cls.dependent_data.dependent_data(exe_data[8], res, cls.new_data_dict)? ? ? ? # 第6步,根據鍵位庶艾,在返回的內容提取值

? ? ? ? ? ? else:

? ? ? ? ? ? ? ? res = cls.m.myrequests(cls.host + exe_data[2], req_data, exe_data[4], exe_data[6])? ? ????# 第4步灵妨,進行無body替換的接口請求

? ? ? ? ? ? ? ? for key, value in data.items():? ? # 第5步,預期結果與實際結果對比

? ? ? ? ? ? ? ? ? ? res_value = cls.dependent_data.replace_data(key, res)

? ? ? ? ? ? ? ? ? ? cls.assertEqual(value, res_value)

? ? ? ? ? ? ? ? if exe_data[8] != '':? ? #? 判斷是否需要提取

? ? ? ? ? ? ? ? ? ? cls.new_data_dict = cls.dependent_data.dependent_data(exe_data[8], res, cls.new_data_dict)? ? # 第6步落竹,根據提取的鍵位,在返回值中提取對應的值

# 該文件的程序入口

if __name__ == '__main__':

?????unittest.main()


3货抄、整個項目的脊柱已經弄好述召,現在就需要各個內容來支配整個項目

?----從test文件整理出,我們可以察覺到缺少的函數文件蟹地,我們一一列出:

---1积暖。excel表格的數據獲取方法

---2。請求body的數據獲取方法

---3怪与。提取值的方法

---4夺刑。替換body的方法

---5。接口請求的方法

從這5點中分别,我們就來一一編寫需要的方法:

3-1遍愿、excel的獲取數據方法:operationExcel.py

????在test文件里,我們發(fā)現了這兩句代碼耘斩,屬于excel的操作

rows_count = self.operation_excel.get_all_lines()

exe_data = self.operation_excel.get_a_row_data(i)

????那么我們就需要在common公用文件下新建一個operationExcel.py文件沼填,來針對excel表格數據的操作

# coding=utf-8

import xlrd, os, time, xlwt

from xlutils.copy import copy

class OperationExcel(object):

? ? def __init__(self, file_name=None, sheet_id=None):

? ? ? ? if file_name:

? ? ? ? ? ? self.file_name = file_name

? ? ? ? ? ? self.sheet_id = sheet_id

? ? ? ? else:

? ? ? ? ? ? self.file_name = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'data/ApiList1.xlsx')

? ? ? ? self.data = self.get_data()


? ? # 獲取數據

? ? def get_data(self):

? ? ? ? data = xlrd.open_workbook(self.file_name)

? ? ? ? tables = data.sheets()[self.sheet_id]

? ? ? ? return tables


? ? # 獲取sheet下的行數

? ? def get_all_lines(self):

? ? ? ? tables = self.data

? ? ? ? return tables.nrows


? ? # 獲取某一行的內容

? ? def get_a_row_data(self, row_num):

? ? ? ? tables = self.data

? ? ? ? row_data = tables.row_values(row_num)

? ? ? ? return row_data

3-2、body的獲取數據方法:operationReqData.py

? ? 在test文件里括授,我們會發(fā)現以下的代碼:

req_data = cls.operation_req_data.get_req_data(exe_data[5])

? ? 這樣的代碼坞笙,是我們從excel表取標識字段,到request_data文件里req_data取對應key的value荚虚,這樣body就能取出來了

from data import request_data

class OperationReqDate(object):

? ? def __init__(self):

? ? ? ? self.data = request_data.req_data? # 修改req_data的文件名

? ? # 根據關鍵key來獲取req_data文件的內容

? ? def get_req_data(self, key):

? ? ? ? if key == '':

? ? ? ? ? ? return None

? ? ? ? return self.data.get(key)

3-3薛夜、根據excel的數據,提取返回值的內容:dependentData.py

? ? ????我們在現實的測試中版述,往往發(fā)現梯澜,這個接口運行的時候,會調用上一個接口的數據渴析,而且還有一些數據值腊徙,都是重復調用,總不可能請求一個接口檬某,去多次調用其他接口吧撬腾,這樣就導致了接口的請求量變大了,增加了服務器的負載能力恢恼。

? ? ? ? 解決方案:我們在請求前民傻,我們新建一個空的字典,自定義key來獲取對應的value值,成成一個新的字典漓踢,請求body需要的時候牵署,就直接從這里取值,這樣就減少了請求次數喧半。

? ? ? ? 然而奴迅,在test文件中,我們會發(fā)現有這樣的代碼存在:

if exe_data[8] != '':

? ? ? ? ? ? ? ? ? ? cls.new_data_dict = cls.dependent_data.dependent_data(exe_data[8], res, cls.new_data_dict)

? ? 這樣是進行判斷是否有提取值挺据,有則需要提取取具,反之則不需要,然后我們的提取方法:

? ? 提取方法的思路:

? ? ? ? 1扁耐、根據依賴的鍵位暇检,去遍歷返回的res,鍵位提取的格式:id=(result.id)

? ? ? ? 2婉称、找到了鍵位的值后块仆,把鍵位的key作為字典的key存放,找的值當做value存放王暗,組成一個新的字典

# 根據exe表格中的key=(value)來獲取一個新增的dict-data

? ? def dependent_data(self, dependent_data, res, data_dict):

? ? ? ? exe_data = dependent_data.split('\n')

? ? ? ? # print('11: ', exe_data)

? ? ? ? for data in exe_data:

? ? ? ? ? ? data_value = data.split('=')

? ? ? ? ? ? # print('data_value:', data_value)

? ? ? ? ? ? dependent_key = data_value[1]

? ? ? ? ? ? value = self.replace_data(dependent_key, res)

? ? ? ? ? ? data_dict[data_value[0]] = value

? ? ? ? return data_dict

在此時悔据,就會發(fā)現一個新的語句:

value = self.replace_data(dependent_key, res)

然而我們就需要在該文件下再創(chuàng)建一個函數方法,這里提取的方法是采用jsonpath:

def replace_data(self, data_key, data_value):

? ? ? ? """

? ? ? ? :param data_key: 依賴的key值

? ? ? ? :param data_value: 遍歷的返回頁面數據

? ? ? ? :return:

? ? ? ? """

? ? ? ? try:

? ? ? ? ? ? json_exe = parse(data_key)

? ? ? ? ? ? madles = json_exe.find(data_value)

? ? ? ? except Exception as msg:

? ? ? ? ? ? print(msg)

? ? ? ? return [madle.value for madle in madles][0]

????????這樣我們的程序就不會報錯俗壹,該方法的用途我也不做多解釋蜜暑,網上有類似的專業(yè)講解。那么我們繼續(xù)我們項目其他方法解析

3-4策肝、替換請求的body里的鍵位值:dependentData.py

? ? 在3-3中肛捍,我已經講解了提取值的方法,主要是為了便于替換的時候需要之众,在新的一個字典里拙毫,我們只有傳入key,就能把之前接口請求返回的value取到棺禾,進行替換缀蹄,就可以直接請求了,我在excel表的替換值的格式:id={{user_id}}膘婶,格式可以根據自己喜歡來寫缺前,切割點就需要重新變化下即可。

# 根據exe的表格key={{value}}去替換值

? ? def replace_req_data(self, dependent_data, req_data, new_data_dict):

? ? ? ? exe_data = dependent_data.split('\n')

? ? ? ? for data in exe_data:

? ? ? ? ? ? data_value = data.split('=')

? ? ? ? ? ? value = new_data_dict.get(data_value[1][2:-2])

? ? ? ? ? ? req_data = self.check_json_data.check_json_data(req_data, data_value[0], value)

? ? ? ? return req_data

? ? 在上面的方法中悬襟,發(fā)現有一行新的代碼

?req_data = self.check_json_data.check_json_data(req_data, data_value[0], value)

? ? 這行代碼是進行替換的操作衅码,遍歷操作替換的工作量大,因此我們重新編寫一個文件來實現此功能:

3-4-1脊岳、數據替換方法:checkJsonData.py

? ? 遍歷我們的請求的body逝段,根據對應的鍵位垛玻,去實現value的一個更新,實現數據更新功能

# coding=utf-8

from httprunner import exceptions, logger

from httprunner.compat import OrderedDict, basestring, is_py2

class Check_Json_Data(object):

? ? # 替換json數據中對應的value

? ? def change_json(self, json_content, query, new, delimiter='.'):

? ? ? ? raise_flag = False

? ? ? ? response_body = u"response body: {}\n".format(json_content)

? ? ? ? try:

? ? ? ? ? ? keys = query.split(delimiter)

? ? ? ? ? ? if len(keys) == 1:

? ? ? ? ? ? ? ? if isinstance(json_content, (list, basestring)):

? ? ? ? ? ? ? ? ? ? json_content[int(keys[0])] = new

? ? ? ? ? ? ? ? elif isinstance(json_content, dict):

? ? ? ? ? ? ? ? ? ? json_content[keys[0]] = new

? ? ? ? ? ? if len(keys) > 1:

? ? ? ? ? ? ? ? for key in keys:

? ? ? ? ? ? ? ? ? ? if isinstance(json_content, (list, basestring)):

? ? ? ? ? ? ? ? ? ? ? ? return self.change_json(json_content[int(key)], ".".join(keys[1:]), new, delimiter='.')

? ? ? ? ? ? ? ? ? ? elif isinstance(json_content, dict):

? ? ? ? ? ? ? ? ? ? ? ? return self.change_json(json_content[key], ".".join(keys[1:]), new, delimiter='.')

? ? ? ? except (KeyError, ValueError, IndexError):

? ? ? ? ? ? raise_flag = True

? ? ? ? if raise_flag:

? ? ? ? ? ? err_msg = u"Failed to extract! => {}\n".format(query)

? ? ? ? ? ? err_msg += response_body

? ? ? ? ? ? logger.log_error(err_msg)

? ? ? ? ? ? raise exceptions.ExtractFailure(err_msg)


# 數據替換的方法

? ? def check_json_data(self, old_req_data, dependent_key, values):

? ? ? ? """

? ? ? ? 把舊的請求數據奶躯,根據鍵位帚桩,替換掉舊數據

? ? ? ? :param old_req_data: json文件的舊數據

? ? ? ? :param dependent_key: excel表中的鍵位值

? ? ? ? :param values: 獲取依賴的接口返回的鍵位值,也就是新值

? ? ? ? :return: 返回一個替換后的請求數據

? ? ? ? """

? ? ? ? self.change_json(old_req_data, dependent_key, values)

? ? ? ? return old_req_data

3-5嘹黔、請求的方法:myrequests.py

? ? 我們采用request模塊進行url的請求账嚎,這里需要更新自己的token,各個平臺不同儡蔓,token的取值也不同郭蕉,這個因系統(tǒng)而異。

? ? 首先浙值,我們需要提取token

????# 獲取token

? ? def login(self):

? ? ? ? global token

? ? ? ? if "Authorization" in self.s.headers.keys():? ? ? ? # 判斷是否存在token,如果有就直接跳過

? ? ? ? ? ? # print('--------token is exits!!---------')

? ? ? ? ? ? return self.s

? ? ? ? else:

? ? ? ? ? ? excel_data = self.operation_excel.get_a_row_data(1)

? ? ? ? ? ? url = self.host + excel_data[2]

? ? ? ? ? ? req_data = login_data

? ? ? ? ? ? res = self.s.post(url, json=req_data)

? ? ? ? ? ? r = res.content.decode('utf-8')

? ? ? ? ? ? r = json.loads(r)

? ? ? ? ? ? token = r['result']['token']

? ? ? ? ? ? self.s.headers.update({"Authorization": token})

? ? ? ? ? ? print("----------token create successfully!--------")

? ? ? ? ? ? return self.s

????????其次檩小,封裝自己的請求方式开呐。網上有很多種封裝方式,小伙伴可以選擇自己喜歡的封裝方式规求,這里我貼上我自己的封裝方式筐付,方法不完美,能實現就好阻肿。

????# 自定義請求函數

? ? def myrequests(self, url, req_data, req_type, data_type):

? ? ? ? """

? ? ? ? 自定義請求函數

? ? ? ? :param url: 請求的url

? ? ? ? :param req_data: 請求的data

? ? ? ? :param req_type: 請求方式

? ? ? ? :param data_type: 數據的傳遞格式

? ? ? ? :return: res頁面結果

? ? ? ? """

? ? ? ? if req_type == "POST":? # 判斷請求方式:POST

? ? ? ? ? ? if data_type == 'JSON':? # 判斷請求參數的數據類型

? ? ? ? ? ? ? ? # post_data = json.loads(req_data)

? ? ? ? ? ? ? ? # res = self.login().post(url, json=req_data)

? ? ? ? ? ? ? ? res = self.login().post(url, json=req_data)

? ? ? ? ? ? elif data_type == '':

? ? ? ? ? ? ? ? res = self.login().post(url, data=req_data)

? ? ? ? ? ? else:

? ? ? ? ? ? ? ? res = self.login().post(url, data=req_data)

? ? ? ? elif req_type == "GET":

? ? ? ? ? ? if data_type == 'JSON':

? ? ? ? ? ? ? ? get_params = json.loads(req_data)

? ? ? ? ? ? ? ? res = self.login().get(url, params=get_params)

? ? ? ? ? ? elif data_type == '':

? ? ? ? ? ? ? ? res = self.login().get(url, params=req_data)

? ? ? ? ? ? else:

? ? ? ? ? ? ? ? res = self.login().get(url, params=req_data)

? ? ? ? elif req_type == "DELETE":

? ? ? ? ? ? if data_type == 'JSON':

? ? ? ? ? ? ? ? get_params = json.loads(req_data)

? ? ? ? ? ? ? ? res = self.login().delete(url, params=get_params)

? ? ? ? ? ? elif data_type == '':

? ? ? ? ? ? ? ? res = self.login().delete(url, params=req_data)

? ? ? ? ? ? else:

? ? ? ? ? ? ? ? res = self.login().delete(url, params=req_data)

? ? ? ? print("request_req_url: ", res.url)

? ? ? ? print("request_req_data: ", req_data)

? ? ? ? res = res.content

? ? ? ? res = json.loads(res.decode('utf-8'))

? ? ? ? print('res: ', res)

? ? ? ? return res


在附上配置文件內容:config

# coding=utf-8

HOST = "http://172.16.62.66"

# HOST = "http://172.16.62.71"

SQL_IP = "172.16.62.66"

# SQL_IP = "172.16.62.71"

db_message = {

? ? ? ? "host": SQL_IP,

? ? ? ? "username": "root",

? ? ? ? "password": "123456",

? ? ? ? "port": 3306,

? ? ? ? "charset": "utf8"

}

login_url = HOST + '/xxx-x'x'x'x/login/login'

login_data = {

? ? ? ? "mobile": "18100000000",

? ? ? ? "smsCode": "888888"

}


????????總結:項目的方法封裝不是很好瓦戚,這里介紹我使用的辦法,如果有更好的方法丛塌,方便留言较解,多多研究,讓自動化測試更加完美赴邻。郵件的發(fā)送方法印衔,請求頭文件的更新,我這邊都沒做姥敛,后期實現了奸焙,再更新。彤敛。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末与帆,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子墨榄,更是在濱河造成了極大的恐慌玄糟,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件袄秩,死亡現場離奇詭異茶凳,居然都是意外死亡嫂拴,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進店門贮喧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來筒狠,“玉大人,你說我怎么就攤上這事箱沦”缒眨” “怎么了?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵谓形,是天一觀的道長灶伊。 經常有香客問我,道長寒跳,這世上最難降的妖魔是什么聘萨? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮童太,結果婚禮上米辐,老公的妹妹穿的比我還像新娘。我一直安慰自己书释,他們只是感情好翘贮,可當我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著爆惧,像睡著了一般狸页。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上扯再,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天芍耘,我揣著相機與錄音,去河邊找鬼熄阻。 笑死齿穗,一個胖子當著我的面吹牛,可吹牛的內容都是我干的饺律。 我是一名探鬼主播窃页,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼复濒!你這毒婦竟也來了脖卖?” 一聲冷哼從身側響起哪痰,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤忘衍,失蹤者是張志新(化名)和其女友劉穎趋距,沒想到半個月后瓜挽,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡凯砍,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年见剩,在試婚紗的時候發(fā)現自己被綠了剃法。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡勾栗,死狀恐怖惨篱,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情围俘,我是刑警寧澤砸讳,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站界牡,受9級特大地震影響簿寂,放射性物質發(fā)生泄漏。R本人自食惡果不足惜宿亡,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一常遂、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧挽荠,春花似錦克胳、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽馒过。三九已至臭脓,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間腹忽,已是汗流浹背来累。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留窘奏,地道東北人嘹锁。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像着裹,于是被迫代替她去往敵國和親领猾。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,614評論 2 353

推薦閱讀更多精彩內容

  • 再次強調骇扇,因為視頻中實戰(zhàn)地址已無法訪問摔竿,建議大家根據原理,用自己公司的業(yè)務邏輯少孝、代碼來練手继低。本人公司使用pyhon...
    DayBreakL閱讀 816評論 0 2
  • 本文是《手把手教你用Python實現接口自動化測試》這一系列文章的開篇,筆者將從本文開始給大家介紹一下如何使用Py...
    Lxn的小二閱讀 1,531評論 0 15
  • 我一生都在追求 怎么入睡 這是一件極大的事情 于我 夏日的蚊子實在是太厲害了 總能想到辦法咬我一口稍走,吸走我的血 得...
    石頭Q晴閱讀 287評論 0 0
  • 冊頁尺寸:45×32cm 生宣冊頁 潘承袁翁,江蘇鹽城人柴底,自幼習畫,師承徐忠平粱胜,近僧等先生柄驻。
    潘承青衿墨堂閱讀 1,455評論 0 2
  • (一)分詠 一行側影南飛去,萬里橫云上繞開年柠。 (二)七唱 雁聲遠送清秋冷凿歼,山色閑流碧水寒。 青山送去天涯月冗恨,鴻雁傳...
    嬋月舞羅衣閱讀 1,330評論 1 15