DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Because the DevOps movement has redefined engineering responsibilities, SREs now have to become stewards of observability strategy.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Related

  • How to Build a React Native Chat App for Android
  • How To Create a Homescreen Widget in Android
  • Be Punctual! Avoiding Kotlin’s lateinit In Spring Boot Testing
  • Transitioning From Groovy to Kotlin for Gradle Android Projects

Trending

  • Enforcing Architecture With ArchUnit in Java
  • The Role of AI in Identity and Access Management for Organizations
  • Monolith: The Good, The Bad and The Ugly
  • Resolving Parameter Sensitivity With Parameter Sensitive Plan Optimization in SQL Server 2022
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. Testing, Tools, and Frameworks
  4. Automated Android Testing With Kotlin

Automated Android Testing With Kotlin

Learn how to write UI and unit tests in Kotlin with the Espresso and JUnit frameworks in Android Studio, and related app development techniques.

By 
Niklas Wuensche user avatar
Niklas Wuensche
·
Sep. 03, 17 · Tutorial
Likes (6)
Comment
Save
Tweet
Share
17.1K Views

Join the DZone community and get the full member experience.

Join For Free

This article is featured in the new DZone Guide to Automated Testing. Get your free copy for more insightful articles, industry statistics, and more! 

As of  Android Studio Version 3.0, Kotlin is officially joining the Android language family. However, we don’t want to lose our ability to test our app by using a different language. Luckily, we can use our Java knowledge and many new techniques to test our apps in Kotlin.
After reading this article, you should be able to:

  1. Set up Kotlin in Android Studio.
  2. Write unit tests in Kotlin.
  3. Write UI tests in Kotlin.
  4. Use extension functions.

Why Kotlin?

Kotlin’s simple and elegant. If you have a Java background, you’re ready to develop in Kotlin. Some of the best Kotlin features are:

  • 100% compatible with Java and all of its libraries.
  • Extension functions.
  • Awesome frameworks for Android development.

Of course, we will talk about all of these features later on.

Why Should We Create Tests?

Testing should be an integral part of every developer’s routine. If you release an app, there should be no bugs left. You definitely don’t want your users to find bugs because this will damage your reputation as a developer. This alone should be more than enough motivation for you to start testing if you haven’t done so already.

So, let’s learn how to set up Kotlin in Android Studio.

Set Up Kotlin in Android Studio

Since Kotlin is a language developed by JetBrains, the support for Kotlin in Android Studio is superb. First off, you’ll have to install the Kotlin Plugin in Android Studio. To do this, just install it in the File > Settings > Plugins > Install JetBrains plugin...dialog. Now, we’ll need to import or create a Java app.

After you’ve done this, you have to convert the Java files into Kotlin files. Just open a Java file and press Ctrl + Alt + Shift + K. By the way, Java and Kotlin can work side-by-side, so if you don’t want to convert all your files, that should work just fine.

Right now, Android Studio will probably tell you that Kotlin isn’t configured. To do this, just press Configure > Android with Gradle > OKand sync Gradle. Voilà, you are ready to develop in Kotlin.

Our Example App

Before we can start testing an app, we actually have to create one. For this guide, we will test an app that takes the name of the user and creates a greeting. The app consists of two input views, one output view, and a button. You can find the finished project on GitHub.

We use one input view for the first name and one for the last name. When you click the button, the message Hello $firstName $lastName! will appear in the output view. Underneath the surface, the message will be computed by a function fun greeting(firstName: String, lastName: String): String, which we’re going to test later on.

In the next section, we are going to create unit tests for this app.

Unit Tests

Unit tests check the concrete functions and their output but don’t interact with the UI. The default framework for writing unit tests is Android’s JUnit, so we’re going to use it too.

Our app has two test cases that need to be checked. First, we have to test that our greeting() function returns the right message if the first and last name parameters aren’t empty. Second, we want to check that the same method returns an empty string if the first or last name is empty.

With this in mind, let’s look at the default Android Studio unit test class.

Our Default Test Class

After we convert the default unit test class into Kotlin, it should look something like this:

Kotlin
 
class ExampleUnitTest {      
  @Test
  fun addition_isCorrect() {
    assertEquals(4, (2 + 2).toLong())
  }
}


As you can see, unit tests in Kotlin look like the ones in Java so that we can reuse and extend our knowledge. As we’ve discussed earlier, we have two cases we have to test.

Without further ado, let’s get to testing.

Our Unit Tests

Check Normal Behavior and Extend JUnit

Kotlin
 
class ExampleUnitTest {
  @Test
  fun testNormalGreeting() {
    greeting(firstName = “first”, lastName = “last”)
    equals “Hello first last!”
  }
}

infix fun Any?.equals(o2: Any?) = assertEquals(this, o2)


If you’ve written any unit tests before, this should look pretty familiar to you. We check greeting()
with a first and last name and test whether or not greeting() returns our desired message.

We’ve also added an extension function. It helps us to make our code more readable by hiding redundant code.

The extension function converts assertEquals() into an infix function. You could do the same, for example, for assertThat() or assertArrayEquals(). Next, let’s test greeting() with empty parameters.

Check Empty Parameters

Kotlin
 
class ExampleUnitTest {
  //...
  @Test
  fun testEmptyFirstName() {
    greeting(firstName = “”, lastName = “last”) equals “”
  }

  @Test
  fun testEmptyLastName() {
    greeting(firstName = “first”, lastName = “”) equals “”
  }
}
//...


When you look at this case, you shouldn’t forget that we have two parameters that can be empty.
Nevertheless, for both tests, the greeting() should return an empty message.

And that’s it for our unit tests. We created all the necessary tests for greeting(). Now, we can close our unit test files and step right into UI tests.

UI Tests

Up until now, we have just created tests for the internal mechanisms inside our app. Unfortunately, if our UI’s broken, unit tests won’t warn us. They don’t rely on the UI, but users do! For this reason, we have to test it. UI tests interact with the UI, not with the underlying method calls. They check that everything works hand-in-hand when the user interacts with the app.

We will use the Espresso framework for our UI tests. It’s already part of our app and works really well.

How To Set Up Espresso

As you can see, there isn’t only a default test class for unit tests but a class for integration tests, too! The latter one can be used for our UI tests. However, we need to prepare the class for Espresso by adding a rule. Otherwise, our tests will fail.

In the end, it should look something like this:

Kotlin
 
@RunWith(AndroidJUnit4::class)
  class MainActivityTest {
    @Rule @JvmField val activity = 
ActivityTestRule<MainActivity>(MainActivity::class.java)
    @Test
    //...
  }


Next, we can consider for which cases we have to create UI tests.

Our UI Tests

The test cases are still the same as in our unit tests, but this time, we are going to check the UI. UI tests are really easy to read, so even if you haven’t seen any UI tests before, you will understand the following example:

Check Normal Behavior

Kotlin
 
@RunWith(AndroidJUnit4::class)
  class MainActivityTest {
    @Rule @JvmField val activity =
    ActivityTestRule<MainActivity>(MainActivity::class.java)

    @Test
    @Throws(Exception::class)
    fun testNormalGreeting() {
      val firstName = “first”
      val lastName = “lastName”
      val expected = “Hello $firstName $lastName!”
      onView(withId(R.id.firstNameView)).
perform(typeText(firstName))
      onView(withId(R.id.lastNameView)).
perform(typeText(lastName))
      R.id.messageButton.click()
      onView(withId(R.id.messageView)).
check(matches(w ithText(expected)))
    }
  }
  fun ID.click() = onView(withId(this)).
  perform(ViewActions.click()


And here’s our very first Espresso test! This test writes the first and last name into the input view, presses the button, and checks that our output view contains the right message. As you can see, the extension function can help us create UI tests too. In the next example, we will use many more.

Check Empty Input Views

If one of the input views is empty, the output view should remain empty. However, we also want to display a Toast that tells the user what went wrong. Because a Toast lacks an ID, we have to find it by its message. This message is: You forgot to write your full name!

Kotlin
 
@RunWith(AndroidJUnit4::class)
class MainActivityTest {
  //...

  @Test
  @Throws(Exception::class)
  fun testEmptyFirstName() {
    R.id.firstNameView.write(“”)
    R.id.lastNameView.write(“last”)
    R.id.messageButton.click()
    R.id.messageView.textEquals(“”)
    activity containsToast “You forgot to write your full name!”
  }

  @Test
  @Throws(Exception::class)
  fun testEmptyLastName() {
    R.id.firstNameView.write(“first”)
    R.id.lastNameView.write(“”)
    R.id.messageButton.click()
    R.id.messageView.textEquals(“”)
    activity containsToast “You forgot to write your full name!”
  }
}


(You can find all extension functions on GitHub.)

As you can see, most Espresso methods consist of two parts:

  1. Find the view you need.
  2. Do something with this view.

You have many, many choices for both parts. But all of them work in the same way. You can find more methods on this site.

Next Steps

Now, you know the basic concepts of how to test your app in Kotlin. You know how to set up Kotlin in Android Studio, how to write unit tests with JUnit and UI tests with Espresso, and how to simplify them by using extension functions.

But there are many techniques left to learn. You can learn how to use functional programming, UIAutomator, Kotlinx, and KotlinTest in your tests. And always keep in mind that if your Kotlin code doesn’t look good, there’s probably a better way.

unit test Kotlin (programming language) Android (robot) app

Published at DZone with permission of Niklas Wuensche, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • How to Build a React Native Chat App for Android
  • How To Create a Homescreen Widget in Android
  • Be Punctual! Avoiding Kotlin’s lateinit In Spring Boot Testing
  • Transitioning From Groovy to Kotlin for Gradle Android Projects

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!