An approach to help developers write meaningful tests

Over the last few years we have been adding unit tests to our existing product to improve its internal quality. During this period we always had the challenge of choosing unit-vs-Integration tests. I would like to mention some of the approaches we have applied to improve the quality of existing system.

At its core, unit testing is about testing a single component at a time by isolating its dependencies. The classical Unit tests have these properties "Fast, Independent, Repeatable, Self-Validating,Timely". Typically in java a method is considered as a unit. So traditional  (and most common) approach is to test the single method of a class separated from all its dependencies.

Interestingly there is no hard-core definition of "what makes a unit". Many times a combination of methods which spread across multiple classes can form a single behavior. So in this context the behavior should be considered as a unit. I have seen people breaking these units and writing multiple tests for the sake of testing a single method. If the intermediate results are not significant this will only increase the complexity of the system. The best way to test a system is to test with its dependencies where ever we can accommodate them. Hence we should try to use the actual implementation and not mocks. Uncle bob puts this point very well, "Mock across architecturally significant boundaries, but not within those boundaries." in his article.

If the software is build with TDD approach it might not be a challenge to isolate dependencies or adding a test for your next feature. But not all software's built like these. Unfortunately we have systems where there are only few or none of the test are written. When working with these systems we can  make use of the above principle and use tests at different levels. Terry Yin provides an excellent graphics (which is show below) in his presentation titled Misconceptions of unit testing. This shows how different tests can add values and what are its drawbacks.

Many of our projects uses Java and Spring framework. We have used springs @RunWith and SpringJUnit4ClassRunner to create AppLevel Tests which gives you the objects with all its dependencies initiated. You could selectively mock certain dependencies if you would like to isolate them. This sets a nice platform to write unit tests with multiple collaborating objects. we call them App level tests. These are still fast running test with no external dependencies. A different term was chosen to differentiate itself from the classical unit test. We also had Integration test which would connect with external systems. So, the overall picture of developer tests can be summarized as below,  

Tests Naming convention Runs at When to use Exec Time
Unit Test Ends with Test Every build Rule based implementations where the logic can be tested in isolation Few Milliseconds
App Level Tests Ends with TestApp Every build / Nightly builds (Teams choice) Tests the service layers in connection with others. Frees you from creation of mock objects. Application context is loaded in the tests. Few Seconds
Integration Test Ends with TestIntg Runs on demand when a special profile is used in build. All the above + Use when you need to connect to external points like DB, web services etc.. Depends on the integration points.
Manually Running Tests Ends withTestIntgManual Manually running tests, Used debugging a specific problem locally All the above - Can't be automated. Depends on the integration points.

This approach gives the developers choose the right level of abstractions to test and helps in optimizing their time. Nowadays my default choice is App Level tests and I go to unit tests if I have a complicated logic to implement.

Further reading:

Do you need microservices architecture?

Over the last few years there has been lot of attention on microservices. After the initial "hype" we saw that what problems it solves and what it can not. I have tried to cover what are microservices and where it can be useful and where it is not. I want to share the guidelines which can be used to choose between a monolith and microservices.

I feel that one must answer the below questions before they choose a microservices architecture and it will be beneficial to you if the answer to these questions are "YES".

1. Does your services represents different business cases/domains..?
2. Does the services needs to be deployed and managed independently..?
3. Does different parts of the application has different scaling/Technology needs..?

A modular monolith can be transformed to a set of microservices in case the need arises. So, we should start with monolith when we are not sure about the future.

I have spoken couple of times about the microdervices. In April 2016, I spoke at the Bangalore Software Architects Meetup on the topic "Do you need microservices architecture?". Later in 2017 April there was a brief introductory talk titled, Introduction to Microservices at the Microservices and Serverless event. I hope this post helps to complement the slides.

Application Security for Java Developers

Security is a top priority item on everyone's checklist nowadays. In this post, I will introduce you to useful reference material that can help you get started with securing applications. I want to focus more on web applications built with Java related technologies.

1. Authentication and Authorization

When it comes to security the most fundamental concepts are Authentication and Authorization. Unless you have a strong reason you should be following a widely accepted framework for this purpose. We have Java EE Authentication and Spring Security to help us out in this context. I have worked with spring security in the past and it can be customized to suite your specific needs. 

2. Security in the Web Layer

In our application stack the web layer is most vulnarable to attacks. We have may established standard practices and detection mechanisms to minimize these risks. OWASP Top 10 list is a must have check point for security checks. The Open Web Application Security Project (OWASP) mission is to make software security visible, so that individuals and organizations worldwide can make informed decisions about true software security risks.

3. API Security

With the rise of mobile applications and stronger browsers expressing functionalities using the API is more popular day by day. We need to follow the same security practices for the web layer. All the API requests should be authenticated and we should use the principle of least privilege. I found the presentation from Greg Patton in the AppSec EU15 titled The API Assessment Primer is a great start for API security validations. Two major points focused in his talk are,
Do not expose any operations that are not needed
Do not expose any data that is not required

Which is in line with the basic security principle of giving least privilege by default.

To authenticate the services, we can create simple token-based API authentication mechanism based OAuth2 standards. If the services expose any sensitive data, it is better to use https so that man-in-the-middle attacks can be avoided.

4. Validating the User Input

Be aware that any JavaScript input validation performed on the client can be bypassed by an attacker that disables JavaScript or uses a Web Proxy. Ensure that any input validation performed on the client is also performed on the server. Go through the OWASP and WASC checklist to identify the potential validations you need to do in your application.

Other Useful Reference Materials