> For the complete documentation index, see [llms.txt](https://practical-testing.gitbook.io/home/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://practical-testing.gitbook.io/home/techniques/ep-and-bva.md).

# EP & BVA

### Quick Summary

* **Equivalence (Class) Partitioning (ECP or just EP)** - group values or other things together that are expected to behave the same way, then pick one (or a few) to test
  * **EP is not limited to input values**. EP can be applied to output, versions of products or environments (e.g., consider groups of browsers and/or their versions as "equivalent" or "close enough")&#x20;
* **Boundary Value Analysis (BVA)** - testing around partition edges generally yields a higher chance of finding bugs. For the example above - values 17 (reject) and 18 (accept)
  * **BVA may be "normal" or "robust"**, based on system criticality and risk
  * Use  `min`, `min+`, `nom (nominal, or “mid”)`, `max–`, `max` and context-driven special values
  * 0 is a frequent special value
  * Other special numerical values: `-1`, `0`, `0.01`, `100`, `100.1`, `101`
  * Other common special technical numerical values:&#x20;
    * Unsigned 8-bit Integer Max (`uint8`): 255
    * Signed 32-bit Integer Min and Max (`int32`): –2,147,483,648 and 2,147,483,647
    * Unsigned Integer Max (`uint32`): 4,294,967,295
    * JavaScript Safe Integer Min and Max (–9,007,199,254,740,991 and 9,007,199,254,740,991)
  * Boundaries exist for other data types&#x20;
    * Time and Dates: start or end of minute/hour/day/etc.
    * Strings: min, max length restrictions,&#x20;

### EP Basics

Even if the System Under Test (SUT) has a single number input, there are an infinite number of possible test values. We may test with `-2,147,483,649`, `0` , `10.555` or `65,535`.

We don't have infinite time to test infinitely, so what numbers do we pick?

{% hint style="success" %}
EP is a prioritization technique - a way to guess where bugs are most likely to be systematically. It helps you reduce test effort intelligently by focusing on representative values, not exhaustive ones.
{% endhint %}

> Example: Shipping Delivery Fee based on distance (whole values only)
>
> * **Free:** 0–49 km
> * **Standard:** 50–499 km
> * **Not Supported:** 500 km and above
>
> ```
>   Valid (Free) | Valid (Standard) | Invalid (not supported)
> <------------->|<---------------->|<------------------------->
> 0              50                500 
> ```

Without using BVA, we may pick one value for each partition, for example `5`, `32`, `700`.

Thus

> Number of partitions = the number of test values (bare minimum)

### Adding BVA to EP

Picking representative 1+ values for each partition helps reduce effort, but it is not targeted enough. Practice shows that bugs are frequently found around **the edges,** for example, because code implementation may be incorrect (e.g., using `>` instead of `>=` ),&#x20;

#### Base or Normal BVA

In [Software Testing literature](#user-content-fn-1)[^1], you will encounter "Base" or "Normal" BVA that includes more values. For a single partition or parameter, you may use all or some of these - `min`, `min+`, `nom (nominal, or “mid”)`, `max–`, and `max`.

> ```
>    |<------------------------------->|
> 50 , 51          275             498, 499
> min, min+        mid            max-, max 
>
> (note: any random value within the partition may do as "mid")
> ```

This translates to the general formula:

> an
>
> * a - number of valid values per partition
> * n - number of partitions

Use `4n` (min, min+, max-, max per partition) without `mid` or `4n + 1` with it.

#### Robust or Standard BVA

If we add `min-` and `max+` (invalid values just outside the boundaries), we get "Robust BVA".

> ```
>        |<------------------------------------>|
> 49  , 50 , 51          275             498, 499, 500
> min-, min, min+        mid             max-, max, max+ 
> ```

{% hint style="info" %}
`min–` and `max+` values may belong to adjacent partitions and thus can be considered valid test inputs for those neighboring partitions.
{% endhint %}

### Special Business Values

It is often wise to add special values. "Special" depends on the domain (medicine, banking, etc.).&#x20;

{% hint style="warning" %}
**0 is frequently a special value**

* Can trigger division-by-zero errors
* May behave incorrectly in calculations (e.g., multiplying by 0 unintentionally nullifies results)
  {% endhint %}

While 0 is arguably the most common special value, others exist.

<table><thead><tr><th width="145.54547119140625">Value</th><th>Why special</th></tr></thead><tbody><tr><td>100</td><td>Where percent-based values are used, i.e., 100% is the maximum of something</td></tr><tr><td>100.1 or 101</td><td>Invalid or excessive percentage</td></tr><tr><td>.01</td><td>Smallest currency denomination in most systems.<br>In other cases, .001 or .0001, etc. may be the smallest allowed <strong>decimal</strong> value</td></tr><tr><td>1</td><td>Minimum whole (integer) value</td></tr><tr><td>-1</td><td> "Missing value", "not available" or similar meaning. <br>1) Usually, this value should not be exposed to users<br>2) If this value is generated as an (internal) intermediate result, it may lead to incorrect calculations in later processes.</td></tr><tr><td>Any</td><td>To highlight that any value may be special depending on the domain, e.g. <code>212</code> Fahrenheit (100 Celsius) at which water boils at sea level.<br></td></tr></tbody></table>

&#x20;Thus, the updated desired number of test values may be expressed as:

> an + c (special values)
>
> Example: 4n + 2 (4 edge values for each partition n, and 2 special values, such as -1 and 0)

### Special Technical Numerical Values

It is useful to know Computer Science (CS) Fundamentals to be aware of special **technical** values that may break the software. For example, the Delivery Fee app may work correctly if you input a large number, such as `2,000,000,000` , but will break with `2,147,483,648` .

> ```
>    |<---------------------------->|<------------------------------------>
> -9,007,199,254,740,992         499, 500                          2,147,483,648
>    BOOM!                                                             BOOM!
>    
> ```

Why?

Data is stored in program variables in memory. For numbers representing business values, common data types are `int/integer` or JavaScript's `Number` (whole numbers: age, count, quantity) and `double / float 64` (wherever decimals are needed, e.g. `10.50` or `12.4567`).

{% hint style="warning" %}
Numerical data types have range limits. They can store a value only up to a certain value and not more.
{% endhint %}

Min and Max Values may vary depending on the type and the technology used. CS Fundamentals are a separate topic worth studying by all involved in IT, but here is a non-exhaustive list of values to use for testing (add 1 to Max or subtract 1 from Min):

<table><thead><tr><th width="117.9090576171875">Type</th><th width="194.81817626953125">Use Case Example</th><th width="217.9998779296875">Min Value</th><th width="247.99993896484375">Max Value</th></tr></thead><tbody><tr><td><code>byte</code> / <code>uint8</code>*</td><td><p>Small positive integers </p><p>(flags, statuses)</p></td><td><code>0</code></td><td><code>255</code></td></tr><tr><td><code>short</code> / <code>int16</code></td><td><p>Small integers </p><p>(e.g. config codes)</p></td><td><code>-32,768</code></td><td><code>32,767</code></td></tr><tr><td><code>unsigned int</code> / <code>uint32</code></td><td>Non-negative integers</td><td><code>0</code></td><td><code>4,294,967,295</code></td></tr><tr><td><code>int</code></td><td></td><td><code>-2,147,483,648</code></td><td><code>2,147,483,647</code></td></tr><tr><td><code>double</code></td><td>Where decimals are needed</td><td><p><code>±4.9e-324</code> </p><p></p><p>(smallest pos)</p></td><td><p><code>±1.7976931348623157e308</code><br><br>(ca. 1.797 sextillion × 10³⁰⁸, </p><p>an enormous number)</p></td></tr><tr><td><p><code>Number</code></p><p>(JavaScript)</p></td><td>Wherever this tech is used</td><td><p><code>-9,007,199,254,740,991</code></p><p>See <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MIN_SAFE_INTEGER">MIN_SAFE_INTEGER</a></p></td><td><p><code>9,007,199,254,740,991</code></p><p>See <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER">MAX_SAFE_INTEGER</a></p></td></tr></tbody></table>

<mark style="color:$info;">\*"u" stands for "unsigned". Numbers may be unsigned (only 0 or greater), or signed (both negative and positive).</mark>

{% hint style="info" %}
Learn the technology stack of your SUT and test accordingly.
{% endhint %}

### EP & BVA for non-number inputs

Boundaries and partitions apply to more than just numbers. Test what is relevant to your context.

This table focuses on boundaries; it is not an exhaustive list of possible or useful test values.

<table><thead><tr><th width="319.3636474609375">Type</th><th width="426.727294921875">Example</th></tr></thead><tbody><tr><td><strong>Time</strong></td><td></td></tr><tr><td>Start / end of second / minute / hour</td><td>00:00 - 00:59</td></tr><tr><td>Midnight or noon</td><td>00:00:00, 12:00:00 </td></tr><tr><td><strong>Dates</strong></td><td></td></tr><tr><td>Start / end of day, month, year, etc.</td><td><br>Jan 1, Dec 31, Feb 29 in leap years</td></tr><tr><td>Always invalid days (invalid partitions)</td><td> Feb 29 in non-leap years, Feb 30, Apr 31</td></tr><tr><td>Daylight Savings Time (DST) Transitions</td><td>1) DST rules vary by country<br>2) Days vary by year<br>3) Some countries abolished DST</td></tr><tr><td>1 Jan 1970 (<a href="https://en.wikipedia.org/wiki/Unix_time">Unix Time</a>)</td><td><p>For example, JavaScript counts negative milliseconds for dates earlier than Unix time.<br><br><code>const date = new Date('1969-12-31T23:59:59Z');</code><br><code>console.log(date.getTime());</code> </p><p><code>// -1000 (negative milliseconds)</code></p></td></tr><tr><td><strong>Strings</strong></td><td></td></tr><tr><td>Invalid String or Character</td><td>Any of:<br>1) Empty string<br>2) Whitespace only<br>3) Outside Min / Max length <br>4) Accented chars (àáâãçèéìíîðö, etc.)<br>5) Special chars (( “ ‘ ` | / \ , ; : &#x26; &#x3C; > ^ * ?, etc.)<br>6) <code>255</code> or <code>260</code> - max file name length and max full <a href="https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation">file path length</a> in some Operating Systems.</td></tr></tbody></table>

### EP for things other than inputs

Most resources on software testing limit the concept of EP to inputs (mostly numbers, sometimes strings, dates, and others). But EP is about **grouping things with similar behavior** - whether that’s inputs, states, configurations, or outputs - and testing a representative from each group. It’s a **prioritization** and **risk-based** technique, not limited to raw input fields.\
\
Depending on your context and needs, you may apply EP to:<br>

**1. Outputs / Results**

* Group expected outputs into equivalence classes.
* Example 1: For a payment system, outputs might be:
  * `"Success"`, `"Insufficient funds"`, `"Invalid card"`, etc.

**2. System States**

* For state-based testing, partition based on states.
* Example: Logged in, logged out; account locked, account frozen.

**3. User Roles / Permissions**

* Different roles = different behavior.
* Example: Admin, Editor, Viewer.

**4. Test Environments or App Versions**

* Example 1 (simple - app versions):&#x20;
  * Split the app versions into "oldest supported", "current," and "beta" partitions.
* Example 2 (more advanced - test environments):
  * To test Web App feature X, you might group Google Chrome versions 130-139 as *Partition A*, and versions 140-145 as *Partition B*
  * To test feature Y, a different grouping might make more sense - 135-145 as *Partition A*, and 146-150 as *Partition B*
  * In such cases, traditional BVA ideas like testing *min–*, *min+*, or *max–* may not apply meaningfully.

**5. Timing / Events**

* Before the event, during, after.
* Example: Before a sale, during active discount, after expiration.

[^1]: 1\) Software Testing: A Craftsman’s Approach (Paul C. Jorgensen)

    2\) Software Testing: Techniques, Principles, and Practices (JJ Shen)
