使用Python高效生成逼真的測試數(shù)據(jù)
在軟件開發(fā)和數(shù)據(jù)分析的日常工作中,我們經(jīng)常面臨一個頭疼的問題:測試數(shù)據(jù)從哪來?
- 開發(fā)后端接口,需要500個用戶數(shù)據(jù)來測分頁?
- 做數(shù)據(jù)可視化,需要幾萬條模擬的銷售記錄?
- 測試支付系統(tǒng),需要生成合法的信用卡號和身份證號?
- 壓力測試,需要構(gòu)造包含特殊字符、Emoji甚至SQL注入片段的“臟數(shù)據(jù)”?
如果靠手動編造或者Excel公式拖拽,不僅效率低下,而且數(shù)據(jù)毫無隨機性,很難覆蓋邊緣Case。今天,我們就來盤點Python生態(tài)中生成測試數(shù)據(jù)的“三板斧”。
第一板斧:原生random模塊 —— 簡單場景的快手
對于只需要生成簡單數(shù)字、隨機字符串的場景,Python自帶的 random 模塊足夠用了。
1. 基礎(chǔ)數(shù)值與字符串
import random import string # 1. 隨機整數(shù)/浮點數(shù) print(random.randint(1, 100)) # 1-100隨機整數(shù) print(random.uniform(1.0, 10.0)) # 1.0-10.0隨機浮點數(shù) # 2. 隨機選擇 choices = ['Apple', 'Banana', 'Orange'] print(random.choice(choices)) # 隨機選一個水果 # 3. 生成隨機字符串(指定長度) # 生成10位由字母和數(shù)字組成的隨機密碼 rand_str = ''.join(random.choices(string.ascii_letters + string.digits, k=10)) print(rand_str) # 輸出類似: 'aB3x9ZkL2p'
2. 加權(quán)隨機(模擬真實分布)
現(xiàn)實世界中,數(shù)據(jù)往往不是均勻分布的。比如“省份”字段,河南省的人口概率肯定比海南高。我們可以用 random.choices 的 weights 參數(shù):
provinces = ['廣東', '山東', '河南', '四川', '西藏'] weights = [0.15, 0.10, 0.09, 0.08, 0.01] # 概率權(quán)重 # 生成10個樣本 result = random.choices(provinces, weights=weights, k=10) print(result) # 廣東出現(xiàn)的頻率會明顯高于西藏
缺點:原生模塊只能生成“無意義”的隨機數(shù)。它生成不了像“北京市朝陽區(qū)”這樣的地址,也生成不了符合校驗規(guī)則的身份證號。
第二板斧:Faker 庫 —— 生成逼真業(yè)務(wù)數(shù)據(jù)的神器
這是Python生態(tài)中最著名的測試數(shù)據(jù)生成庫。它能生成姓名、地址、公司、日期、甚至Lorem Ipsum文本,且支持中文!
1. 快速上手
pip install faker
from faker import Faker
# 初始化中文環(huán)境
fake = Faker('zh_CN')
# 生成單條數(shù)據(jù)
print(f"姓名: {fake.name()}") # 張偉
print(f"地址: {fake.address()}") # 四川省成都市錦江區(qū)
print(f"公司: {fake.company()}") # 某某科技有限公司
print(f"郵箱: {fake.email()}") # wei.zhang@example.com
print(f"日期: {fake.date_of_birth()}") # 1985-04-12
print(f"段落: {fake.text()}") # 生成一段隨機中文文本
2. 批量生成(List Comprehension)
# 一次性生成100個用戶
users = [
{
'id': i,
'name': fake.name(),
'email': fake.email(),
'address': fake.address(),
'created_at': fake.date_time_this_year()
}
for i in range(100)
]
# 查看第一個用戶
print(users[0])
3. 進階:種子(Seed)與唯一性
測試時我們常希望“每次運行生成的數(shù)據(jù)都一樣”,以便復(fù)現(xiàn)Bug。
Faker.seed(0) # 設(shè)置全局種子
fake1 = Faker('zh_CN')
print(fake1.name()) # 每次運行都是同一個名字
第三板斧:Pandas + Faker —— 大數(shù)據(jù)量的終極方案
當(dāng)你需要生成10萬+條數(shù)據(jù)并導(dǎo)出為Excel或CSV時,循環(huán)拼接字典會很慢。這時候要請出數(shù)據(jù)處理之王 Pandas。
實戰(zhàn):生成10000條電商訂單數(shù)據(jù)
import pandas as pd
from faker import Faker
import random
fake = Faker('zh_CN')
# 定義數(shù)據(jù)量
n = 10000
# 使用Pandas直接生成列數(shù)據(jù)(比循環(huán)快得多)
data = {
'order_id': range(1, n + 1),
'user_name': [fake.name() for _ in range(n)],
'product_name': [fake.word().capitalize() + random.choice(['手機', '電腦', '耳機', '鍵盤']) for _ in range(n)],
'price': [round(random.uniform(9.9, 9999.9), 2) for _ in range(n)],
'status': random.choices(['已支付', '待發(fā)貨', '已完成', '已取消'], weights=[0.6, 0.2, 0.15, 0.05], k=n),
'created_at': [fake.date_time_between(start_date='-30d', end_date='now') for _ in range(n)]
}
# 創(chuàng)建DataFrame
df = pd.DataFrame(data)
# 數(shù)據(jù)清洗與加工(Pandas強項)
# 1. 計算總價(假設(shè)隨機數(shù)量1-3件)
df['quantity'] = [random.randint(1, 3) for _ in range(n)]
df['total_amount'] = (df['price'] * df['quantity']).round(2)
# 2. 構(gòu)造關(guān)聯(lián)字段(例如:根據(jù)狀態(tài)決定是否有物流單號)
import numpy as np
df['tracking_number'] = np.where(
df['status'] == '已發(fā)貨',
['SF' + str(random.randint(100000, 999999)) for _ in range(n)],
None
)
# 預(yù)覽數(shù)據(jù)
print(df.head())
# 導(dǎo)出到文件
df.to_csv('mock_orders.csv', index=False, encoding='utf-8-sig')
df.to_excel('mock_orders.xlsx', index=False)
print(f"\n成功生成 {len(df)} 條數(shù)據(jù)!")
為什么用Pandas?
- 速度快:向量化操作比Python原生循環(huán)快幾個數(shù)量級。
- 易分析:生成完可以直接做統(tǒng)計(
df.describe())、分組、畫圖。 - 格式全:一鍵導(dǎo)出CSV、Excel、SQL、JSON。
進階技巧:構(gòu)造“臟數(shù)據(jù)”與邊緣案例
好的測試不僅要有“正常數(shù)據(jù)”,還要有“異常數(shù)據(jù)”。
1. 構(gòu)造空值和異常值
import numpy as np # 在Pandas中插入空值 df.loc[random.sample(range(n), 50), 'user_name'] = np.nan # 50個空姓名 # 插入極端值 df.loc[0, 'price'] = -1000 # 負(fù)價格(測試系統(tǒng)容錯) df.loc[1, 'price'] = 999999 # 天價訂單
2. 構(gòu)造特定格式(正則+Faker)
如果需要生成手機號(11位數(shù)字):
# Faker自帶phone_number,但也可以自定義
phone = fake.numerify('1##########') # #代表數(shù)字
print(phone) # 13812345678
3. 構(gòu)造SQL注入片段(安全測試用)
malicious_inputs = [
"'; DROP TABLE users; --",
"admin' OR '1'='1",
"<script>alert('xss')</script>"
]
df['malicious_input'] = random.choices(malicious_inputs, k=n)
總結(jié):選型指南
| 場景 | 推薦工具 | 理由 |
|---|---|---|
| 簡單腳本/算法題 | random + string | 無需安裝第三方庫,輕量 |
| Web開發(fā)/接口測試 | Faker | 數(shù)據(jù)逼真,支持多國語言,覆蓋常見業(yè)務(wù)字段 |
| 大數(shù)據(jù)分析/報表 | Pandas + Faker | 性能強,便于后續(xù)處理和導(dǎo)出Excel/CSV |
| 數(shù)據(jù)庫壓測 | Pandas + SQLAlchemy | 可直接將DataFrame寫入數(shù)據(jù)庫 |
| 特殊格式/協(xié)議 | 自定義函數(shù) + re | 靈活度最高,可生成正則匹配的特定字符串 |
最后提醒:生成的測試數(shù)據(jù)僅用于開發(fā)和測試環(huán)境,嚴(yán)禁用于生產(chǎn)環(huán)境或涉及真實用戶的隱私場景。另外,利用Faker生成的身份證號雖然符合校驗規(guī)則,但在法律上是無效的,請勿用于實名認(rèn)證!
到此這篇關(guān)于使用Python高效生成逼真的測試數(shù)據(jù)的文章就介紹到這了,更多相關(guān)Python生成測試數(shù)據(jù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
代碼詳解django中數(shù)據(jù)庫設(shè)置
在本篇文章里小編給大家分享了關(guān)于django中數(shù)據(jù)庫設(shè)置的相關(guān)實例內(nèi)容,有興趣的朋友們跟著學(xué)習(xí)下。2019-01-01

