# Techniques Used in Integration Testing

## Types of Integration Testing

## 💥 Big Bang Integration Testing

**💡 Idea:** Integrate and test all modules together at one go in one big bang.

**📦 Process:**

* Take all modules/components and integrate them into the software build
* Validate that all modules connect and function together as expected
* Test interfaces between modules by performing end-to-end tests on the entire system

**👍 Use When:**

* The application is small or has few modules
* Modules have low interdependency
* Quick validation is needed with minimal debugging

**❗Considerations:**

* Difficult to isolate defects to a module
* Not suitable for complex systems
* Hard to test incrementally

## 🔼 Top Down Integration Testing

**💡 Idea:** Begin integration from top level modules and progressively add lower level modules

**📦 Process:**

* Start integrating from high level modules to low level modules
* Test the functionality of top level modules first
* Add lower level modules one by one and test integration
* Follow the sequence of module dependencies top to bottom

**👍 Use When:**

* High level logic and structure needs to be tested first
* Top modules are critical functionality
* Low level modules can be tested more easily later

**❗Considerations:**

* Lower level defects may be missed initially
* Stubs/drivers may be needed to test top level independent of low level

## ⬇️ Bottom Up Integration Testing

**💡 Idea:** Begin integration from lowest level modules and progress upwards to higher level modules

**📦 Process:**

* Start integrating from low level modules to high level modules
* Test the functionality of bottom modules first
* Progressively add higher level modules on top and test integration
* Follow the sequence of module dependencies bottom up

**👍 Use When:**

* Lower modules are reusable components
* High level modules are dependent on low level interfaces
* Critical low level components need to be tested first

**❗Considerations:**

* May not find defects in high level logic initially
* Low level functionality may need stubs/drivers for initial testing

## 💼 Risk Based Integration Testing

**💡 Idea:** Identify and test high risk modules and interfaces first based on priority

**📦 Process:**

* Analyze the modules and interfaces to identify high risk areas
* Prioritize testing for modules that are complex, frequently used, mission critical etc.
* Start integration testing from highest risk areas first
* Progressively move to lower risk modules and interfaces

**👍 Use When:**

* Modules have varying levels of risk, complexity or usage
* Testing priority needs to be given based on risk
* Resources are limited and critical areas need focus first

**❗Considerations:**

* Dependent modules may still need testing for defects to be found
* Understanding integration risks is important

## 💽 Stub

**💡 Definition:** A dummy module that simulates the intended behavior of an actual module

**📦 Usage:**

* Used when the actual module is unavailable or unfinished
* Allows testing even if dependencies do not exist
* Mimics how a real module would function
* Helps isolate code under test from external dependencies

**Example:**

```
// Actual module
class PaymentGateway {
  chargeCreditCard(amount) {
    // charge credit card  
  }
}

// Stub module  
class PaymentGatewayStub {
  chargeCreditCard(amount) {
    return true; 
  }
}

// In test class
let gateway = new PaymentGatewayStub();
// Can test even if actual gateway unavailable
```

## 🚘 Driver

**💡 Definition:** A module that invokes functionality of another module being tested

**📦 Usage:**

* Drives the code in another module by invoking it
* Allows testing modules in isolation
* Removes the need to rely on external sources of input
* Often used along with stubs to test

**Example:**

```
// Driver
class UserInputDriver {

  simulateInput() {
    // Can send simulated input    
  }

}

// Class under test
class UserInput {
  
  getInput() {
    // Reads input from driver
  }
  
}

// In test class
let driver = new UserInputDriver();
let input = new UserInput();

// Drive input
driver.simulateInput(); 
```

## 🎭 Mock Object

**💡 Definition:** An object that simulates real objects to test interactions and outputs

**📦 Usage:**

* Used for testing by mimicking real dependencies
* Allow control over test environment
* Can inject behavior needed to exercise specific paths
* Track interactions like method calls during test

**Example:**

```
// Mock object
let mockDB = MockDatabase();

// Class under test
class UserManager {
  constructor(db) {
    this.db = db;
  }
  
  getUser(userId) {
    return this.db.query("SELECT * FROM users WHERE id = " + userId);
  }
}  

// In test
let manager = new UserManager(mockDB);

// Test query interaction
manager.getUser(1);
assert(mockDB.verifyQueryCalled());
```
