skip to content

When should you use assertTrue/assertFalse over assertEquals, and what does the lambda-message overload give you?

level: middleimportance: should knowfreq 50%

answer

  1. assertTrue/False for real predicates
  2. prefer assertEquals to show both values
  3. assertTrue(a==b) -> weak 'expected true' message
  4. lambda overload: message/condition lazy
  5. block form: assertTrue { ... }

basics

~20 s

Use assertTrue/assertFalse for genuine yes/no conditions like isEmpty() or contains(). For comparing two values use assertEquals because it shows both values on failure. assertTrue also has a form where the message is built only if the test fails.

solid answer

~30 s

`assertTrue(actual, message?)` fails unless the boolean is `true`; `assertFalse` is its mirror. Reach for them only for real predicates (`list.isEmpty()`, `"abc".contains("z")`, range checks) — for comparing two concrete values prefer `assertEquals`, because `assertTrue(a == b)` only prints 'expected true' whereas `assertEquals(a, b)` prints both operands. assertTrue also has a lazy overload `assertTrue(message: String? = null, block: () -> Boolean)` (and a block-only form). The lambda message/condition is evaluated lazily, so an expensive diagnostic string is only built when the assertion actually fails, not on every passing run.

code

kotlin · 8 lines
kotlin
import kotlin.test.assertTrue
import kotlin.test.assertFalse

assertTrue(list.isEmpty())
assertFalse("abc".contains("z"), "should not contain z")

// lazy message + block: built only on failure
assertTrue(message = "value was $value") { value > 0 }

go deeper

for a junior

Knows assertTrue passes on true and assertFalse on false, with an optional message.

for a middle

Chooses assertEquals over assertTrue(a==b) for better messages and knows the lambda-message overload exists.

for a senior

Explains lazy evaluation of the message/block overload and picks the most specific assertion for diagnosability.

for a principal

Frames 'most specific assertion = best failure signal' as a testing standard and weighs message-construction cost in large suites.

## `assertTrue` and `assertFalse` These check a `Boolean` condition. - `assertTrue(actual, message?)` fails unless `actual` is `true`. - `assertFalse(actual, message?)` fails unless `actual` is `false`. ```kotlin import kotlin.test.assertTrue import kotlin.test.assertFalse assertTrue(list.isEmpty()) assertFalse("abc".contains("z"), "should not contain z") ``` ### The lazy-message overload There is a second form where the **message comes first as a lambda** that is only evaluated on failure: ```kotlin assertTrue(message = "value was $value") { value > 0 } // or the block form assertTrue { user.isActive } ``` The lambda overload `assertTrue(message: String? = null, block: () -> Boolean)` lets you build an expensive message string without paying the cost when the test passes. ### Why prefer the specific assertion `assertTrue(a == b)` works but produces a poor message (just "expected true"). Prefer `assertEquals(a, b)` which prints both values. Use `assertTrue`/`assertFalse` only for genuine boolean predicates (`isEmpty()`, `contains()`, range checks) where there is no richer specific assertion.

  • Why is assertTrue(a == b) discouraged?
    Its failure message is just 'expected true'; assertEquals(a, b) prints both expected and actual, making the failure diagnosable.
  • What does the lambda overload save you?
    The message (and/or condition) is computed lazily — only when the assertion fails — avoiding the cost of building diagnostic strings on every passing run.

saying these in an interview costs you the question

  • Uses assertTrue(a == b) instead of assertEquals
  • Thinks assertTrue prints both values on failure
  • Unaware of the lazy/lambda message overload
  • Confuses assertTrue and assertFalse semantics
  • Builds expensive eager messages on the hot path

context