Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Kotlin all your tests (CodeFest.ru 2017)

Kotlin all your tests (CodeFest.ru 2017)

Kotlin was the rising star of programming languages in 2016. It not only became final with version 1.0 but also got rapidly adopted in the android community. But many companies are struggling to add Kotlin to an existing Java project. It's not easy to add a new language to an existing team. But it's much easier to introduce Kotlin to your project using the backdoor: your unit tests. So let's look at Kotlin more from a testing perspective. How does it look like to write tests in Kotlin, what possibilities of the language will help us?

A8b79d304b5184e5a5b0a109590f6683?s=128

Danny Preussler

April 01, 2017
Tweet

Transcript

  1. Kotlin all your tests Danny Preussler Android Lead, (Google Developer

    Expert)
  2. Kotlin all your tests Danny Preussler Android Lead, (Google Developer

    Expert)
  3. fun test() Kotlin all your tests Danny Preussler Android Lead,

    (Google Developer Expert)
  4. @PreusslerBerlin

  5. @PreusslerBerlin Our world so far …

  6. @PreusslerBerlin Android Firewall by Uncalno Tekno, CC, flickr.com/photos/uncalno/8538679708

  7. @PreusslerBerlin Watch the cool kids …

  8. @PreusslerBerlin onika Durickova, CC, flickr.com/photos/98873911@N07/15683534672

  9. @PreusslerBerlin But then …

  10. @PreusslerBerlin http://davidojedalopez.com/2016/06/07/getting-started-with-kotlin-for-android-development/

  11. @PreusslerBerlin Fly into new horizons ! (c) Sunny M5, CC

    flickr.com/photos/84935187@N04/16171765851
  12. @PreusslerBerlin Kotlin stole the best from the best

  13. @PreusslerBerlin Kotlin stole got inspired by the best from of

    the best
  14. @PreusslerBerlin JVM based

  15. @PreusslerBerlin Functional inspired

  16. @PreusslerBerlin Statically typed

  17. @PreusslerBerlin Statically typed val number = 5

  18. @PreusslerBerlin Designed with Android in mind

  19. @PreusslerBerlin Null safe

  20. @PreusslerBerlin Null safe

  21. @PreusslerBerlin Reduce boilerplate

  22. @PreusslerBerlin No need for Java8

  23. @PreusslerBerlin Awesome tooling support

  24. @PreusslerBerlin Awesome tooling support

  25. @PreusslerBerlin Excited by eltpics, CC flickr.com/photos/eltpics/14554630040

  26. @PreusslerBerlin BUT

  27. @PreusslerBerlin The Boss by Joselito TagaraoFollow, CC, flickr.com/photos/lidocaineus/7803665222/

  28. @PreusslerBerlin “No Kotlin in production”

  29. @PreusslerBerlin Depressed by wheatfieldbrown, CC flickr.com/photos/wheatfieldbrown/2233487982

  30. @PreusslerBerlin But wait …

  31. @PreusslerBerlin But wait … A backdoor

  32. @PreusslerBerlin No one cares about your tests anyway right?

  33. @PreusslerBerlin Tests are a safe place for experiments

  34. @PreusslerBerlin Let’s test in Kotlin

  35. @PreusslerBerlin Kotlin is expressive

  36. @PreusslerBerlin @Test void testHandlesNullArguments()

  37. @PreusslerBerlin @Test fun testHandlesNullArguments()

  38. @PreusslerBerlin @Test fun testHandlesNullArguments()

  39. @PreusslerBerlin @Test fun handlesNullArguments()

  40. @PreusslerBerlin @Test fun handles_null_arguments()

  41. @PreusslerBerlin @Test fun ‘handles null arguments’()

  42. @PreusslerBerlin Readability first

  43. @PreusslerBerlin String jsonText = "{\r\n \"deal\" : {\r\n \"isTipped\" :

    true,\r\n \"id\" : \"D- Company-241907\",\r\n \"areas\" : [],\r\n \"smallImageUrl\" : \"http://uat- static.groupon.de/00/00/small0000.jpg\",\r\n \"finePrint\" : \"MULTI DEAL ext Codes\",\r\n \"says\" : {\r\n \"emailContent\" : \"\",\r\n \"id\" : \"\",\r\n \"websiteContent\" : \"\",\r\n \"title\" : \"\",\r\n \"websiteContentHtml\" : \"\",\r\n \"emailContentHtml\" : \"\"\r\n },\r\n \"endAt\" : \"2014-03-31T22:59:00Z\",\r\n \"shortAnnouncementTitle\" : \"D-Company: 50% sparen in QA_AutoTestCity2\",\r\n \"placeholderUrl\" : \"http://assets2.grouponcdn.com/images/groupon/grayPlaceholder.png\",\r\n \"shippingAddressRequired\" : false,\r\n \"type\" : \"groupon\",\r\n \"isSoldOut\" : false,\r\n \"priority\" : 0,\r\n \"options\" : [\r\n {\r\n \"status\" : \"open\",\r\n \"title\" : \"MULTI DEAL ext Codes Option1\",\r\n \"isLimitedQuantity\" : false,\r\n \"tax\" : {\r\n \"amount\" : 16,\r\n \"currencyCode\" : \"EUR\",\r\n \"formattedAmount\" : \"0,16 \u20AC\"\r\n },\r\n \"minimumPurchaseQuantity\" : 1,\r\n \"expiresInDays\" : 62,\r\n \"discount\" : {\r\n \"amount\" : 100,\r\n \"currencyCode\" : \"EUR\",\r\n
  44. @PreusslerBerlin val jsonText = """ { "channels":{ "BOOKING":1443439538, "GTG":1443439537, }

    } """
  45. @PreusslerBerlin ... tested.updateNetworkStatus(networkInfo) assertFalse(tested.isCellularConnected()) assertFalse(tested.isWifiConnected()) ...

  46. @PreusslerBerlin ... tested.updateNetworkStatus(networkInfo) assertFalse(tested.isNotOnAnyNetwork()) ...

  47. @PreusslerBerlin fun ConnectivityReceiver.isNotOnAnyNetwork(): Boolean { return !isCellularConnected() && !isWifiConnected()) }

  48. @PreusslerBerlin fun ConnectivityReceiver.isNotOnAnyNetwork() = !isCellularConnected() && !isWifiConnected())

  49. @PreusslerBerlin ... tested.updateNetworkStatus(networkInfo) tested.assertNotOnAnyNetwork() ...

  50. @PreusslerBerlin fun ConnectivityReceiver.assertNotOnAnyNetwork(){ assertFalse(isConnected()) assertFalse(isWifiConnected()) }

  51. @PreusslerBerlin Keep it short

  52. @PreusslerBerlin ... Map<TYPE, Integer> signalStrength = new HashMap<>(); signalStrength.put(EDGE, 80);

    signalStrength.put(WIFI to 90); ...
  53. @PreusslerBerlin ... val signalStrength = hashMapOf(EDGE to 80, WIFI to

    90) ...
  54. @PreusslerBerlin Make it consistent

  55. @PreusslerBerlin assertFailsWith<NoSuchElementException>( none.get() )

  56. @PreusslerBerlin What about mocks?

  57. @PreusslerBerlin Kotlin Mockito github.com/nhaarman/mockito-kotlin

  58. @PreusslerBerlin Syntactical Sugar around Mockito

  59. @PreusslerBerlin val resources = mock<Resources>()

  60. @PreusslerBerlin val resources : Resources = mock()

  61. @PreusslerBerlin whenever(resources.getString(R.string.title) .thenReturn(”Title")

  62. @PreusslerBerlin val resources = mock<Resources> { on { getString(R.string.title) }

    doReturn ”Title” }
  63. @PreusslerBerlin recyclerview.setAdapter(mock()) * without Java8

  64. @PreusslerBerlin recyclerview.adapter = mock() * without Java8

  65. @PreusslerBerlin verify(recyclerview).adapter = any() * without Java8

  66. @PreusslerBerlin InOrder verifier = inOrder(parcel); verifier.verify(parcel).writeByte((byte)0); verifier.verify(parcel).writeString("path");

  67. @PreusslerBerlin inOrder(parcel).apply { verify(parcel).writeByte(0) verify(parcel).writeString("path") }

  68. @PreusslerBerlin ArgumentCaptor<Adapter> captor = ArgumentCaptor.forClass(Adapter.class); verify(recyclerview).setAdapter(captor.capture()); assertEquals(1, captor.getValue().getItemCount());

  69. @PreusslerBerlin argumentCaptor<Adapter<ViewHolder>>().apply { verify(recyclerview).adapter = capture() assertEquals(1, value.itemCount) }

  70. @PreusslerBerlin Kluent github.com/MarkusAmshove/Kluent

  71. @PreusslerBerlin Readability first

  72. @PreusslerBerlin assertEquals("hello", greeting);

  73. @PreusslerBerlin greeting shouldEqual "hello"

  74. @PreusslerBerlin list shouldContain “jon”

  75. @PreusslerBerlin No magic here

  76. @PreusslerBerlin infix fun <T> Array<T>.shouldContain(theThing: T)

  77. @PreusslerBerlin list.shouldContain(“jon”)

  78. @PreusslerBerlin list shouldContain “jon”

  79. @PreusslerBerlin Spek github.com/JetBrains/spek

  80. @PreusslerBerlin SimpleSpec: Spek({ describe("a calculator") { val calculator = SampleCalculator()

    on("addition") { val sum = calculator.sum(2, 4) it("should return the sum") { assertEquals(6, sum) } } } }
  81. @PreusslerBerlin SimpleSpec: Spek({ describe("a calculator") { val calculator = SampleCalculator()

    on("addition") { ... } on(”substraction") { ... } } }
  82. @PreusslerBerlin SimpleSpec: Spek({ describe("a calculator") { val calculator = SampleCalculator()

    on("addition") { ... } on(”substraction") { ... } } describe("a broken calculator") {… }
  83. @PreusslerBerlin describe(...) context(...) given(...) on(...) it(...)

  84. @PreusslerBerlin Tests are a great way to learn Kotlin

  85. @PreusslerBerlin Make a plan how to continue

  86. @PreusslerBerlin Make a plan how to continue •tutorials

  87. @PreusslerBerlin Make a plan how to continue •tutorials •hackathons

  88. @PreusslerBerlin Make a plan how to continue •tutorials •hackathons •coding

    Kata
  89. @PreusslerBerlin Build an experiment, learn from it, see prove it’s

    working
  90. @PreusslerBerlin

  91. fun test() Kotlin all your tests Danny Preussler @PreusslerBerlin