初识 Faker.js -- 生成测试数据
发布于 2年前 作者 lhfcws 2289 次浏览

我们为了做黑盒测试经常会需要做一些数据来模拟输入,NodeJS有丰富的第三方模块可以实现类似的功能。模拟输入可以用Sinon,它可以模拟包括ajax调用的各类程序调用来进行测试。但本文着重介绍的是如何做数据,也就是用Faker.js来生成软件测试时所需要的各式各样的数据。

####>> Faker.js on Github


### Installation
$ git clone https://github.com/Marak/Faker.js.git
$ cd Faker.js/
$ npm install

### Faker.js 的基本目录结构
.
├── BUILD                   // 用于自动生成文档,一般可无视
├── examples/               // Examples 目录
├── Faker.js                // Faker.js 主文件
├── index.js                // 入口文件
├── lib
│   ├── address.js          // 用于生成地址
│   ├── company.js          // 用于生成公司信息
│   ├── definitions.js      // 信息生成来源的定义文件
│   ├── helpers.js          // 一些在Faker数据时常用的函数
│   ├── internet.js         // 用于生成Internet相关信息
│   ├── lorem.js            // 用于生成随机文本
│   ├── name.js             // 用于生成人名
│   ├── phone_number.js     // 用于生成电话号码
│   ├── random.js           // 随机实现,包括随机函数,正态分布函数等
│   └── version.js          // 空文件,可用于生成版本信息
├── logo.png
├── Makefile
├── MinFaker.js             // Lite版Faker,已包含了lib里的功能,最小化最基本的Faker实现。
├── MIT-LICENSE.txt
├── package.json
├── Readme.md
└── test                    // 单元测试代码文件夹
    ├── address.unit.js
    ├── all.functional.js   // 测试Faker.js 功能是否正常
    ├── browser.unit.html
    ├── company.unit.js
    ├── helpers.unit.js
    ├── internet.unit.js
    ├── lorem.unit.js
    ├── mocha.opt           // Mocha 配置
    ├── name.unit.js
    ├── phone_number.unit.js
    ├── run.js              // test 主文件
    └── support
        ├── chai.js
        ├── sinon-1.5.2.js
        └── walk_dir.js

### Faker.js API使用 那么Faker.js怎么用呢?我们在其github的README里看到,可以调用API。比如 Faker.Internet.email() 就可以随机生成一个合法的email。调用API谁都会,只要参照我上面目录结构lib下js文件里的源码,用jsdoc把结构导出来阅读函数接口就好了。
var Faker = require('./Faker');
var randomName = Faker.Name.findName(); // Rowan Nikolaus
var randomEmail = Faker.Internet.email(); // Kassandra.Haley[@erich](/user/erich).biz
var randomCard = Faker.Helpers.createCard(); // random contact card containing many properties

Browser里理所当然也可以类似的使用,只不过require改成用script标签引入,此处不赘述。


### Faker.js 源码自定义 但是我们知道,现实生活中的输入数据形式是多种多样的,就比如这个是英语国家程序员开发的Faker,他很难去考虑到中文人名,日文人名,中文文本等这些因素。如果真的只能调用API,Faker就会具有极大的局限性。

实际上,作者Marak实际也不打算去考虑别的国家的习惯,源码是开放的,你完全可以通过修改lib里的代码来实现自己的特殊目的。

举例如下:

/** 
 * [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[@author](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author): Marak 
 * [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[@file](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file): lib/phone_number.js
 */
var phone = {
    phoneNumber: function () {
        return Helpers.replaceSymbolWithNumber(Faker.random.phone_formats());
    },
    // FIXME: this is strange passing in an array index.
    phoneNumberFormat: function (phoneFormatsArrayIndex) {
        return Helpers.replaceSymbolWithNumber(definitions.phone_formats[phoneFormatsArrayIndex]);
    }
};

你可以按照需要修改函数或者添加函数:

/** 
 * [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[@author](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author)](/user/author): Marak 
 * [[[[[[[[[[[[[[[[[[[[[[[[[[[[@modifier](/user/modifier)](/user/modifier)](/user/modifier)](/user/modifier)](/user/modifier)](/user/modifier)](/user/modifier)](/user/modifier)](/user/modifier)](/user/modifier)](/user/modifier)](/user/modifier)](/user/modifier)](/user/modifier)](/user/modifier)](/user/modifier)](/user/modifier)](/user/modifier)](/user/modifier)](/user/modifier)](/user/modifier)](/user/modifier)](/user/modifier)](/user/modifier)](/user/modifier)](/user/modifier)](/user/modifier)](/user/modifier): Lhfcws
 * [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[@file](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file)](/user/file): lib/phone_number.js
 */
var phone = {
    phoneNumber: function () {
        // return Helpers.replaceSymbolWithNumber(Faker.random.phone_formats());
        return Helpers.replaceSymbolWithNumber('13#########');
    },
    // FIXME: this is strange passing in an array index.
    phoneNumberFormat: function (phoneFormatsArrayIndex) {
        return Helpers.replaceSymbolWithNumber(definitions.phone_formats[phoneFormatsArrayIndex]);
    },
    // Just a demo, added by Lhfcws
    teleNumber: function () {
        return Helpers.replaceSymbolWithNumber('020-########');
    }
};

### Faker.js 源码测试 在目录结构中我们见到test/ 里的代码都是单元测试代码,是用来测试Faker.js源码的。而Marak提供的Makefile让你只需要执行 make test 就可以跑一遍mocha的单元测试。

自定义源码一节前可能还会有人有疑问为什么需要测试Faker.js源码,现在大家应该毫无疑问了。

比如上一节中我们添加的teleNumber 函数,我们可以在test/phone_number.unit.js中添加一个describe。

describe("teleNumber()",function () {
    it("return random telephone number with format (020-########)", function () {
        var tele_number = Faker.PhoneNumber.teleNumber();
        assert.ok(tele_number.match(/020-\d\d\d\d\d\d\d\d/));
    })
})

跑一次 make test就可以得到测试结果。

因此当修改了lib下的源码后,对应的也要注意修改test下的测试代码,这样才保证Faker的数据与预期相符。

回到顶部