Key to Successful Unit Testing – How Developers Test Their Own Code?

Black Box testers don’t care about Unit Testing. Their main goal is to validate the application against the requirements without going into the implementation details.

But as a curious or out of the box thinking, have you ever wondered how developers test their code? What method do they use to test before releasing the code for testing? How is dev-testing important in an agile process?

The answer to all this is Unit Testing. I want to educate you on the importance of Unit Testing so that development and testing teams can work more collaboratively to design, test and release an excellent application.

Who knows, in the future some of you may even switch to white box testing and use these code validation and improvement techniques!

Unit Testing

What is Unit Testing?

Unit Testing is not a new concept. It’s been there since the early days of programming. Usually, developers and sometimes white box testers write Unit tests to improve code quality by verifying every unit of the code used to implement functional requirements (aka test driven development TDD or test-first development).

Most of us might know the classic definition – “Unit Testing is the method of verifying the smallest piece of testable code against its purpose.” If the purpose or requirement fails then the unit test has failed.

In simple words, it means – writing a piece of code (unit test) to verify the code (unit) written for implementing requirements.

Unit Testing in SDLC

Unit Testing in SDLC

For Unit testing, developers use manual or automated tests to ensure that each unit in the software meets the customer’s requirement. This unit can be an individual function, object, method, procedure, or module in the software under test.

Writing unit tests to test the individual units makes writing comprehensive tests easier as all the units are put together. During software development, it is done as the first level of testing.

Importance of Writing Unit Tests

Unit Testing is used to design robust software components that help maintain code and eliminate issues in code units. We all know the importance of finding and fixing defects in the early stages of the software development cycle. This testing serves the same purpose.

It is an integral part of the agile software development process. When a nightly build is run the unit test suite should run and a report should be generated. If any of the unit tests have failed then the QA team should not accept that build for verification.

If we set this as a standard process, many defects would be caught in the early development cycle, thereby saving much testing time.

I know many developers hate to write unit tests. They either ignore or write bad unit test cases due to tight scheduled or lack of seriousness (yea they write empty unit tests, so 100% of them pass successfully ;-)). It’s important to write good unit tests or not write them at all. It’s even more important to provide sufficient time and a supportive environment for real benefits.

Unit Testing Methods

It can be performed in 2 ways :

  1. Manual Testing
  2. Automated Testing

In Manual Testing, the tester manually executes test cases without using any automation tool. Here, each stage of the test is executed manually. Manual Testing is tedious especially for tests that are repetitive and requires more effort to create and execute test cases. Manual Testing does not require knowledge of any testing tool.

It is a fact that 100% of Automation is not possible and thus there will always be some level of manual testing performed.

In Automated Testing, software testing automation tools are used to automate test/test cases. The automation tool can record and save your test and it can be re-played as many times as needed without any further human intervention.

These tools can even enter test data into the system being tested as well as it can compare the expected results to the actual results and automatically generate the reports. However, the initial cost of setting up test automation tools is high.

Techniques Within Unit Testing

#1) White Box Testing:

In white-box testing, the tester knows the internal structure of the software including the code and can test it against the design and requirements. Hence, white box testing is also known as transparent testing.

white box testing

#2) Black Box Testing:

In black-box testing, the tester does not know the internal structures or either the code of the software.

black box testing

#3) Grey Box Testing:

This is also referred to as semi-transparent technique testing which means the testers are only partially aware of the internal structure, functions, and designs along with the requirements.

Debugging is done by actual input from the front-end to get exact data from the back-end. The grey box is therefore considered a combination of black box and white box testing techniques.

Grey box testing

Grey box testing covers the following types of testing:

  • Matrix Testing.
  • Pattern Testing.
  • Orthogonal Pattern Testing.
  • Regression Testing.

Benefits of Unit Testing

  1. The process becomes agile: To add new functions or features to the existing software, we need to make changes to the old code. But changing things to the already tested code can be risky as well as costly.
  2. Code quality improves: The quality of the code is automatically improved when unit testing is done. The bugs identified during this testing are fixed before they are sent for the integration testing phase. Results in robust design and development as developers write test cases by understanding the specifications first.
  3. Detects bugs early: As developers run unit tests, they detect bugs early in the software development life cycle and resolve them. This includes flaws or missing parts in the specification as well as bugs in the programmer’s implementation.
  4. Easier changes and simplified integrations: Doing unit testing makes it easy for the developer to restructure the code, make changes, and maintain the code. It also makes testing the code after integration much easier. Fixing an issue in Unit Testing can fix many other issues occurring in later development and testing stages
  5. Documentation availability: Developers who are looking into the functionality at a later stage can refer to the unit testing documentation and can easily find the unit test interface and correct or work fast and easily.
  6. Easy debugging process: It helps in simplifying the debugging process. If the test fails at any stage the code needs to be debugged or else the process can be continued without any obstacles.
  7. Lower cost: When bugs are detected and resolved during unit testing, cost and development time is reduced. Without this testing, if the same bugs are detected at a later stage after the code integration, it becomes more difficult to trace and resolve, making it more costly and increasing development time.
  8. Code completeness can be demonstrated using unit tests: This is more useful in the agile process. Testers don’t get functional builds to test until integration is completed. Code completion cannot be justified by showing that you have written and checked the code. However, running Unit tests can demonstrate code completeness.
  9. Save development time: Code completion may take longer but due to fewer bugs in the System and Acceptance testing, overall development time can be saved.
  10. Code coverage can be measured.

Unit Testing Cycle

Unit testing cycle

[image source]

What Makes a Good Unit Test?

Well, I’m not the right person to tell what makes a good Unit Test, but based on my observations on various projects I can tell the characteristics of a good Unit Test. Bad Unit Tests do not add value to the project. Instead, project costs increase significantly by writing and managing bad Unit Tests.

How to write good Unit Tests?

  • Unit tests should be written to verify a single unit of code and not the integration.
  • Small and isolated Unit tests with clear naming would make it very easy to write and maintain.
  • Changing to another part of the software should not affect the Unit test if those are isolated and written for a specific unit of code.
  • It should run quickly.
  • Unit test should be reusable.

Unit Testing Frameworks

Unit Testing frameworks are mostly used to help write unit tests quickly and easily. Most programming languages do not support unit testing with an inbuilt compiler. Third-party open source and commercial tools can be used to make unit testing even more fun.

List of popular Unit Testing tools for different programming languages:

  1. Java framework – JUnit
  2. PHP framework – PHPUnit
  3. C++ frameworks – UnitTest++ and Google C++
  4. .NET framework – NUnit
  5. Python framework – py.test

Misconceptions and Truths

  • It takes more time to write code with Unit test cases, and we don’t have time for that – In reality, it would save your development time in the long run.
  • Unit testing will find all bugs – It won’t, as the intent of the Unit test is not to find bugs but to develop robust software components that will have fewer defects in the later stages of SDLC.
  • 100% code coverage means 100% test coverage – This does not guarantee that the code is error-free.

How to Accept Unit Testing?

Good unit testing can be carried out in 3 basic parts.

  1. Write a unit test code.
  2. Run the unit test code to see if it meets the system requirements.
  3. Execute the software code to test for any defects and see whether the code meets the system requirements.

After undertaking the above 3 steps, if the code appears to be correct then the unit test is said to be passed. If it does not meet the system requirements, then the test fails. In this case, the developer needs to recheck and correct the code.

In some instances, it is necessary to separate the code to perform this testing more accurately.

Best Practice

To create the best code during this testing, consider the following points:

  • Code should be strong: There are instances where the test fails or in worst cases does not get executed at all if the code is broken.
  • Understandable and reasonable: The code should be easy to understand. This makes it easy for the developer to write the code and even other developers who will work on the code subsequently will find it easy to debug.
  • Should be a single case: Tests that define multiple cases in one are complex to work with. Thus, writing a single case code is a best practice, which makes the code easier to understand and debug.
  • Allow automated tests: The developers should make sure that the test runs in an automated form. It should be in a continuous delivery or integration process.

Other points to be kept in mind are as follows:

  • Instead of creating test cases for all the conditions, focus on the test that affects the behavior of the system.
  • There are chances of a bug recurrence due to the browser’s cache.
  • Test cases should not be interdependent.
  • Pay attention to the loop condition also.
  • Plan test cases more frequently.

Conclusion

Unit testing comes into picture when it is required to test every function separately. It is much more reasonable to detect and fix bugs during this testing and save time & cost, rather than finding them at the later stage of software development.

While it offers many advantages, there are also limitations involved with using it. Rigorous discipline and consistency are required throughout the software development process to overcome limitations and get the intended benefits.

Further Reading =>> Devmate Software for Automated Unit Test generation

Your Comments are most welcome!
As a black box tester, what are your observations about Unit Testing on your team? Does anyone have a better idea for successful Unit Testing?

Related Post

One Reply to “Key to Successful Unit Testing – How Developers Test Their Own Code?”

Leave a Reply

Your email address will not be published.