A correct premium on the wrong date is a wrong premium. We test with the clock moved.
Insurance software is a set of money promises that must be recalculable on any date. We reprice real policy shapes before and after every change, and fail on any movement nobody asked for.
ISO 27001:2022testing other people's software since 2018Reviewed on Clutch€20-45/hour
TB
Written by Tudor Brad, founder, 15+ years in software testingLast reviewed October 2026
// what keeps you up at night, and what you get
"A rate change reprices policies we've already sold."
A sample of real policies repriced before and after every rate change, failing on any movement nobody asked for.Flows
"A backdated change breaks the refund maths."
Tests run with the clock moved: backdated changes, mid-term adjustments, cancellations and reinstatements.embedded testers
"Ten thousand renewal letters go out with one wrong figure."
Policy documents checked at volume, not one sample PDF.embedded testers
// four places insurance systems break
01 · effective dating
A backdated cancellation refunds the wrong amount
A policy is cancelled effective 1 July but keyed on 20 August. The refund routine counts the unexpired days from the date the transaction was posted, not the effective date. The customer is refunded for 134 days instead of 184, and nothing on screen looks wrong.
also: reinstatement three weeks later, leap years, 365 vs 366
annual premium120000term days365effective 01 Jul, keyed 20 Augrefund, effective date (184 d)60493refund, posting date (134 d)44055customer short16438
120000 x 184 / 36560493rounded once, at the end
FAILrefund counts from the posting date
PASSafter the fix
how we test itMove the clock, post the change late, and compare the refund with an independent pro-rata calculation. Repeat for every boundary: month end, leap day, term end.
Rate tables are versioned by effective date. Version 13 goes live on 1 March for new business. A mid-term change on a policy incepted in February looks up the table by today's date, reprices the whole policy at version 13, and the customer sees a premium jump they did not cause.
also: a quote saved yesterday and bound tomorrow
1 Febincept
1 Marv13 live
9 Maradd driver
9 Marexpected
RATED v12only the change, at v12 rates
how we test itReprice a fixed sample of real policy shapes before and after each rate deployment and fail on any difference. Then run mid-term changes after the switch date.
const before = await rating.priceAll(sample, { asOf: '2026-02-28' })
await deployRates('v13', { effective: '2026-03-01' })
const after = await rating.priceAll(sample, { asOf: '2026-02-28' })
expect(diff(before, after)).toEqual([]) // must not moveawait clock.set('2026-03-09')
expect((await mta(policy, addDriver)).tableVersion).toBe('v12')
03 · claims ledger
A reserve movement posts to the ledger twice
A reserve increase of 5,000 is published to the finance interface. The ledger commits it but the acknowledgement times out, so the bus delivers the message again. With no idempotency key on the journal, the ledger posts it a second time and the claim shows 5,000 where the general ledger holds 10,000.
also: partial settlement, reopened claims, a payment that fails after the reserve moved
FAILclaim C-77: 5000 in claims, 10000 in ledger
how we test itRedeliver every finance message and reopen closed claims, then reconcile the claims sub-ledger to the control account, claim by claim.
The renewal batch reads the instalment amount from last year's premium field. The total payable is right and the instalment line is wrong, so every letter shows 12 payments that add up to less than the total. A single sample PDF passes review. The complaints arrive at volume.
also: aggregator feeds with latency budgets, bordereaux at month-end
Policy PX-20931 renewal 01 Nov 2026Last year EUR 412.00This year EUR 438.00Payment plan 12 x EUR 34.33Total payable EUR 438.00
10,000 LETTERSinstalments add to 411.96, not 438.00
how we test itGenerate the whole batch in a test environment, extract the text of every PDF and recompute each figure from the policy data. Totals must reconcile.
const pdfs = await renewals.generate(testBook) // all of themfor (const pdf of pdfs) {
const doc = parse(pdfText(pdf))
const p = policyApi.get(doc.policyNo)
expect(doc.total).toBe(p.premium)
expect(sum(doc.instalmentList)).toBe(p.premium) // last one adjusted
}
Illustrative examples built from defect patterns we test for. Not client data.
// on every pull request
Your code is written in hours. Our pipeline keeps up.
Pull requestfrom your coding agent
Flowsjourneys and fault injection
Security Toolkit15 scanners + 20 own checks
QA engineerconfirms every finding
BugBoardrelease report, Jira sync
// the regulation, in testing terms
regime
where it actually breaks
what we run
IDD
Product information must reach the customer before the contract is concluded
product information document present and correct before bind
DORA
Applies to insurers too: resilience and ICT third parties
Effective dating. A policy is a state machine that moves through time, and most defects live in the gap between the date something happened and the date it takes effect. Mid-term adjustments, backdated endorsements, pro-rata refunds, cancellations with a reinstatement three weeks later. A test suite that only ever runs against today's date cannot see any of this. We test with the clock moved.
Rating. Rate tables are versioned by effective date, and a rate change deployed against the wrong version reprices business you have already written. Testing a rating engine means testing the table, the date the table applies from, and what happens to a quote saved yesterday and bound tomorrow. The arithmetic is the easy half.
Claims. First notification, reserving, payment, recovery and subrogation, salvage. Reserve movements land in the general ledger, so a claims defect is an accounting defect one hop later. The path that gets tested is the claim that gets paid. The paths that do not get tested are partial settlement, reopening a closed claim, and a payment that fails after the reserve has already moved.
Documents. Schedules, certificates, renewal notices. The single most visible defect class in this industry is a correct policy with a wrong document, because the document is the only thing the policyholder reads. Generating ten thousand PDFs where one figure is wrong is a complaint file, not a bug ticket.
Integration. ACORD messages between broker and carrier, aggregator and comparison feeds with hard latency budgets, bordereaux from delegated authority. These fail quietly and on a schedule, which means they fail at the end of the month when nobody is watching.
// 02
Test automation for insurance
Insurance is an unusually good fit for automation and an unusually bad fit for the way automation is normally done here.
The good fit: rate changes are frequent, and every one of them risks business already on the books. A regression suite that reprices a fixed sample of real policy shapes before and after a rate deployment, and fails on any movement nobody asked for, is worth more than any number of UI tests. That suite is data driven by construction. You build it once and feed it a matrix.
The bad fit: quote and bind journeys are long, branchy and rendered by portals that change quarterly, so UI-first automation in this market rots faster than anywhere else. We push as much as possible down to the rating service and the policy API, where the contract is stable, and keep the browser tests to the handful of journeys where the browser is the thing under test. Where we do drive a UI, we use Flows, our own recorder, which proposes selector fixes when a portal is redesigned, and an engineer approves each one.
Test data, which is the part everyone underestimates
Policy data is personal data, and in health, life and some liability lines it is special category data. Copying production into a test environment solves the realism problem and creates a much larger one.
So the first thing we usually build is not a test. It is a way to generate policy and claim data that is shaped like yours without being yours. Real distributions, real edge shapes, synthetic people. If that already exists in your organisation, we use it and say so. If it does not, we will tell you in week one that it is the prerequisite, because testing rating against four sample policies tells you almost nothing about a book of two hundred thousand.
// 04
Regulatory reporting we test
Solvency II reporting and IFRS 17 measurement are data pipelines with an audience of regulators. They can be tested the way any pipeline is tested: reconcile the output to an independently computed figure, and fail on any difference. We do that part.
We test that the software computes what your actuary specified.
Our certifications, and what each one is actually worth, are set out at certifications. ISO/IEC 27001:2022 is the relevant one here, because it governs how we handle your data, your credentials and your environments.
// 05
How we start, and what it costs
A one-month trial. We embed, learn the product, write tests and file real bugs against your actual software. The first two weeks are complimentary if you are not happy with what we deliver. You decide whether to carry on at the end of the first month. We do this because nobody can judge testing quality from a proposal, and every QA company's proposal reads the same.
After that, €20 to €45 an hour depending on seniority, commitment length and the mix of manual, automation and specialist work. Longer commitments move down the range. Every engineer on your product has shipped commercial releases before.
Included at no licence cost: BugBoard for test management, Flows for automation where an engineer approves each selector fix, Auditi for GDPR, WCAG and FDA auditing, BetterFlow so you can see where the hours went, and our AI Security Toolkit. We built all five because the off the shelf versions did not keep up with us.
Our engineers are in Cluj-Napoca, Romania, on GMT+2 and GMT+3 in summer. That covers the European working day and overlaps the start of the US East Coast day.
// 06
Talk to us
Tell us what you underwrite, how often you deploy, and what went wrong most recently. We will tell you whether this helps, and if it does not, we will tell you that instead.
We use cookies to see how the site is used and to improve it. You can change your choice at any time.
Functional
Always active
The technical storage or access is strictly necessary for the legitimate purpose of enabling the use of a specific service explicitly requested by the subscriber or user, or for the sole purpose of carrying out the transmission of a communication over an electronic communications network.
Preferences
The technical storage or access is necessary for the legitimate purpose of storing preferences that are not requested by the subscriber or user.
Statistics
The technical storage or access that is used exclusively for statistical purposes.The technical storage or access that is used exclusively for anonymous statistical purposes. Without a subpoena, voluntary compliance on the part of your Internet Service Provider, or additional records from a third party, information stored or retrieved for this purpose alone cannot usually be used to identify you.
Marketing
The technical storage or access is required to create user profiles to send advertising, or to track the user on a website or across several websites for similar marketing purposes.