Simple code: Simplicity

Simplest solutions are usually the best solutions.

We as software developers work with hard problems and solve a lot of small problems every day. Solving a hard problem itself is a hard job. Though in my opinion it's not enough to solve a hard problem in any possible way but a hard problem should be solved with a simple solution. When a developer comes up with a simple solution to a hard problem then they can declare the problem solved.

First a disclaimer. Coming up with a simple solution to a hard problems is itself a very hard problem and takes a lot of time, effort and practice.

I've seen my share of "clever" solutions for hard problems and the problem with those is that usually the solution itself is so hard to understand that depending on the size of the problem it may take a developer from hours to days or even weeks to understand how that "clever" solution works. It's a rare occasion when a developer has come up with a simple solution to a hard problem. So simple that it needs to be read only once and it makes sense. I dare to say I've made a few of these solutions and I've also seen these from other developers but way less often than hard to understand solutions for hard problems.

So how does one come up with simple solutions to hard problems?
First step is to split the problem to smaller problems. How this works for me is that I try to identify smaller problem areas within the original problem. Once I have identified smaller problems I can usually find yet smaller problems to solve within those and I continue to do it until I have a plan, a set of tasks or small problems to solve. Usually I identify even more problems to solve once I start to work on them and I just add them to the list of small problems to solve. With this iterative process I can solve the problem one small piece at a time.

Splitting the problem to multiple smaller problems gives other benefits too. Each small problem can be tested individually and the big problem's tests work as acceptance tests for the whole set of small problems. Smaller problems are easier to solve and therefore the code is easier to write and when the code is easier to write it's easier to write readable code.

In a ideal situation the big problem would be solved by sequentially calling functions that solve a smaller problem within the problem space. In a way it could be thought like the solution to a problem can be solved by a function introduced in a interface. That interface is tested with a acceptance tests and it can be tested with mocks or spies to verify it calls the correct functions in correct order with correct parameters. The implementation of the interface is actually a series of function calls that each solve a portion of the problem. Each of those functions is tested with unit tests. Each of functions can be written as easily readable by keeping them small and naming the functions and things within those functions meaningfully. When a function is small and solves a single problem the solution is easy to define with immutable data structures or by avoiding mutating the variables. Also when each function works as it's own unit it's easier to isolate integration tests to those functions.

This is how simple solutions are crafted and this is how all the topics I have covered earlier are tied together to create simple, readable, verified and long lasting solutions to problems.

With all this tied up what started with a working title "My version of clean code" could also be simplified and after thinking about it more while writing these posts I decided to name the approach and conventions as "Simple code".


DevOps Your Skill: Integration Tests

Integration tests ensure that the components of an application is running properly at a level that includes the auxiliary infrastructure of the application, such as the voice user interface, the backend, and the integration with external systems.

Integration tests evaluate the components of an application at a higher level than unit tests. Unit tests are used to test isolated software components, such as individual class methods. Integration tests check that two or more components of an application work together, and they generate an expected result, possibly including all the components necessary to fully process a request.

Microservices in Publish-Subscribe Communication Using Apache Kafka

Publish-Subscribe Communication Using Apache Kafka.
You may also like: Comparing Publish-Subscribe Messaging and Message Queuing

Publish-Subscribe Messaging systems play an important role in any enterprise architecture as it enables reliable integration without tightly coupling the applications. The ability to share data between decoupled systems is not a problem that is easily tackled.

Consider an enterprise with multiple applications that are being built independently, with different languages and platforms. It needs to share data and processes responsively. We can achieve this using Messaging to transfer packets of data frequently, immediately, reliably, and asynchronously, using customizable formats. Asynchronous messaging is fundamentally a pragmatic reaction to the problems of distributed systems. Sending a message does not require both systems to be up and ready at the same time.

Integration Test With Multiple Databases

Multiple databases

Recently, I worked on a generic JDBC component that is able to execute SQL queries to read/load data from/to any database supporting JDBC specification and providing a driver for it.

As a part of this development, I needed to ensure that the component can run correctly with multiple databases. So, what I needed was to have multiple database environments and integration tests that can be parameterized and executed on all the environments.

Thoughts on Efficient Enterprise Testing (Part One)

Multitasking is the MOST efficient.


Testing in the enterprise is still a topic that is not as extensively used as it should be. Writing and especially maintaining tests takes time and effort, however, cutting short on software tests can’t be the solution. Which scopes, approaches, and test technology should be pursued in order to make testing more efficient?

Defining Test Boundaries — An Example

I think that everybody agrees that testing is required in order to build a quality product. But there’s also a lot of confusion about the boundaries of each test type. What’s the scope of a unit test? What’s the difference between an integration test, an integrated test and a contract test? If you ask three developers about test boundaries, you’ll most likely get three different answers. For example, I still talk to people who consider that a unit test should test a single class/method.

What’s clear is that most teams don’t have a consensus on what’s the scope of the different types of automated tests and the differences between them. Getting to a universal consensus might be hard, but getting to a consensus inside the team should be easy enough. In this blog post, we’ll see an example of how to do that.

Integration Testing: What It Is and How to Do It Right

For software to work properly, all units should integrate together and behave correctly.

Integration testing is like inviting your two favorite groups of friends to the same birthday party and hoping they all get along. Will they cooperate and “blend” when they’re all in the same room? The only way to know is to perform an “integration test” by pulling them all together and seeing how they interact with one another.

File Uploads in ASP.NET Core Integration Tests

Writing integration tests for ASP.NET Core controller actions used for file uploads is not a rare need. It is fully supported by ASP.NET Core integration tests system. This post shows how to write integration tests for single and multiple file uploads.

Getting Started

Suppose we have controller action for file upload that supports multiple files. It uses a complex composite command for image file analysis and saving. Command is injected to action by framework-level dependency injection using controller action injection.