Test Levels (part 1)

In the last two posts, we explained what the Software Development Life Cycle (SDLC) is.

We also got an answer to the question: Why is the SDLC important from the tester’s point of view and what is the role of the tester in it?
We also explained how the SDLC presents itself in the context.

Because this subject is much longer than I thought I decided do divided the post into the two parts.

With that information, we can go to test levels.
What exactly are they?

They are the groups of test activities that we organise and manage together.

Each test level is an instance of the test process.
It consists of activities performed for software at a given level of development.

That means, for instance, is the designation of components, from single components to complete systems (or system of systems – if applicable).

These levels are related to other activities that are performed within the SDLC.

Now we know the definition of test levels.

What are these test levels actually?

I will already explain.
Well, the ISTQB Foundation Level syllabus lists these levels:

  • Component Testing
  • Integration Testing
  • System Testing
  • Acceptance Testing

A suitable test environment is required for every test level.

Let’s take a look at the story.

In a company, we have a team that includes, among others, testers and programmers who deal with software development. At this point, let’s focus on test levels and environments.
Our team executes unit and acceptance tests.
For the environments to be well suited to the work of the team, they must be different for the individual test levels.
In this case, our developers use their own development environment for modular testing during unit testing, while our testers use a production-like environment for acceptance testing.

With this example, I wanted to show you how important it is to choose the right test environment for the test levels.

At this stage, it would be worth discussing the individual test levels.

Let’s start from Unit testing
Unit Testing
Unit Testing

Unit testing (known also as module testing or component testing) focuses on modules that can be tested separately.

Objectives:

  • Risk reduction
  • Verification of whether the functional and non-functional behaviors of the component are designed and specified
  • Building confidence in the component’s quality
  • Finding defects in the component
  • Preventing defects from escaping to higher test levels

In some cases, especially in incremental and iterative development models (e.g., Agile) where code changes, automated component regression tests play a key role in building confidence that changes have not broken existing components.

Typically, we can do the unit testing in isolation from the rest of the system (depending on SDLC and system).

In such a situation we will use mock objects, virtualization of services, plugs, or drivers. Isolation means that we can perform the unit tests in any order, and their result should be the same regardless of the order.

To understand this better, let’s take the following example.

A programmer (let’s say his name is C) needs to execute a unit test of a certain feature.
It carries out tests of modules in isolation with the use of mock objects, thanks to which, even without having any data, it can test the functionality of the code.
At this stage, he is not interested in the communication itself or the interaction of the tested module with the mock object, as communication testing is a task of integration testing.

As we can see from the example above, the executing of test units in isolation is very important.
In this example, we also mentioned the mock objects and, interestingly, we have already explained what they are.
There is one more thing about mock objects.

Mock object example
Mock Object example
Mock objects are divided into two types:
  • Stub (tested module calls stub)
  • Driver (the driver calls the tested module)

Both simulate the work of other objects that do not exist yet.

Test basis (examples of work products, that we can use as a test basis for component testing):

  • Detailed design
  • Code
  • Data model
  • Component specifications

Test objects (typical test objects for component testing):

  • Components, units or modules
  • Code and data structures
  • Classes
  • Database modules

Typical defects and failures (examples of typical defects and failures for component testing):

  • Incorrect functionality (e.g., not as described in design specifications)
  • Data flow problems
  • Incorrect code and logic

Specific approaches and responsibilities:

Unit testing is usually performed by the developer who wrote the code, but it at least requires access to the code being tested. Developers may alternate component development with finding and fixing defects.

Developers will often write and execute tests after having written the code for a component. However, in Agile development especially, writing automated component test cases may precede writing application code.

TDD
TDD

For example, we may consider Test-Driven Development (TDD). Test-driven development is highly iterative and is based on:

  • cycles of developing automated test cases, then
  • building and integrating small pieces of code, next
  • executing the component tests, then
  • correcting any issues
  • re-factoring the code

This process continues until the component has been completely built and all component tests are passing.

While test-driven development originated in eXtreme Programming (XP), it has spread to other forms of Agile and also to sequential lifecycles

Now we know a lot about Unit testing.

So let’s write about Integration Testing
Integration Testing
Integration Testing

Integration testing focuses on interactions between components or systems.

Objectives:

  • Reducing risk
  • Verifying whether the functional and non-functional behaviors of the interfaces are designed and specified
  • Building confidence in the quality of the interfaces
  • Finding defects (which may be in the interfaces themselves or within the components or systems)
  • Preventing defects from escaping to higher test levels

As with component testing, in some cases, automated integration regression tests provide confidence that changes have not broken existing interfaces, components, or systems.

We have two different levels of integration testing described in this syllabus, which may be carried out on test objects of varying size as follows:

Unit integration testing focuses on the interactions and interfaces between integrated components.
Unit integration testing is performed after component testing and is generally automated.
In iterative and incremental development, component integration tests are usually part of the Continuous Integration (CI) process.

Continuous Integration
Continuous Integration
CI is integrating the software the module after module (e.g., functional integration).
System Integration Testing
System Integration Testing

System integration testing focuses on the interactions and interfaces between systems, packages, and microservices.
It can also cover interactions with, and interfaces provided by, external organizations (e.g., web services).
In this case, the developing organization does not control the external interfaces, which can create various challenges for testing (e.g., ensuring that test-blocking defects in the external organization’s code are resolved, arranging for test environments, etc.).
System integration testing may be done after system testing or in parallel with ongoing system test activities (in both sequential development and iterative and incremental development).

Test basis (examples of work products, that we can use as a test basis for component testing):

  • Software and system design
  • Sequence diagrams
  • Interface and communication protocol specifications
  • Use cases
  • Architecture at component or system level
  • Workflows
  • External interface definitions

Test objects (typical test objects for component testing):

  • Subsystems
  • Databases
  • Infrastructure
  • Interfaces
  • APIs
  • Microservices

Typical defects and failures (examples of typical defects and failures for component testing):

  • Incorrect data, missing data, or incorrect data encoding
  • Incorrect sequencing or timing of interface calls
  • Interface mismatch
  • Failures in communication between components
  • Unhandled or improperly handled communication failures between components
  • Incorrect assumptions about the meaning, units, or boundaries of the data being passed between components
Specific approaches and responsibilities:

Unit integration tests and system integration tests should concentrate on the integration itself.

Integration Testing Approaches
Integration Testing Approaches

We can consider the example.

Our team needs to test the specific modules of the system. The module’s names are: A, B, C, D. Module A includes the login feature of the application. B has the searching feature. Module C contains the subscribing feature. D has the menu feature. Our team uses the most important tasks based strategy.

As we can see from this example, it’s really important to choose a good integration test strategy to get the testing process easier.

Unit integration testing is often the responsibility of developers. System integration testing is generally the responsibility of testers. Ideally, testers performing system integration testing should understand the system architecture and should have influenced integration planning.

If we plan integration tests and the integration strategy before components or systems are built, we can build those components or systems in the order required for the most efficient testing.

Systematic integration strategies may be based on the system architecture (e.g., top-down and bottom-up), functional tasks, transaction processing sequences, or some other aspect of the system or components.

In order to simplify defect isolation and detect defects early, integration should normally be incremental.

Big bang integration is the method, which integrating all components or systems in one single step.
Risk Analysis
Risk Analysis

A risk analysis of the most complex interfaces can help to focus the integration testing.

We know a lot about the unit testing and integration testing.

I hope you enjoyed the reading and saw some useful information about Unit Testing and Integration Testing in this article.
The second part of the Test levels post about the System Testing and Acceptance Testing will arrive the next week, on Friday 🙂

The part content of this post was based on ISTQB FL Syllabus (v. 2018).

Graphics with hyperlinks used in this post have a different source, the full URL included in hyperlinks.

Leave a Reply

Your email address will not be published. Required fields are marked *