Advanced Testing Patterns

As presented @ KDG University College

Session Content


Slides available as pdf.


The code is available on Github <3

Discussed Topics:


Why do you call the instance of the class you are testing “sut”?

“sut” is short for “Subject/System Under Test” and makes it clear what class the focus of the test is. If your testclass is very big, I have found that using “sut” is easier than relying on the name of the testclass (scrolling up).

Is it possible to generate Liquibase files from code?

Apparently, there is a way to do that. Never seen it used before.

The power of Liquibase for me is in being able to design the schema once and Liquibase will handle the details of different databases for us. Makes working in a larger team way easier, as Liquibase can make sure everyones database is aligned with what the code expects (if done right)

For the TestContainers frame, do you need Docker installed?

Yes, but that is all you really need! So I don’t consider it much of a big deal. Most buildservers/testservers already have a Docker on them these days.

TestContainers: Do they spin up a new container for every test, or does it create a new one each time?

Well, you can configure it to do whatever you want. The default is pretty much that it keeps running.

This is pretty important to know when you are running your tests. If you use a container with a database (ex. PostgreSQL) and it keeps running, you might need to run some cleanup script to remove data from previous tests. That part is pretty much up to you! :-)

Contract Testing: If the contract changes, do both Consumer and Producer see it / get the changes?


If a contract is agreed upon between Consumer and Producer, the general assumption is that it will not change without notice. Much like a real contract (buying a house, employment), any change in contract should be communicated between parties.

  • Consumer wants an extra field? -> contract change
  • Producer wants to remove a field? -> contract change

The real power is in what the contracts provide in the example case:

  • Consumer gets a stub which matches the contract, so they can test their app against a realistic stub. If the consumer breaks the contract, maybe because they are not sending enough fields in the request, the stub will send an error. Normally, consumers should have a test for this.
  • Producer gets tests to validate the contract. If he would break the contract, a test will fail and they can see exactly which contract was broken.

So, contract changes will not be automatically passed to the consumer, because there shouldn’t be a change in contract without communication between consumer and producer.