Backend Development 10 min read

Why Generate Simulated ID Card Numbers for API Automation Testing and a Python GUI Generator

Generating simulated, legally‑formatted ID card numbers for API automation testing improves data realism, protects privacy, expands test coverage, and enables efficient, repeatable, parameterized, and performance testing, while the provided Python GUI script demonstrates how to create such data programmatically.

Test Development Learning Exchange
Test Development Learning Exchange
Test Development Learning Exchange
Why Generate Simulated ID Card Numbers for API Automation Testing and a Python GUI Generator

Why generate simulated ID card numbers for interface automation testing?

Data realism simulation: ID numbers identify individuals in many systems; generating valid numbers mimics real user scenarios, allowing accurate verification of handling sensitive information.

Privacy protection: Using real IDs may violate privacy laws; simulated IDs retain correct format without exposing personal data.

Test coverage: ID numbers follow region, birthdate, sequence and checksum rules; automatically creating diverse and edge‑case numbers increases case variety and system robustness.

Efficiency and repeatability: Scripts can quickly produce large datasets, ensuring consistent data across test runs for reproducibility.

Parameterized testing: Parameterizing ID numbers enables data‑driven test cases without modifying test scripts, improving flexibility and maintainability.

Reduced external dependencies: Simulated IDs avoid frequent calls to real identity verification services, lowering cost and complexity.

Exception handling testing: Crafted invalid IDs (wrong region, future birthdate, bad checksum) help verify proper error responses.

Performance testing support: Bulk generation of virtual users with unique IDs facilitates high‑concurrency performance assessments.

import tkinter as tk
from tkinter import ttk, messagebox
import random
from datetime import datetime, timedelta

from demoTest.idcardTest import province_codes
from lyPublicMethod.tools_logger import *

# 姓氏和名字列表(这里仅示例,实际应用中可以扩展)
surnames = ["王", "李", "张", "刘", "陈", "杨"]
names = ["浩宇", "欣怡", "浩然", "诗涵", "宇轩", "梓涵"]

def is_leap_year(year):
    return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)

def days_in_month(year, month):
    if month in [1, 3, 5, 7, 8, 10, 12]:
        return 31
    elif month == 2:
        return 29 if is_leap_year(year) else 28
    else:
        return 30

def calculate_checksum(id_no_17):
    """计算校验码"""
    weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
    check_codes = '10X98765432'
    sum_of_products = sum(int(digit) * weight for digit, weight in zip(id_no_17, weights))
    remainder = sum_of_products % 11
    return check_codes[remainder]

def generate_valid_date(min_age, max_age, gender):
    """根据指定的年龄范围和性别生成一个有效的出生日期字符串,格式为YYYYMMDD"""
    current_year = datetime.now().year
    min_year = current_year - max_age
    max_year = current_year - min_age + 1
    year = random.randint(min_year, max_year)
    month = random.randint(1, 12)
    max_day = days_in_month(year, month)
    if gender.lower() == 'male':
        day = random.randint(1, max_day) | 1
        day = day if day <= max_day else max_day
    elif gender.lower() == 'female':
        day = random.randint(1, max_day // 2) * 2
        day = day if day <= max_day else max_day - 1
    else:
        raise ValueError("Invalid gender value. Must be either 'male' or 'female'.")
    return f"{year:04d}{month:02d}{day:02d}"

def generate_id_card(area_code, birth_date_code, gender):
    if gender.lower() == 'male':
        order_code_base = random.randint(101, 999)
    elif gender.lower() == 'female':
        order_code_base = random.randint(100, 998)
    else:
        raise ValueError("Invalid gender value. Must be either 'male' or 'female'.")
    order_code = '{:03d}'.format(
        order_code_base if gender.lower() == 'male' and order_code_base % 2 == 1 else
        order_code_base - 1 if gender.lower() == 'female' and order_code_base % 2 == 0 else
        order_code_base)
    id_no_17 = area_code + birth_date_code + order_code
    check_digit = calculate_checksum(id_no_17)
    return id_no_17 + check_digit

def generate_id_cards(num, min_age, max_age, gender_distribution={'male': 0.5, 'female': 0.5}):
    generated_ids = []
    genders = ['male', 'female']
    for _ in range(num):
        gender = random.choices(genders, weights=list(gender_distribution.values()), k=1)[0]
        area_code = random.choice(province_codes) + '0000'
        birth_date_code = generate_valid_date(min_age, max_age, gender)
        id_number = generate_id_card(area_code, birth_date_code, gender)
        generated_ids.append(id_number)
    return generated_ids

def generate_random_name():
    surname = random.choice(surnames)
    name = random.choice(names)
    return surname + name

def on_generate_click():
    try:
        num = int(entry_num.get())
        min_age = int(entry_min_age.get())
        max_age = int(entry_max_age.get())
        male_ratio = float(entry_male_ratio.get())
        female_ratio = float(entry_female_ratio.get())
        if male_ratio + female_ratio != 1:
            messagebox.showerror("错误", "性别比例之和必须为1")
            return
        gender_distribution = {'male': male_ratio, 'female': female_ratio}
        generated_id_cards = generate_id_cards(num, min_age, max_age, gender_distribution)
        result_text.delete(1.0, tk.END)
        for id_card in generated_id_cards:
            name = generate_random_name()
            result_text.insert(tk.END, f"{name}: {id_card}\n")
    except ValueError:
        messagebox.showerror("错误", "请输入有效的数字")

# GUI
app = tk.Tk()
app.title("身份证号码生成器")
frame = ttk.Frame(app, padding="10")
frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))

ttk.Label(frame, text="生成数量:").grid(row=0, column=0, sticky=tk.W)
entry_num = ttk.Entry(frame)
entry_num.grid(row=0, column=1)

ttk.Label(frame, text="最小年龄:").grid(row=1, column=0, sticky=tk.W)
entry_min_age = ttk.Entry(frame)
entry_min_age.grid(row=1, column=1)

ttk.Label(frame, text="最大年龄:").grid(row=2, column=0, sticky=tk.W)
entry_max_age = ttk.Entry(frame)
entry_max_age.grid(row=2, column=1)

ttk.Label(frame, text="男性比例:").grid(row=3, column=0, sticky=tk.W)
entry_male_ratio = ttk.Entry(frame)
entry_male_ratio.grid(row=3, column=1)

ttk.Label(frame, text="女性比例:").grid(row=4, column=0, sticky=tk.W)
entry_female_ratio = ttk.Entry(frame)
entry_female_ratio.grid(row=4, column=1)

generate_button = ttk.Button(frame, text="生成", command=on_generate_click)
generate_button.grid(row=5, column=0, columnspan=2)

result_text = tk.Text(frame, wrap=tk.WORD, height=10)
result_text.grid(row=6, column=0, columnspan=2)

for child in frame.winfo_children():
    child.grid_configure(padx=5, pady=5)

app.mainloop()
backendGUIPythonData Generationtest automationID Card
Test Development Learning Exchange
Written by

Test Development Learning Exchange

Test Development Learning Exchange

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.