javafaker测试数据生成实战

1.背景

最近需要测试mysql的json字段的相关性能如查询性能,需要大量数据场景下验证,比如100万条信息。本来要自己造,但是不够真实写起来挺麻烦。笔者是懒人,研究下了JavaFaker 可以正好满足场景,本文总结下使用用法,及碰到一些不满足要求场景的解决方案

需要造数据如下:

字段名说明
name姓名
username用户名
address地址
email电子邮件地址
phoneNumber手机号码
date生日日期
scope范围
password密码
ipAddressIPv4地址
bloodGroup血型

2.介绍

JavaFaker 是一个用于生成假数据(例如姓名、地址、电子邮件、日期等)的Java库。它可以帮助开发人员在开发和测试过程中生成真实和随机的数据,而不必依赖于真实的数据集。以下是 JavaFaker 的主要特点和用法:

2.1 特点

  • 多语言支持: JavaFaker 支持多种语言,包括英语、中文、法语、德语等。

  • 丰富的数据类型: JavaFaker 可以生成各种类型的假数据,包括姓名、地址、电子邮件、日期、电话号码、公司名称、文本段落等。

  • 随机性和真实性: 生成的数据是随机的,但是符合真实世界的模式和格式,使得生成的数据看起来更真实。

  • 可自定义: 可以通过扩展和自定义来满足特定需求,例如自定义国家、姓氏、名字等。

3. 使用

3.1 基础使用

3.1.1 maven依赖

        <!--随机生成测试数据-->
        <dependency>
            <groupId>com.github.javafaker</groupId>
            <artifactId>javafaker</artifactId>
            <version>1.0.2</version>
        </dependency>

3.1.1 使用示例

import com.github.javafaker.Faker;

public class JavaFakerBaseTest {
    public static void main(String[] args) {
        Faker faker = new Faker(); // 默认语言为英语

        // 生成随机姓名、地址、电子邮件等
        String name = faker.name().fullName();
        String address = faker.address().fullAddress();
        String email = faker.internet().emailAddress();
        String phoneNumber = faker.phoneNumber().cellPhone();
        String date = faker.date().birthday().toString();

        // 输出生成的数据
        System.out.println("姓名: " + name);
        System.out.println("地址: " + address);
        System.out.println("邮箱: " + email);
        System.out.println("电话号码: " + phoneNumber);
        System.out.println("生日: " + date);
    }
}

效果:
在这里插入图片描述

3.2 进阶使用

3.1 生成中文信息

Faker faker = new Faker(new Locale(“zh”, “CN”)); // 设置语言为简体中文

public class JavaFakerTest {
    public static void main(String[] args) {
        Faker faker = new Faker(new Locale("zh", "CN")); // 设置语言为简体中文

        for (int i = 0; i < 100; i++) { // 生成10个随机中文名字
            String name = faker.name().fullName(); // 随机生成姓名
            String address = faker.address().fullAddress(); // 随机生成地址
//            String email = faker.internet().emailAddress(); // 随机生成电子邮件地址
            //String username = PinyinUtils.convertToPinyin(name);
            String email = faker.internet().emailAddress(username);
            String phoneNumber = faker.phoneNumber().cellPhone(); // 随机生成手机号码
            Date date = faker.date().birthday(); // 随机生成生日日期
            int scope = faker.number().numberBetween(1, 100); // 在指定范围内生成随机整数

            String password = faker.internet().password(8, 9, true); // 随机生成密码
            String ipAddress = faker.internet().ipV4Address(); // 随机生成IPv4地址
            String bloodGroup = faker.name().bloodGroup(); //随机生成血型

            // 打印生成的随机数据,使用制表符分隔
            System.out.println(name + "\t" + username + "\t" + address + "\t" + email + "\t" + phoneNumber + "\t" + date + "\t" + scope + "\t" + password + "\t" + ipAddress + "\t" + bloodGroup);


        }
    }



}

3.2 根据姓名生成账号

根据用户名生成拼音作为用户的用户名。 需要借助pinyin4j 来实现

3.2.1 maven依赖
        <!--汉字转拼音-->
        <dependency>
            <groupId>com.belerweb</groupId>
            <artifactId>pinyin4j</artifactId>
            <version>2.5.1</version>
        </dependency>

3.2.2 中文转拼音工具类


/**
 * 依赖如下
 *         <dependency>
 *             <groupId>com.belerweb</groupId>
 *             <artifactId>pinyin4j</artifactId>
 *             <version>2.5.1</version>
 *         </dependency>
 */
public class PinyinUtils {

    private static final HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();

    static {
        format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
    }

    /**
     * 将中文字符串转换为拼音
     *
     * @param chinese 中文字符串
     * @return 拼音字符串,如果无法转换返回空字符串
     */
    public static String convertToPinyin(String chinese) {
        StringBuilder pinyinBuilder = new StringBuilder();

        for (char ch : chinese.toCharArray()) {
            // 判断是否为汉字字符
            if (Character.toString(ch).matches("[\\u4E00-\\u9FA5]+")) {
                try {
                    String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(ch, format);
                    if (pinyinArray != null && pinyinArray.length > 0) {
                        // 多音字只取第一个拼音
                        pinyinBuilder.append(pinyinArray[0]);
                    }
                } catch (Exception e) {
                    // 异常时保持原样
                    pinyinBuilder.append(ch);
                }
            } else {
                // 非汉字字符保持原样
                pinyinBuilder.append(ch);
            }
        }

        return pinyinBuilder.toString();
    }



    public static void main(String[] args) {
        String chineseName = "张三"; // 中文名字
        String pinyin = PinyinUtils.convertToPinyin(chineseName);
        System.out.println("拼音: " + pinyin);
    }
}

  • 效果

在这里插入图片描述

3.3 高级使用

3.3.1 中文性名重复处理

在实际使用测试数据导入,数据库中,当循环生成测试数据,当数据量较大时候(一万多条时候). 会出现性名重复情况。虽然姓名重复,在现实存在, name可以重复,但是username用来用户登录唯一标识,肯定需要唯一性。

方案1: 偷懒方式

重复username使用累计编号,使用先来后到重名就加一。如: zhangsan -> zhangsan1

  1. 先获取所有用户名
  2. 判断如果重复则在根据name生成的username加序号
@Service
public class AccountServiceImpl implements AccountService {
    private static final Logger LOGGER = LoggerFactory.getLogger(AccountServiceImpl.class);

    @Autowired
    private AccountMapper accountMapper;

    private Faker faker = new Faker(new Locale("zh", "CN")); // 设置语言为简体中文

    public void batchInitAccount(int count) {
        List<Object> allUsername = listAllUsername();
        Faker faker = new Faker(new Locale("zh", "CN")); // 设置语言为简体中文

        for (int i = 0; i < count; i++) {

            String name = faker.name().fullName(); // 随机生成姓名
            String username = PinyinUtils.convertToPinyin(name);
            // 名字重复继续生成
            int num = 1;
            while (allUsername.contains(username)) {

                username = PinyinUtils.convertToPinyin(name) + num ++;

            }
            allUsername.add(username);
            String address = faker.address().fullAddress(); // 随机生成地址
//            String email = faker.internet().emailAddress(); // 随机生成电子邮件地址
            String email = faker.internet().emailAddress(username);
            String phoneNumber = faker.phoneNumber().cellPhone(); // 随机生成手机号码
            Date date = faker.date().birthday(); // 随机生成生日日期
            int scope = faker.number().numberBetween(1, 100); // 在指定范围内生成随机整数
            String password = faker.internet().password(8, 9, true); // 随机生成密码
            String ipAddress = faker.internet().ipV4Address(); // 随机生成IPv4地址
            String bloodGroup = faker.name().bloodGroup(); //随机生成血型

            Account account = new Account();
            account.setUsername(username);
            account.setPassword(password);
            account.setName(name);
            account.setPhone(phoneNumber);
            account.setEmail(email);
            account.setCreateTime(date);
            JSONObject extendJson = new JSONObject();
            extendJson.put("address", address);
            extendJson.put("scope", scope);
            extendJson.put("ip", ipAddress);
            extendJson.put("bloodGroup", bloodGroup);
            account.setExtendJson(extendJson);
            try {

                this.accountMapper.insert(account);
                System.out.println(account.getId());
            } catch (Exception e) {
//                e.printStackTrace();
                // 名字重复忽略
                LOGGER.error("名字重复");
            }

        }
    }
}
方案2: 较真模式

TODO

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值