I searched GitHub for Python test files that reference credit_score. Across about 100 repos, every single one hardcodes an integer:
user["credit_score"] = 720
Not one of them uses a generator, a factory, or even random.randint. They just pick a number and move on and random.randint isn't much better.
720 doesn't mean what you think it means
A FICO 8 score of 720 falls in the "good" tier. But if your code handles Equifax Beacon 5.0 scores, the valid range is 334 - 818 vs. 300 - 850. A score of 720 is still "good," but the boundary math is different.
If your lending flow branches on tier thresholds and you're testing with a hardcoded 720, you're testing one path of one model. You'll never catch the edge case where a 320 is valid for FICO 8 but impossible for Equifax Beacon 5.0.
random.randint is worse
random.randint(300, 850) will happily give you 845. That's a valid FICO 8 score, but it's above the max value for Equifax Beacon 5.0. If your code doesn't validate against model-specific ranges, you won't know until production.
The gap
Here's what surprised me most: many of the repos I looked at already use Faker for names, addresses, and emails. But when it comes to credit scores, they drop back to a hardcoded integer. The gap exists because there hasn't been a Faker provider for credit scores -- so even developers who know better default to 720 and move on.
What I wanted
I wanted fake credit scores that:
- Come from real scoring models with real ranges
- Can be constrained to a tier (poor, fair, good, very_good, exceptional)
- Include the bureau name and model name, not just a number
- Leverage Faker, a testing scaffolding I'm a big fan of
How it works
Install it:
pip install faker-credit-score
Add it to your Faker setup:
from faker import Faker
from faker_credit_score import CreditScore
fake = Faker()
fake.add_provider(CreditScore)
Generate scores:
fake.credit_score()
# 791
fake.credit_score("fico5")
# 687 (Equifax Beacon 5.0, range 334-818)
Test specific tiers:
fake.credit_score(tier="poor")
# 542
fake.credit_score(tier="exceptional")
# 831
Get the full picture:
result = fake.credit_score_full("fico5")
# CreditScoreResult(name='Equifax Beacon 5.0', provider='Equifax', score=687)
name, provider, score = result # destructure it
Classify a score you already have:
fake.credit_score_tier(score=720)
# 'good'
You can also combine tier and model. If you ask for an "exceptional" score on a model that tops out at 818, the range gets clamped:
fake.credit_score(score_type="fico5", tier="exceptional")
# 812 (clamped to 800-818)
The models
Ten scoring models, each with real ranges:
| Model | Range |
|---|---|
| FICO Score 8, 9, 10, 10 T | 300-850 |
| VantageScore 3.0, 4.0 | 300-850 |
| UltraFICO | 300-850 |
| Equifax Beacon 5.0 | 334-818 |
| Experian/Fair Isaac Risk Model V2SM | 320-844 |
| TransUnion FICO Risk Score, Classic 04 | 309-839 |
The point
If your code branches on credit scores, your tests should use scores that behave like real ones.
Top comments (0)