Slide 1

Slide 1 text

Mobile AB Testing tips ~ RemoteConfigΛఴ͑ͯ~ Mercari, Inc. Tomoaki Imai

Slide 2

Slide 2 text

twitter: @tomoaki_imai github: tomoima525 ࠓҪ ஐষ Android Engineer 2016.1 Mercari US ग़޲ ඒຯ͍͠ΧϨʔͷΑ͏ʹ ਓΛ޾ͤʹग़དྷΔΑ͏ʹͳΓ͍ͨ

Slide 3

Slide 3 text

Mercari in US Mercari USΦϑΟεΛ Sanfranciscoʹઃཱ 2014.9 ϦϦʔε 1200ສDLಥഁ ࠓ೔΋ݩؾʹαʔϏε ֦େத!

Slide 4

Slide 4 text

Why AB Testing is important?

Slide 5

Slide 5 text

Great things about AB Testing • ࡉ͔͍ௐ੔ʹΑΔޮՌͷ࠷େԽ • େ୾ͳมߋʹର͢ΔϦεΫͷ࠷খԽ • ݕূͷύϥϨϧԽʹΑΔظؒͷ୹ॖԽ

Slide 6

Slide 6 text

Things need to take care • ਖ਼͍͠ޮՌଌఆ ‣ ҙຯͷͳ͍ςετΛ΍͍ͬͯͳ͍͔ ‣ ฼਺ʁάϧʔϐϯάʁ༗ҙࠩ? • ͍ͭͰ΋σϑΥϧτʹ໭ͤΔ ‣ Ξοϓσʔτͳ͘ରԠͰ͖Δ ‣ ιʔείʔυΛԚ͞ͳ͍

Slide 7

Slide 7 text

࠷ߴͷAB Test͠Α͏ͥ • ࣮ྫΛ௨ͯ͡ޮՌతͳAB Testingͷํ๏Λ஌Δ • Firebase RemoteConfigͱ͍͏ڧྗͳAB Test πʔ ϧΛ࢖࣮ͬͯݱ͢Δํ๏Λ஌Δ

Slide 8

Slide 8 text

Before we go…

Slide 9

Slide 9 text

AB Testing at Mercari

Slide 10

Slide 10 text

History of AB Test AB Testಋೖ ໨త: ͞ΒͳΔػೳվળ Apptimize(AB Testing Tool) + Segment(τϥοΩϯά) + mixpanel(෼ੳ) 2014 Ն 2015 य़ AB TestͷΠϯϋ΢εԽ ݱࡏ τϥοΩϯάͷΠϯϋ΢εԽ (Pascal) 2015 Ն ৗ࣌ 10݅લޙ ͷAB TestΛ࣮ࢪ ෼ੳͷ Big Query΁ͷҠߦ

Slide 11

Slide 11 text

Type of AB Test • UI Test ‣ ݟͨ໨ɺϨΠΞ΢τͷมߋ ‣ ྫ) Ձ֨දࣔํ๏ͷมߋ • Flow Test ‣ ಛఆϑϩʔͷ௥Ճ/εΩοϓ ‣ ྫ)ೖྗ߲໨ͷ௥Ճ/εΩοϓ • New feature Test ‣ ৽ػೳͷදࣔ/ඇදࣔ ‣ ྫ) ύʔιφϥΠζػೳ

Slide 12

Slide 12 text

AB Testing tool + ίϯιʔϧ্ͰτϥοΩϯάઃఆͰ͖Δ + ಈతʹUIΛมߋͰ͖Δ - τϥοΩϯάσʔλͷऔΓ͜΅͠༗ - σʔλͷexport͕ग़དྷͳ͍ - ஋ஈ - ࡉ͔͍λʔήοτઃఆ͕೉͍͠

Slide 13

Slide 13 text

AB Testing tool • In House + αʔόαΠυ͔Βॊೈͳλʔήοτઃఆ + Pascal, Big Queryͱ૊Έ߹Θ༷ͤͯʑͳ੾Γޱ͔Β෼ੳ AB Test Client ͸ ϥΠϒϥϦԽ https://github.com/mercari/siberi-android - Apptimize like ͳ Interface - ςετσʔλΛDBͰ؅ཧ - iOS΋ۙ೔ϦϦʔε༧ఆ

Slide 14

Slide 14 text

What about Firebase RemoteConfig?

Slide 15

Slide 15 text

"QQUJNJ[F *O)PVTF 3FNPUF $POpH ಋೖ༰қ͞ ̋ ˚ ˕ Ձ֨ ☓ ̋ ̋ ઃఆͷ ॊೈੑ ☓ ̋ ˚ ֦ுੑ ☓ ˕ ˚ • MercariͰͷಋೖ༧ఆ͸ͳ͠ ‣ ৽نࣄۀͰ͸ಋೖ༰қ͞ɺՁ֨ͷ؍఺ͰקΊ͍ͨ ‣ ·ͩ଍Γͯͳ͍෦෼͕͋ΔͷͰ࢖͏࣌͸஫ҙ(ޙड़)

Slide 16

Slide 16 text

AB Testing Tips

Slide 17

Slide 17 text

Tips1. TargetઃఆΛద੾ʹ͢Δ • ౷ܭֶతʹҙຯ͕͋Δ͔ʹ഑ྀ ྫ) αϯϓϧ਺ - AB TestͷԾઆʹରͯ͠ద੾ͳαϯϓϧ਺͕ઃఆͰ͖͍ͯΔ͔ - R ͰܭࢉՄೳ QPXFSQSPQUFTU Q Q TJHMFWFM QPXFS ex) AB ςετͷ݁Ռߪೖ཰͕ 5% -> 6%ͱͳΔͱ͍͏Ծઆ ࢀߟ: http://oku.edu.mie-u.ac.jp/~okumura/stat/150922.html sig.level -> ༗ҙਫ४ (Ծઆ͕ਖ਼͍͠ͱޡͬͯ൑அ͢Δ֬཰) power -> ݕఆྗ (Ծઆ͕ਖ਼͍͠ͱ൑அ͢Δ֬཰) O -> 8100݅Ҏ্ͷαϯϓϧ͕ඞཁ

Slide 18

Slide 18 text

Tips1. TargetઃఆΛద੾ʹ͢Δ • ౷ܭֶతʹҙຯ͕͋Δ͔ʹ഑ྀ άϧʔϐϯά - ςετಉ͕࢜Өڹ͠ͳ͍Α͏௚ަͯ͠άϧʔϐϯά͞Ε͍ͯΔ͔ - ࣮ݧ܈, ରর܈ʹରͯ͠1 : 1ͰৼΓ෼͚ΒΕ͍ͯΔ͔ 5FTU" $POUSPM 5FTU" &YQFSJNFOU 5FTU#$POUSPM 5FTU#&YQFSJNFOU

Slide 19

Slide 19 text

Tips1. TargetઃఆΛద੾ʹ͢Δ • Firebase Ͱ͸ॊೈʹTargetΛઃఆͰ͖Δ&ॏෳΛڐ͢ ͷͰར༻ऀଆͰ஫ҙ͕ඞཁ!! μϝͳྫ ରর܈࣮ݧ܈ͷൺ཰ʹେ͖͕ࠩ͋͘ Δ )0-*%":@130.0ͷςετͱ௚ަ͠ ͍ͯͳ͍)0-*%":@130.0ͷ݁ ՌͷӨڹΛड͚ΔՄೳੑ͕͋Δ ಉ͡ൺ཰ʹ͢Δ͔ɺॏͳΒͳ͍Α ͏ʹ͢Δ

Slide 20

Slide 20 text

Tips1. TargetઃఆΛద੾ʹ͢Δ • Best practice? ׂΓৼΓͷ$POEJUJPOΛఆٛ $POEJUJPOΛઃఆ͢Δ ͦΕҎ ֎ͷઃఆ͸͠ͳ͍

Slide 21

Slide 21 text

Tips 2. VariantϕʔεͰςετ͢Δ • AB Testͷ࢓ํ ‣ Keyϕʔε ‣ Buttonͷ৭, ςΩετ,ͦΕͧΕʹ஋Λઃఆ͢Δ ‣ Variantϕʔε ‣ ςετ಺༰ΛέʔεผͰఆٛ͢Δ 7BSJBOU &YQFSJNFOU$POFOU /PUJO5FTU EJTDPVOU DPMPSSFE UFYUlz $POUSPM EJTDPVOU DPMPSSFE UFYUlz &YQFSJNFOU EJTDPVOU DPMPSSFE UFYUl4VNNFSDBNQBJHOz

Slide 22

Slide 22 text

• 1ͭͷςετͷઃఆ߲໨͕૿͑ΔͱKeyϕʔε͸൥ࡶʹͳΔ => ࡉ͔͍ॲཧ͸Clientଆʹ೚ͤͨํ͕҆શ • αʔόଆ͸VariantΛৼΓ෼͚Δ͚ͩʹ͢Δͱɺςετ಺༰͕؅ ཧ͠΍͍͢ Siberi.runTest(Test.HOLIDAY_PROMO, content -> { switch(content.getVariant()){ case 0: break; // not test group case 1: break; // control group case 2: setDiscount(30); button.setBackgroundColor(red); button.setText("Summer Campaign"); break; } }); Tips 2. VariantϕʔεͰςετ͢Δ 5JQT ͸ςετ֎ͱ͢Δ JOU͕EFGBVMUͷͨΊ

Slide 23

Slide 23 text

remoteConfig.fetch(len).addOnCompleteListener(this, new OnCompleteListener() { @Override public void onComplete(@NonNull Task task) { switch ((int)remoteConfig.getLong(HOLIDAY_PROMO)){ case 0: // not test group case 1: // control group case 2: setDiscount(30); button.setBackgroundColor(red); button.setText("Summer Campaign"); break; } } }); Tips 2. VariantϕʔεͰςετ͢Δ • RemoteConfig SFNPUF$POpHHFU-POH͸஋͕ औΕͳ͍৔߹͸͕ฦΔ

Slide 24

Slide 24 text

Tips 3. ݕূ͠΍͍͢࢓૊ΈΛ࡞Δ • AB Test͸֤έʔεͰͷϨϏϡʔϫʔɺQAͷෛ୲͕େ͖͍ => ϩʔΧϧ্Ͱ੾ସ͑ΒΕΔ࢓૊Έ ‣ ςετσʔλΛϩʔΧϧDBʹอଘ ‣ Stetho Ͱςετσʔλͷ஋Λมߋ 42-Ͱ஋Λߋ৽Ͱ͖Δ DISPNFJOTQFDU ͰࢀরͰ͖Δ

Slide 25

Slide 25 text

Tips 3. ݕূ͠΍͍͢࢓૊ΈΛ࡞Δ • RemoteConfig͸ίϯιʔϧ্ͰͷϦΞϧλΠϜͷςετσʔλมߋ͕Մೳ • มߋ࿙Ε/ϛεͰଞͷݕূऀ΁ͷΠϯύΫτ͕͋ΔͷͰ஫ҙ͕ඞཁ • DEV؀ڥͷΈςετσʔλΛDBͰ؅ཧ͢Δͱ͍ͬͨ࢓૊Έ͕͋Δͱྑͦ͞͏

Slide 26

Slide 26 text

• ςετ࣮ࢪޙͷ͋Δ͋Δ ‣ ͋ΔςετͰ͔͠࢖Θͳ͍ϑΟʔϧυม਺/ϝιουΛফ͠ ๨ΕΔ ‣ ͲͷςετͷͨΊͷϑΟʔϧυม਺/ϝιου͔൑அͣ͠Β͍ • @ForExperiment Annotation ‣ ςετίʔυʹ෇Ճ͢ΔAnnotation ‣ @ForExperiment(Test໊) ͱ͢Δ͜ͱͰՄಡੑΛ্͛Δ Tips 4. AnnotationʹΑΔςετίʔυͷ؅ཧ

Slide 27

Slide 27 text

Tips 4. AnnotationʹΑΔςετίʔυͷ؅ཧ @ForExperiment(Experiments.TEST_002) TextView testTv; @ForExperiment(Experiments.TEST_002) private void changeText(String text){ testTv.setText(text); } public interface Experiments { String TEST_001 = "test_001_change_button_color"; String TEST_002 = "test_002_change_text"; } • @ForExperimentͰͲͷTest༻ͷม਺/ϝιουͳͷ͔໌ࣔతʹͳΔ • Testऴྃޙ͸ Experiments.java಺ͷStringΛফͤ͹ফ͠࿙Ε͕ແ͘ͳΔ @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.FIELD, ElementType.TYPE, ElementType.LOCAL_VARIABLE, ElementType.METHOD})
 public @interface ForExperiment {
 String value();
 }

Slide 28

Slide 28 text

Wrap up • ࠓ͙͢ʹAB TestΛ࢝ΊΔͳΒ Firebase RemoteConfig ͸Φεεϝ(͚Ͳར༻ʹ͸·ͩ·ͩ஫ҙ) • ͪΐͬͱͨ͠഑ྀͰҙຯͷ͋ΔAB Test ͕ޮ཰ྑ࣮͘ ࢪͰ͖Δ • ద੾ͳλʔήοτઃఆ • Variant ϕʔεͰͷςετ • ಈ࡞ݕূ͠΍͍͢࢓૊Έ • AnnotationͰςετ༻ίʔυΛ؅ཧ