When writing tests, there are always three words we need to remember. Arrange, act and assert! These three words can be used as a mnemonic of how a test should be structured.

The AAA (Arrange, Act, Assert) pattern is a standard way of writing tests for a subject under test. You can also find these rules written as "given, when, then" in other blog posts or books. The Arrange section of a test method initializes the subject under test and sets the value of the data that is passed as input. The Act section invokes the subject under test with the arranged parameter. The Assert section verifies that the action of the subject under test behaves as expected. Here you can find an example of this tests structure:

@Test fun showsSuperHeroNameAsPartOfTheSuperHeroScreen() { val superHero = givenThereIsASuperHero() showSuperHeroScreen() assertSuperHeroNameIsDisplayed() }

But today we are not going to review different ways of structuring your tests; today we have something new to announce! Today, smile 😃 and say cheese to Kotlin Snapshot 📸.

Kotlin Snapshot is a testing assertion library we've built based on Gabriel Aumala repository that simplifies how to make assertions. As other testing libraries we've released in the past, this library focuses on a different way of asserting the correct behavior of a test thanks to the use of snapshots. Highly inspired by Jest, KotlinSnapshot let you simplify your assertions saving a snapshot of your data the first time the assertion is evaluated and using this snapshot on consequent runs to verify the behavior of your software is the expected one. Snapshot tests are a handy and powerful tool whenever you want to make sure your software is still working, and you need to make assertions over a big data structure. Thanks to KotlinSnapshot you can transform a test like this:

@Test fun returnsAllTheTasksObtainedFromOurServer() { enqueueMockResponse(200, "getTasksResponse.json") val tasks = apiClient.fetchTasks() val firstTask = tasks[0] assertEquals(firstTask.id, "1") assertEquals(firstTask.userId, "1") assertEquals(firstTask.title, "delectus aut autem") assertFalse(firstTask.isFinished) val secondTask = tasks[1] assertEquals(secondTask.id, "2") assertEquals(secondTask.userId, "1") assertEquals(secondTask.title, "lorem ipsum") assertTrue(secondTask.isFinished) }

into this:

@Test fun returnsAllTheTasksObtainedFromOurServer() { enqueueMockResponse(200, "getTasksResponse.json") val tasks = apiClient.fetchTasks() tasks.matchWithSnapshot() }

Thanks to KotlinSnapshot, this matchWithSnapshot() call will save a snapshot file you can add to your repository with the information the list of tasks named tasks contains. Next time your tests are executed KotlinSnapshot will evaluate if the data is the same if someone introduces a bug the tests will fail, and you'll see an error report that will let you find the difference easily:

As you see in the previous examples, this assertion strategy could be helpful when you need to simplify your assertions. You can find all the information needed in the project GitHub repository. These different assertions doesn't replace your regular hamcrest or junit assertions, but it could be advantageous in some scenarios.

We'd like to continue working on this library by improving how it works. In the future, we'd like to improve how the library serializes data before taking the snapshot. Thanks to the new Kotlin 1.3 release we will be able to do it thanks to the new sealed classes reflection feature.

If you'd like to read more about this assertion technique named snapshot testing, we'd recommend you to take a look at the following blog posts. Even when these are related to UI testing or written using other programming languages, you can extrapolate the usage of the technique.

We hope you find the library useful and you can improve your tests thanks to KotlinSnapshot. Happy snapshot testing 📸 📸 📸

P.D: If you'd like to learn about how to write tests for your Android or iOS app take a look at this astonishing training we are offering.