question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Assert with JUnit for easier debugging in Android Studio

See original GitHub issue

I’ve been using Kluent in Android projects for years because the syntax is great and I really like writing tests with it. However, there has always been a little problem when comparing “big” structures like data classes or with several fields or long lists. The error message printed by assertion methods of kotlin.test get really hard to read when the toString() methods of the compared objects are very large. For reference here is how it is implemented:

fun assertEquals(message: String?, expected: Any?, actual: Any?): Unit {
        assertTrue({ messagePrefix(message) + "Expected <$expected>, actual <$actual>." }, actual == expected)
    }

As you can see the message gets printed on a single line. When it gets wrapped in a terminal it’s really hard to figure out what is going on. Consider this example that compares lists of timestamps:

    @Test
    fun test_equal_lists() {
        val listA = listOf(1590026561, 1590026579, 1590026590, 1590026597,
            1590026608, 1590026619, 1590026639, 1590026648)
        val listB = listOf(1590026561, 1590026579, 1590026590, 1590026597,
            1590026608, 1590026619, 1590028639, 1590026648)
        listA `should be equal to` listB
    }

One of them is off by a single digit. This is the console output :

Screenshot from 2020-05-20 21-51-09

This list isn’t really that long, but it’s really hard to spot that wrong digit. It would be nice if the objects could be printed on different lines so that they can be compared side by side. Unfortunately no matter how we print it, it’s going to be hard figure out errors on a console because toString() implementations don’t follow any standards whatsoever.

I think the best bet here is to leave this job to existing tooling. Android Studio has great integration with JUnit 4. When you create a new project, you get example tests generated with JUnit 4. This tests use org.junit.Assert.* methods for assertion. When assertEquals fails it prints each object on a different line as I suggested earlier. But the really cool thing here is that when the assertion fails you get a nice “Click to see difference” link that opens a new window that highlights the difference. You can see it here:

Screenshot from 2020-05-20 21-51-39

Screenshot from 2020-05-20 21-53-17

To get this in my tests I can easily implement should be equal to like this:

import org.junit.Assert.assertEquals

infix fun <T> T.`should be equal to`(expected: T?): T {
    assertEquals(expected, this)
    return this
}

This would be pretty easy to implement, but it’s a significant change nevertheless. A good thing is that the API remains the same. The only problem that I see is that if your setup doesn’t include JUnit 4, then there aren’t much benefits. I’d assume that if this works on Android Studio, it works on all of JetBrains IDEs as well, but I really don’t know. Let me know what you guys think.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:5 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
GAumalacommented, May 24, 2020

Ok, I’ve been looking up things in Kotlin’s source code for hours and this isn’t a bug on kotlin.test, we’re just using it wrong.

The folks at JetBrains seem to want to provide good testing tools without getting coupled to a single testing framework. Naturally, Kluent should do the same.

Under the hood kotlin.test uses an Asserter interface to delegate the actual assertions. When the assertions API loads, it uses ServiceLoader to look for an AsserterContributor implementation in the classpath that can contribute a different Asserter implementation. JetBrains already provides contributors for both JUnit 4 and 5 in different artifacts.

So, to get diff viewers with Kluent, all I have to do is add this line to my build.gradle:

    testImplementation "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version"

No additional configuration is required. Maybe we could add this to the README.

0reactions
MarkusAmshovecommented, Jun 1, 2020
Read more comments on GitHub >

github_iconTop Results From Across the Web

Assert - Android Developers
java.lang.Object. ↳, junit.framework.Assert ... A set of assert methods. Messages are only displayed when an assert fails.
Read more >
How to use assert in Android Studio - Stack Overflow
1 Answer 1 ... The adb shell setprop debug.assert 1 from your referred question is to be executed on the device you are...
Read more >
Unit Testing in Android Studio given when then assertTrue
Write a simple unit test in Android Studio with an InstrumentationTestCase, given when then syntax, an interface, a stub, and a test runner....
Read more >
Migrating from JUnit 4 to JUnit 5: Important Differences and ...
Update imports to remove JUnit 4 and add JUnit 5. · Globally replace old annotations and class names with new ones. · Update...
Read more >
Tips & Tricks for Debugging in Android Studio | by Danish Amjad
Log filtering; Folding logs; Conditional breakpoints; Apply changes; Analyze stacktrace. Demo Application. To start, I've created a really simple ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found