Skadoosh
Skadoosh

Reputation: 2623

What qualifies as a unit test & what qualifies as a functional/integration test?

I am a bit confused on what the limits are for a unit tests and integration/functional tests? Are there any definite boundaries between these?

Let me start with a scenario ....

If I have a set of classes that perform a process. Each processes comprises have a few tasks.

ProcessA {
   var a = do TaskA;
   var c = do TaskC;
   var b = do TaskB;
}

ProcessB {
   var c = do TaskC;
   var d = do TaskD;
}

ProcessC {
   var a = do TaskA;
   var d = do TaskD;
}

If we take the above design, then I can write unit tests to test out each of the Tasks to make sure that they do what they are supposed to. I am cool with that.

My problem arises with the fact that I would like write unit test, or I think they would be unit tests, for all the Processes. I want to make sure that the tasks are in the proper order, and the business rules are correct within the process itself.

The definition of a unit test is that unit tests test out a bite size chunk of the code. What I am trying to test out is a larger, 'ProcessA', 'ProcessB', code. In those tests, I will still be decoupling from the datastore & services. Would that still be considered a unit test or integration/functional test?

UPDATE

Based on all the comments, I guess the proper question to ask is that if all the external dependencies are mocked in 'ProcessA', 'ProcessB', etc. classes, would a unit test for those classes be considered a unit test or a integration test?

And thanks for being patient with me ....

Upvotes: 0

Views: 146

Answers (3)

Robert H
Robert H

Reputation: 11730

As soon as you said I want to make sure that the tasks are in the proper order, and the business rules are correct within the process itself. you stopped talking about unit tests and began talking about integration tests.

Even though you are decoupling from the datastore and services you are testing busines rules. If your organization is anything like mine, business rules can (and often do) change. It is this volatile nature that makes it an integration test.

The base rule I've used is "unit tests are modular, independent pieces of code not dependant upon external data sources. whereas integration tests are tests that require the use of external data sources, either mocked up or from production."

The art of Unit Testing, second edition lists Integration tests with the following definition:

I consider integration tests as any tests that aren’t fast and consistent and that use one or more real dependencies of the units under test. For example, if the test uses the real system time, the real filesystem, or a real database, it has stepped into the realm of integration testing.

and unit tests with the following (emphasis mine):

A unit test is an automated piece of code that invokes the unit of work being tested, and then checks some assumptions about a single end result of that unit. A unit test is almost always written using a unit testing framework. It can be written easily and runs quickly. It’s trustworthy, readable, and maintainable. It’s consistent in its results as long as production code hasn't changed.

Based upon the same book as above. A unit test :

  • Is an automated piece of code that invokes a different method and then checks some assumptions on the logical behaviour of that method or class.
    • This is true if you can reduce ProcessA/B/C into small chunks that can be tested independently of one another.
  • can be executed repeatedly by anyone on the development team.
    • If someone from your team requires values or a cheat sheet to refer to determine if the test passes or not, it is not a unit test.

Now based upon your edit it depends. Integration tests and unit tests can overlap and many other developers may have different ideas on to how they would label the tests.

The answer to your question is to determine the best practice for you and your development team. If the consensus it's a unit test, then consider it as such.

Unit and integration tests should help the process, not hinder it. Please don't let semantics get in the way of that.

Upvotes: 2

Grzenio
Grzenio

Reputation: 36649

I would say that a unit test is a test that tests one class only (a unit), whereas integration tests test the integration of multiple classes/assemblies and/or even external data sources. Functional tests should explicitly test the functionality exposed to the users (which may be internal users, outside of the dev team etc.)

EDIT: The only way to implement unit tests for composite classes is to use dependency injection. This means that you should define an interface (possibly more than one), e.g.:

interface ITask
{
  Perform();
}

and inject it into your Process classes:

class ProcessC
{
  ITask taskA;
  ITask taskD;
  ProcessA(ITask taskA, ITask taskD)
  {
    this.taskA = taskA;
    this.taskD = taskD;
  }

  void Run() //change to your real methods
  {
    taskA.Perform(); //capture results
    taskD.Perform();
  }
}

Now you can mock the injected interface ITask (using a mocking framework), so that you can isolate the behaviour of a process from the behaviour of the tasks.

Upvotes: 1

T McKeown
T McKeown

Reputation: 12847

Setting aside tools etc... Unit test is simply testing a specific piece of code and would typically be performed by the programmer.

Functional and Integration are typically performed by QA team:

Functional Testing is testing if the code does what it was intended to do.

Integration Testing is about testing code and measuring how it interacts with other modules/parts of the system.

Upvotes: 1

Related Questions