# Boundary Value Analysis

Testing at the edges of input ranges, where off-by-one and comparison errors concentrate.

**Rests on:** Equivalence Partitioning

*Software Engineering · Software Testing*


## Why learn this

Boundary value analysis is the technique that catches the most common class of software bug — the off-by-one error. When a user enters an age, a price, a date, a page number, a loan amount, or any quantity with a minimum and maximum, the code that checks the range usually fails at the edges, not in the middle. By learning this, you will be able to design test cases that reliably find these defects. For example, imagine building an AI system that approves loans. If the code mistakenly rejects a valid loan amount because it compared 'greater than' instead of 'greater than or equal to', your business loses money. Or consider a chatbot that truncates user responses; if it cuts off one character too early, the meaning is lost. This skill lets you catch these specific defects before they reach your users, ensuring that the systems you build work correctly exactly where people expect them to.


## The intuition

Think about the last time you filled out an online form that asked for your age. There was probably a rule: you must be between 18 and 60, or between 0 and 120, or something similar. Where do you think most bugs happen? Not for a 30-year-old — that's the safe middle. Bugs happen at 17, 18, 19, and 59, 60, 61. Why? Because the code that checks the boundary uses a comparison like 'age >= 18' or 'age <= 60'. If the programmer accidentally wrote 'age > 18' instead of 'age >= 18', then a person who is exactly 18 is wrongly rejected. If they wrote 'age < 60' instead of 'age <= 60', a person who is 60 is wrongly rejected. These errors are called off-by-one errors, and they are incredibly common because humans naturally think '18 or above' but write '> 18' by mistake. Boundary value analysis is a systematic way to test just below, at, and just above each boundary, so you catch these errors before your users do. It is not about testing every possible value — that would be impossible. It is about testing the few values where defects cluster: the edges.


## An analogy

Imagine you are a security guard at a concert. The rule is that only people who are 18 or older can enter. You stand at the door and check IDs. Where do you pay the most attention? Not to a 30-year-old — that's an easy yes. You watch the people who look like they might be 18, maybe 17, maybe 19. The person who is exactly 18 is the most important to check, because the rule could be '18 or older' or 'over 18' — and the difference matters. So you check the 17-year-old (just below), the 18-year-old (at the boundary), and the 19-year-old (just above). That is boundary value analysis. A caveat: unlike a human guard who can use judgment, a computer relies on exact code logic, making these edge cases critical.


## Definition

Boundary value analysis is a software testing technique where test cases are designed to exercise the values at the edges of an input range — just below, exactly at, and just above each boundary — because defects are most likely to occur there due to off-by-one and comparison errors.


## How it connects

This concept sits inside Software Testing, the parent topic you have notes on. It pairs naturally with Equivalence Partitioning, which divides inputs into classes that behave the same and picks one representative from each. Boundary value analysis goes one step further: within each class, you test the edges. For example, if a valid age is 18–60, equivalence partitioning says test one valid value (e.g., 30) and one invalid value (e.g., 15). Boundary value analysis says test 17, 18, 19, 59, 60, and 61. The two techniques together give you a powerful, systematic way to choose test cases without testing everything.


## The mathematics

The mathematics here is simple arithmetic — no algebra, no calculus. The branch of mathematics is arithmetic, because we are only adding and subtracting 1 from numbers. This concept rests on the idea of a range: a minimum value and a maximum value. For any boundary, we want to test three numbers: the boundary minus one, the boundary itself, and the boundary plus one. That is all. The reason is that a comparison like 'age >= 18' has two outcomes: true and false. The boundary is the point where the outcome flips. Just below the boundary, the comparison is one way; just above, it's the other way. The boundary itself is where off-by-one errors happen. So we test all three to make sure the flip happens at the right place.

For a boundary B, the test values are: B - 1, B, B + 1. For a range [min, max], the test values are: min - 1, min, min + 1, max - 1, max, max + 1. Each symbol: B is the boundary value; min is the lower bound of the valid range; max is the upper bound; - 1 and + 1 are the arithmetic operations of subtracting and adding one.


## A worked example

```
Suppose a system accepts a bank account balance in rupees. The rule is: balance must be between 1000 and 100000 (inclusive). We want to test the lower boundary 1000 and the upper boundary 100000.

Step 1: Lower boundary minus one: 1000 - 1 = 999   # This value should be rejected (invalid).
Step 2: Lower boundary: 1000   # This value should be accepted (valid).
Step 3: Lower boundary plus one: 1000 + 1 = 1001   # This value should be accepted (valid).
Step 4: Upper boundary minus one: 100000 - 1 = 99999   # This value should be accepted (valid).
Step 5: Upper boundary: 100000   # This value should be accepted (valid).
Step 6: Upper boundary plus one: 100000 + 1 = 100001   # This value should be rejected (invalid).

Result: We have six test cases: 999, 1000, 1001, 99999, 100000, 100001. The expected results are: reject, accept, accept, accept, accept, reject. If any of these behave differently, there is a boundary bug.
```


## From scratch, in Python

```python
# Let's write a function that checks if an age is valid (18 to 60 inclusive)
# Then we'll test it using boundary value analysis.

def is_valid_age(age):
    if age >= 18 and age <= 60:
        return True
    else:
        return False

# Test cases from boundary value analysis
# We'll use a list of (input, expected_output) pairs

test_cases = [
    (17, False),  # just below lower boundary
    (18, True),   # at lower boundary
    (19, True),   # just above lower boundary
    (59, True),   # just below upper boundary
    (60, True),   # at upper boundary
    (61, False),  # just above upper boundary
]

# Run the tests
for age, expected in test_cases:
    result = is_valid_age(age)
    if result == expected:
        print(f"PASS: age {age} -> {result}")
    else:
        print(f"FAIL: age {age} -> {result} (expected {expected})")
```


## What the code does

First, we define a function named `is_valid_age` that takes one argument, `age`. In Python, `def` creates a function. The `if` statement checks if `age` is greater than or equal to 18 AND less than or equal to 60. If both are true, it returns `True`; otherwise, it returns `False`. Next, we create a list called `test_cases` containing tuples. A tuple is like a list but you can't change it after creation. Each tuple has two values: the input age and the expected output. For example, `(17, False)` means age 17 should be invalid. Then we loop through each `(age, expected)` pair. The `for` loop repeats the code inside for each item in the list. We call `is_valid_age(age)` and store the result in `result`. We compare `result` to `expected`. If they match, we print PASS; otherwise, we print FAIL. This is a simple way to run boundary value tests. In real projects, you would use a testing framework like `pytest`, but the logic is the same.


## Common misconceptions

**Testing only the middle is enough** — If I test a regular value like 30, that should be enough to verify the age check works.

The middle value tells you nothing about the edges. A bug like 'age > 18' would still pass for 30, because 30 is greater than 18. You need to test the boundary where the behavior changes. In fact: You must test the edges where the comparison flips. The middle only proves the obvious cases work.

**Boundaries are only about numbers** — Boundary value analysis is only for numeric ranges; strings and lists don't have boundaries.

Strings have a length, lists have a length, and dates have a range. Any place where code checks a minimum or maximum is a boundary, regardless of the type. In fact: Boundary analysis applies to length of strings, size of lists, date ranges, count of items — anywhere there is a comparison like 'less than' or 'greater than'.

**You must test every value in the range** — To be safe, I should test every value from 18 to 60, not just the edges.

That is impractical for large ranges and unnecessary. The behavior is the same in the middle; defects cluster at the edges. Testing every value wastes time without finding more bugs. In fact: Test the boundary values and a few representatives from the middle. The edges are where the risk is.

**If the boundary passes, the range is safe** — If 18, 19, 59, and 60 all behave correctly, the age validation is bug-free.

Boundary tests catch comparison errors, but there could be other bugs, like using a different variable in the check or a wrong formula elsewhere. Also, the boundaries might be inclusive or exclusive, and you need to test both sides to know which one the code uses. In fact: Boundary analysis is a strong technique, but not a guarantee. Combine it with equivalence partitioning and other testing methods.

**Boundary analysis is only for testing, not for writing code** — I only need to think about boundaries when I test; my code can just use 'if age > 18' without worrying.

Boundary thinking is also important when writing code. If you write the comparison, you decide whether it is inclusive or exclusive. Testing is what reveals if you got it right, but thinking about boundaries while coding reduces the chance of bugs. In fact: When writing code, explicitly decide whether a boundary is inclusive or exclusive, and choose the correct operator (>= vs >). Then use boundary tests to verify.


## In short

Boundary value analysis is the practice of testing the edges of input ranges: just below, at, and just above each boundary. It catches off-by-one and comparison errors, which are among the most common bugs in software. Pair it with equivalence partitioning for a systematic approach to test case selection. Remember: defects cluster at boundaries, so test there.


## Where this is used

Boundary value analysis is used everywhere in software development, including AI systems. In large language models (LLMs), there are many limits: maximum token count for input, maximum output length, temperature range, and so on. When you build an API that calls an LLM, you must validate these parameters. For example, if the API allows `temperature` between 0 and 1, you test 0, 1, and if the API uses inclusive bounds, test -0.01, 0, 0.01, 0.99, 1, 1.01. A developer writes code like `if temperature > 1.0: raise ValueError` and boundary testing ensures that doesn't reject 1.0 or accept 1.01. In small language models running on devices (e.g., a keyword spotter on a phone), there are constraints on audio buffer sizes and sample rates. The model might expect exactly 16000 samples; testing 15999, 16000, 16001 could reveal array indexing bugs. In retrieval-augmented generation (RAG), you often fetch a top_k set of documents. If you write `if top_k > 20: limit to 20`, you test 19, 20, 21 to make sure the limit works. A developer would write `min(top_k, 20)` or a conditional, and boundary tests ensure the `min` or `max` works at the edges. In agentic systems that plan and call tools, there are often limits on the number of steps an agent can take. If an agent is allowed up to 5 tool calls, you test 4, 5, 6. A developer checks `if len(calls) >= 5: stop` and boundary testing catches off-by-one that prematurely stops at 4 or allows 6. In everyday applied ML, boundary value analysis is used in fraud detection when checking transaction amounts, in a recommendation system when page size for a list is specified, in forecasting when the number of time steps is validated, and in speech recognition when the maximum audio length is set. For instance, a loan approval model might take an `income` input; the API validates it is between 0 and 10,000,000 rupees. Boundary tests catch if 10,000,000 is accidentally rejected or accepted. In practice, a developer rarely writes a complete suite from scratch; they use a test framework like `pytest`. They write a test function that calls the validation function with each boundary value and asserts the expected outcome. They might use a library like `hypothesis` for property-based testing, but still hand-add boundary cases. What breaks when this is done badly? Users get rejected for valid inputs (e.g., a 60-year-old can't sign up) or invalid inputs are accepted (e.g., a 100-year-old can create an account, causing downstream errors). In AI systems, a single bad boundary check can crash the whole pipeline when an unexpected value arrives. So boundary value analysis is not a niche technique; it is a fundamental part of writing robust code.


---

Read this on the web: https://basavapurushottam.com/learn-ai/boundary-value-analysis
