Categories
Development Tech

Reduced complexity with HTMX on the front end?

I recently stumbled upon HTMX and found the concepts really interesting. Many front ends does not have to be a SPA, and I think HTMX can be a really simple and efficient tool for many of the pages that I make. Even quite close to SPA in dynamic behaviour.

I have been playing around with KTor, TailwindCSS and HTMX and it is a really powerful combination. I will share some more details on that stack in a different post later. 🙂

There is a free book online. It is worth a read. I even picked up some new things about HTTP. You can find it here: https://hypermedia.systems/book/contents/

Anyway, check it out and let me know what you think.

Subscribe below for updates.

Categories
Development Tech

Better syntax highlighting in Intellij IDEA

Free code on a MacBook

Quick tip if you’re using Intellij IDEA and not every framework is supported: Add the annotations dependency.

This enables IDEA to get information about certain things in your code and apply the correct validation, information and/or formatting.

We only use it for one thing so far: Marking strings as SQL. That enables IDEA to recognize it and apply the correct highlighting.

The below example shows a wrapper method we have for JDBI, and because of the @Language annotation IDEA knows that it should apply SQL syntax highlighting.

fun createQuery(@Language("sql") sql: String): Query
Kotlin

Dependency:

implementation("org.jetbrains:annotations:24.0.0")
Kotlin

Try it out! 🙂


Subscribe for more 🙂

Categories
Development

JUnit and ParameterResolver — Caching database connections in your tests

This is a re-post of an original Medium article. As I am moving my content here I will re-post some content.


Car speeding on the road

We aim for fast tests, ideally completing all tests within 30 seconds. Currently, our tests take 1 minute and 30 seconds, but we are determined to to get ther. 😃 To achieve this goal, we must reduce the overhead of each run.

Read on to learn about the techniques we use to speed up DB connection handling and migrations.


We aim to minimize the number of database tests we write by using fakes, but we still require some tests to verify our DB layer. We just don’t want the majority of our tests slowed with network access (even locally in Docker).

Establishing connections takes time, and the overhead of checking migrations before each test can also be time-consuming. We usually run a persistent DB in a Docker container, so we only have to create connections and migrate once for each run. We do use Test Containers if no DB is available, but it is slower. Every millisecond counts. 😃

Therefore we looked for a way to minimize this when running thousands of tests.

JUnit enforces strict isolation between tests so you can’t just inherit a class or something and get a shared value across the run. But as we knew Spring caches contexts across tests, there had to be a way. JUnit ParameterResolvers come to the rescue:

class DatabaseTestExtension : ParameterResolver {
private val STORE_NAME = "main-database"
override fun supportsParameter(parameterContext: ParameterContext, extensionContext: ExtensionContext?): Boolean {
return parameterContext.parameter.type == Database::class.java
}
override fun resolveParameter(parameterContext: ParameterContext, extensionContext: ExtensionContext): Any {
// We do the store thing here to avoid loading and migrating the DB for each test/class
// Will however load per thread, so are not guaranteed to be done only once
val store = extensionContext.root.getStore(Namespace.create(DatabaseTestExtension::class.java.simpleName))
val db: Database = (store.get(STORE_NAME) as Database?) ?: Database(Config.load()).also {
// New object so do initialization and store
it.initializeAndMigrate()
store.put(STORE_NAME, it)
}
return db
}
}

The Database and Config objects are just custom wrappers around HikariJDBI and Liquibase. You can store the JDBI object or a Hikari connection pool directly by changing the code above and adjustinng the class type. The important part is putting it in the store so it is persisted across runs.

To use it you do something like this:

@Test
@ExtendWith(DatabaseTestExtension::class)
fun testSomething(db: Database) {
}

Pro tip: You can add the ExtendWith annotation to the entire test class, not just the test method.

And just like that you have a resource that won’t take extra time/load to run when running all your tests. 😃


Subscribe for further updates 🙂