I work as a test manager on pension projects in the Netherlands. Each one of them needs test data that looks Dutch and passes the checks the system runs, without being a real person. Each of them started with someone typing numbers by hand until the validator stopped complaining.
I got tired of that and built the generators I kept needing. They are free, they run in the browser, and this is what is in them and what I learned making them.
BSN: the check is the elfproef
A BSN is nine digits. The check is the elfproef. Multiply the digits by 9, 8, 7, 6, 5, 4, 3, 2, and the last one by minus 1. Add them up. The total has to divide by 11. Most made up numbers fail. A generator that only knows "nine digits" produces test data that gets rejected at the first form.
Test BSN generator gives you numbers that pass the elfproef. They are valid by checksum, not registered to anyone I know of, and meant for test environments only. Do not put them in production and do not use them to impersonate anyone.
IBAN: do not run the elfproef on it
This one cost me time. The old Dutch bank account numbers had an elfproef of their own. The IBAN does not. NL IBANs use the standard mod 97 check and nothing else. Since 1 July 2020 banks issue account numbers that do not pass the old elfproef, and some validators still reject them. If your test IBAN validator fails on a real ING account, this is why.
Test IBAN generator makes IBANs that pass mod 97 for NL and other countries, with a real bank code in the right position. The IBAN validator is the one I use to check what a supplier sends me. It knows that the bank code sits at a different position per country: Italy starts at position 5, Germany has eight digits. The naive substring(4, 8) everyone writes first is wrong for a third of Europe.
UPA and BRP: whole files, not single values
Pension administration in the Netherlands runs on UPA deliveries from employers. Testing that chain means you need an UPA file with a plausible mix of employments, salaries and dates. And you need twenty of them, not one. Typing those in XML by hand is how a week disappears.
The UPA file generator builds a complete file from a few settings. The BRP test data generator does the same for person records: names, birth dates, addresses that fit together, BSNs that pass. Both run locally in the browser. Nothing you generate is sent anywhere, which matters when the test environment is under an NDA.
The rest of the Dutch set
Everything Dutch is grouped on toolforte.com/netherlands. A VAT number checker. Working days between two dates with Dutch public holidays. Holiday allowance, notice periods, severance. The test data tools by themselves are on toolforte.com/test-data.
If you write test automation, the same generators are callable from an API and from an MCP server. A test can ask for a fresh valid BSN instead of reading one from a fixture file. Fixture files are what someone eventually copies into production.
What I still want
I keep a list of checks that Dutch systems run on incoming data and I add generators when I hit a new one. If your project validates something I do not cover yet, tell me which field and which rule.
Top comments (1)
Phone numbers would be a useful field to add, with a rule that's the opposite of a checksum: ranges a regulator keeps out of use. Ofcom sets aside London 020 7946 0xxx for TV and radio drama and NANPA reserves 555-0100 to 555-0199 as fictitious, so +44 20 7946 0958 and +1 212 555 0123 are well formed but aren't assigned to real subscribers. Since fixture files end up in production, as you say, a generated phone column drawn from ranges like these won't reach a stranger's phone when it gets there.