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

テストを楽に書きたい

 テストを楽に書きたい

Tomoki Yamashita

October 11, 2024
Tweet

More Decks by Tomoki Yamashita

Other Decks in Technology

Transcript

  1. JUnit class PersonTest { @Test fun birthdayAsString_test() { val birthday

    = LocalDate.of(2000, 11, 23) val person = Person(birthday) assertThat(person.birthdayAsString("yyyy/MM/dd")).isEqualTo("2000/11/23") } } 10 - テスト名は一意でなければならない - 抽象的な名前では重複してしまう - 具体的な名前をつけようとするとメソッド名が長くなりがち - 認知負荷が高い
  2. RSpec RSpec.describe Person do describe '#birthday_as_string' do let(:person) { Person.new(birthday)

    } context 'when birthday is 2000/11/23' do let(:birthday) { Date.new(2000, 11, 23) } context 'when format is %Y/%m/%d' do let(:format) { '%Y/%m/%d' } it do expect(person.birthday_as_string(format)). to eq('2000/11/23') end end end end end 12 - 構造的に記述できる - テストケースの多様性を 表現しやすい - 適切な情報量
  3. JUnit + Kotest class PersonTest: DescribeSpec() { describe("#birthdayAsString") { context("when

    birthday is 2000/11/23") { val birthday = newDate(2000, Calendar.NOVEMBER, 23) context("when format is yyyy/MM/dd") { val format = "yyyy/MM/dd" it("returns 2000/11/23") { val person = Person(birthday) person.birthdayAsString(format) shouldBe "2000/11/23" } } } } } 13 Kotestを使えば構造化されたテストを記述できるため、解決する
  4. DroidKaigi Conference Appのアプローチ @RunWith(ParameterizedRobolectricTestRunner::class) class KaigiAppTest(private val testCase: DescribedBehavior<KaigiAppRobot>) {

    @Test fun runTest() { runRobot(kaigiAppRobot) { testCase.execute(kaigiAppRobot) } } companion object { @ParameterizedRobolectricTestRunner.Parameters(name = "{0}") fun behaviors(): List<DescribedBehavior<KaigiAppRobot>> { return describeBehaviors<KaigiAppRobot>(name = "KaigiApp") { describe("when app is starting") { doIt { waitUntilIdle() } itShould("show timetable items") { captureScreenWithChecks { runRobot(timetableScreenRobot) { checkTimetableListItemsDisplayed() } } } } } } } } 17
  5. DroidKaigi Conference Appのアプローチ @RunWith(ParameterizedRobolectricTestRunner::class) class KaigiAppTest(private val testCase: DescribedBehavior<KaigiAppRobot>) {

    @Test fun runTest() { runRobot(kaigiAppRobot) { testCase.execute(kaigiAppRobot) } } companion object { @ParameterizedRobolectricTestRunner.Parameters(name = "{0}") fun behaviors(): List<DescribedBehavior<KaigiAppRobot>> { return describeBehaviors<KaigiAppRobot>(name = "KaigiApp") { describe("when app is starting") { doIt { waitUntilIdle() } itShould("show timetable items") { captureScreenWithChecks { runRobot(timetableScreenRobot) { checkTimetableListItemsDisplayed() } } } } } } } } 18
  6. DroidKaigi Conference Appのアプローチ @RunWith(ParameterizedRobolectricTestRunner::class) class KaigiAppTest(private val testCase: DescribedBehavior<KaigiAppRobot>) {

    @Test fun runTest() { runRobot(kaigiAppRobot) { testCase.execute(kaigiAppRobot) } } companion object { @ParameterizedRobolectricTestRunner.Parameters(name = "{0}") fun behaviors(): List<DescribedBehavior<KaigiAppRobot>> { return describeBehaviors<KaigiAppRobot>(name = "KaigiApp") { describe("when app is starting") { doIt { waitUntilIdle() } itShould("show timetable items") { captureScreenWithChecks { runRobot(timetableScreenRobot) { checkTimetableListItemsDisplayed() } } } } } } } } 19
  7. DroidKaigi Conference Appのアプローチ @RunWith(ParameterizedRobolectricTestRunner::class) class KaigiAppTest(private val testCase: DescribedBehavior<KaigiAppRobot>) {

    @Test fun runTest() { runRobot(kaigiAppRobot) { testCase.execute(kaigiAppRobot) } } companion object { @ParameterizedRobolectricTestRunner.Parameters(name = "{0}") fun behaviors(): List<DescribedBehavior<KaigiAppRobot>> { return describeBehaviors<KaigiAppRobot>(name = "KaigiApp") { describe("when app is starting") { doIt { waitUntilIdle() } itShould("show timetable items") { captureScreenWithChecks { runRobot(timetableScreenRobot) { checkTimetableListItemsDisplayed() } } } } } } } } 20 https://robolectric.org/javadoc/4.1/org/robolectric/ParameterizedRobolectricTestRunner.Parameters.html