On Testing — Part 1

Deniz Bilgin
heycar
Published in
5 min readDec 15, 2021
Photo by Testalize.me on Unsplash

Testing a software is as important as creating it, if not more. If used efficiently, tests can save teams so much time and effort, in addition to providing a stable software. In this article, I will be mentioning test types and styles, their upsides and downsides, as well as how they are generally used.

TDD (Test-Driven Development)

When you want to implement a new feature, you first write a test that would describe this feature which would just fail initially. Then you would write the code for the feature in the simplest way it can make this test pass and finally you refactor the existing code, replace the duplications and clean everything up. This is called red-green-refactor and it is the basis of TDD.

With TDD, the application should already be tested before the development process finishes, which allows you to build a sturdy base. Since the test cases cover everything and you are already testing all the small bits of the application, meaning the units, this is a very healthy approach to take while testing and a good way to make sure you have all the necessary unit tests in place.

BDD (Behavior-Driven Development)

Just like TDD, BDD also carries the test-first principle. The main differences of BDD are the requirement for communication and the integration tests that are usually hand-in-hand with BDD.

The requirement for communication is there, because rather than unit tests BDD requires integration tests. Just like the name suggests, it tests the behavior of the application. The aim here is to make sure the user actually has the desired experience. The exact desired experience isn’t always something a developer can decide on their own, which brings in others like the product manager into the whole thing. The scenarios that need to be tested, should be discussed and decided together with other stakeholders while planning the feature, so that the developer can ensure that their test is actually what is needed.

One of the biggest bonuses that integration testing brings over unit testing is testing with the dynamic data. Generally with integration tests, the data or APIs can be mocked in a way that it can imitate the user behavior, which can create an environment very similar to what the end-user sees in production.

As both of these approaches have a test-first philosophy, I do not believe that this is necessarily for everyone. Keep in mind that not doing test-first development doesn’t mean not testing properly. It comes down to a choice, as long as the tests are written properly. However much safer it seems with test-first, it still completely depends on the person to write the tests properly.

The test-first approach certainly brings focus into the development process and very rarely results in missing test cases. The developer needs to consider all the conditions and possibilities that their code may bring before writing it. A downside could be considered to be restrictive for explorative development. Unless an extremely straightforward and simple feature is being developed, it is not that possible to write down the specs of what will be developed fully, which already leaves an open door. Restricting an implementation to a test may actually stop the developer from being able to think outside the box for a solution to a complicated task.

As I mentioned earlier, in my opinion this part comes down to the team’s preference, but test-first is widely considered a better practice.

On Unit Testing

Unit testing handles the testing of individual units. A unit is the smallest testable part of an application and several of such units can create integrations that can also be tested in a different way.

The goal of a unit test is to isolate the smallest part of an application and test it so that they all are certain to work well. Unit tests can create rules for how the application and its parts work, which can stop you from implementing something that would crash the application unintentionally.

Another good way to look at the advantages of this is, if the code piece you are checking out has some uncertainty and you are not sure what it is supposed to do, you can check the well-written unit test for it and understand the possible outcomes. This can also be considered as a small documentation on the codebase for the developers.

The main downside of unit tests is that they cannot catch every error, since they only focus on one unit and in no way a combination of units, this gives an opening for integration errors.

You should also always consider if a unit test you are writing is realistic and useful, writing useless tests that don’t really test anything will just add on top of all the other tests.

White-Box

This type of unit test can also be called transparent, since it means that the tester actually knows what the functionality of the tested unit is and has a test for it in exact correlation.

Black-Box

Here, the internal functionality of the unit is not known and the tests exist according to the expected outcome and not the known functionality.

Gray-Box

If the tester is aware of the functionality but without a deep knowledge of the unit, this can be called gray-box testing.

These phrases can of course be used for other testing methods than unit testing, but they are an important aspect of the unit tests as so many mocks come into play while writing them. You can’t always have a perfect understanding of what a unit is doing and yet still want to test it.

On Integration Testing

Integration tests are at least as vital as the unit tests for an application. The main idea of an integration test is to test a bundle of unit tests, which basically creates a user journey. In other words, testing from the eyes of the user/client. Generally, the important parts of an application are determined and the user behaviors are replicated within these tests.

The advantage of integration testing is that it’s a more solid way of testing things as it tests multiple units together and can imitate the behavior of the user, but unfortunately it can take a lot of time. So, the more tests and user journeys you have, the more time would be spent. There are some ways like parallel testing that saves time for such things, but it can also be very costly to do so.

On the second part of this article, I will be talking about different integration testing types and how E2E testing comes into play between all this.

--

--