Pages

Showing posts with label testing. Show all posts
Showing posts with label testing. Show all posts

Wednesday, August 8, 2018

Using Wiremock to simulate a slow responding server.

Here a little example of a stub created with Wiremock that simulates a slow reply from a server:

 import com.github.tomakehurst.wiremock.WireMockServer;  
 import java.util.Scanner;  
 import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;  
 import static com.github.tomakehurst.wiremock.client.WireMock.get;  
 import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;  
 public class FakeThirdPartySystem {  

   public static void main(String[] args) {  
     WireMockServer server = new WireMockServer(8081);  
     server.start();  
     server.stubFor(get(urlEqualTo("/someUrl"))  
         .willReturn(aResponse()  
             .withStatus(200)  
             .withFixedDelay(10000)  
             .withBody("Slow reply!")));  

     //This is just so that the app doesn't exit straight away
     Scanner scanner = new Scanner(System.in);  
     System.out.println("Press enter to exit");  
     scanner.nextLine();  
     server.stop();  
   }  

 }  

Note: This is just for illustration purposes but this same way of stubbing can be added to an acceptance test. 

Thursday, April 20, 2017

Browser automation in Java using Cucumber and Selenium


This is video I created to explain some of the very basics of browser automation in Java. Using the the classic tools Cucumber and Selenium.


Thursday, June 9, 2016

Mockito ArgumentCaptor example

Lets observe the following class

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
public class MyService {

    private Collaborator collaborator;

    public MyService(Collaborator collaborator) {
        this.collaborator = collaborator;
    }

    public void doSomething() {
        Thing thing = new Thing();
        thing.setType("ABC");
        collaborator.doStuffWith(thing);
    }
}

If we were to test the method doSomething() what we would be interested in,
perhaps mostly is to make sure that the collaborator that it uses is reached and the appropriate
parameters are passed. We could do that very easily by just verifying on a mock

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
public class MyServiceTest {

    private Collaborator collaborator = Mockito.mock(Collaborator.class);
    private MyService myService = new MyService(collaborator);


    @Test
    public void shouldDoSomething() throws Exception {
        myService.doSomething();
        verify(collaborator).doStuffWith(any(Thing.class));
    }
}


But there is a peculiar thing about this method. The argument that is passed into the collaborator
function doStuffWith() its using an object. Objects as its well known, contain other objects and/or
primitive variables. Since the object thing its being created internally in the method rather than be
injected(Its a hardwired dependency), we have no way of accurately knowing about it anything else but its type. So if we were curious about knowing more precisely about that object, what we would have to do is to spy on it. Mockito, allows us to spy on the objects that are passed to the mocks using a little tool called Argument Captor.
Let's have a look at how this test would look like if we were spying the object thing.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
public class MyServiceTest {

    private Collaborator collaborator = mock(Collaborator.class);
    private MyService myService = new MyService(collaborator);


    @Test
    public void shouldUseTheRightThing() throws Exception {
        ArgumentCaptor<Thing> argument = ArgumentCaptor.forClass(Thing.class);

        myService.doSomething();

        verify(collaborator).doStuffWith(argument.capture());
        assertThat(argument.getValue().getType(),is("ABC"));
    }
}

As you see, spying is an interesting way of in a non intrusive manner(without having to refactor), you can discover things about your code.

Now a question comes to our head. But declaring that object of type Thing in the method like that, is not an smell? Well, maybe but have in mind that if you were to inject that object from either the constructor or via a setter injection, we could say that you would be changing the api of the class. So that is not very good, because maybe you don't know if the clients that use the class are actually capable of providing the object thing or if would that even make sense form a design point of view.

To express this last point in a more pragmatical form, I am going to show you another 2 more intrusive refactoring to this class that could help you test that object, but that will need from you to sacrifice in design.  

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
public class MyService {

    private Collaborator collaborator;
    private ThingBuilder thingBuilder;

    public MyService(Collaborator collaborator, ThingBuilder builder) {
        this.collaborator = collaborator;
        this.thingBuilder = builder;
    }

    public void doSomething() {
        Thing thing = thingBuilder.withType("ABC").build();
        collaborator.doStuffWith(thing);
    }
}
If you had a builder, you could mock it and train it, but you would pay a design price of having to add the builder to the constructor.
Even if you choose to use a setter to set the builder or keeping the original constructor as it is(so you don't affect the clients) and overloading, you are still sacrificing your design for the purpose of the test. Your test would also become more complex. It would look like this:

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
@Test
    public void shouldUseTheRightThing() throws Exception {
        Thing thing = new Thing();
        thing.setType("ABC");
        when(thingBuilder.withType(anyString())).thenReturn(thingBuilder);
        when(thingBuilder.build()).thenReturn(thing);

        myService.doSomething();

        verify(collaborator).doStuffWith(thing);
    }
The other alternative I was thinking about would be to override equals and hashcode, so you could do a comparison in your test against a newly created object that would be the
expectation.

1
2
3
4
5
6
7
8
9
@Test
    public void shouldUseTheRightThing() throws Exception {
        Thing thing = new Thing();
        thing.setType("ABC");

        myService.doSomething();

        verify(collaborator).doStuffWith(thing);
    }

It looks naive, but again is intrusive. You are adding 2 methods in your entity, just for the purpose of making the test green.

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class Thing {
    private String type;

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Thing thing = (Thing) o;

        return type != null ? type.equals(thing.type) : thing.type == null;

    }

    @Override
    public int hashCode() {
        return type != null ? type.hashCode() : 0;
    }
}

Monday, June 8, 2015

Stefan Birkner's system-rules library

Just a super quick post about an interesting library I just discovered :)

Its very rare the case when you will have to test things such as an String being printed in the console or a System property being set from the program... But in occasions it happens that.

Last week I discovered a library called system-rules, from Stefan Birkner. http://stefanbirkner.github.io/system-rules/
It is really interesting and easy to use, it can help you easily do tests that involve java.lang.System

Lets just quickly saw an example.
Imagine that for some reason you want to test that the console prints some message... I don't know you, but the only way I know to do that, is to redirect the stream that goes to the console, to something that you can control and read from(e.g a file, a log...). This kind of test would have lots of boiler plate. It would look somehow like this:

 @Test  
   public void consoleOutputOldSchoolTest() throws FileNotFoundException {  
     //Create some text file where the output will be redirected, so you can make an assertion later.  
     File testingFile = new File("testingFile.txt");  
     //Create a testing stream and give the file to it  
     PrintStream testingStream = new PrintStream(testingFile);  
     //Keep a copy of the old console output stream  
     PrintStream consoleStream = new PrintStream(System.out);  
     //Reset the object out to the new stream  
     System.setOut(testingStream);  
     //Write something to the "console"  
     System.out.print("test");  
     //Rewire back to the original console output  
     System.setOut(consoleStream);  
     //Just an informative message  
     System.out.println("all back to normal");  
     //Read the output that we are testing  
     String output = new Scanner(testingFile).nextLine();  
     //Do your assertion  
     assertThat(output, is("test"));  
     //Delete the test file  
     testingFile.delete();  
   }  

With Stefan's library you can test the messages that go the terminal in the blink of an eye:

   @Rule  
   public final SystemOutRule systemOutRule = new SystemOutRule().enableLog();  
   @Test  
   public void systemRulesLibraryConsoleOutputTest() {  
     System.out.print("test");  
     assertThat(systemOutRule.getLog(), is("test"));  
   }  

Ok, now back to work now ;)

Wednesday, March 18, 2015

Contract testing

Let's imagine the following scenario...
We are working in distributed system with lots of applications.
The developers understand the importance of avoiding coupling amoung componets, so they decide to create restful applications to communicate via xml and json,
instead of building applications that are binary dependant with other applications.

During the development of a feature, the development team, did a change to the API, and unconciously they broke one of the consummer apps.
Unfortunately, this bug was really expensive, since the company just managed to discover it in its replica, pre-production environment by a long running
end to end functional test, after determining that what was broken was actually a marshaller of xml, there was no quick fix and they had to roll back.

In the root cause analysis meeting, developers from each of the teams, that own the apps that failed realised that the API change was the reason for the bug
and that there was no aditional work done in one of the unmarshallers.
The developers were told to fix the bug and also to come up with a solution that would avoid this from happening again.

After fixing the bug the developers toke some time to think how they could catch this kind of bugs before the pre-production environment where the expensive
integration tests run. One of them said, "What we need is consummer contract testing!"...

Consumer contract testing, allows consumers and providers of an API knowing if their latest changes on their marshallers or unmarshallers, could potentially be
harmful for the other party, without the necessity of performing an integration test. This is how it works:


1- The provider of the API, publishes an example of the API somewhere where he knows the consumer can access it(e.g publish it in a repo, sending it via email...).
2- The consummer takes the API example and writes a test that tolerantly accesses the values of interest.
   This in-document path(e.g xpath,jsonpath...) used to retrieve the values from the API example, is known as the contract.
3- The consummer publishes the contract in a place where knows the provider has access to it(e.g publish it in a repo, sending it via email...).
4- The provider will take the contract, and will use it in a test, against the generated output of the application. If the test fails when being run, the provider will know that they could potentially be breaking the the consumer, if they were to release the current version under test(a negotiation can take place).

Let's now have a look at a practical example of each of the steps above.

1- The developers that own the provider app, take from their passing acceptance test the output that the application is sending back to the consumer and they save
it into a file called "apiexample.xml", which looks like this:

 <output>  
      <content>  
           <partA>A</partA>  
           <partB>B</partB>  
      </content>  
 </output>  

They send this file over email to the team that owns the consumer application.

2- The developers that own the consumer app, will take the exampe and will write queries to it, to determine the contract they need. A unit test against the example, could be fine.

 @Test  
    public void apiExampleGeneratesValidatesToContract() throws Exception {  
     XPath xPath = XPathFactory.newInstance().newXPath();  
     String value = xPath.evaluate("/output/content/partB", getSource(readExample("apiexample.xml")));  
     assertThat(value,is(notNullValue()));  
    }  

3- Now that the developers know that the contract to access what they are interested in is:
 "/output/content/partB"
They can save it in a file called "contract.txt" and send it over email to the other team for they to make sure they will always be outputing according to the contract. Note that this tolerant
paths, allow to the provider to change any part of the API they want to change, as long as the contract is respected.

4- The provider will read the "contract.txt" file and will write a test where the contract will be applied to the applications output.

 @Test  
    public void apiExampleGeneratesValidatesToContract() throws Exception {  
     XPath xPath = XPathFactory.newInstance().newXPath();  
     String value = xPath.evaluate("/output/content/partB", getSource(readExample("apiexample.xml")));  
     assertThat(value,is(notNullValue()));  
    }  

Now when any of the teams run their builds, they will know if they are in breaching the contract and they will avoid the bug going further than the development environment.

You can find the complete source code of this example here.

Tuesday, September 23, 2014

The Add-Delete ratio as a metric of code quality

Recently after reading some articles about software quality metrics, I started thinking a lot about what would be for me a metric that really could reflect the quality of the code in the system I am working in.

I am not a big fan of numbers but in the same way of an altimeter is a useful thing you want to look at when you are driving a plane, a good code quality metric could give you warning signs about system that you are building.

In page 15 of the book "Clean Code" by R.C Martin, it says that the only valid measure of code quality is, "What The Fucks per second".



Couldn't agree more, but the only problem with this metric is that is not easy to reflect in a chart so all others can see it and therefore have an idea of how bad the system really is...

Time ago while talking to a colleague here in London, we came to the conclusion that a really good metric to reflect the quality of the code we write, is the "Added-Removed code ratio".

So this is basically the ratio of added to removed lines of code in your system. 
To measure this, what you do is:

1 - At a point in time, take your system as a whole and count the amount of lines of code, of the target language, lets say Java(Just java, dont take xmls and other configuration files...).

2 - At a future point in time, take again the same system, and count the lines again.

3 - Write down the ratios and take note of the percentages the amounts of line are increasing, or decreasing and present the data in some chart.

 This metric if tracked often, such as the altimeter, will warn your department about when you need to invest more time in technical debt, and when your system is sustainable and you can keep pushing features.

I guess you wonder, how do I know this is right? 
Well, it is very simple, we just need to understand the definition of re-factoring which is:

"a change made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behavior."

Re-factoring its very important, because the more understandable the system is, the better quality it will have. So it is not about just the smaller your code is, but about tracking the amount of effort you expend in adding and removing(specially removing) stuff from it.
- In a system where we see that the remove ratio numbers across time are going in a down trend(smaller gap between added and removed lines), it means that the developers are taking care and the overall  quality is improving.

- In a system where we see that the remove ratio numbers across time are going in an up trend(big gap between added and removed lines), it means that the teams are not investing enough time in improving the quality of the software they make.

I hope you liked the post, I appreciate feedback, this is just my opinion.



Monday, February 24, 2014

paranoia testing

Somebody told me once a funny story about a woman who day after day kept arriving late to work, because once on her way to the office, she kept having the need to go back home again and again just to check that she unplugged the iron from the wall socket. Her unfounded fear was such that one day she finally decided to take the iron with her to the office in her handbag.

A common unfounded fear that some developers sometimes have when working with the database, is that they will fail to query it for whatever reason and they feel the need of testing that the database is returning them the expected values. It is common to see horrible tests like this one:

   @Test  
   public void whenAddingANewUserTheUserIsSavedToTheDatabase() {  
     //Tell hibernate to add this user to the database   
     ormAdapter.add(userFactory("djordje", "123"));  
     //Find the user and check its values  
     User savedValueInDatabase = adapter.find("djordje");  
     assertThat(savedValueInDatabase.getName(),is("djordje"));  
     assertThat(savedValueInDatabase.getPassword(),is("123"));  
     //Delete the test data  
     ormAdapter.delete(savedValueInDatabase.getName());  
   }   

The above test has many problems, not just it is slow, also it is wrongly aimed because is not testing the functionality of the application, it just testing that some third party framework(hibernate in this case) is working properly.

Developers who do this, don't understand that the database is just a detail/add-on of the application.
It is fine to perform a smoke test to ping the database if they want(just to verify that the configuration of the ORM framework was correctly done), but testing that the HQL or the hibernate criteria are returning some values is wrong.
"Hibernate, MySQL, Oracle... all are just vendors, their solutions will work, you don't need to test them again!"

Focus on testing the functionality by mocking the dependencies you have with the database.
The only thing that counts at the end of the day is that the inputs and outputs to the service layer are processed correctly. If the data comes from a database, a file, a socket... doesn't matter at all.
Here an alternative test that will mock a dependency to the database and will check that the data is processed correctly:

   @Test  
   public void loginTest() {   
     PersonManagementAdapterORM adapterORM = mock(PersonManagementAdapterORM.class);  
     when(adapterORM.find("djordje","123")).thenReturn(new Person("djordje","123"));  
     LoginService service = new LoginServiceImpl(adapterORM);  
     boolean authorized = service.login("djordje","123");  
     verify(adapterORM).find("djordje","123");  
     assertThat(authorized,is(true));  
   }  

Now tests main concern is the functionality and not how the data is added to, or retrieved from the database.
I trained the mock to behave as expected and I verified that its behavoir was executed as expected.
The database was not at all a concern.

Friday, July 26, 2013

If you break something you have to pay for it!

Many years ago in Spain(as a kid) I was probably in second or third year of primary school, I had to buy a gift for somebody's birthday.
All I had was 500 pesetas(a bit less than 3 euros) and I wanted to buy something cheap, but at the same time beautiful and also decorative.
I was walking around the neighbourhood and not far away from my house, I found a glass craft shop.
I went into the shop and started walking the corridors, there were all sort of glass crafts: from ashtrays to lamps... and everything was all over the place, not just in selves also there were dozens of crafts on the ground.
Quickly I noticed a little figure with a price tag that said 500, that was the gift I wanted to buy. Unfortunately It was in the ground placed at least 2 meters away from were I was, and there were lots of other glass crafts on the way to it. If I wanted to reach it all I could do was move away each of those other crafts that were on the way. I carefully started doing it until I've got the figure I wanted. When I was ready to go back and turned around the shop attendant was looking at me and said: "If you break something you have to pay for it!", I've got a bit scared and... well... is up to your imagination how this story ended.

This story reminds me a bit to the feeling that we all have sometimes when unit testing some code: "Is this really a unit test?".
Sometimes we think we tested correctly but if we are not extra careful with our unit tests we might unconsciously be creating a poisonous integration test.

Let's have a look at an example:

1:  public class ProductDiscountCalculator {  
2:       public void apply50PercentDiscount(Product product) {  
3:            ProductManager manager = new ProductManager();  
4:            if(product.isExpired()) {  
5:                 product.setPrice(product.getPrice() - product.getPrice() * 0.5);  
6:            }  
7:            manager.updateProduct(product);  
8:       }  
9:  }  

We want to unit test the method in the above class and this is what we do:

1:  public class ProductDiscountCalculatorSpecification {  
2:       private ProductDiscountCalculator calculator;  
3:       private Product sampleProduct;  
4:       @Before  
5:       public void arrange() {  
6:            calculator = new ProductDiscountCalculator();  
7:            sampleProduct = new Product();  
8:            sampleProduct.setPrice(10);  
9:            sampleProduct.setExpired(true);  
10:       }  
11:       @Test  
12:       public void priceDiscounted50Percent() {  
13:            calculator.apply50PercentDiscount(sampleProduct);  
14:            assertThat(sampleProduct.getPrice(), is(5D));  
15:       }  
16:  }  

When we run this test, it will go green, but... Is this really a unit test?
What about this line:
 manager.updateProduct(product);  

That line is very dangerous, maybe it is accessing a database and we are poisoning it every time we run our tests.
That's why we need to have extra careful and make sure that we use techniques to break dependencies, stubs, fakes, spies, mocks... or anything
that takes, to make sure at 100% that we are unit testing.
Lets see how we can break the ProductManager dependency and create a more testable alternative:

1:  public class ProductDiscountCalculator {  
2:       private ProductManager manager;  
3:       public ProductDiscountCalculator(ProductManager manager) {  
4:            this.manager = manager;  
5:       }  
6:       public void apply50PercentDiscount(Product product) {  
7:            if(product.isExpired()) {  
8:                 product.setPrice(product.getPrice() - product.getPrice() * 0.5);  
9:            }  
10:            manager.updateProduct(product);  
11:       }  
12:  }  

In the above example we extract the dependency and make sure that we can set it from outside of the class.  We could do it different ways I just used composition for this example.

1:  public class ProductDiscountCalculatorSpecification {  
2:       class ProductManagerStub extends ProductManager {  
3:            @Override  
4:            public void updateProduct(Product product) {  
5:            }  
6:       }  
7:       private ProductDiscountCalculator calculator;  
8:       private Product sampleProduct;  
9:       @Before  
10:       public void arrange() {  
11:            calculator = new ProductDiscountCalculator(new ProductManagerStub());  
12:            sampleProduct = new Product();  
13:            sampleProduct.setPrice(10);  
14:            sampleProduct.setExpired(true);  
15:       }  
16:       @Test  
17:       public void priceDiscounted50Percent() {  
18:            calculator.apply50PercentDiscount(sampleProduct);  
19:            assertThat(sampleProduct.getPrice(), is(5D));  
20:       }  
21:  }  

In what regards to the test I used the subclass and override technique to make sure that we are not poisoning a the database if the real object was passed. Since the object that we are passing to the constructor of ProductDiscountCalculator is just an stub, we are now 100% sure that this was correctly tested without poisonous integration tests.

Share with your friends