Integration testing. Chapter 8

In the beginning everything was going smooth. But when I started reading Chapter 8, I’d been a bit confused about Integration testing. What is Integration testing actually?

In the example you tested a viewmodel (which should be unit tested according to google docs) as an integration test. You acknowledged that. But I think you didn’t give a concrete example.

I am stuck in this topic. What is Integration test actually? What is the difference beetwen UI test and Integration test? Can you please answer to my questions?

Note:
I read statements like this:
‘Integration testing also is a type of software testing in which the different units, modules or components of a software application are tested as a combined entity’

I need a concrete example in Android Development rather than general concept.

Hi @xudoyshukur,
I can tag the author to respond to this query, but here is my attempt at the same.

When you write code, say a function add, that adds two numbers and returns the result. You write a test to test so when you call the function add(1, 3) you expect it to return 4. That is the unit test that you will write. Then say you write another function that subtracts two numbers and then you write a unit test for that too. However when you put them all together in a calculator app, you want to make sure that they all work together because no one is going to use your function (unit) in isolation. It may be called from a UI or from another function. The Integration tests are basically the collective test of all these together to see how they work when used together.

The difference between UI Tests and Integration tests is all about how you test it. So you may have a viewModel that calls these functions based on the operations which is your integration test (which may or may not have an UI) then you could also write a UI test that taps the number 1, then taps a + then the number 3 and finally the + to show the result, this is the UI test and this is to test if there are any issues with the UI, a button being disabled or exhibiting a different behaviour or no code/function assigned to the button.

Hope that helps you clarify your question,

Cheers,

Jayant

1 Like

Let’s say we have:

class Adder {
    fun add(a: Int, b: Int): Int {
        return a + b
    }
}
class Subtractor {
    fun subtract(a: Int, b: Int): Int {
        return a - b
    }
}

Let’s assume that we unit tested these classes separately.


Then we have calculator class:

class Calculator(
    private val adder: Adder,
    private val subtractor: Subtractor,
    ....
) {

   ...
   fun add(a: Int, b: Int): Int {
       return adder.add(a, b)
   }

   fun subtract(a: Int, b: Int): Int {
       return subtractor.add(a, b)
   }
   ...
}

So, when we are testing we can pass mock dependencies for Calculator class.
From your view point:

When we are testing ViewModel (Usually viewmodel depends on domain layer interactor classes) we can mock use case classes and unit test that viewmodel.

So where is the example of integration testing?

Hi @xudoyshukur ,
If you are after a very specific example from real world applications, then the integration is slightly larger in scope, the example I had provided was for you to get a concept. I do not write Java or Kotlin code, so I will not even attempt to write classes and code to illustrate that here. However, lets say you are working on the Secure Calculator that needs to first get you to login which is another module and then uses another module that would either print the results of the calculator onto a printer or a PDF. Your unit tests is only testing the add and the subtract units/functions but what happens when you put them together, do they all work in unison, what are the things that work/don’t work that is the aim of Integration tests.

I am looping in the authors to take this on for the specific code examples if this is still unclear
@fernandospr , @vgonda , @lgleason

cheers,

Jayant

Hi @xudoyshukur thanks for your question!

Unit Tests normally focus on a single class, therefore you need a way to avoid using their actual collaborators (dependencies). Otherwise, you’d be doing integration testing.

In Chapter 7, you’ll find how to mock those collaborators by learning about Mockito.
In the same chapter, you’ll also find that due to a refactoring you did (created the Score class dependency) some previously written unit tests have now been converted to integration tests. You’ll see how to refactor those tests back to the “unit” level, by removing tests from GameUnitTests.kt and creating ScoreUnitTests.kt.

Other concrete example, let’s say you have the following classes:

interface Engine {
   fun isWorking(): Boolean
}

class WorkingEngine: Engine {
   override fun isWorking(): Boolean {
      return true
   }
}

class Car(val engine: Engine) {
   private var speed = 0

   fun speedUp(): Int {
      if (engine.isWorking()) {
         speed = speed + 10
      }
      return speed
   }
}

You could create the following test:

@Test
fun `Speeding up when engine is working should increment speed`() {
   val engine = mock<Engine>()
   whenever(engine.isWorking()).thenReturn(true)
   val car = Car(engine)
   
   val speed = car.speedUp()

   Assert.assertTrue(speed > 0)
}

But you could also create the following test:

@Test
fun `Speeding up when engine is working should increment speed`() {
   val engine = WorkingEngine()
   val car = Car(engine)
   
   val speed = car.speedUp()

   Assert.assertTrue(speed > 0)
}

Both cases are valid tests.

  • The first one is a unit test, because you isolate the Car by mocking the Engine dependency, allowing you to control how the Engine should respond.
  • The second one is an integration test because you’re instantiating a real WorkingEngine and providing it as a dependency for the Car. Here, you’re not isolating the Car, you don’t have control over the dependency, you’re using real instances making them work together, therefore it’s an integration test.

I hope this clarifies, otherwise let us know!

Regards.

@jayantvarma, @fernandospr. Thank you all. I have understood the integration testing. Thank you for all examples you provided.