چندین کاربر را تست کنید

این صفحه جنبه‌های مهم آزمایش چندین کاربر در پلتفرم اندروید را شرح می‌دهد. برای اطلاعات بیشتر در مورد پیاده‌سازی پشتیبانی از چند کاربر، به بخش «پشتیبانی از چندین کاربر» مراجعه کنید.

مسیرهای دستگاه

جدول زیر چندین مسیر دستگاه و نحوه‌ی حل آنها را فهرست می‌کند. تمام مقادیر موجود در ستون مسیر ، یک فضای ذخیره‌سازی سندباکس‌شده‌ی مخصوص کاربر هستند. داستان فضای ذخیره‌سازی اندروید در طول زمان تغییر کرده است؛ برای اطلاعات بیشتر، مستندات فضای ذخیره‌سازی را مطالعه کنید.

مسیر مسیر سیستم (اختیاری) هدف
/data/user/{userId}/{app.path} /data/data فضای ذخیره‌سازی برنامه
/storage/emulated/{userId} /sdcard حافظه داخلی مشترک
/data/media/{userId} هیچ کدام داده‌های رسانه‌ای کاربر (مثلاً موسیقی، ویدیو)
/data/system/users/{userId} هیچ کدام پیکربندی/وضعیت سیستم به ازای هر کاربر

فقط توسط برنامه‌های سیستمی قابل دسترسی است

در اینجا مثالی از استفاده از یک مسیر خاص کاربر آورده شده است:

# to access user 10's private application data for app com.bar.foo:
$ adb shell ls /data/user/10/com.bar.foo/

تعاملات adb بین کاربران

چندین دستور adb هنگام کار با چندین کاربر مفید هستند. برخی از این دستورات فقط در اندروید ۹ و بالاتر پشتیبانی می‌شوند:

  • adb shell am instrument --user <userId> یک تست ابزار دقیق را روی یک کاربر خاص اجرا می‌کند. به طور پیش‌فرض، این تست از کاربر فعلی استفاده می‌کند.
  • adb install --user <userId> یک بسته را برای یک کاربر خاص نصب می‌کند. برای اطمینان از نصب یک بسته برای همه کاربران، باید این دستور را برای هر کاربر فراخوانی کنید.
  • adb uninstall --user <userId> یک بسته را برای یک کاربر خاص حذف می‌کند. برای حذف کامل بسته برای همه کاربران، بدون استفاده از پرچم --user فراخوانی می‌شود.
  • adb shell am get-current-user شناسه کاربر فعلی (پیش‌زمینه) را دریافت می‌کند.
  • adb shell pm list users لیستی از تمام کاربران موجود را دریافت می‌کند.
  • adb shell pm create-user یک کاربر جدید ایجاد می‌کند و شناسه (ID) آن را برمی‌گرداند.
  • adb shell pm remove-user یک کاربر خاص را بر اساس شناسه (ID) حذف می‌کند.
  • adb shell pm disable --user <userId> یک بسته را برای یک کاربر خاص غیرفعال می‌کند.
  • adb shell pm enable --user <userId> یک بسته را برای یک کاربر خاص فعال می‌کند.
  • adb shell pm list packages --user <userId> بسته‌های یک کاربر خاص ( -e برای فعال -d برای غیرفعال) را نمایش می‌دهد. به طور پیش‌فرض، این دستور همیشه بسته‌های کاربر سیستم را نمایش می‌دهد.

اطلاعات زیر به توضیح نحوه رفتار adb با چندین کاربر کمک می‌کند:

  • adb (یا به طور دقیق‌تر، سرویس adbd ) صرف نظر از اینکه کدام کاربر فعلی است، همیشه به عنوان کاربر سیستم (شناسه کاربر = 0) اجرا می‌شود. بنابراین، مسیرهای دستگاهی که به کاربر وابسته هستند (مانند /sdcard/ ) همیشه به عنوان کاربر سیستم شناسایی می‌شوند. برای جزئیات بیشتر به مسیرهای دستگاه مراجعه کنید.

  • اگر کاربر پیش‌فرض مشخص نشده باشد، هر زیردستور adb کاربر متفاوتی دارد. بهترین روش این است که شناسه کاربر را با استفاده از دستور am get-current-user بازیابی کنید و سپس به طور صریح از --user <userId> برای هر دستوری که از آن پشتیبانی می‌کند استفاده کنید. پرچم‌های کاربر صریح تا اندروید ۹ برای همه دستورات پشتیبانی نمی‌شد.

  • دسترسی به مسیرهای /sdcard کاربران ثانویه از اندروید ۹ به بعد مسدود شده است. برای جزئیات بیشتر در مورد نحوه بازیابی فایل‌ها در حین آزمایش، به ارائه‌دهنده محتوا برای داده‌های چندکاربره مراجعه کنید.

ارائه دهنده محتوا برای داده‌های چند کاربره

از آنجا که adb به عنوان کاربر سیستم اجرا می‌شود و داده‌ها در اندروید ۹ و بالاتر در محیط sandbox قرار می‌گیرند، شما باید از ارائه‌دهندگان محتوا برای ارسال یا دریافت هرگونه داده آزمایشی از یک کاربر غیرسیستمی استفاده کنید. در صورت وجود شرایط زیر، این کار ضروری نیست :

  • adbd به عنوان کاربر ریشه (از طریق adb root ) اجرا می‌شود، که فقط با استفاده از buildهای userdebug یا usereng امکان‌پذیر است.

  • شما از ITestDevice فدراسیون تجارت (Trade Federation's (Tradedefed)) برای ارسال یا دریافت فایل‌ها استفاده می‌کنید، که در این صورت /sdcard/ paths در پیکربندی تست خود استفاده کنید (برای مثال، به کد منبع pushFile در NativeDevice.java مراجعه کنید).

وقتی یک ارائه‌دهنده محتوا در کاربر ثانویه در حال اجرا است، می‌توانید با استفاده از دستور adb shell content به همراه user ، uri و سایر پارامترهای مشخص شده، به آن دسترسی پیدا کنید.

راه حل برای توسعه دهندگان برنامه

به جای دستور push یا pull ، با استفاده از adb content و یک نمونه از ContentProvider با فایل‌های آزمایشی تعامل داشته باشید.

  1. یک نمونه از ContentProvider که توسط برنامه میزبانی می‌شود، ایجاد کنید که بتواند فایل‌ها را در صورت نیاز ارائه و ذخیره کند. از حافظه داخلی برنامه استفاده کنید.
  2. از دستورات read یا write adb shell content برای ارسال یا دریافت فایل‌ها استفاده کنید.

راه حل برای فایل های رسانه ای

برای ارسال فایل‌های رسانه‌ای به پارتیشن رسانه کارت SD، از APIهای عمومی MediaStore استفاده کنید. برای مثال:

# push MVIMG_20190129_142956.jpg to /storage/emulated/10/Pictures
# step 1
$ adb shell content insert --user 10 --uri content://media/external/images/media/ --bind _display_name:s:foo.jpg

# step 2
$ adb shell content query --user 10 --projection _id --uri content://media/external/images/media/ --where "_display_name=\'foo.jpg\'"

# step 3
$ adb shell content write --user 10 --uri content://media/external/images/media/8022 < MVIMG_20190129_142956.jpg

نصب یک ارائه دهنده محتوای عمومی

یک ارائه‌دهنده محتوای موجود را نصب و استفاده کنید که فایل‌ها را در مسیر /sdcard مخصوص کاربر می‌خواند و می‌نویسد.

با استفاده از make TradefedContentProvider فایل TradefedContentProvider.apk را از منبع بسازید:

```
# install content provider apk
$ adb install --user 10 -g TradefedContentProvider.apk

# pull some_file.txt
$ adb shell content read --user 10 --uri content://android.tradefed.contentprovider/sdcard/some_file.txt > local_file.txt

# push local_file.txt
$ adb shell content write --user 10 --uri content://android.tradefed.contentprovider/sdcard/some_file.txt < local_file.txt
```

پشتیبانی چند کاربره فدراسیون تجارت

Tradefed ابزار رسمی تست اندروید است. این بخش خلاصه‌ای از پشتیبانی داخلی Tradefed برای سناریوهای تست چندکاربره را ارائه می‌دهد.

بررسی‌کننده‌های وضعیت

بررسی‌کننده‌های وضعیت سیستم (SSC) قبل از آماده‌سازهای هدف اجرا می‌شوند و پاکسازی آنها پس از آن آماده‌سازها انجام می‌شود.

UserChecker به طور صریح برای کمک به توسعه‌دهندگان هنگام آزمایش چندین کاربر تعریف شده است. این ابزار پیگیری می‌کند که آیا یک آزمایش وضعیت کاربران روی دستگاه را تغییر داده است یا خیر (برای مثال، کاربران ایجاد شده بدون حذف آنها در مرحله جداسازی). علاوه بر این، اگر user-cleanup تنظیم شده باشد، به طور خودکار پس از آزمایش تلاش می‌کند تا داده‌ها را پاک کند، در حالی که همچنان خطاهای مفیدی را ارائه می‌دهد تا آزمایش بتواند اصلاح شود.

<system_checker class="com.android.tradefed.suite.checker.UserChecker" >
    <option name="user-cleanup" value="true" />
</system_checker>

آماده‌کننده هدف

آماده‌سازهای هدف معمولاً برای راه‌اندازی یک دستگاه با پیکربندی خاص استفاده می‌شوند. در مورد آزمایش چندکاربره، آماده‌سازها می‌توانند برای ایجاد کاربرانی از یک نوع خاص و همچنین تغییر به کاربران دیگر مورد استفاده قرار گیرند.

برای انواع دستگاه‌هایی که کاربر ثانویه ندارند، می‌توانید CreateUserPreparer برای ایجاد و تغییر به یک کاربر ثانویه در AndroidTest.xml استفاده کنید. در پایان آزمایش، آماده‌ساز به عقب برمی‌گردد و کاربر ثانویه را حذف می‌کند.

<target_preparer
  class="com.google.android.tradefed.targetprep.CreateUserPreparer" >
</target_preparer>

اگر نوع کاربری که می‌خواهید از قبل روی دستگاه وجود دارد، SwitchUserTargetPreparer برای تغییر به کاربر موجود استفاده کنید. مقادیر رایج برای user-type شامل system یا secondary است.

<target_preparer
  class="com.android.tradefed.targetprep.SwitchUserTargetPreparer">
    <option name="user-type" value="secondary" />
</target_preparer>

تست‌های مبتنی بر میزبان

در برخی موارد، یک تست نیاز به تغییر کاربران در داخل تست دارد. این تغییر را از داخل یک چارچوب تست سمت دستگاه، مانند UI Automator ، انجام ندهید، زیرا فرآیند تست می‌تواند در هر زمانی از بین برود. در عوض، از یک چارچوب تست سمت میزبان مانند چارچوب تست Host-driven از Tradefed استفاده کنید که به ITestDevice دسترسی می‌دهد و امکان هرگونه دستکاری کاربر مورد نیاز را فراهم می‌کند.

UserChecker (که در بررسی‌کننده‌های وضعیت توضیح داده شده است) برای تست‌های مبتنی بر میزبان که وضعیت کاربر را تغییر می‌دهند استفاده کنید، زیرا تضمین می‌کند که تست پس از خود به درستی پاک‌سازی می‌شود.