<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Phat Nguyen</title>
    <description>The latest articles on DEV Community by Phat Nguyen (@phatnhse).</description>
    <link>https://dev.to/phatnhse</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F220243%2F556af5ba-1f3c-46fa-bc61-5b604f37e78f.jpg</url>
      <title>DEV Community: Phat Nguyen</title>
      <link>https://dev.to/phatnhse</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/phatnhse"/>
    <language>en</language>
    <item>
      <title>Build a Lightweight Docker Container For Android Testing</title>
      <dc:creator>Phat Nguyen</dc:creator>
      <pubDate>Fri, 06 Dec 2019 05:21:58 +0000</pubDate>
      <link>https://dev.to/phatnhse/build-a-lightweight-docker-container-for-android-testing-ikh</link>
      <guid>https://dev.to/phatnhse/build-a-lightweight-docker-container-for-android-testing-ikh</guid>
      <description>&lt;p&gt;Testing helps us identify any defects or errors that may have been made during development. But it takes time and resources, especially in Android where it requires the installation of many dependencies and a device to perform UI tests.&lt;/p&gt;

&lt;p&gt;By using a Docker container, we can build and run tests for multiple feature branches, speeding up the development and increasing productivity.&lt;/p&gt;

&lt;p&gt;In this tutorial, we’re going to learn how to build a lightweight Android container to isolate the testing process.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;No Android Studio/GUI applications required.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Android emulator runs on a Docker container.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Has ability to cache dependencies for later build.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Wipe out everything after the process.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1. Start docker container
&lt;/h2&gt;

&lt;p&gt;The image that we build on top of is: ubuntu:latest&lt;/p&gt;

&lt;p&gt;Assuming you have docker installed (if not, please follow this &lt;a href="https://docs.docker.com/docker-for-mac/install/"&gt;link&lt;/a&gt;), you can run this to start docker container:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker run --privileged -dit --name android-container ubuntu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;— &lt;code&gt;privileged&lt;/code&gt;: grant permission to launch VM on container.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;— &lt;code&gt;it&lt;/code&gt;: interactively execute shell cmd.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;— &lt;code&gt;d&lt;/code&gt;: run container in the background.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;— &lt;code&gt;name android-container&lt;/code&gt;: container’s name, will use later to attach and commit docker image.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(Optional) To run docker as non-root, the simplest way is adding the current user to group docker&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo groupadd docker // Add group docker if it doesn't already exist
$ sudo gpasswd -a $USER docker // Add current user to group docker
$ newgrp docker // reload (or you can re-login to reload)
$ docker run hello-world // check if it works
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  2. Install SDK packages
&lt;/h2&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Prerequisites&lt;/strong&gt;:
&lt;/h3&gt;

&lt;p&gt;Make sure you install the following dependencies. Otherwise, you may notice No such file or directory when installing android SDK or start emulator&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Please double-check the redundant dependencies.&lt;/em&gt;🙇 (ex: vim — if you’re not a fan)&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ apt update &amp;amp;&amp;amp; apt install -y openjdk-8-jdk vim git unzip libglu1 libpulse-dev libasound2 libc6  libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxi6  libxtst6 libnss3 wget
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Gradle&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Install &lt;code&gt;gradle&lt;/code&gt; and &lt;code&gt;gradle-wrapper&lt;/code&gt; . We’ll use version &lt;code&gt;5.4.1&lt;/code&gt; in this tutorial. No worries, it can be updated with &lt;code&gt;build-arg&lt;/code&gt; later 😊&lt;/p&gt;

&lt;p&gt;Download &lt;code&gt;gradle-5.4.1&lt;/code&gt; to &lt;code&gt;/tmp/gradle-5.4.1&lt;/code&gt; and unzip the content within &lt;code&gt;/opt/gradle&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ wget https://services.gradle.org/distributions/gradle-5.4.1-bin.zip -P /tmp \
&amp;amp;&amp;amp; unzip -d /opt/gradle /tmp/gradle-5.4.1-bin.zip 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Make a new directory &lt;code&gt;/opt/gradlew&lt;/code&gt; and install &lt;code&gt;gradle-wrapper&lt;/code&gt; there. (The directory names can be anything, but save the files to somewhere that easy to find)&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mkdir /opt/gradlew \
&amp;amp;&amp;amp; /opt/gradle/gradle-5.4.1/bin/gradle wrapper --gradle-version 5.4.1 --distribution-type all -p /opt/gradlew \
&amp;amp;&amp;amp; /opt/gradle/gradle-5.4.1/bin/gradle wrapper -p /opt/gradlew
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Android SDK&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;You will need to download SDK manually without Android Studio bundled, SDK tools only, check the link &lt;a href="https://developer.android.com/studio"&gt;here&lt;/a&gt; to get the URL.&lt;/p&gt;

&lt;p&gt;Like Gradle, we’ll save it to &lt;code&gt;/tmp&lt;/code&gt; and get it extracted in &lt;code&gt;/opt&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ wget 'https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip' -P /tmp \
&amp;amp;&amp;amp; unzip -d /opt/android /tmp/sdk-tools-linux-4333796.zip \
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;The Android software development kit (SDK) includes different components, including SDK Tools, Build Tools, and Platform Tools. The SDK Tools primarily includes the stock Android emulator, &lt;a href="https://developer.android.com/studio/profile/hierarchy-viewer.html"&gt;hierarchy viewer&lt;/a&gt;, &lt;a href="https://developer.android.com/studio/intro/update.html"&gt;SDK manager&lt;/a&gt;, and &lt;a href="https://guides.codepath.com/android/Configuring-ProGuard"&gt;ProGuard&lt;/a&gt;. The Build Tools primarily include aapt (Android packaging tool to create .APK), dx (Android tool that converts .java files to .dex files). Platform Tools include the &lt;a href="https://developer.android.com/studio/command-line/adb.html"&gt;Android debug shell&lt;/a&gt;, &lt;a href="https://developer.android.com/studio/command-line/sqlite3.html"&gt;sqlite3&lt;/a&gt; and &lt;a href="https://developer.android.com/studio/profile/systrace-commandline.html"&gt;Systrace&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Most important packages are &lt;code&gt;platform-tools&lt;/code&gt;, &lt;code&gt;tools&lt;/code&gt; and &lt;code&gt;emulator&lt;/code&gt;. Run this to install them quickly:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ yes Y | /opt/android/tools/bin/sdkmanager --install "platform-tools" "system-images;android-*28*;google_apis;x86" "platforms;android-28" "build-tools;28.0.3" "emulator"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;platform-tools&lt;/code&gt; contains &lt;code&gt;adb&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;tools&lt;/code&gt; contains &lt;code&gt;avdmanager&lt;/code&gt; and &lt;code&gt;sdkamanager&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;emulator&lt;/code&gt; : run emulator&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;system-images;android-*28*;google_apis;x86&lt;/code&gt; : use to create avd&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Accept all licenses of Android SDK&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ yes Y | /opt/android/tools/bin/sdkmanager --licenses
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Seems good, now create an avd &lt;strong&gt;&lt;code&gt;test&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ echo "no" | /opt/android/tools/bin/avdmanager --verbose create avd --force --name "test" --device "pixel" --package "system-images;android-28;google_apis;x86" --tag "google_apis" --abi "x86"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;— name: device’s name.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;— abi: CPU architecture.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;— tag &lt;code&gt;google_api&lt;/code&gt;: support Google API.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Check one more time to see if it works!&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ /opt/android/emulator/emulator -list-avds 
# Expected Result: test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  3. Set up environment variables
&lt;/h2&gt;

&lt;p&gt;Edit your &lt;code&gt;.bashrc&lt;/code&gt; or any config files that you’re familiar with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;GRADLE_HOME=/opt/gradle/gradle-5.4.1&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;ANDROID_HOME&lt;/em&gt;=/opt/android&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;PATH=&lt;/em&gt;$&lt;em&gt;PATH&lt;/em&gt;:$&lt;em&gt;GRADLE_HOME&lt;/em&gt;/bin:/opt/gradlew:$&lt;em&gt;ANDROID_HOME&lt;/em&gt;/emulator:$&lt;em&gt;ANDROID_HOME&lt;/em&gt;/tools/bin:$&lt;em&gt;ANDROID_HOME&lt;/em&gt;/platform-tools&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;LD_LIBRARY_PATH= $ANDROID_HOME&lt;/em&gt;/emulator/lib64:$&lt;em&gt;ANDROID_HOME&lt;/em&gt;/emulator/lib64/qt/lib&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then reflect the changes with &lt;code&gt;source ~/.bashrc&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note&lt;/em&gt;&lt;/strong&gt;: The order of PATH variable is important because android provides 2 executed file for &lt;code&gt;emulator&lt;/code&gt;, one is packaged in &lt;code&gt;/android/emulator&lt;/code&gt; and another is in &lt;code&gt;/android/tools/bin&lt;/code&gt;. We’ll use &lt;code&gt;/android/emulator&lt;/code&gt; to run android device.&lt;/p&gt;

&lt;p&gt;More detail is this &lt;a href="https://stackoverflow.com/a/49511666/5460066"&gt;SO answer&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  4. Run emulator
&lt;/h2&gt;

&lt;p&gt;Here are some minor steps before running emulator:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Stop any running emulators with ADB.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Start emulator in the background with flag &lt;code&gt;-no-window&lt;/code&gt; and &lt;code&gt;-gpu off&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Turn off animation to avoid flaky tests.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some test cases will perform an action on a view that might be not visible on a small screen — so we set the emulator up to have a high resolution (1440x2880)&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function wait_emulator_to_be_ready() {
  adb devices | grep emulator | cut -f1 | while read line; do adb -s $line emu kill; done
  emulator -avd test -no-audio -no-boot-anim -no-window -accel on -gpu off -skin 1440x2880 &amp;amp;

boot_completed=false
  while [ "$boot_completed" == false ]; do
    status=$(adb wait-for-device shell getprop sys.boot_completed | tr -d '\r')
    echo "Boot Status: $status"

    if [ "$status" == "1" ]; then
      boot_completed=true
    else
      sleep 1
    fi
  done
}

function disable_animation() {
  adb shell "settings put global window_animation_scale 0.0"
  adb shell "settings put global transition_animation_scale 0.0"
  adb shell "settings put global animator_duration_scale 0.0"
}

wait_emulator_to_be_ready
sleep 1
disable_animation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Start the emulator with sh &lt;code&gt;start.sh&lt;/code&gt; or &lt;code&gt;./start.sh&lt;/code&gt; and wait until &lt;code&gt;Boot Status: 1&lt;/code&gt; which means the device is fully loaded and ready to use.&lt;/p&gt;

&lt;p&gt;Check again by enter &lt;code&gt;bg&lt;/code&gt; to see the background jobs.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ./start.sh
emulator: WARNING: Your AVD has been configured with an in-guest renderer, but the system image does not support guest rendering.Falling back to 'swiftshader_indirect' mode.
WARNING: change of renderer detected.
checkValid: hw configs not eq
emulator: Cold boot: different AVD configuration
Your emulator is out of date, please update by launching Android Studio:
 - Start Android Studio
 - Select menu "Tools &amp;gt; Android &amp;gt; SDK Manager"
 - Click "SDK Tools" tab
 - Check "Android Emulator" checkbox
 - Click "OK"

Boot Status: 
Boot Status: 
Boot Status: 
Boot Status: 
Boot Status: 
Boot Status: 
Boot Status: 
Boot Status: 
Boot Status: 
Boot Status: 1
emulator: INFO: boot completed
emulator: INFO: boot time 13200 ms
emulator: Increasing screen off timeout, logcat buffer size to 2M.
emulator: Revoking microphone permissions for Google App.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Check running emulators&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ adb devices
List of devices attached
emulator-5554   device
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We have an Android emulator running in the container successfully!&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Build docker image
&lt;/h2&gt;

&lt;p&gt;Open a new terminal tab, stop &lt;code&gt;android-container&lt;/code&gt; and commit your changes to create a new Docker image:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker stop android-container &amp;amp;&amp;amp; docker commit android-container android-container:v1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Test once again:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker images
# Expected result: REPOSITORY          TAG
                   android-container   v1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;For further extending with more configurations (ex: Flutter), let’s wrap things up and finalize the &lt;code&gt;Dockerfile&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM ubuntu

LABEL maintainer "codecaigicungduoc@gmail"

WORKDIR /

SHELL ["/bin/bash", "-c"]

RUN apt update &amp;amp;&amp;amp; apt install -y openjdk-8-jdk vim git unzip libglu1 libpulse-dev libasound2 libc6  libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxi6  libxtst6 libnss3 wget

ARG GRADLE_VERSION=5.4.1
ARG ANDROID_API_LEVEL=28
ARG ANDROID_BUILD_TOOLS_LEVEL=28.0.3
ARG EMULATOR_NAME='test'

RUN wget https://services.gradle.org/distributions/gradle-${GRADLE_VERSION}-bin.zip -P /tmp \
&amp;amp;&amp;amp; unzip -d /opt/gradle /tmp/gradle-${GRADLE_VERSION}-bin.zip \
&amp;amp;&amp;amp; mkdir /opt/gradlew \
&amp;amp;&amp;amp; /opt/gradle/gradle-${GRADLE_VERSION}/bin/gradle wrapper --gradle-version ${GRADLE_VERSION} --distribution-type all -p /opt/gradlew  \
&amp;amp;&amp;amp; /opt/gradle/gradle-${GRADLE_VERSION}/bin/gradle wrapper -p /opt/gradlew

RUN wget 'https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip' -P /tmp \
&amp;amp;&amp;amp; unzip -d /opt/android /tmp/sdk-tools-linux-4333796.zip \
&amp;amp;&amp;amp; yes Y | /opt/android/tools/bin/sdkmanager --install "platform-tools" "system-images;android-${ANDROID_API_LEVEL};google_apis;x86" "platforms;android-${ANDROID_API_LEVEL}" "build-tools;${ANDROID_BUILD_TOOLS_LEVEL}" "emulator" \
&amp;amp;&amp;amp; yes Y | /opt/android/tools/bin/sdkmanager --licenses \
&amp;amp;&amp;amp; echo "no" | /opt/android/tools/bin/avdmanager --verbose create avd --force --name "test" --device "pixel" --package "system-images;android-${ANDROID_API_LEVEL};google_apis;x86" --tag "google_apis" --abi "x86"

ENV GRADLE_HOME=/opt/gradle/gradle-$GRADLE_VERSION \
ANDROID_HOME=/opt/android
ENV PATH "$PATH:$GRADLE_HOME/bin:/opt/gradlew:$ANDROID_HOME/emulator:$ANDROID_HOME/tools/bin:$ANDROID_HOME/platform-tools"
ENV LD_LIBRARY_PATH "$ANDROID_HOME/emulator/lib64:$ANDROID_HOME/emulator/lib64/qt/lib"

ADD start.sh /

RUN chmod +x start.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  6. Build project and run tests
&lt;/h2&gt;

&lt;p&gt;Check out your project configurations and build the ocker image with appropriate arguments:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker build \
--build-arg GRADLE_VERSION=5.4.1 \
--build-arg ANDROID_API_LEVEL=28 \
--build-arg ANDROID_BUILD_TOOLS_LEVEL=28.0.3 \
--build-arg EMULATOR_NAME=test \
-t android-container .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Enter the top level of your project directory and run:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run --privileged -it --rm -v $PWD:/data android-container bash -c ". /start.sh &amp;amp;&amp;amp; gradlew build -p /data"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;-&lt;code&gt;it&lt;/code&gt;: interactive mode.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;— &lt;code&gt;rm&lt;/code&gt;: remove volume after the process is completed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;-v &lt;code&gt;$PWD:/data&lt;/code&gt;: mount your directory into the container:/data&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;bash &lt;code&gt;-c “ . /start.sh &amp;amp;&amp;amp; gradlew build -p /data”&lt;/code&gt;: start the emulator and build project.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Voilà! We have the whole testing process run independently on docker container. Let’s get back to other stuff while waiting for the report. 😝 😝&lt;/p&gt;

&lt;p&gt;For more detailed about build steps and sample, please check out this &lt;a href="https://github.com/fastphat/android-container"&gt;GitHub repo&lt;/a&gt;. I’ve made a cool sample with &lt;a href="https://github.com/android/sunflower"&gt;Sunflower&lt;/a&gt; project.&lt;/p&gt;

&lt;p&gt;If you have any questions, feel free to ask, reach out to me via &lt;em&gt;&lt;a href="mailto:codecaigicungduoc@gmail.com"&gt;codecaigicungduoc@gmail.com&lt;/a&gt;&lt;/em&gt; or creating a new issue on my github repo.&lt;/p&gt;

&lt;p&gt;Thanks for reading 🙇 🙇 🙇&lt;/p&gt;

</description>
      <category>android</category>
      <category>docker</category>
      <category>productivity</category>
      <category>testing</category>
    </item>
  </channel>
</rss>
