Kotlin Multiplatform (KMP) plugin and library for reading resources in tests.
It bridges the gap between different Kotlin Multiplatform targets, allowing you to access files from your resources folders in a single, consistent way.
Apply the plugin and add the library as a dependency in your build.gradle.kts:
plugins {
id("com.goncalossilva.resources") version "<version>"
}
// ...
kotlin {
sourceSets {
val commonTest by getting {
dependencies {
implementation("com.goncalossilva:resources:<version>")
}
}
}
}Replace <version> with the latest version shown in the badge above.
Different Kotlin versions require different versions of the plugin/library:
| Kotlin | kotlinx-resources |
|---|---|
| 2.1 and above | 0.10 and above |
| 2.0 | 0.9 |
| 1.9 and below | 0.8 and below (plus k1 branch) |
To access a file in your tests:
- Place it in a
resourcesfolder. For example, insrc/commonTest/resources/to have it available in all targets, orsrc/jsTest/resources/to limit access to JS. - Instantiate a
Resourceclass with the path relative to that folder.
For a file located at src/commonTest/resources/data/example.json:
import com.goncalossilva.resources.Resource
class MyTest {
@Test
fun `example data exists`() {
val resource = Resource("data/example.json")
assertTrue(resource.exists())
}
@Test
fun `example data ends in a newline`() {
val content = Resource("data/example.json").readText()
assertTrue(content.endsWith("\n"))
}
}For Android device tests, resources are packaged as assets. Place them under src/androidDeviceTest/resources/ and access using the same relative paths:
import com.goncalossilva.resources.Resource
import kotlin.test.Test
import kotlin.test.assertEquals
class AndroidResourceTest {
@Test
fun readsFromAssets() {
assertEquals("hello", Resource("data/hello.txt").readText().trim())
}
}The Resource class provides a clean and simple API:
class Resource(path: String) {
// Checks if the resource exists at the given path.
fun exists(): Boolean
// Reads the entire resource content as a string decoded using the specified charset.
fun readText(charset: Charset = Charsets.UTF_8): String
// Reads the entire resource content as a byte array.
fun readBytes(): ByteArray
}Library tests use the library itself, so they serve as a practical example.
See ResourceTest for example usage, and resources-test/src/commonTest/resources for the associated folder structure for resources.
As a rule of thumb, place test files in src/commonTest/resources/. This avoids collisions entirely.
But if you want to override a common file, you can have a platform-specific version of it in the platform-specific source set (e.g., src/jvmTest/resources/). By default, Gradle will throw a "Entry (...) is a duplicate" error during the build process, prompting you to set a duplicateStrategy in your build.gradle.kts.
To have platform-specific resources override common ones, set the strategy to EXCLUDE:
afterEvaluate {
tasks.withType<AbstractCopyTask>().configureEach {
if (name.contains("Test") && (name.endsWith("Resources") || name.endsWith("JavaRes"))) {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
}
}Other DuplicatesStrategy options are available, but avoid INCLUDE, as the override behavior becomes inconsistent across platforms.
In browser runtimes, readBytes() uses a synchronous XHR-based implementation to keep the API synchronous.
Some browser+tooling stacks can corrupt leading UTF-16 BOM bytes (0xFF 0xFE / 0xFE 0xFF), which makes
readText(Charsets.UTF_16) unreliable for UTF-16 files that include a BOM. Prefer Charsets.UTF_16LE /
Charsets.UTF_16BE (or files without a BOM) for browser tests.
This library is inspired by this gist by @dellisd.
Released under the MIT License.