Showing posts with label TDD. Show all posts
Showing posts with label TDD. Show all posts

Monday, June 19, 2017

The Patterns of the Antipatterns: Design / Testing

It's been a while since I have started my professional career as the software developer. Over the years I worked for many companies, on a whole bunch of different projects, trying my best to deliver them and be proud of the job. However, drifting from company to company, from project to project, you see the same bad design decisions made over and over again, no matter how old the codebase is or how many people have touched it. They are so widely present that truly become the patterns themselves, thereby destine the title of this blog: the patterns of the antipatterns.

I am definitely not the first one who identified them and certainly not the last one either (so let all the credits go to the original sources if any exist). They all come from the real projects, primarily Java ones, though other details should stay undisclosed. With that ...

Code first, no time to think

This is hardly sounds like a name of the antipattern but I believe it is. We all are developers, and unsurprisingly love to code. Whenever we have gotten some feature or idea to implement, we often just start coding it, without thinking much about the design or even not looking around if we could borrow / reuse some functionality which is already there. As such, reinventing the wheel all the time, hopefully enjoying at least the coding part ...

I am absolutely convinced that spending some time just thinking about high-level design, incarnating it in terms of interfaces, traits or protocols (whatever your favoring language is offering) is a must-do exercise. It won't take more time, really, but the results are rewarding: beautiful, well-thought solution at the end.

TDD is a set of the terrific practices to help and guide your through. While you are developing test cases, you are iterating over and over, making changes and with each step getting close to the right implementation. Please, adopt it in each and every project you are part of.

Occasional Doer

Good, enough philosophy, now we are moving on to a real antipatterns. Undoubtedly, many of you witnessed such pieces of code:

public void setSomething(Object something) {
    if (!heavensAreFalling) {
        this.something = something;
    }
}

Essentially, you call the method to set some value, and surely you expect the value to be set once the invocation is completed. However, due to presence of some logic inside the method implementation it may actually do nothing, silently ...

This is an example of really bad design. Instead, such interactions could be modeled using for example State pattern or at least just throwing an exception saying that the operation cannot be completed due to internal constraints. Yes, it may require a bit more code to be written but at least the expectations will be met.

The Universe

Often there is a class within the application which is referencing (or is referenced by) mostly every other class of the application. For example, all classes in the project must be inherited from some base class.

public class MyService extends MyBase {
  ...
}
public class MyDao extends MyBase {
  ...
}

In most cases, this is not a good idea. Not only it creates a hard dependency on this single class but also on every dependency this guy is using internally. You may argue that in Java every single class implicitly is inherited from Object. Indeed, but this is part of the language specification and has nothing to do with application logic, no need to mimic that.

Another extreme is to have a class which serves as a central brain of the application. It knows about every service / dao / ... and provides accessors (most of the time, static) so anyone can just turn to it and ask for anything, for example:

public class Services {
    public static MyService1 getMyService1() {...}
    public static MyService2 getMyService2() {...}
    public static MyService3 getMyService3() {...}
}

Those are universes, eventually they leak into every class of the application (it is easy to call static method, right?) and couple everything together. In more or less large codebase, getting rid of such universes is exceptionally hard.

To prevent such things to poison your projects, use dependency injection pattern, implemented by Spring Framework, Dagger, Guice, CDI, HK2, or pass the necessary dependencies through constructors or method arguments. It will actually help you to see the smells early on and address them even before they become a problem.

The Onionated Inheritance

This is a really fun and scary one, very often present in projects which expose and implement REST(ful) web services. Let us suppose you have a Customer class, with quite a few different properties, for example:

public class Customer {
    private String id;
    private String firstName;
    private String lastName;
    private Address address;
    private Company company;
    ...
}

Now, you have been asked to create an API (or expose through other means) which finds the customer but returns only his id, firstName and lastName. Sounds straightforward, isn't it? Let us do it:

public class CustomerWithIdAndNames {
    private String id;
    private String firstName;
    private String lastName;
}

Looks pretty neat, right? Everyone is happy but next day you get to work on another feature where you need to design an API which returns id, firstName, lastName and also company. Sounds pretty easy, we already have CustomerWithIdAndNames, only need to enrich it with a company. Perfect job for inheritance, right?

public class CustomerWithIdAndNamesAndCompany extends CustomerWithIdAndNames {
    private Company company;
}

It works! But after a week, another request comes in, where a new API also needs to expose the address property, anyway, you got the idea. So at the end you end up with dozen of classes which extends each other, adding properties here and there (like onions, hence the antipattern name) to fulfill the API contracts.

Yet another road to hell ... There are quite a few options here, the simplest one is JSON Views (here are some examples using Jackson) where the underlying class stays the same but different views of it could be returned. In case you really care about not fetching the data you don't need, another option is GraphQL which we have covered last time. Essentially, the message here is: don't create such onionated hierarchies, use single representation but use different techniques to assemble it and fetch the necessary pieces efficiently.

IDD: if-driven development

Most of real-world projects internally are built using pretty complex set of application and business rules, cemented by applying different layers of extensibility and customizations (if needed). In most cases, the implementation choice is pretty unpretentious and the logic is driven by a conditional statements, for example:

int price = ...;
if (calculateTaxes) {
    price += taxes;
}

With time, the business rules evolve, so do the conditional expression they are impersonated, becoming a real monsters at the end:

int price = ...;
if (calculateTaxes && (country == "US" || country == "GB") && 
    discount == null || (discount != null && discount.getType() == TAXES)) {
    price += taxes;
}

You see where I am going with that, the project is built on top IDD practices: if-driven development. Not only the code becomes fragile, prone to condition errors, very hard to follow, it is very scary to change as well! To be fair, you also need to test all possible combinations of such if branches to ensure they make sense and the right branch is picked up (I bet no one is actually doing that because this is a gigantic amount of tests and efforts)!

In many cases the feature toggles could be an answer. But if you get used to write such a code, please take some time and read the books about design patterns, test-driven development and coding practices. There are so many of them, below is the list I would definitely recommend:

There are so many great ones to add here, but those are a very good starting point and highly rewarding investment. Much better alternatives to if statements are going to fill you mind.

Test Lottery

When you hear something like "All projects in our organization are agile and using TDD practices", the idealistic pictures come in mind, you hope everything is done right by the book. In reality, in most projects things are very far from that. Hopefully, at least there are some test suites you could trust, or could you?

Please welcome the test lottery: the kingdom of flaky tests. Have you ever seen builds with random test failures? Like on every consecutive build (without any changes introduced) some tests suddenly pass but others are starting to fail? And may be one of ten builds may turn green (jackpot!) as stars finally got aligned properly? If no one cares, it becomes a new normal and every team member who joins the team is being told to ignore those failures, "they are failing for ages, screw them".

Tests are as important as the mainstream code you push into production. They need to be maintained, refactored and kept clean. Keep all your builds green all the time, if you see some flakiness or random failures, address them right away. It is not easy but in many cases you may actually run into real bugs! You have to trust your test suites, otherwise why do you need them at all?

Test Framework Factory

This guy is an outstanding one. It happens so often, it feels like every organization is just obligated to create own test framework, usually on top of existing ones. At first it sounds like a good idea, and arguably, it really is. Unfortunately, in 99% the outcome is yet another monstrous framework no one wants to use but is forced to because "it took 15 men / years to develop and we cannot throw it away after that". Everyone struggles, productivity is going down at the speed of light, and quality does not improve at all.

Think twice before taking this route. The goal to simplify testing of complex applications the organization is working on is certainly a good one. But don't fall into the trap of throwing people at it, who are going to spend few months or even years working on the "perfect & mighty test framework" in isolation, may be doing great job overall, but not solving any real problems. Instead, just creating new ones. If you decided to embark on this train anyway, try hard to stay focused, address the pain points at their core, prototype, always ask for feedback, listen and iterate ... And keep it stable, easy to use, helpful, trustful and as lightweight as possible.

Conclusions

You cannot build everything right from the beginning. Sometimes our decisions are impacted by pressure and deadlines, or the factors outside of our control. But it does not mean that we should let things stay like that forever, getting worst and worst every single day, please, don't ...

This post is a mesh of ideas from many people, terrific former teammates and awesome friends for good, credits go to all of them. If you happens to like it, you may be interested in checking out the upcoming post, where we are going to talk about architectural antipatterns.

Monday, January 9, 2017

Overcast and Docker: test your apps as if you are releasing them to production

I am sure everyone would agree that rare application architecture these days could survive without relying on some kind of data stores (either relational or NoSQL ones), or/and messaging middleware, or/and external caches, ... just to name a few. Testing such applications becomes a real challenge.

Luckily, if you are a JVM developer, things are not as bad. Most of the time you have an option to fallback to an embedded version of the data store or message broker in your integration or component test scenarios. But what if the solution you are using is not JVM-based? Great examples of those are RabbitMQ, Redis, Memcached, MySQL, Postgresql which are extremely popular choices these days, and for a very good reasons. Even better, what if your integration testing strategy is set to exercise the component (read, microservice) in the environment as close to production as possible? Should we give up here? Or should we write a bunch of flaky shell scripts to orchestrate the test runs and scary most of the developers to death? Let us see what we can do here ...

Many of you are already screaming at this point: just use Docker, or CoreOS! And this is exactly what we are going to talk about in this post, more precisely, how to use Docker to back integration / component testing. I think Docker does not need an introduction anymore. Even those of us who spent a last couple of years in a cave on a deserted island in the middle of the ocean have heard about it.

Our sample application is going to be built on top of Spring projects portfolio, heavily relying on Spring Boot magic to wire all the pieces together (who doesn't, right? it works pretty well indeed). It will be implementing a very simple workflow: publish a message to RabbitMQ exchange app.exchange (using app.queue routing key), consume the message from the RabbitMQ queue app.queue and store it in Redis list data structure under the key messages. The three self-explanatory code snippets below demonstrate how each functional piece is being done:

@Component
public class AppQueueMessageSender {
    @Autowired private RabbitTemplate rabbitTemplate;
 
    public void send(final String message) {
        rabbitTemplate.convertAndSend("app.exchange", "app.queue", message);
    }
}
@Component
public class AppQueueMessageListener {
    @Autowired private AppMessageRepository repository;
 
    @RabbitListener(
        queues = "app.queue", 
        containerFactory = "rabbitListenerContainerFactory", 
        admin = "amqpAdmin"
    )
    public void onMessage(final String message) {
        repository.persist(message);
    }
}
@Repository
public class AppMessageRepository {
    @Autowired private StringRedisTemplate redisTemplate;
 
    public void persist(final String message) {
        redisTemplate.opsForList().rightPush("messages", message);
    }
 
    public Collection<String> readAll() {
        return redisTemplate.opsForList().range("messages", 0, -1);
    }
 
    public long size() {
        return redisTemplate.opsForList().size("messages");
    }
}

As you can see, the implementation is deliberately doing the bare minimum, we are more interested in the fact that quite a few interactions with RabbitMQ and Redis are happening here. The configuration class includes only the necessary beans, everything else has been figured out by Spring Boot automatic discovery from the classpath dependencies.

@Configuration
@EnableAutoConfiguration
@EnableRabbit
@ComponentScan(basePackageClasses = AppConfiguration.class)
public class AppConfiguration {
    @Bean
    Queue queue() {
        return new Queue("app.queue", false);
    }

    @Bean
    TopicExchange exchange() {
        return new TopicExchange("app.exchange");
    }

    @Bean
    Binding binding(Queue queue, TopicExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(queue.getName());
    }
 
    @Bean
    StringRedisTemplate template(RedisConnectionFactory connectionFactory) {
        return new StringRedisTemplate(connectionFactory);
    }
}

At the very end comes application.yml. Essentially it contains the default connection parameters for RabbitMQ and Redis, plus a bit of logging level tuning.

logging:
  level:
    root: INFO
    
spring:
  rabbitmq:
    host: localhost
    username: guest
    password: guest
    port: 5672
    
  redis:
    host: localhost
    port: 6379

With that, our application is ready be run. For convenience, the project repository contains docker-compose.yml with official RabbitMQ and Redis images from the Docker hub.

Being TDD believers and practitioners, we make sure no application leaves the gate without thorough set of test suites and test cases. Keeping unit tests and integration tests out of scope of the subject of our discussion, let us jump right into component testing with this simple scenario.

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(
    classes = { AppConfiguration.class }, 
    webEnvironment = WebEnvironment.NONE
)
public class AppComponentTest {
    @Autowired private AppQueueMessageSender sender;
    @Autowired private AppMessageRepository repository;
 
    @Test
    public void testThatMessageHasBeenPersisted() {
        sender.send("Test Message!");
        await().atMost(1, SECONDS).until(() -> repository.size() > 0);
        assertThat(repository.readAll()).containsExactly("Test Message!");
    }
}

It is really basic test case, exercising the main flow, but it makes an important point: no mocks / stubs / ... allowed, we expect the real things. The line is somewhat blurry but this is what makes component tests different from let say integration or e2e tests: we test a single full-fledged application (component) with the real dependencies (when it makes sense).

This is a right time for an excellent Overcast project to appear on the stage and help us out. Overcast brings the power of Docker to enrich test harness of the JVM applications. Among many other things, it allows to define and manage lifecycle of Docker containers from within Java code (or more precisely, any programming language based on JVM).

Unfortunately, the last released version 2.5.1 of Overcast is pretty old and does not include a lot of features and enhancements. However, building it from source is no-brainer (hopefully the new release is going to be available soon).

git clone https://github.com/xebialabs/overcast
cd overcast
./gradlew install

Essentially, the only prerequisite is to provide the configuration file overcast.conf with the list of named containers to run. In our case, we need RabbitMQ and Redis.

rabbitmq {
    dockerImage="rabbitmq:3.6.6"
    exposeAllPorts=true
    remove=true
    removeVolume=true
}

redis {
    dockerImage="redis:3.2.6"
    exposeAllPorts=true
    remove=true
    removeVolume=true
}

Great! The syntax is not as powerful as Docker Compose supports, but simple, straightforward and quite sufficient to be fair. Once configuration file is placed into src/test/resources folder, we could move on and use Overcast Java API to manage these containers programmatically. It is natural to introduce the dedicated configuration class in this case as we are using Spring framework.

@Configuration
public class OvercastConfiguration {
    @Autowired private ConfigurableEnvironment env;

    @Bean(initMethod = "setup", destroyMethod = "teardown")
    @Qualifier("rabbitmq")
    public CloudHost rabbitmq() {
        return CloudHostFactory.getCloudHost("rabbitmq");
    }

    @Bean(initMethod = "setup", destroyMethod = "teardown")
    @Qualifier("redis")
    public CloudHost redis() {
        return CloudHostFactory.getCloudHost("redis");
    }

    @PostConstruct
    public void init() throws TimeoutException {
        final CloudHost redis = redis();
        final CloudHost rabbitmq = rabbitmq();

        final Map<String, Object> properties = new HashMap<>();
        properties.put("spring.rabbitmq.host", rabbitmq.getHostName());
        properties.put("spring.rabbitmq.port", rabbitmq.getPort(5672));

        properties.put("spring.redis.host", redis.getHostName());
        properties.put("spring.redis.port", redis.getPort(6379));

        final PropertySource<?> source = new MapPropertySource("overcast", properties);
        env.getPropertySources().addFirst(source);
    }
}

And that is literally all we need! Just a couple of important notes here. Docker is going to expose random ports for each container, so we could run many test cases in parallel on the same box without any port conflicts. On most operating systems it is safe to use localhost to access the running containers but for the ones without native Docker support the workarounds with Docker Machine or boot2docker exist. That is why we override connection settings for both host and port for RabbitMQ and Redis respectively, asking for the bindings at runtime:

properties.put("spring.rabbitmq.host", rabbitmq.getHostName());
properties.put("spring.rabbitmq.port", rabbitmq.getPort(5672));

properties.put("spring.redis.host", redis.getHostName());
properties.put("spring.redis.port", redis.getPort(6379));

Lastly, more advanced Docker users may wonder how Overcast is able to figure out where Docker daemon is running? Which port it is bound to? Does it use TLS or not? Under the hood Overcast uses terrific Spotify Docker Client which is able to retrieve all the relevant details from the environment variables, which works in majority of use cases (though you can always provide your own settings).

To finish up, let us include this configuration into the test case:

@SpringBootTest(
    classes = { OvercastConfiguration.class, AppConfiguration.class }, 
    webEnvironment = WebEnvironment.NONE
)

Easy, isn't it? If we go ahead and run mvn test for our project, all test cases should pass (please notice that first run may take some time as Docker would have to pull the container images from the remote repository).

> mvn test
...
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
...

No doubts, Docker raises testing techniques to a new level. With the help of such awesome libraries as Overcast, seasoned JVM developers have even more options to come up with realistic test scenarios and run them against the components in "mostly" production environment (on the wave of hype, it fits perfectly into microservices testing strategies). There are many areas where Overcast could and will improve but it brings a lot of value even now, definitely worth checking out.

Probably, the most annoying issue you may encounter when working with Docker containers is awaiting for the moment when the container is fully started and ready to accept the requests (which heavily depends on what kind of underlying service this container is running). Although the work on that has been started, Overcast does not help with this particular problem yet though simple, old-style sleeps may be good enough (versus a bit more complex port polling for example).

But but but ... always remember about testing pyramid and strive for a right balance. Create as many test cases as you need to cover most critical and important flows, but no more. Unit and integration tests should be your main weapon.

The complete project is available on Github.

Tuesday, December 13, 2011

Testing highly concurrent code

How often are you facing the issues with testing highly concurrent code? It's not so easy to write a test which verifies asynchronous procedure call or verifies that some tasks has been executed by some thread pool worker. Fortunately, it's getting much easier with this awesome library - Awaitility.

Let me demonstrate on a few simple but meaningful enough examples how easy it is to enrich your tests with it. Let's start with a POM file including only necessary stuff - JUnit and Awaitility.

 4.0.0

 com.example
 awaitility
 0.0.1-SNAPSHOT
 jar

 
  UTF-8
 

 
  
   com.jayway.awaitility
   awaitility
   1.3.3
   test
  

  
   junit
   junit
   4.8.2
   test
  
 

Nothing special here. Our class under the test will collect notifications for particular users. As creating the notifications could take some time, the implementation will collect those using thread pool and asynchronous method invocation pattern: the method will return immediately delegating execution to thread pool. Pretty typical design decision. Let take a look on sample implementation.
package com.example.awaitility;

import java.util.Collection;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class AsyncQueueService {
    private final ExecutorService executor = Executors.newFixedThreadPool( 3 );
    private final ConcurrentLinkedQueue< Notification > queue = new ConcurrentLinkedQueue< Notification >();

    public static class Notification {
        private final long userId;

        public Notification( final long userId ) {
            this.userId = userId;
        }

        public long getUserId() {
            return userId;
        }
    }

    public void enqueue( final Collection< Long > users ) {
        executor.execute( new Runnable() {
                public void run() {
                    for( final long userId: users ) {
                        // do some work with notifications
                        queue.add( new Notification( userId ) );
                    }
                }
            }
        );
    }

    public void clear() {
        queue.clear();
    }

    public int size() {
        return queue.size();
    }
}
I omit a bunch of details trying to make code simple and concentrate on important: method enqueue. As we can see, this method delegates all the work to internal thread pool. Now, how would we create a test to verify that this method actually works? It's difficult because method returns immediately, the result of its execution will be available sometime in the future. Mocking thread pool (executor service) is not a very good idea as it uses the internals of implementation. What if we decide to move from thread pool to scheduled task? Test should work without any change. It's where Awaitility comes on a rescue. Let's take a look on this test case:
package com.example.awaitility;

import static com.jayway.awaitility.Awaitility.await;
import static org.hamcrest.core.IsEqual.equalTo;

import java.util.Arrays;
import java.util.concurrent.Callable;

import org.junit.Before;
import org.junit.Test;

public class AsyncQueueServiceTestCase {
    private AsyncQueueService service;

    @Before
    public void setUp() {
        service = new AsyncQueueService();
    }

    @Test
    public void testEnqueueManyNotifications() throws Exception {
        final Long[] users = new Long[] { 1L, 2L, 3L, 4L, 5L };

        service.enqueue( Arrays.asList( users ) );

        await().until(
            new Callable< Integer >() {
                public Integer call() throws Exception {
                    return service.size();
                }
            },
            equalTo( users.length )
        );
    }
}
As we see, the test method calls enqueue with some list of users. The test verifies that same amount of notifications should be in queue as users passed to enqueue method. With Awaitility such assertion is very trivial: just wait till service.size() will be equal to users.length!

I have just touched the surface of Awaitility. It has many features and even specific DSLs for Groovy and Scala. I highly encourage to take a look on it!

Tuesday, May 10, 2011

Testing untestable: JUnit + Mockito + Spring Test against static instances

This post is about my recent experience with the projects I thought don't exists anymore nowadays. Unreadable code base, chaotic design, any minor change breaks everything and, for sure, no tests. Worth mentioning deployment is nightmare. How this projects are supposed to evolve? I have no idea ... but we need to make fixes and changes. So ... what should we do? Write tests first!

That's not about how to write tests, but about techniques which allows to overcome some very bad coding practices in case you are not allowed to modify code base (as my team was put in such restrictions).

Let's start with such a pearl: private static initialized members (we will skip the thread safety aspects and concentrate on instance member only).
package org.example;

public class SomeStaticUtil {
    private static SomeStaticUtil instance = SomeStaticUtil.getInstance();
 
    public static SomeStaticUtil getInstance() {
        if( instance == null ) {
            instance = new SomeStaticUtil();
        }
  
        return instance;
    }
}
So how to substitute SomeStaticUtil with different implementation suitable for testing scenarios (aka mocks)? Remember, you are not allowed to modify the code (I would love to). There are few ways to do that:
- Excellent PowerMock framework. Didn't fit this project because bytecode manipulations crashed JVM.
- Magnificent AspectJ framework. Didn't fit this project because of complex aspects and necessary runtime weaving.
- Old and well-known reflection :-)

So what we can do here? Let's us exploit two excellent and very powerful test scaffolding frameworks: Mockito and Spring Test. Here is what we can do:
package org.example;

import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.test.util.ReflectionTestUtils;

public class SomeStaticUtilTestCase {
    private SomeStaticUtil someStaticUtil;
 
    @Before
    public void setUp() {
        someStaticUtil = Mockito.mock( SomeStaticUtil.class );
        ReflectionTestUtils.setField( someStaticUtil, "instance", someStaticUtil );
    }
 
    @Test
    public void someTest() {
        // ... some tests
    }
}
Very simple but powerful: replace private static member instance with mock implementation. Cool.

Saturday, March 26, 2011

Testing Spring Web Service endpoint

In previous post we have covered very interesting approach to build SOAP web services using lightweight by very powerful Spring Web Services framework. To wrap it up, let me show how easy you can test your web services.

Let me start with Spring context for test case (which is 99% the copy-paste from previous post).



    

    
 
    

    
        
            
                
             
        
        
            
                
            
        
     
 
    

    
         

Let us save this context to /src/test/resources/META-INF/spring-context.xml. There are two minor differences (comparing to initial one):
  • element <ws:static-wsdl/> has been removed
  • element <bean id="schema" ... /> has been added
Having context prepared, let us move on to test case itself.
package org.example;

import static org.springframework.ws.test.server.ResponseMatchers.validPayload;
import static org.example.SoapActionRequestCreator.withPayload;

import java.io.IOException;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.ws.test.server.MockWebServiceClient;

@RunWith( SpringJUnit4ClassRunner.class )
@ContextConfiguration( locations = "/META-INF/spring-context.xml" )
public class UserProfileEndpointTestCase {
    @Autowired private ApplicationContext applicationContext;
    @Autowired private Resource schema;
 
    private MockWebServiceClient client; 

    @Before
    public void setUp() {
        client = MockWebServiceClient.createClient( applicationContext );
    }
   
    @Test
    public void testServiceCall() throws IOException {
        final Resource payload = applicationContext.getResource( "Request.xml" );
  
        client.sendRequest( withPayload( "UserProfile", request ) ).   
            andExpect( validPayload( schema ) ); 
    }
}
This particular example does send request to SOAP web service and ensures that response is valid (against XSD schema), all that by leveraging Spring Web Services test scaffolding. There is one class which requires a bit of explanation: org.example.SoapActionRequestCreator. Nevertheless Spring Web Services provides rich set of payload builders, I didn't find the one which allows to pass SOAP action into request. So this small utility class has been developed. Here is a code for it:
package org.example;

import java.io.IOException;

import org.springframework.core.io.Resource;
import org.springframework.util.Assert;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.WebServiceMessageFactory;
import org.springframework.ws.soap.SoapMessage;
import org.springframework.ws.test.server.RequestCreator;
import org.springframework.ws.test.support.creator.PayloadMessageCreator;
import org.springframework.ws.test.support.creator.WebServiceMessageCreator;
import org.springframework.xml.transform.ResourceSource;

public class SoapActionRequestCreator implements RequestCreator {
    private final WebServiceMessageCreator adaptee;
    private final String action;
 
    private SoapActionRequestCreator ( final String action, 
            final WebServiceMessageCreator adaptee ) {
        this.action = action;
        this.adaptee = adaptee;
    }

    public static RequestCreator withPayload( final String action, 
            final Resource payload )throws IOException {
        Assert.notNull(payload, "'payload' must not be null");
        return new SoapActionRequestCreator( 
            action, new PayloadMessageCreator( new ResourceSource( payload ) ) );
    }
   
    @Override
    public WebServiceMessage createRequest( 
            final WebServiceMessageFactory messageFactory ) throws IOException {
        final WebServiceMessage message = adaptee.createMessage( messageFactory );
        Assert.isInstanceOf( SoapMessage.class, message );

        if( message instanceof SoapMessage ) {
            ( ( SoapMessage )message ).setSoapAction( action );
        }
  
        return message;
    }
}
This is just a very basic example. There are a bunch of tests you can do to ensure your SOAP web service performs as expected. I encourage to explore Spring Web Services documentation. All that should help us to develop high quality code and be proud of it.

Sunday, June 6, 2010

Testing BlazeDS remote objects with soapUI

Testing never was an easy thing. I am following TDD approach for at least last 5-6 years and really excited about it. But for me, TDD is not only unit testing. It is whole set of testing techniques I find appropriate for particular project (unit tests, integration tests, performance tests, ...). Recently I discovered excellent tool - soapUI. It has a bunch of useful features but the one I would like to cover today is testing BlazeDS services using AMF protocol.

Before we start with code snippets, let's copy BlazeDS libraries to bin/ext folder of soapUI installation:
- commons-codec-1.3.jar
- commons-httpclient-3.0.1.jar
- commons-logging.jar
- flex-messaging-common.jar
- flex-messaging-core.jar
- flex-messaging-opt.jar
- flex-messaging-proxy.jar
- flex-messaging-remoting.jar

Among other very cool features, soapUI supports Groovy as a scripting language which is just awesome. So all my examples will be in Groovy. Let's start with necessary part: creating connection and aliasing services.
import flex.messaging.io.amf.ASObject;
import flex.messaging.io.amf.client.AMFConnection;
import flex.messaging.messages.CommandMessage;
import flex.messaging.util.Base64.Encoder;
import flex.messaging.messages.Message;
import flex.messaging.io.amf.ASObject;

def clientId = "soapUI." +  UUID.randomUUID().toString();
def amfConnection = new AMFConnection();
amfConnection.instantiateTypes = false

amfConnection.connect(  "http://localhost:8080/server/messagebroker/amf" );   
amfConnection.addAmfHeader( Message.FLEX_CLIENT_ID_HEADER, clientId );

// Create remote object aliases
amfConnection.registerAlias( "testService", "com.example.remoteobjects.TestFacade" );
Having connection established, we are ready to call service methods of any aliased remote objects. Here is a code snippet to call service method foo() which has no parameters.
// Calling service method without arguments
def result = amfConnection.call( "testService.foo" );
And here is a code snippet to call service method foo() which accepts one parameter of type Person.
// Calling service method with object as argument
def person = new ASObject( "com.example.Person" );
person["name"]= "John Smith" ;

result = amfConnection.call( "testService.foo", person );
There's one issue which I've omitted for a moment. If you have security enabled for channels, you must proceed with authentication before calling any services. It's quite simple to do:
def credentials = encodeToBase64( username ) + ":" + encodeToBase64( password );

CommandMessage c = new CommandMessage();
c.setHeader( Message.FLEX_CLIENT_ID_HEADER, clientId );
c.setOperation( CommandMessage.LOGIN_OPERATION );
c.setDestination( "auth" );
c.setBody( encodeToBase64( credentials ) );      
amfConnection.call( null, c );

def encodeToBase64( final byte[] bytes ) {
    Encoder encoder = new Encoder( bytes.length );
    encoder.encode( bytes );
    return encoder.drain();     
}
When we are done, let's be a good citizens and close connection:
amfConnection.close();
Again, if security for channels is enabled, do logout before closing connection:
CommandMessage c = new CommandMessage();  
c.setHeader( Message.FLEX_CLIENT_ID_HEADER, clientId );
c.setOperation( CommandMessage.LOGOUT_OPERATION );
c.setDestination( "auth" );   
amfConnection.call( null, c );
Having such a script, soapUI allows you to create load test based on it. It also support quite complicated scenarios with many scripts involved and parameters passed from one to another. There is very good blog which contains tons of very useful information how to use soapUI for different kind of testing.

Wednesday, April 1, 2009

Testing Spring applications

In my last post we talked about Spring. As a test infected developer, my commitment is to test as much as I can to be sure in quality of my code. So, is it feasible to test (and how?) applications which heavily use Spring? The answers are: yes and very easy with help of Spring testing framework. We will consider a few basic scenarios with testing simple Spring beans and then touch a little bit context-related issues.

So. let's start with Spring beans under the test. I prefer to use Java 5 and annotations to publish regular POJOs as Spring beans and declare dependency injection between beans as well. The bean will be MessageService as in code snippet below:

package com.krankenhouse.services;

@Component
public class MessageService {
@Autowired private ITransport impl;
@Autowired private ILogger logger;

public void send( final String message ) {
logger.log( message );
impl.send( message );
}

public String receive() {
final String message = impl.receive();
logger.log( message );
return message;
}
}

This bean is pretty simple and just demonstrates two important concepts: exporting POJO as Spring bean (@Component) and using dependency injection (@Autowired). Before diving into how to test it, let's create applicationContext.xml (placed inside WEB-INF folder) file.
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">

<context:annotation-config/>
<context:component-scan base-package="com.krankenhouse.services" />
</beans>

OK, now we're ready to write our first test, named MessageServiceTestCase. There are basically several ways to do that, depending which features do you need. The first one looks like:

package com.krankenhouse.services;

@RunWith( SpringJUnit4ClassRunner.class )
@ContextConfiguration( locations = {
"classpath:/META-INF/applicationContext.xml"
}
)
public class MessageServiceTestCase {
@Autowired private MessageService messageService;

public void testSend() {
messageService.send( "Message" );
}
}
And that's it! Spring takes care about context initialization, beans creation, dependency injection, etc. If you need application context inside the test, then a little bit different approach could be used (by inheriting test class from AbstractJUnit4SpringContextTests class):
package com.krankenhouse.services;

@RunWith( SpringJUnit4ClassRunner.class )
@ContextConfiguration( locations = {
"classpath:/META-INF/applicationContext.xml"
}
)
public class MessageServiceTestCase
extends AbstractJUnit4SpringContextTests {
public void testSend() {
MessageService messageService =
( MessageService )applicationContext
.getBean( "messageService");
messageService.send( "Message" );
}
}
There's one important issue concerning Spring context: only one context will be created for each test class instance (not test method!). If you would like to recreate context for each single test method, you have to adorn these ones with @DirtiesContext annotation. Unfortunately, there is no class-level annotation for that up to 2.5.x versions.

Wednesday, September 24, 2008

Is BDD good addition to TDD?

Recently I've opened for myself newest modern testing approach - BDD or behavior-driven development. Unit tests are quite familiar for most of the developers (but how many developers use item?). BDD just adds some new, powerful features by means of descriptive test stories.

I guess, everyone agrees that test cases (xUnit, ...) mostly should contain simple and straightforward code (like compare call this method, compare this value with that one, etc.). But in my practice the complex test methods are not so rare (probably, I'm doing something wrong?) and because of this complexity it is often unclear what test method is actually for.

That's where BDD can help. I've found it very useful. It's easy to tell a test story first and then decorate it with test code either write a large test case surrounded by bunch of comments (I personally don't like comments and use them very rarely).

Because right now I'm developing on Java, I would like to recommend few BDD frameworks which still in development but are ready for use.

First is easyb: http://easyb.org/
And second one is JBehave: http://jbehave.org/

Both can be easily integrated in build process (Maven, Ant, ...).
So ... I'm looking forward to increase quality of my code with help of BDD. I'm going to post some practical BDD aspects in future posts.

Cheers.