Blog

27.01.2021. | Autor: Eni Sinanaj

Working with TDD

Best practices, naming conventions, processes to keep in mind, development practices and tools to use for a complete tested/testable environment.

Naming conventions

• Separate implementation from test code
Benefits: avoids packaging tests together with the production binaries

• Keep packaging of test classes the same as the unit they’re testing
Benefits: Helps finding and running tests obviously
e.g.: src/main/java/com.newlinecode.swimper.SwaggerParse.java -> src/test/java/com.newlinecode.swimper.SwaggerParseTest.java

• Name test classes similarly to the units they’re testing
Benefits: Helps finding and running tests obviously
e.g.: src/main/java/com.newlinecode.swimper.SwaggerParse.java -> src/test/java/com.newlinecode.swimper.SwaggerParseTest.java

• Use descriptive names for test methods
Benefits: helps understanding the objective of tests, serves as documentation for the implementation being tested
One of the most used methods is naming them using the Given/When/Then syntax used in Behavioural Driven Development.

Processes

• Write the test before the implementation code (obvious)
Benefits: ensures that testable code is being written; ensures that every line of code gets tests written for it. By writing or modifying test first, developer is focused on requirements before starting to work on a code.

• Only write new code when test is failing
Benefits: confirms that the test does not work without the implementation

• Rerun all tests every time implementation code changes
Benefits: ensures that there is no unexpected side-effect caused by code changes. There are the so-called watchers that you turn on when starting with development and runs all tests every time an implementation is added.

• All tests should pass before a new test is written
Benefits: focus is maintained on a small unit of work; implementation code is (almost) always in working conditions.

• As the other rules above this requires refactoring to be done only after all tests are passing
Benefits: refactoring is safe

Development practices

• Write the simplest/smallest code to pass the test
Benefits: ensures cleaner and clearer design; avoids unnecessary features

• Write assertions first, act later
Benefits: tells exactly what the implementation should be about by clarifying the purpose of the requirement and test early

• Minimize assertions in each test because if it fails it might be hard to find which of the assertions failed in some environments
Benefits: avoids assertion roulette; allows execution of more asserts.

• Don’t introduce dependencies in your tests; the execution of your test shoud have no order
Benefits: tests work in any order independently whether all or only subset is run

• Use mocks
Benefits: reduced code dependency; faster tests execution.

• Use setup and tear-down methods
Benefits: allows setup and tear-down code to be executed before and after the class or each method.

• Do not use base classes. It shouldn’t be needed to go to a parent class of a parent class of a test to understand what a test does.
Benefits: test clarity.

Important and helpful tools

• Code coverage. Tools like JaCoCo, Clover and Cobertura that scan your project and check for untested methods and units.
Benefit: assurance that everything is tested.

• Continuous integration (CI). Huge must in a tested environment. At fixed intervals or at every push to the remote repository the CI application downloads your project builds it and runs all the test. If any of the tests fail, the CI notfies the team. e.g.: Jenkins
Benefits: Always know ahead if builds are broken

Bonus: There are also tools that change conditional operators, return types, return values and more in your source code and then run all the tests. In this case, all of them are expected to fail, otherwise the test was not written correctly.

Eni Sinanaj
JIT Senior Software Engineer



Photo by Oli Dale on Unsplash

Weitere Blog

04.04.2022.

Maler oder Macher sein

Autor: Mirko Pawlak

Digitale Transformation ohne Grenzen. Ich bin Prozessmacher. Ich hocke tief drinnen im Maschinenraum und schau mir an, was das Unternehmen einzigartig macht. Ich tu das gern, denn jeder Prozess ist lebendig und einzigartig. Es gibt einen Anfang, dann passiert etwas und am Ende ist es vorbei. Wie geht man am besten mit seinen Prozessen um? […]

Blog lesen
02.12.2021.

How to deploy a Camunda Spring Boot application to a shared application server

Autor: Maximilian Kamenicky

Context Do you still remember our Blog: How to deploy a Camunda Spring Boot application to an external application server? In that blog, my colleague Gerardo Manzano Garcia explained the steps necessary to run a spring boot application on a dedicated application server i.e. an external Tomcat. In other words, run the spring boot application […]

Blog lesen
15.11.2021.

Ways to integrate Kafka with Databases

Autor: Denis Savenko

Kafka is a great instrument. It is widely used in event-driven architectures, and it does the job perfectly fine. However, this is not the only use-case for it. Kafka is also very well suitable for data replication and ingestion use-cases, as well as for building modern ETL or ELT pipelines. The most noteworthy reasons for […]

Blog lesen