Friday, June 28, 2013

Test Me If You Can (#1)

The purpose of this post series

During my career I often observed people who claim that they are not writing tests because "can't cover" integration between components. Well, I believe most of such people just don't know some simply techniques or don't have time to dig them out because of stress at their work place. The lack of such knowledge results into neglecting of integration tests and thus worse software, more bugs and disappointed customer.

So I've decided to share some practices collected during last couple of years that are revealing mystery surrounding integration testing. The series will be concentrated around Spring framework, that I'm most familiar with. Let's start :)

Better integration test for Spring based projects

Tools: Spring, JUnit, Mockito
Imagine the situation with Spring based project that's integrating an external service, e.g. some bank web services. Issues related to writing test cases and running them within CI for such code are usually the same
  • price per transaction, each time test executed - customer pays
  • tests requests can be interpreted as suspicious traffic, account blocked - tests failures
  • when using non production environments for tests, it can be unstable - again, tests failures
Usually such problems can be solved by mocking such external service while testing single class that using it, but when it comes to the need for test larger business flow - you need to run your tests again many components and made them managed by your container - Spring. Luckily Spring has great test framework  but one needs to mock external services herself. First intention could be creating mocks in setUp section of your test and override Spring beans, but think more about it
You're overriding behavior of container for your test, so there's no guarantee it will work the same way for real services.
We have not to mock our external services and then re-inject them into corresponding beans, we have to make Spring inject mocks in place of particular beans, necessary for our goals. Let's illustrate this with code.

My sample project comprises BankService representing external service and UserBalanceService - our business entity working with BankService. UserBalanceService is quite simple wrapper - just making conversion from String to Double.
public interface BankService {
    String getBalanceByEmail(String email);
}
public class BankServiceImpl implements BankService {
    @Override
    public String getBalanceByEmail(String email) {
        throw new UnsupportedOperationException("Operation failed due to external exception");
    }
}
interface UserBalanceService {
    Double getAccountBalance(String email);
}
public class UserBalanceServiceImpl implements UserBalanceService {
    @Autowired
    private BankService bankService;
    @Override
    public Double getAccountBalance(String email) {
        return Double.valueOf(bankService.getBalanceByEmail(email));
    }
}
And Spring dependency XML configuration wiring everything together
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="bankService" class="ua.eshepelyuk.blog.springtest.springockito.BankServiceImpl"/>
    <bean id="userBalanceService" class="ua.eshepelyuk.blog.springtest.springockito.UserBalanceServiceImpl"/>
</beans>
Our test will look like
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:/springtest/springockito/applicationContext.xml")
public class UserBalanceServiceImplProfileTest {
    @Autowired
    private UserBalanceService userBalanceService;
    @Autowired
    private BankService bankService;
    @Test
    public void shouldReturnMockedBalance() {
        Double balance = userBalanceService.getAccountBalance("user@bank.com");
        assertEquals(balance, Double.valueOf(123.45D));
    }
}
As expected after test run we will have UnsupportedOperationException. Our intention is to replace BankService with mock and tune its behaviour. It's possible to use Mockito directly as factory bean but there's better alternative - Springockito framework. Please take a look before proceed :)

The remaining question is how to instruct spring to inject mocks, Prior to version 3.1 there were no alternatives except creating brand new XML configuration for using it in test. But with introduction of Bean Definition Profiles  we now able to create more elegant solution for this, although we still need separate XML for test purposes. This is how resulting test XML configuration will look like
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mockito="http://www.mockito.org/spring/mockito"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.mockito.org/spring/mockito https://bitbucket.org/kubek2k/springockito/raw/tip/springockito/src/main/resources/spring/mockito.xsd">
    <import resource="classpath:/springtest/springockito/applicationContext.xml"/>
    <beans profile="springTest">
        <mockito:mock id="bankService" class="ua.eshepelyuk.blog.springtest.springockito.BankService"/>
    </beans>
</beans>

And the test modified accordingly.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:/springtest/springockito/testApplicationContext.xml")
@ActiveProfiles(profiles = {"springTest"})
public class UserBalanceServiceImplProfileTest {
    @Autowired
    private UserBalanceService userBalanceService;
    @Autowired
    private BankService bankService;
    @Before
    public void setUp() throws Exception {
        Mockito.when(bankService.getBalanceByEmail("user@bank.com")).thenReturn(String.valueOf(123.45D));
    }
    @Test
    public void shouldReturnMockedBalance() {
        Double balance = userBalanceService.getAccountBalance("user@bank.com");
        assertEquals(balance, Double.valueOf(123.45D));
    }
}
You may notice appearance of setUp method for setting up the mock behavior and new @Profile annotation. The annotation activates our profile springTest, so bean mocked with Springockito will be injected where necessary. When run this we will have test passed since spring injected mock that we've configured and not the external service.

Don't stop on the way to perfectness

It could be the end of the story be we could still go deeper on the problem. Springockito creator has another framework springockito-annotations . The framework allows mock injection using annotation within test classes. Please skim read it before proceed :)

After some modification code of our test will look this way.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = SpringockitoContextLoader.class, 
    locations = "classpath:/springtest/springockito/applicationContext.xml")
public class UserBalanceServiceImplAnnotationTest {
    @Autowired
    private UserBalanceService userBalanceService;
    @Autowired
    @ReplaceWithMock
    private BankService bankService;
    @Before
    public void setUp() throws Exception {
        Mockito.when(bankService.getBalanceByEmail("user@bank.com")).thenReturn(String.valueOf(valueOf(123.45D)));
    }
    @Test
    public void shouldReturnMockedBalance() {
        Double balance = userBalanceService.getAccountBalance("user@bank.com");
        assertEquals(balance, valueOf(123.45D));
    }
}

Please note that no new XML configuration required. We're using production XML config and just override single bean using @ReplaceWithMock annotation. Later we can customize the mock in setUp method.

P.S.

Springockito-annotations project has one great advantage - it provides test code only based dependency override mechanism. Neither additional XML, nor production code modifications for test purposes. Unlike springockito-annotations the XML based  approach makes creation of test specific XML mandatory always. So I strongly recommend iusing Springockito-annotations project for your integration tests, so they won't affect your production code design and won't produce additional artifacts - i.e. configuration files.

P.P.S.
Writing integration tests for Spring is easy ! Project can be found on my GitHub

Saturday, September 15, 2012

Duck typing in Java ? Well, not exactly

What is it all about ?

According to Wikipedia duck typing is
style of dynamic typing in which an object's methods and properties determine the valid semantics, rather than its inheritance from a particular class or implementation of a specific interface
In simplier words
When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck
In languages with dynamic typing this feature allows creating function that are not checking type of passed object but instead rely on existence of particular methods/properties within it and throws runtime exception when those properties not found. For instance, in groovy we could have method for printing info about some entity

def printEntity = {entity ->
 println "id: ${entity.id}, name: ${entity.name}" 
}
Let's say we have following class
class Entity {
 Long id
 String name
}
So we can invoke our function
printEntity(new Entity(id: 10L, name: 'MyName1'))
id: 10, name: MyName1
But the same time we could pass map as argument
printEntity(['id':10L, 'name':'MyName2'])
id: 10, name: MyName2
Using some metaprogramming magic we could write even following
class Ghost {
 def propertyMissing(String name) {
  if (name == 'id') {
   return -1L
  } else if (name == 'name') {
   return "StubName"
  }
 }
}
And we will be still able to call our function
printEntity(new Ghost())
id: -1, name: StubName

Welcome to the real world 

Fortunately this concept can be used not only for languages with dynamic typing but for ones with more strict typing model, as Java. Wikipedia has good example of duck typing implementation in Java using Proxy class.

Well, you say, what is the practical usage of this except feeling oneself the wisest guru :) Let me show some real life task that was solved in Java using duck typing technique.

From the beginning I had simple report generator that queries DB of products and outputs id and name of certain entity. But then customer says: "I'd like to also have link to the entity detail page at our site. Beautiful, SEO friendly link. Could you do it to me". "Sure ", I said. After digging our codebase I've discovered cool function generateSeoUrl() that does the job. The function takes one argument of type Entity, which is interface. So my intention was to observe implementations of Entity and try to use one of them for the report generation. How surprised was I after discovering that all of them are part of some self made ORM tool and their constructors accept query DB to get the entire information about product.

So if I were using Entity implementations I had to deal with one extra query per row of my report and this is unacceptable since report was comprised of huge number of rows. So I decided to try other approach and implement Entity interface, overriding methods that are used by generateSeoUrl(). I clicked my IDE shortcut and got surprised again. Entity had about 50 (!!!) methods. Well, I already knew that only getEntityId() and getName() are used by generateSeoUrl() function, but then again, having new class with 50 empty methods just to override 2 of them doing useful action seemed not good idea for me.

Thus I've decided stop trying coding and start to think :) Extend some of the Entity implementation to prevent querying DB or copy + paste generateSeoUrl() and adopt it for my needs were the options but still it was not beautiful. Especially when I reminded duck typing. I said to myself, we have a function that takes instance of Entity but only uses two method of this interface, so to complete my task I need something that looks like Entity and able to handle getEntityId() and getName() methods.

Since entityId and name were already present in data used for generating my report I could reuse them in my new class to stub data for getEntityId() and getName(). To achieve duck typing we need to create Proxy that also implements InvocationHandler interface and static method to retrieve instance of Proxy. Final code of my class looks like

public class ReportEntitySupport implements InvocationHandler {

    public static Entity newInstance(Long entityId, String name) {
        return (Entity) Proxy.newProxyInstance(
                Product.class.getClassLoader(),
                Product.class.getInterfaces(),
                new ReportEntitySupport(entityId, name)
        );
    }

    private final String name;
    private final Long entityId;

    private ReportEntitySupport(Long entityId, String name) {
        this.name = name;
        this.entityId = entityId;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (method.getName().equals("getName")) {
            return this.name;
        } else if (method.getName().equals("getEntityId")) {
            return this.entityId;
        }
        return null;
    }
}

So how to use it ?

Inside my report generator class while iterating over ResultSet I'm using following
Long entityId;
String name;
....
Entity entity = ReportEntitySupport.newIntance(entityId, name);
String seoUrl = generateSeoUrl(entity);
....

P.S.

This post just illustrates that some uncommon for Java language concepts could be successfully applied for completing real life tasks improving your programming skills and making your code more beautiful.

Saturday, July 28, 2012

CodingDojoCnUa #6

Today, 28th of July, our CodingDojoCnUa community successfully conducted 6th Coding Dojo. We met at Chernihiv's office of SysIQ, as few times before. The subject of our session was RomanNumerals kata - description can be found by this link. Main thing distinguishing this Dojo from previous ones was splitting the attendees into two separate teams that were working on their own without shared Design Session. Each team was responsible for figuring out own implementation and eventually produced working code together with unit tests. Both implementation can be found at GitHub
What we've discovered

First things to mention that team provided completely different solutions to the same problem. Relative simplicity of Kata seemed to help coders to split task into smaller parts thus supporting true incremental development, concentrating on providing small slices of functionality after creating failed test. Unlike previous  times there were no attempts to create God functions immediately after start of Dojo. Although longer Design Sessions are essential to make team move faster and effectively with incremental development

Second main observation is that few peoples who don't use TDD on daily basis realized that this approach could significantly affect original design of algorithm and even imposes final design. On retrospective meeting one of us described this impression -  "People saw TDD in action"

3rd and the shortest - CoffeeScript tastes better each time you try it :)

What we're gonna try next time

Apparently largest negative issue raised on retro was isolation of members within own team and lack of  inter team communication. Attendees suggested various options, even tackle more complicated task than kata, like some sort of network game, and go through complete process of application development.

But finally we agreed on just to exchange team members in the middle of next Dojo to see if this is helpful for  coding and / or brings more fun to the event :)

Some photos @Facebook

Wednesday, July 11, 2012

Selenium/WebDriver tricks - part 3

Intro

It's common case for dynamic pages to show / hide some elements basing on user's actions. But covering them with stable WebDriver tests could be sometimes cumbersome. I'll try to explain couple of techniques helping to deal with that sort of web pages.

Case #1

First approach I'd like to describe is rendering all the elements on page load but set CSS display property to none and later set it to empty or block to make element visible.

In this case we can't just check visibility by using webDriver.findElement(...) since it will return valid element but we don't know if it visible or not. Fortunately WebElement interface has method isDisplayed() however obvious solution webDriver.findElement(...).isDisplayed() could be erroneous because JavaScript code that changes element visibility works with delays. To overcome such problems we can use WebDriverWait class.
WebDriverWait webDriverWait = new WebDriverWait(webDriver, 10L);
WebElement visibleElement = webDriverWait.until(new Function<Webdriver, WebElement>() {
 @Override
 public WebElement apply(WebDriver webDriver) {
  WebElement we = webDriver.findElement(...);
  return we.isDisplayed() ? we : null;
 }
});

The code periodically finds element and checks its visibility. When element exist and visible it will be returned by until(..) method.

To check if element is invisible at the moment we can use similar approach just negating the condition in the function body

Case #2

There's another option for dealing with show/hide certain parts of the page. Your code can create required HTML on the fly while showing and remove elements from DOM while hiding. To check element visibility we can use approach described above. But for checking if the part of the page is not shown to customer we can't use that because there's no elements in DOM and if we try to use findElement(...) we will get the exception.

Issue could be solved by using WebDriverWait and findElements(...) method that doesn't throw an exception but return empty list if no elements found.
WebDriverWait webDriverWait = new WebDriverWait(webDriver, 10L);
webDriverWait.until(new Predicate<WebDriver>() {
 @Override
 public boolean apply(WebDriver webDriver) {
  return webDriver.findElements(...).size() == 0;
 }
});

Code periodically searches for elements matching criteria and return true when no elements found.

P.S.

It could save your time and make your code cleaner if you put code samples from above as static methods into utility class. This allows you to easily reuse such functionality while writing WebDriver tests for your pages.

Thursday, July 5, 2012

Grails + AngularJS + CoffeeScript

Intro

Responsive design is a must for modern web-applications. Today this is attempted to achieve by using JavaScript MVC frameworks. But more often than not those frameworks originate from Rails, NodeJS and other non-Java communities. This makes it hard for Java-boys (as me) to jump into. So purpose of this short tutorial is to explain in few easy steps how to start with JS MVC framework and CoffeeScript on Grails.
.
In this certain case AngularJS is my personal choice taken up after playing around with few other libraries but principles described below should work for other frameworks.

Our intention will be to write one-page application having single input field and what's typed there is immediately reflected below in span tag.

I'm assuming readers could be unfamiliar with AngularJS, but, still, the application is really simple and should be easy to read.

Implementation
  1. First let's create Grails application
    grails create-app testApp

  2. After application is created let's change folder and all subsequent commands should be executed there.
    cd testApp

  3. Grails already has plugin that support on-the fly conversion of your CoffeeScript files into JavaScript. To install it type following
    grails install-plugin coffeescript-resources
  4. After plugin installed we are going to create empty file for our CoffeeScript sources at web-app/cs/angularIndex.coffee
  5. What's great about Grails - is the fact that it abounds with plugins. AngularJS library can be installed by typing
  6. grails install-plugin angularjs-resources
  7. Thanks to great resources plugin JavaScript files management is quite easy in Grails. Let's create file grails-app/conf/MyResources.groovy with following content
    modules = {
        angularIndex {
            dependsOn 'angular'
            resource url: 'cs/angularIndex.coffee'
        }
    }
    
    Code above declares resource for our AngularJS module written in CoffeeScript.
  8. Next we need controller to serve starting point HTML with AngularJS module. We can do it with following command
    grails create-controller AngularIndex
  9. Also we need manually create Grails view for index action of our controller. For this we have to create new file grails-app/views/angularIndex/index.gsp with following content
    <!DOCTYPE html>
    <html>
    <head>
        <r:require modules="angularIndex"/>
        <r:layoutResources/>
    </head>
    <body ng-app="MyApp">
    <div ng-controller="MyCtrl">
        What typed reflected below<br>
        <input type="text" ng-model="myText"/><br>
        <span><b>{{myText}}</b></span>
    </div>
    </body>
    <r:layoutResources/>
    </html>
    
  10. Last step is to create AngularJS module in CoffeeScript. For this we have to fill web-app/cs/angularIndex.coffee created before with following content
    app = angular.module "MyApp", []
    app.controller "MyCtrl", ($scope) ->
      $scope.myText = "INITIAL"
    
  11. Let's run application
    grails run-app

P.S.

Please notice that setup described above shouldn't be considered for production usage. You probably need minification, zipping resources, etc - but then again it can be good starting point for research, prototyping and similar activities towards developing modern front-ends.

Links

AngularJS - http://angularjs.org/
CoffeeScript - http://coffeescript.org/
Grails - http://grails.org/

Monday, February 6, 2012

CodingDojoCnUa #2 results

On 5th of February our small Cherhihiv community made 2nd СodingDojo. This time it was dedicated to JavaScript programming. We tried to code some Design Patterns in new language.
What we attained during 2 two 1 our long session is following patterns implemented

  1. Singleton, yeah yeah yeah :)
  2. Factory method
  3. Template method v1 (prototype hierarchy) 
  4. Template method v2 (runtime meta-programming)
  5. Decorator

What we found very good during retrospection is usage of TimeBox policy for changing pilot/co-pilot, we used 7 minutes limited time box and Idea Pomodoro plugin was helpful on this.

During programming we all suffered of our Java mindset. Even plain  looking into Wikipedia description and attempt to re-implement Java code samples in JavaScript were damaging our brains :) Lack of interfaces (Java) and completely different approach of creating class hierarchy slowed down our development speed. Another issue was immense scope of our Dojo. Certain targets (patterns) were chosen only at the beginning of session and it was a challenge to create domain object for certain patterns without detailed design session for which we have no time..

What we decided to do next
  1. Pick up and implement some Kata to have more certainty on what we wanna achieve
  2. Increase time box to 10 minutes, let's see if helps
  3. Get some cookies and drinks to not starve during session :)
My personal observations 

The easiest part was Jasmine. This BDD tool was adopted seamlessly by all of us since TDD tools and practices are familiar to us from Java world and Jasmine is very similar.

The hardest was start thinking again in higher level OOP terms, not in their equivalents in Java. All those interfaces, classes limited to the same named file and other limitation imposed by Java were hard to overcome. Considering present of duck typing in JavaScript we get rid of interfaces, abstract classes and class hierarchy at all. Another uncommon point was API concentrated in module not in class as in Java it it was also a bit frustrating from the beginning.

But anyway the coolest thing was our success in short and stressful session as well as knowledge obtained. I think attitude to JavaScript should change a bit towards paying more respect for this amazing and underestimated language (my IMO though).

Saturday, January 28, 2012

CodingDojoCnUa #2 agenda and tools

Intro

On 5th of  February we are going to have 2nd CodingDojo meeting dedicated to improve our JavaScript skills. The purpose of our gathering will be implementation of design patterns using JavaScript language.
The good list of patterns could be found at Wikipedia page. Please read the list before meeting :)

Links below are also good starting point for exploring JavaScript. At least skim reading of links below is required before Dojo.
Agenda 


We're going to pair-program using TDD while implementing few of Software Design Patterns. 
At our previous retro we've chosen to use TimeBox mechanism for changing pilot/co-pilot. Let's consider our participants gonna change every 5-7 minutes.

10:30 - Start & intro. Decide what exactly we gonna do, so-called "design session"
10:50 - 1st coding session start
11:50 - Break and "how it's going" discussion, maybe lunch ?
12:20 - 2nd "design session "
12:30 - 2nd coding session begin 
13:30 - Retro
14:00 - End

Exact agenda timings are subject to change depending on our progress during Dojo.

Tools we gonna use

We will be using NodeJS as our JavaScript engine. Jasmine as TDD/BDD framework and IntelliJ IDEA.
Although NodeJS is rich featured server-side framework we are intended to use it only as JS interpreter.
More docs could be found at NodeJS site


Jasmine is popular BDD framework for testing in JavaScript. It has support for test suites, human  friendly assertions, basic mocking support so its good choice for beginners like us :). 
Find more on their Docs page