Some of the most expensive software bugs produce differences that look almost meaningless.
A total might be off by:
- $0.01
- €0.02
- ₹0.01
- ¥1
- 0.001 KWD
To a tester looking at one transaction, that difference may seem insignificant.
At scale, it can become a serious financial problem.
Consider an application processing millions of transactions.
If a calculation is wrong by even a small amount on every transaction, the accumulated difference can become significant.
And the problem is not limited to payment systems.
Rounding affects:
- ecommerce checkouts
- invoices
- subscriptions
- taxes
- discounts
- commissions
- payroll
- accounting
- refunds
- currency conversion
- financial reports
- marketplaces
- loyalty programs
- shipping calculations
- billing systems
- payment gateways
- dashboards
The difficult part is that rounding bugs are often hidden inside otherwise correct calculations.
For example:
Product price
↓
Discount
↓
Tax
↓
Currency conversion
↓
Rounding
↓
Final amount
Each individual calculation may appear correct.
The final result can still be wrong because the application rounded at the wrong stage.
This is why QA should not treat currency rounding as a formatting problem.
It is a data accuracy and business logic problem.
---
What Is Currency Rounding Testing?
Currency rounding testing verifies that monetary values are calculated, stored, displayed, converted, and persisted according to the application's defined financial rules.
It covers questions such as:
- How many decimal places does a currency support?
- When should a value be rounded?
- Which rounding rule is used?
- Is rounding performed before or after tax?
- Is rounding performed before or after discounts?
- Are intermediate calculations rounded?
- Are negative values handled correctly?
- Does the database preserve the required precision?
- Does the API return the correct amount?
- Does the UI display the same amount?
- Does the payment provider receive the correct amount?
- Does the invoice contain the same amount?
- Does a refund use the same calculation rules?
A basic example:
10.005
Depending on the system's defined precision and rounding policy, this value may become:
10.01
But another system could use a different rounding rule.
The important QA principle is:
Do not assume the mathematically obvious result is the expected result.
The expected result must come from the product's financial rules.
---
Why Rounding Bugs Are So Dangerous
A normal UI defect might cause:
A button appears slightly misaligned.
A rounding defect might cause:
Thousands of customers were charged incorrectly.
The visual difference may be tiny.
The business impact may not be.
Rounding problems can also spread across systems.
Imagine:
Checkout
↓
Billing Service
↓
Payment Gateway
↓
Accounting System
↓
Financial Report
If the checkout calculates:
19.99
but the accounting system receives:
20.00
the problem may not become visible until reconciliation.
This makes financial calculation bugs particularly dangerous.
---
The First Rule: Define the Money Contract
Before writing test cases, QA should understand the application's monetary rules.
Document:
- supported currencies
- decimal precision
- rounding mode
- calculation order
- tax rules
- discount rules
- conversion rules
- storage precision
- display precision
- minimum transaction amount
- maximum transaction amount
- negative amount behavior
- refund behavior
- partial payment behavior
- split payment behavior
For example:
Currency: USD
Decimal places: 2
Rounding: Half-up
Storage: Minor units
Display: 2 decimal places
The exact rules will vary by product.
The important point is that QA should not invent expected values independently of the business specification.
---
Currency Precision Is Not the Same as Display Formatting
One of the most common mistakes is assuming that the number shown to the user is the number stored internally.
For example, the UI might display:
$10.50
But the application might internally represent the amount as:
1050 cents
Or:
10.500000
Or another decimal representation.
Testing should therefore happen at multiple layers.
UI
What does the customer see?
API
What value does the service return?
Database
What value is actually stored?
Payment gateway
What amount is sent externally?
Accounting
What amount is recorded?
These values should follow the system's defined contract.
---
Test Currency Decimal Rules
Different currencies can have different decimal conventions.
Do not build a test suite around the assumption that every currency behaves like USD.
Create test data that includes currencies with different precision requirements.
For example:
| Currency | Example Precision |
|---|---:|
| USD | 2 decimal places |
| EUR | 2 decimal places |
| GBP | 2 decimal places |
| JPY | 0 decimal places |
| KWD | 3 decimal places |
The exact supported currency set depends on the application.
For every supported currency, verify:
- input precision
- calculation precision
- storage precision
- display precision
- payment amount
- refund amount
- report amount
A common defect is implementing one universal rule such as:
round(value, 2)
and applying it to every currency.
That can be incorrect for currencies with different decimal requirements.
---
Test Values Exactly at the Rounding Boundary
Boundary values are particularly important.
Suppose the application rounds to two decimal places.
Test values around the boundary:
10.004
10.005
10.006
Also test:
10.014
10.015
10.016
And values involving multiple decimal positions:
0.001
0.004
0.005
0.006
0.009
The purpose is not simply to test random numbers.
The purpose is to test where the application's rounding decision changes.
---
Test Both Rounding Directions
A good test suite should contain values that round:
Down
and
Up
For example:
10.004 → expected lower value
and:
10.006 → expected higher value
Also test values exactly at the midpoint according to the application's rounding rule.
Do not create only happy-path prices such as:
10.00
20.00
50.00
Those values rarely expose rounding defects.
---
Test the Exact Halfway Value
The halfway value is one of the most important cases.
For two decimal places, values such as:
10.005
20.015
99.995
can reveal differences between rounding strategies.
Depending on the application's defined rule, the result can differ.
Possible rounding strategies include:
- half up
- half down
- half even
- toward zero
- away from zero
The application should have one explicitly defined behavior.
QA should build tests around that rule.
---
Test Negative Monetary Values
Negative amounts are frequently forgotten.
Examples include:
- refunds
- credits
- account adjustments
- chargebacks
- discounts
- accounting corrections
If the system supports negative amounts, test:
-10.004
-10.005
-10.006
Do not assume that the same implementation behaves symmetrically for positive and negative values.
A rounding function can produce surprising results around zero.
Test:
-0.006
-0.005
-0.004
0
0.004
0.005
0.006
This is particularly important for financial adjustments.
---
Test Zero and Near-Zero Values
Small values can expose defects that normal transactions never reveal.
Test:
0
0.001
0.004
0.005
0.009
Also test negative near-zero values where supported.
Check whether the application produces:
0.00
or:
-0.00
A displayed `-0.00` can be a small UI defect, but it can also reveal deeper inconsistencies in calculation logic.
---
Test Decimal Representation
Floating-point arithmetic can introduce unexpected precision behavior.
For example, many programming languages use binary floating-point representations for ordinary numeric types.
That means calculations that look simple in decimal arithmetic may not be represented exactly internally.
A classic example is:
0.1 + 0.2
which can produce a value extremely close to, but not exactly, `0.3` in binary floating-point systems.
This does not automatically mean the application is broken.
What matters is whether the system uses an appropriate monetary representation and applies the required rounding rules.
QA should therefore test the actual output of financial calculations rather than trusting the language's default number type.
---
Test Addition of Monetary Values
Start with simple arithmetic.
For example:
10.10
20.20
30.30
Expected:
60.60
Then introduce values that require precision handling:
10.005
20.005
30.005
The expected result depends on where and when the application rounds.
Test both:
Round before addition
round(10.005)
+
round(20.005)
and:
Add before rounding
round(10.005 + 20.005)
These can produce different results.
The product specification must define which behavior is correct.
---
Test Tax Calculation
Tax is one of the most common sources of rounding problems.
Suppose:
Product = 19.99
Tax = 18%
The application calculates:
19.99 × 0.18
The resulting value may contain more precision than the customer-facing currency supports.
QA needs to know:
When is the tax rounded?
Possible strategies include:
Calculate tax per item
↓
Round each item tax
↓
Add taxes
or:
Add item totals
↓
Calculate total tax
↓
Round once
These can produce different totals.
The test suite should explicitly cover the application's chosen method.
---
Test Tax Per Line vs Tax on the Total
Consider:
Item A = 10.01
Item B = 10.01
If tax is calculated separately:
Tax A
+
Tax B
the result can differ from:
Total = 20.02
Tax on total
Neither approach is automatically correct.
The important thing is consistency with the business and regulatory rules that apply to the product.
Build tests that compare:
- line-level tax
- order-level tax
- invoice-level tax
- displayed tax
- stored tax
---
Test Discounts Before and After Tax
Discount ordering can dramatically change the final amount.
Consider:
Product
↓
Discount
↓
Tax
versus:
Product
↓
Tax
↓
Discount
The final values may differ.
QA should therefore test the calculation sequence explicitly.
For example:
Price = 100
Discount = 10%
Tax = 18%
Verify the expected result according to the application's business rules.
Then test:
- percentage discount
- fixed discount
- multiple discounts
- maximum discount
- minimum order threshold
- tax-exempt items
- discounted taxable items
---
Test Multiple Discounts
Multiple discounts are another common source of calculation errors.
For example:
Price = 100
Discount 1:
10%
Discount 2:
20%
Does the system calculate:
100 × 0.70
or:
100 - 10
= 90
then:
90 - 18
= 72
Those are mathematically equivalent in this simple case.
But rounding, minimum discounts, caps, and fixed-value promotions can change the outcome.
Test combinations such as:
- percentage + percentage
- fixed + percentage
- percentage + fixed
- coupon + loyalty discount
- promotion + tax exemption
---
Test Currency Conversion
Currency conversion introduces another rounding layer.
For example:
100 USD
×
FX rate
=
EUR amount
Then:
Round EUR amount
But the application may have:
- FX rate precision
- markup
- conversion fee
- currency precision
- final rounding rule
Test each component independently.
For example:
Source amount
↓
Exchange rate
↓
Converted amount
↓
FX fee
↓
Final amount
↓
Currency rounding
Do not validate only the final displayed number.
---
Test Exchange Rates With Deterministic Data
Never make your core rounding tests depend on live exchange rates.
Live rates can change.
That makes the expected result unstable.
Instead, use deterministic test data.
For example:
USD → EUR
Rate = 0.912345
Then calculate expected values independently.
This allows the test to determine whether the system:
- applied the rate correctly
- applied the fee correctly
- rounded at the correct stage
Live exchange-rate integration should have separate tests.
---
Test Fees and Commissions
Many systems calculate fees using:
- percentage
- fixed amount
- minimum fee
- maximum fee
- tiered fee
Example:
Transaction = 99.99
Fee = 2.9% + fixed fee
Test:
- very small transaction
- normal transaction
- large transaction
- fee minimum
- fee maximum
- exact threshold
- just below threshold
- just above threshold
Rounding should be checked after every business rule where the specification requires it.
---
Test Refund Calculations
Refunds are particularly important because the original transaction may already contain:
- discounts
- taxes
- fees
- currency conversion
- rounding
A full refund should normally follow the product's defined financial rules.
A partial refund is more complicated.
For example:
Order = 100
Discount = 10
Tax = 18
Then a customer refunds one of several items.
What amount should be returned?
Test:
- full refund
- partial refund
- multiple partial refunds
- refund after discount
- refund after tax
- refund with fees
- refund in converted currency
Also verify that repeated refund requests cannot exceed the refundable amount.
---
Test Split Payments
If the application supports split payments, rounding becomes even more interesting.
Suppose:
Total = 100.00
Three users split the payment equally.
Mathematically:
100 / 3 = 33.333...
But the currency may only support two decimal places.
Possible allocation:
33.33
33.33
33.34
The system needs a defined allocation rule.
QA should verify:
Sum of allocations = original total
This is more important than simply checking that each individual amount looks reasonable.
---
Test Percentage Allocation
The same principle applies to percentages.
Suppose:
Total = 100
Allocation:
33%
33%
34%
Expected:
33
33
34
But if percentages or amounts contain more precision, rounding can create discrepancies.
Always test:
Sum of parts = expected total
This is a powerful invariant for financial testing.
---
Test Invariants Instead of Only Expected Numbers
One of the best ways to test financial calculations is to define invariants.
Examples:
Total invariant
Sum(line items) + tax - discount = final total
Refund invariant
Total refunds ≤ original refundable amount
Split payment invariant
Sum(payment parts) = order total
Balance invariant
Opening balance + credits - debits = closing balance
Conversion invariant
Converted amount follows the defined rate and rounding rule
Invariants are powerful because they catch entire classes of bugs.
A test may not know every possible output in advance.
But it can still know what must always remain true.
---
Test Database Storage Precision
The database layer can introduce its own rounding behavior.
For example, an application may calculate:
19.999999
but store:
20.00
depending on the database column definition.
Test:
- database precision
- database scale
- insert behavior
- update behavior
- aggregation behavior
- serialization behavior
Also test values near the database boundary.
For example, if the database supports:
DECIMAL(12,2)
test:
9999999999.99
and values beyond the supported range.
The application should reject values that cannot be represented safely rather than silently corrupting them.
---
Test API Serialization
The database might store:
10.50
The API could return:
10.5
or:
"10.50"
or:
10.5000
The correct representation depends on the API contract.
Do not assume that formatting differences are harmless.
If clients depend on a fixed monetary representation, the contract should define it.
Test:
- numeric vs string representation
- decimal places
- null handling
- negative values
- zero
- large values
- currency code
For example:
{
"amount": "19.99",
"currency": "USD"
}
can communicate monetary intent differently from:
{
"amount": 19.99
}
The API contract should make the representation explicit.
---
Test UI Formatting Separately From Calculation
A calculation can be correct while the UI displays it incorrectly.
For example:
API:
1234.50
UI:
$1,234.5
Or:
$1234.50
Or:
1.234,50 €
Depending on locale.
Test:
- currency symbol
- decimal separator
- thousands separator
- decimal places
- negative formatting
- zero formatting
- locale
- currency code
Do not confuse display formatting with financial calculation.
A UI can display a rounded value while the underlying API contains the correct precision.
---
Test Locale Differences
International applications create another layer of risk.
For example:
US:
1,234.56
Many European locales:
1.234,56
Some systems may use:
1 234,56
The underlying amount should remain consistent.
Test the same monetary value across:
- English
- European locales
- Asian locales
- supported regional formats
Also test that parsing user-entered values does not change the amount.
---
Test Currency Symbols
Do not assume the symbol uniquely identifies the currency.
For example, `$` can represent multiple currencies.
Where appropriate, verify:
- currency code
- symbol
- locale
- amount
For financial applications, displaying:
$100
may be insufficient if the user could be operating in different dollar-denominated currencies.
---
Test Large Monetary Values
Small values are not the only risk.
Test large amounts near system limits.
Examples:
999.99
9,999.99
999,999.99
9,999,999.99
maximum supported value
Look for:
- overflow
- truncation
- scientific notation
- database errors
- API serialization problems
- incorrect formatting
- rounding differences
Large-value testing is particularly important for business-to-business applications.
---
Test Very Small Monetary Values
Also test values close to zero.
Examples:
0.01
0.02
0.05
0.09
0.10
And where supported:
0.001
0.005
0.009
Small values often expose:
- minimum transaction bugs
- rounding to zero
- negative zero
- fee calculation errors
- discount calculation errors
---
Test Aggregation and Reporting
A major financial bug can appear when individual transactions are correct but aggregated reports are wrong.
For example:
Transaction A:
10.004
Transaction B:
10.004
Should the report calculate:
round(10.004) + round(10.004)
or:
round(10.004 + 10.004)
The result can differ depending on the application's accounting rules.
Test:
- transaction totals
- daily totals
- monthly totals
- invoice totals
- dashboard totals
- exported totals
- accounting totals
Verify that aggregation rules are consistent.
---
Test CSV and Report Exports
Financial reports frequently introduce formatting and precision defects.
For example:
UI:
€1,234.50
CSV:
1234.5
Database:
1234.5000
Accounting system:
1234.50
These values may represent the same amount, but the downstream system may require a specific format.
Test:
- CSV
- Excel
- PDF
- API
- UI
- accounting exports
For every output, verify the amount and currency.
---
Test Payment Gateway Amounts
The final payment request is one of the most important assertions.
Suppose the customer sees:
$19.99
The payment gateway should receive the amount according to its API contract.
For gateways using minor units:
$19.99
may be represented as:
1999
The test should verify the transformation.
Do not rely only on the UI.
Inspect the outbound API request or use a test gateway environment.
---
Test Double-Rounding
Double-rounding is a subtle but important problem.
Imagine a system:
1. calculates a high-precision amount
2. rounds it
3. performs another calculation
4. rounds again
The final value may differ from performing the calculation at full precision and rounding once.
For example:
Raw calculation
↓
Round
↓
Tax
↓
Round
versus:
Raw calculation
↓
Tax
↓
Round once
The expected result depends on the business rules.
QA should explicitly test where rounding occurs.
---
Test Rounding Order
Create tests that intentionally distinguish between:
Round A → Calculate B
and:
Calculate B → Round
For example:
Price
↓
Discount
↓
Round
↓
Tax
versus:
Price
↓
Discount
↓
Tax
↓
Round
This is one of the most valuable areas of financial testing because both implementations can look reasonable in code review.
Only the business rule determines which is correct.
---
Test Repeated Calculations
Some applications repeatedly transform amounts.
For example:
USD
↓
EUR
↓
GBP
↓
USD
Every conversion and rounding operation can introduce small differences.
If the product supports such workflows, test whether repeated conversions are expected to preserve a particular invariant.
Do not assume:
USD → EUR → USD
will always produce the original amount exactly.
Currency conversion is not necessarily reversible once rounding has occurred.
The important thing is that the product's expected behavior is clearly defined.
---
Test API and UI Against the Same Expected Value
One useful technique is to maintain an independent expected-value calculator for test data.
For example:
Input:
price = 19.99
tax = 18%
discount = 10%
The test fixture calculates the expected result independently.
Then compare:
Expected
vs
API
vs
UI
This is safer than generating the expected result using the same production calculation function.
If your test uses the same flawed calculation as the application, both can be wrong while the test passes.
---
Avoid Circular Test Calculations
This is an important automation principle.
Bad approach:
expected = application.calculate(amount)
actual = application.calculate(amount)
Result:
expected == actual
Of course it does.
The test has proven almost nothing.
Instead, expected values should come from:
- an independent calculation
- approved test fixtures
- a specification
- known financial examples
- a separate reference implementation
For monetary logic, independence is particularly important.
---
Build a Boundary-Focused Test Dataset
Instead of creating hundreds of random amounts, build a deliberate dataset.
Example:
| Category | Examples |
|---|---|
| Zero | 0 |
| Small | 0.01, 0.05 |
| Halfway | 10.005 |
| Just below | 10.004 |
| Just above | 10.006 |
| Negative | -10.005 |
| Large | 9999999.99 |
| Maximum | System maximum |
| Currency-specific | JPY, KWD |
| Discount | 10%, 33.33% |
| Tax | 5%, 18%, 20% |
| Conversion | Deterministic FX rate |
This gives much more useful coverage than random values alone.
---
Automating Currency Rounding Tests
Currency tests are excellent candidates for data-driven automation.
Example:
test_cases = [
{
"currency": "USD",
"input": "10.004",
"expected": "10.00"
},
{
"currency": "USD",
"input": "10.005",
"expected": "10.01"
},
{
"currency": "USD",
"input": "10.006",
"expected": "10.01"
}
]
Then the same test logic can execute against many datasets.
This is easier to maintain than writing individual tests for every value.
---
Use Independent Decimal Arithmetic for Expected Values
When building test utilities, use a decimal-aware approach rather than relying on ordinary floating-point calculations where precision matters.
The expected-value calculation should reflect the application's defined financial rules.
For example, a test helper might conceptually do:
amount
↓
Decimal representation
↓
Apply business calculation
↓
Apply defined rounding rule
↓
Expected amount
The application under test should be calculated independently.
This separation helps detect arithmetic defects rather than reproduce them.
---
AI-Assisted Currency Testing
AI can help QA teams discover rounding scenarios that are easy to miss.
For example, given:
Price
Discount
Tax
Currency
FX conversion
Payment
an AI-assisted testing system could generate scenarios involving:
- rounding boundaries
- different currencies
- negative values
- large values
- partial refunds
- split payments
- discount combinations
- tax combinations
- conversion sequences
AI can also inspect requirements and identify questions such as:
Is tax rounded per line item or at order level?
Does the refund use the original exchange rate?
Are amounts stored in major or minor currency units?
What happens when a split payment produces fractional cents?
These questions are often more valuable than simply generating more test cases.
AI should help expose uncertainty.
It should not invent financial rules.
For monetary workflows, the expected behavior must come from the product and business specification.
---
Common Currency Testing Mistakes
Mistake 1: Testing only two decimal places
Not every currency follows the same decimal convention.
Test the currencies your product actually supports.
---
Mistake 2: Testing only display values
A UI showing:
$10.50
does not prove that the backend stored or charged:
10.50
Validate the complete data path.
---
Mistake 3: Ignoring negative values
Refunds and credits frequently expose rounding defects.
Test them.
---
Mistake 4: Rounding after every calculation
More rounding is not necessarily safer.
The correct rounding point depends on the financial specification.
---
Mistake 5: Using live FX rates in core tests
Live rates make expected values unstable.
Use deterministic rates for calculation tests.
---
Mistake 6: Reusing production calculation logic for expected values
This can create circular tests.
Expected values should be independently derived.
---
Mistake 7: Ignoring split payments
Dividing an amount among multiple parties can create fractional minor units.
Test allocation rules explicitly.
---
Mistake 8: Testing only one transaction
Financial defects can emerge during:
- aggregation
- refunds
- reporting
- reconciliation
- repeated conversions
Test the full lifecycle.
---
A Practical Currency Rounding Test Matrix
| Area | Test |
|---|---|
| Precision | Supported decimal places |
| Boundary | Just below rounding threshold |
| Boundary | Exactly at threshold |
| Boundary | Just above threshold |
| Negative | Negative midpoint values |
| Zero | Zero and near-zero values |
| Currency | Different currency precisions |
| Tax | Tax rounding |
| Discount | Discount rounding |
| Conversion | FX calculation |
| Fees | Percentage and fixed fees |
| Refund | Full refund |
| Refund | Partial refund |
| Split | Allocation remainder |
| Storage | Database precision |
| API | Monetary serialization |
| UI | Currency formatting |
| Reports | Aggregation |
| Gateway | Outbound payment amount |
| Large values | Maximum supported amount |
| Small values | Minimum supported amount |
| Invariants | Sum of parts equals total |
---
Example End-to-End Test
Imagine an ecommerce order:
Product A = 19.99
Product B = 29.99
Discount:
10%
Tax:
18%
Currency:
USD
The test should not simply check:
Final total = expected
It should validate the complete calculation contract.
Step 1: Add products
Verify:
19.99 + 29.99 = 49.98
Step 2: Apply discount
Verify the defined discount calculation.
Step 3: Apply tax
Verify whether tax is calculated before or after discount according to the product rules.
Step 4: Apply rounding
Verify the exact rounding point.
Step 5: Check API
Verify:
amount
currency
Step 6: Check UI
Verify the displayed total.
Step 7: Check payment request
Verify the gateway receives the correct amount.
Step 8: Check database
Verify the persisted transaction.
Step 9: Check invoice
Verify the invoice total.
Step 10: Check refund
Refund the order and verify the correct amount is returned.
This creates a much stronger test than simply checking the checkout screen.
---
Currency Rounding Testing Checklist
Calculation
- [ ] Correct decimal precision
- [ ] Correct rounding mode
- [ ] Correct calculation order
- [ ] Correct intermediate precision
- [ ] No unintended double-rounding
- [ ] Correct negative value behavior
- [ ] Correct zero behavior
Currency
- [ ] Every supported currency tested
- [ ] Currency-specific precision verified
- [ ] Currency code verified
- [ ] Currency symbol verified
- [ ] Locale formatting verified
Tax
- [ ] Tax calculation verified
- [ ] Tax rounding verified
- [ ] Line-level tax tested
- [ ] Order-level tax tested
- [ ] Discount/tax ordering tested
Discounts
- [ ] Percentage discounts
- [ ] Fixed discounts
- [ ] Multiple discounts
- [ ] Maximum discount
- [ ] Minimum order threshold
- [ ] Discount rounding
Payments
- [ ] Gateway amount verified
- [ ] Minor-unit conversion verified
- [ ] Minimum payment tested
- [ ] Maximum payment tested
- [ ] Duplicate payment protection tested
Refunds
- [ ] Full refund
- [ ] Partial refund
- [ ] Multiple refunds
- [ ] Refund after discount
- [ ] Refund after tax
- [ ] Refund currency verified
Data
- [ ] Database precision verified
- [ ] API representation verified
- [ ] UI representation verified
- [ ] Reports verified
- [ ] Export values verified
- [ ] Accounting values verified
Automation
- [ ] Boundary dataset created
- [ ] Expected values independently calculated
- [ ] Deterministic FX rates used
- [ ] Data-driven tests implemented
- [ ] Financial invariants asserted
---
Final Thoughts
Currency rounding bugs are rarely about whether a number looks right on a screen.
They are about whether the entire financial calculation remains correct from beginning to end.
A strong QA strategy follows the money:
Input
↓
Price
↓
Discount
↓
Tax
↓
Fees
↓
Currency Conversion
↓
Rounding
↓
Payment
↓
Database
↓
Invoice
↓
Refund
↓
Reporting
The most valuable tests are not random monetary values.
They are the values around the points where business rules change.
Test:
- just below the boundary
- exactly at the boundary
- just above the boundary
- positive values
- negative values
- zero
- very small amounts
- very large amounts
- different currencies
- tax and discount combinations
- partial refunds
- split payments
- currency conversion
- aggregation
Most importantly, define the financial rules before testing them.
QA should not guess whether a value should round up or down.
The product specification should tell you.
Your tests should then make sure the application follows that rule consistently across the UI, API, database, payment gateway, reports, and downstream systems.
Because in financial software, a one-cent defect is not necessarily a small defect.
The real question is:
How many times will that one-cent defect happen?
