Quantcast
Channel: cc :: somkiat
Viewing all articles
Browse latest Browse all 1997

Espresso ::  การแก้ไขปัญหาเรื่อง permission บน Android M

$
0
0

android-espresso-permission

android-espresso-permission วันนี้เจอปัญหาที่น่าสนใจสำหรับการทดสอบ Android app ด้วย Espresso มีอาการ คือ ไม่สามารถทำการทดสอบได้ และ ผลการทดสอบผิดพลาด ซึ่งเป็นปัญหาเกี่ยวกับ permission ของ Android app นั่นเอง โดยจะเจอปัญหานี้บน Android M หรือ Android 6 Marshmallow เนื่องจากรูปแบบของการจัดการ permission ที่เปลี่ยนไป มาดูวิธีการแก้ไขว่าทำอย่างไร ? ป.ล. สามารถอ่านเพิ่มเติมเรื่อง Working with Permission ได้ที่ Android Developer ขอขอบคุณผู้สร้างปัญหา คุณเก้อ

ปัญหาที่พบเจอเป็นดังนี้

  • ผลการทดสอบผิดพลาด
  • จำนวน test case ลดลง !!
ที่สำคัญจะมีปัญหาบน Android M เท่านั้น และใน Logcat จะเจอ exception แบบนี้เยอะมาก ๆ [code] java.lang.SecurityException: getDeviceId: Neither user 10340 nor current process has android.permission.READ_PHONE_STATE. [/code]

วิเคราะห์ปัญหากันหน่อย

ประเด็นหลักคือ เจอเฉพาะบน Android M เท่านั้น รวมทั้งมี exception ใน Logcat ซึ่งบอกปัญหาเรื่อง permission ทำให้นึกถึงสิ่งที่เปลี่ยนแปลงไปใน Android M คือ รูปแบบการจัดการ permission และ การขอ permission จากผู้ใช้งาน นั่นคือ จะทำการขอสิทธ์ทีละ permission ดังนั้นจึงลองทดสอบสมมุติฐาน ด้วยการติดตั้งไฟล์ APK ของ Android App ในเครื่องทดสอบ จากนั้นเข้าไปดู permission ของ app ก็พบว่า permission ที่กำหนดไว้ในไฟล์ AndroidManifest.xml นั้น ไม่ได้เปิด หรือ อนุญาตเลย เป็นที่มาของปัญหาข้างต้นนั้นเอง !!

เมื่อรู้ปัญหาเรียบร้อยแล้ว ต่อมาคือ เราจะแก้ไขอย่างไรดีล่ะ ?

เริ่มจากการทำความเข้าใจขั้นตอนการทำงานก่อน เนื่องจากใน Android Studio นั้นทำการ build และ deploy ด้วย Gradle ดังนั้น เราควรรู้ว่า tasks หรือ ขั้นตอนการทำงานต่าง ๆ ของ Gradle เป็นอย่างไรบ้าง สามารถดู task ต่าง ๆ ด้วยคำสั่ง [code] $gradlew tasks [/code] จากนั้นต้องรู้ขั้นตอนการทำงานของแต่ละ task ด้วย โดยขั้นตอนที่ต้องรู้ เพื่อแก้ไขปัญหาประกอบไปด้วย
  • ทำการสร้างไฟล์ APK ตอนไหน ?
  • ทำการติดตั้งไฟล์ APK ไปยัง device ตอนไหน ?
  • ทำการทดสอบด้วย Espresso ตอนไหน ?
ซึ่งเราต้องตอบคำถามเหล่านี้ให้ครบ โดยผมเน้นที่ส่วนของ Dev คือ
  • assembleDevDebugAndroidTest
  • installDevDebug
  • connectedDevDebugAndroidTest
ถ้าอยากรู้ว่าเราเข้าใจถูกหรือไม่ ก็ลองใช้คำสั่ง [code] $gradlew assembleDevDebugAndroidTest $gradlew installDevDebug $gradlew connectedDevDebugAndroidTest [/code]

ปัญหาต่อมาคือ เราจะเพิ่มสิทธิ์ permission ตรงไหนดีล่ะ ?

ตอบง่าย ๆ เลยก็คือ หลังจากที่ทำการติดตั้ง APK ไปยัง device ไงล่ะ

ปัญหาต่อมาคือ เราจะเพิ่มสิทธิ์ permission อย่างไรดีล่ะ ?

สำหรับ Android Devleoper ไม่น่าจะยากเท่าไร เพราะว่า เราจะทำการจัดการผ่านเครื่องมือที่ชื่อว่า adb (Android Debugging Bridge) ซึ่งมีอยู่แล้วใน Android SDK
ถ้า Android Developer คนไหนไม่รู้ ขอแนะนำให้ศึกษาเพิ่มเติมนะครับ
โดยเราสามารถทดสอบเพิ่มสิทธ์ permission ด้วยคำสั่ง [code] $adb shell pm grant "package name of app" "YOUR PERMISSION" [/code] ถ้าต้องการระบุ device ด้วย ใช้คำสั่ง [code] $adb -s "devicename" shell pm grant "package name of app" "YOUR PERMISSION" [/code] เมื่อทดลองเพิ่มสิทธิ์ไปแล้ว อย่าลืมไปลองเล่น app ใน device ด้วยนะ ซึ่ง app ของเราจะไม่ถาม permission อีกเลย แต่ถ้าเปิด app มาแล้วขึ้นหน้าจอแบบนี้ แสดงว่ายังทำไม่สำเร็จนะ !! request_permission_dialog_2x

ปัญหาต่อมาคือ แล้วจะเพิ่มขั้นตอนการเพิ่มสิทธิ์เข้าไปในขั้นตอนของ Gradle อย่างไร ?

เนื่องจากไม่อยากทำงานเดิมซ้ำ ๆ มันน่าเบื่อมาก ๆ ขั้นตอนการทำงานแบบอัตโนมัติต้องทำงานแบบนี้
  1. ทำการ uninstall app ออกจาก device ที่ต้องการ
  2. ทำการสร้างไฟล์ APK
  3. ทำการติดตั้งไฟล์ APK ไปยัง device ที่ต้องการ
  4. ทำการเพิ่มสิทธิ์ของ app ในแต่ละ device
  5. ทำการทดสอบการทำงานของ app ด้วย Espresso
ใน Gradle นั้นอนุญาตให้เราสามารถเพิ่ม task เข้ามาเองได้เลย ดังนั้น ผมจึงทำการสร้าง task ใหม่ชื่อว่า grantPermissions มีการทำงานดังนี้
  • ให้ทำงานหลังจากที่ทำงานติดตั้งไฟล์ APK ไปยัง device หรือ ก่อนการทดสอบด้วย Espresso
  • เนื่องจากสามารถต่อ device ได้หลาย ๆ เครื่อง ดังนั้นต้องทำการเพิ่มสิทธิ์ไปยังทุกเครื่องด้วย
ขั้นตอนการเขียน task ชื่อว่า grantPermissions เป็นดังนี้ สร้าง task ในไฟล์ build.grade ของ app [gist id="9a26521e31f246afb849" file="build.gradle"] จากนั้นสร้างไฟล์ grant_permissions.sh ขึ้นมาเพื่อเพิ่มสิทธ์ให้ทุก ๆ device ดังนี้ [gist id="9a26521e31f246afb849" file="grant_permissions.sh"] เพียงเท่านี้ก็สามารถแก้ไขปัญหา และ ใช้งานได้แล้ว ด้วยคำสั่ง [code] $gradlew unInstallAll connectedDevDebugAndroidTest [/code] ขอให้โลกสงบสุขครับ Reference Websites http://www.savinoordine.com/grantrevoke-permission-with-adb-android-m/ http://testdroid.com/news/how-android-m-new-app-permissions-impact-on-existing-apps https://www.androidpit.com/android-m-release-date-news-features-name https://greenify.uservoice.com/knowledgebase/articles/749142-how-to-grant-permissions-required-by-some-features http://www.fulcrumapp.com/blog/automated-ui-testing-and-fulcrum-android-permissions/

Viewing all articles
Browse latest Browse all 1997

Trending Articles