Android Unit Testing 101: Basics

ibrahimcanerdogan
7 min readNov 16, 2022

--

Photo by Gunnar Ridderström on Unsplash

Unit testing is testing units in the software project being worked on. What is done is simply to check if the class behaviors (methods) work correctly when certain inputs are provided and produce the result we want. In this way, the units are tested internally and confirmed to work correctly.
That is, unit testing is a software testing method in which individual units of source code are tested to determine whether they are fit for use.
The goal is to verify that every unit of software code works as expected. Unit tests isolate a section of code and verify its correctness. It is intended to show that the individual parts are correct by isolating each part of the program.
The test scenario needs to be created independently from the project. For this, so-called “mock” objects will be used.

It is not possible to find faults in a software system with unit tests alone. Because a software system is more than the sum of its parts. The smooth running of unit tests does not mean that users can use your application without any problems.

What are the Software Testing Process Stages?

The software testing process does not have strictly defined lines unless a certain methodology is followed. For example, when the desired improvements are made in the project, unit tests can be made for these developments. Stages can also be performed at different times or at different steps in this context.
A standard testing process includes the following steps.

  1. Planning the test
  2. Test design
  3. Performing the test
  4. Error reporting
  5. Creating and sharing test result reports

Why Unit Testing?

  • It helps fix bugs even before the development phase begins.
  • It helps the operation to be carried out according to the “completeness” rule and accordingly reduces the development cost.
  • It allows developers to understand the development process in more detail so they can make the right changes quickly.
  • It can be considered as project documentation.

What are the Basic Testing Principles?

  1. Tests show the presence of bugs: Tests can show that bugs are found, but cannot prove that bugs are not.
  2. 100% testing is not possible: Relationship with other methods cannot be tested because the condition in unit tests is tested. Since an isolated environment is provided, other tests such as integration tests are also needed.
  3. Early testing is needed: Testing early in the software development lifecycle will reduce cost.
  4. Error rate: Errors in software are concentrated in areas close to each other. 80% of bugs cover 20% of all software
  5. The pesticide paradox (Antibiotic resistance): Test scenarios need to be updated and revised periodically. A suitable software development method should be applied.
    Testing differs in context: Testing can be done differently in different contexts.
  6. Perception of inaccuracy: Correcting the errors detected in the test does not mean that it fully meets the needs of the user. So unit testing is important for functions, but not all.

What are the Unit Testing Advantages?

Photo by Klara Kulikova on Unsplash
  • The biggest advantage of unit tests is actually a written contract with strict rules that pieces of code must meet. In this way, the purpose of the units is drawn in a definite way. Thus, programming can be done in accordance with software principles such as single-responsibility.
  • As with the TDD methodology, unit tests actually find problems early in the development cycle. Detecting errors in the early stages of coding will provide advantages to the software developer in terms of workload and cost, and most importantly, it will prevent the error costs that will increase in this process that goes all the way to the end user.

When the developer refactors their code or updates the version of the project dependencies, they can use unit tests to ensure that the modules still work correctly. Thus, when a change causes an error, the error can be quickly tested.

  • It helps to reduce the uncertainty within the units themselves. Their purpose is to write more specific and pre-planned codes.
  • Unit testing provides a kind of live documentation of the system. Developers who want to learn what functionality is provided by a unit and how to use it can look at unit tests to gain a basic understanding of the unit’s interface.
  • Unit test cases contain features that are critical to the success of the unit. These features may indicate appropriate/inappropriate use of a unit as well as negative behavior that will be trapped by the unit. While most software development environments do not rely solely on code to document the product in development, a unit test case documents these critical features in itself.

What are the Difficulties of Unit Tests?

Photo by Steve Johnson on Unsplash
  • Unit testing should be done in conjunction with other software testing. Because the tests can only show the presence or absence of certain errors; they cannot prove the complete absence of errors. To ensure correct behavior for every execution path and every possible input and to ensure that there are no errors, regression tests or broader system-level tests are required to prove that a software component does not have unexpected behavior.
  • Software testing is an integrative problem. For example, a “Boolean” function needs to be tested for both true/false options. In such cases, programmers usually need 3 to 5 lines of test code for every line of code written. This obviously takes time and the investment may not be worth the effort. Also, it is not easy to test conditions that are not deterministic or contain more than one component.

A unit test code is just as likely to be buggy as the code it tests.

  • Another challenge with writing unit tests is the challenge of creating realistic and useful tests. In order for the part of the application being tested to act as part of the whole system, the corresponding initial conditions must be established. If these initial conditions are not set correctly, the test will not use the code in a realistic context, which reduces the value and accuracy of the unit test results.
  • It is also important to implement a sustainable process to ensure that test case bugs are regularly reviewed and addressed. If such a process is not implemented and not included in the team’s workflow, the application will evolve out of sync with the unit test suite, increasing bugs and reducing the effectiveness of the test suite.
  • Unit tests tend to be easiest when a method has input parameters and some output. Creating unit tests is not so easy when the main function of the method is to interact with something outside the application. For example, a method to work with a database may require building a model of database interactions, which will probably not be as comprehensive as actual database interactions.

Unit Test Development Advice

Photo by Steve Johnson on Unsplash
  • Unit Test cases must be independent. In case of any enhancements or changes to the requirements, the unit test cases should not be affected. In order to achieve this, it is necessary to develop in accordance with the “single-responsibility” principle.
  • Test only one condition at a time. A function can return multiple outputs or results. In this case, it should be noticed that there is an error when using more than one “assert” in the same test. For example, the “if” block and then the “else” block can be tested with different unit tests.
  • Follow clear and consistent naming conventions for your unit tests. The company you are in may have established naming standards within itself. However, apart from this, a person who writes a test should refer to “what he tests” and “under what conditions he tests” in the nomenclature he gives.
  • In case of a change in the code contained in any of its units, it should be ensured that there is a corresponding “test” for the function and that the function passes the tests before making the necessary improvements. In this way, safe developments can be made.
  • Errors detected during unit testing should be fixed before proceeding to the next stage in SDLC (Systems Development Life Cycle). Thus, it will be ensured that the additional cost of development in the future stages will be avoided.
  • The more code you write without testing, the more time you have to spend checking for errors. Therefore, following a test-driven development path such as “TDD” will prevent errors and increase software quality.

Unit Test Sample Practice

Photo by Steve Johnson on Unsplash

The interface named Total has a function named “add” that takes two different values.

interface Total { 
int add(int a, int b);
}

When the Interface class is implemented by the “TotalImpl” class, the “add” function in it is called. Performing an aggregation operation within the function.

class TotalImpl implements Total {

public int add(int x, int y) {
return x + y;
}

}

The test class given below tests the “add” function using JUnit against the expected output over certain inputs. By calling the Total class within the test functions, the mock operation is actually performed at a basic level. After this operation, the “add” function is called.

Another point to be noted is the naming. The word “control” has been added to the naming by me, but it is not mandatory. The naming is followed by the name “tested function”. Then, “tested input condition” was added to the naming and test function naming was completed. This way you can create your naming standard.


import static org.junit.Assert.assertEquals
import org.junit.Test;


public class TotalTest {


@Test
public void controlAddForTwoPositiveNumbers() {
Total total = new TotalImpl();
assertEquals(2, total.add(1, 1));
}

@Test
public void controlAddForTwoNegativeNumbers() {
Total total = new TotalImpl();
assertEquals(-5, total.add(-2, -3));
}
}

Thank You

IBRAHIM CAN ERDOGAN

Linkedin: https://www.linkedin.com/in/ibrahimcanerdogan/

--

--

ibrahimcanerdogan
ibrahimcanerdogan

Written by ibrahimcanerdogan

Hi, My name is Ibrahim, I am developing ebebek android app within Ebebek. I publish various articles in the field of programming and self-improvement.

No responses yet