Showing posts with label unit tests. Show all posts
Showing posts with label unit tests. Show all posts

Monday, 29 June 2020

AssertJ SoftAssertions JavaDoc

I recently came across a great example of JavaDoc. It was regarding the AssertJ SoftAssertions class.

It's in the references1.

In short, we have a dinner party hosted at a mansion.

And we're going to use a UnitTest with Assertions to determine if one of the guests has been murdered and who dun it.

It made me smile.

References

[1] SoftAssertions - AssertJ fluent assertions 3.16.1 API
https://www.javadoc.io/doc/org.assertj/assertj-core/latest/org/assertj/core/api/SoftAssertions.html

Wednesday, 25 December 2019

Improper Use of Softly Asserts

I don't really like Softly Asserts, and I notice that a lot of developers at work seem to use it all the time.

And since it's Christmas today (Merry Christmas!), let's get into the spirit of the season by testing if there is a Miracle on 34th Street.

We are going to use SoftlyAssertions with the following test written below:

And it looks fine if the tests run properly.

But when the tests fail, likely as not we see NullPointerExceptions instead of useful asserts.

Let's try to fail the test, by removing the town.

Street thirtyfourthStreet = new Street("34th Street", null);

And lo and behold, we get this:

java.lang.NullPointerException at com.mrbear.testingtests.SoftlyAssertionTest.testMiracleAt34thStreet(SoftlyAssertionTest.java:80)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:571)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:707)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:979)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
at org.testng.TestRunner.privateRun(TestRunner.java:648)
at org.testng.TestRunner.run(TestRunner.java:505)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
at org.testng.SuiteRunner.run(SuiteRunner.java:364)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1187)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1116)
at org.testng.TestNG.runSuites(TestNG.java:1028)
at org.testng.TestNG.run(TestNG.java:996)
at com.intellij.rt.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:66)
at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:110)

I really would like for SoftAssertions to only be used during checking of simple properties within an object, thanks!

And not this cross-boundary stuff.

Thursday, 30 May 2019

Unit Testing vs. Integration Testing

I was talking with a colleague on the way home, when we started talking about his troubles with his bike.

In short, he could turn the pedals like crazy, and the bike was not moving an inch.

That's when I realized that this is a perfect example of the difference between Unit Testing and Integration Testing.

In short:

unit test

write a unit test, to see if we can properly turn the pedals in the proper direction.

Conclusion: Success! Software works fine. In fact it works extremely well. We achieved a performance increase of over 500%! Yay!

integration test

write an integration test, to see if when we turn the pedals, the bicycle will move.

Conclusion: Failure! Pedals turn fine, but the bicycle doesn't move.

It turns out the integration between the component "pedals" and the component "wheels" was busted.

It totally shows that though Unit tests may all pass, it is not a guarantee that your software is actually doing what it should.

Lesson learned.

Thursday, 5 April 2018

ResourceBundle in Junit tests

I recently was wondering if it was possible and a good idea to test resource bundles in Unit Tests.

Most likely it is not, but in our case we were checking the layout of log messages. To see if the messages lined up properly.

It only works if the properties file is available in the resources of the project. (in our case the properties files are all in an unrelated project (parent project), so it was either moving the unit test to a bad place, or moving the property files.)

public class InternationalisationTest 
{

  @BeforeClass
  public void beforeClass() throws IOException 
  {
    InputStream contentStream = Thread.currentThread().getContextClassLoader()
        .getResourceAsStream("texts_nl.properties");
    assertThat(contentStream).isNotNull();
    ResourceBundle rb = new PropertyResourceBundle(contentStream);
    MessageUtilities.setResourceBundle(rb);
  }

  @AfterClass
  public void afterClass() 
  {
    MessageUtilities.resetResourceBundle();
  }

  @Test
  public void testMessage() 
  {
    assertThat(MessageUtilities.getMessage("file.not.found", "file.txt"))
      .isEqualTo("Bestand 'file.txt' niet gevonden.");
  }

}

References

Oracle JavaDoc - PropertyResourceBundle
https://docs.oracle.com/javase/7/docs/api/java/util/PropertyResourceBundle.html

Friday, 12 May 2017

Eradicating Non-Determinism in Tests

A small blog this time.

At work we sometimes have serious problems with non-deterministic tests.

Martin Fowler mentioned how this can be prevented or dealt with.1

I also noticed that these non-deterministic tests are (almost...) always in the end-to-end tests (or the functional tests, or however you wish to call them).

Martin Fowler also has something to say about those2

References

[1] MartinFowler - Eradicating Non-Determinism in Tests
https://martinfowler.com/articles/nonDeterminism.html
[2] MartinFowler - TestPyramid
https://martinfowler.com/bliki/TestPyramid.html

Thursday, 4 May 2017

REST-assured

I am a card-carrying member of the NLJUG0, which provides Java Magazine (not the Oracle one) six times per year.

One of the issues contained an article about REST-assured1.

I have been using SoapUI5 to test my REST services, and that works fine. It's a nice graphical userinterface for me to fiddle with parameters and urls and HTTP requests and even write tests.

I am aware that it is probably possible to integrate SoapUI into my Build Pipeline, but I was really looking for something different. Something more in the line of programming, which is of course my forte. Something I could use in my unit-tests.

REST-assured was exactly what I needed and let me tell you, it's great!

Usage

I will provide an example of how I use it.

As you can see, REST-assured is a very nice DSL (Domain Specific Language) and reads easily.

Some explanation of the above:
log().ifValidationFails()
I wish to log stuff, if the validation/test fails, so I can find out what is wrong. The output looks like
param(name, value)
for setting parameters at the end of the url, like ?stuff=value
pathParam(tag, value)
replaces {tag} in your url with the values. Convenient!
request methods
in the example above, we are using the PUT HTTP Request.
As it is used for testing, it is possible to verify the values afterwards. In the above this is visible as we expect to receive a 204 (NO_CONTENT).

We can extract the response, as is done above, to verify for example the json payload (if there is one) or get cookie values.

In the above example it is essential for the followup calls that we get the JSESSIONID cookie out of the request.

In subsequent REST calls, it is obvious that we need to send along the same JSESSIONID cookie.

See for more information reference [4].

Some notes

I tried to send parameters, but a POST defaults to FORM parameters in the body, but I already have a BODY. But using "queryParam" instead of "param" fixes this problem.

I do enjoy using the "prettyPrint" method on a Response, to properly format a JSON body and dump it to standard output and see what I get. It's nice.

Getting some values out of your JSON formatted response body does require some serious work, though. Needs more research.

I am not entirely sure, I do not enjoy using http status codes like 200 or 204. I prefer something more readable like "NO_CONTENT", but I suppose I can deal with it myself. No biggy.

Update 14/05/2017: I'm also slightly sorry to find out that rest-assured includes Hamcrest. I prefer AssertJ at the moment myself.

Postscriptum

The article in Java Magazine also mentioned WireMock3.

Though I do not use it, it seems excellent for testing the other side of the communications, if you need to test a client that communicates with a server via rest calls.

References

[0] NLJUG
http://www.nljug.org/
[1] REST-assured
Teije van Sloten Java Magazine | 01 2017
[2] GitHub - Java DSL for easy testing of REST services
https://github.com/rest-assured/rest-assured
[3] WireMock
http://wiremock.org/
[4] GitHub - RestAssured Usage
https://github.com/rest-assured/rest-assured/wiki/usage
[5] SoapUI
https://www.soapui.org/
Testing REST Endpoints Using REST Assured
https://semaphoreci.com/community/tutorials/testing-rest-endpoints-using-rest-assured
RFC2616 - HTTP status codes
https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html