This library is a port of Ruby's faker. It's a library for
producing fake data such as names, addressess and phone numbers. Note
that it directly uses the source data from that library, so the
quality of fake data is quite high!
This package comes in handy when you have to generate large amount of
real like data for various purposes. I have personally used it for
websites where it needs some realistic data in the initial stage,
loading database with real like values etc. There are companies which
have used this for sophisphicated testing purpose.
Additionly, there are two other packages for creating generators which
is useful for property testing:
λ> fullName <- generate name
λ> fullName
"Sherryl Steuber"
Generate quotes from the movie Back to the Future
λ> import Faker.Movie.BackToTheFuture
λ> import Faker.Combinators
λ> qs <- generateNonDeterministic $ listOf 5 quotes
λ> qs
[ "Yes. Yes. I'm George. George McFly. I'm your density. I mean, your destiny."
, "Hello? Hello? Anybody home? Huh? Think, McFly. Think! I gotta have time to get them retyped. Do you realize what would happen if I hand in my reports in your handwriting? I'll get fired. You wouldn't want that to happen, would ya? Would ya?"
, "Lorraine. My density has brought me to you."
, "See you in about 30 years."
, "You really think I ought to swear?"
]
Combining Fake datas
{-#LANGUAGE RecordWildCards#-}
import Faker
import Faker.Name
import Faker.Address
import Data.Text
data Person = Person {
personName :: Text,
personAddress :: Text
} deriving (Show, Eq)
fakePerson :: Fake Person
fakePerson = do
personName <- name
personAddress <- fullAddress
pure $ Person{..}
main :: IO ()
main = do
person <- generate fakePerson
print person
You would have noticed in the above output that the name and address are
the same as generated before in the GHCi REPL. That's because, by
default all the generated data are deterministic. If you want a
different set of output each time, you would have to modify the random
generator output:
main :: IO ()
main = do
gen <- newStdGen
let settings = setRandomGen gen defaultFakerSettings
person <- generateWithSettings settings fakePerson
print person
And on executing the program, you will get a different output:
Person
{ personName = "Ned Effertz Sr."
, personAddress = "Suite 158 1580 Schulist Mall, Schulistburgh, NY 15804-3392"
}
The above program can be even minimized like this:
main :: IO ()
main = do
let settings = setNonDeterministic defaultFakerSettings
person <- generateWithSettings settings fakePerson
print person
Or even better:
main :: IO ()
main = do
person <- generateNonDeterministic fakePerson
print person
This is because generating a Fake parses the data files and builds a
cache for future use. Using the Monad instance on Fake shares that
cache between Fakes, making faking fast. But in the above code, a
new Fake is generated each time - so the cache is discarded, and
performance is much worse.
It's better to use the FakeT monad transformer when writing such code,
to get the benefits of sharing the cache, as well as being able to
perform side effects. FakeT comes with the mtl-style MonadFake
class, for easy use with your monad stack, which lets you lift Fakes
with liftFake.
The problem with both the above libraries is that the library covers
only a very small amount of fake data source. I wanted to have an
equivalent functionality with something like
faker. Also, most of the
combinators in this packages has been inspired (read as taken) from
the fake library. Also, fakedata offers fairly good amount of
support of different locales. Also since we rely on an external data
source, we get free updates and high quality data source with little
effort. Also, it's easier to extend the library with it's own data
source
if we want to do it that way.
Acknowledgments
Benjamin Curtis for his Ruby faker
library from which the data source is
taken from.
请发表评论