Compare commits

...
17 Commits
17 changed files with 120 additions and 82 deletions
+24 -10
View File
@@ -1,16 +1,18 @@
Docker-Android <p align="center">
============== <img id="header" src="./images/logo_dockerandroid_small.png" />
</p>
[![Join the chat at https://gitter.im/butomo1989/docker-android](https://badges.gitter.im/butomo1989/docker-android.svg)](https://gitter.im/butomo1989/docker-android?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Join the chat at https://gitter.im/butomo1989/docker-android](https://badges.gitter.im/butomo1989/docker-android.svg)](https://gitter.im/butomo1989/docker-android?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Build Status](https://travis-ci.org/butomo1989/docker-android.svg?branch=master)](https://travis-ci.org/butomo1989/docker-android) [![Build Status](https://travis-ci.org/butomo1989/docker-android.svg?branch=master)](https://travis-ci.org/butomo1989/docker-android)
[![Docker Pulls](https://img.shields.io/docker/pulls/butomo1989/docker-android-x86-7.1.1.svg?style=flat-square&style=plastic)](https://hub.docker.com/r/butomo1989/docker-android-x86-7.1.1/)
[![codecov](https://codecov.io/gh/butomo1989/docker-android/branch/master/graph/badge.svg)](https://codecov.io/gh/butomo1989/docker-android) [![codecov](https://codecov.io/gh/butomo1989/docker-android/branch/master/graph/badge.svg)](https://codecov.io/gh/butomo1989/docker-android)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/3f000ffb97db45a59161814e1434c429)](https://www.codacy.com/app/butomo1989/docker-appium?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=butomo1989/docker-appium&amp;utm_campaign=Badge_Grade) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/3f000ffb97db45a59161814e1434c429)](https://www.codacy.com/app/butomo1989/docker-appium?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=butomo1989/docker-appium&amp;utm_campaign=Badge_Grade)
Docker-Android is a docker image built to be used for everything related to mobile website testing and Android project. Docker-Android is a docker image built to be used for everything related to mobile website testing and Android project.
Samsung Device | Google Device Emulator - Samsung Device | Emulator - Nexus Device | Real Device
:---------------------------:|:---------------------------: :---------------------------:|:---------------------------:|:---------------------------:
![][docker android samsung] | ![][docker android nexus] ![][emulator samsung] |![][emulator nexus] |![][real device]
Purpose Purpose
------- -------
@@ -28,7 +30,9 @@ Advantages compare with other docker-android projects
2. Emulator for different devices / skins, such as Samsung Galaxy S6, LG Nexus 4, HTC Nexus One and more. 2. Emulator for different devices / skins, such as Samsung Galaxy S6, LG Nexus 4, HTC Nexus One and more.
3. Ability to connect to Selenium Grid 3. Ability to connect to Selenium Grid
4. Ability to control emulator from outside container by using adb connect 4. Ability to control emulator from outside container by using adb connect
5. Open source with more features coming (monkey test, support real devices with screen mirroring and video recording) 5. Support real devices with screen mirroring
6. Ability to record video during test execution for debugging
7. Open source with more features coming
List of Docker images List of Docker images
--------------------- ---------------------
@@ -45,6 +49,7 @@ List of Docker images
|OSX / Windows|6.0|23|butomo1989/docker-android-arm-6.0|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-arm-6.0.svg)](https://microbadger.com/images/butomo1989/docker-android-arm-6.0 "Get your own image badge on microbadger.com")| |OSX / Windows|6.0|23|butomo1989/docker-android-arm-6.0|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-arm-6.0.svg)](https://microbadger.com/images/butomo1989/docker-android-arm-6.0 "Get your own image badge on microbadger.com")|
|OSX / Windows|7.0|24|butomo1989/docker-android-arm-7.0|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-arm-7.0.svg)](https://microbadger.com/images/butomo1989/docker-android-arm-7.0 "Get your own image badge on microbadger.com")| |OSX / Windows|7.0|24|butomo1989/docker-android-arm-7.0|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-arm-7.0.svg)](https://microbadger.com/images/butomo1989/docker-android-arm-7.0 "Get your own image badge on microbadger.com")|
|OSX / Windows|7.1.1|25|butomo1989/docker-android-arm-7.1.1|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-arm-7.1.1.svg)](https://microbadger.com/images/butomo1989/docker-android-arm-7.1.1 "Get your own image badge on microbadger.com")| |OSX / Windows|7.1.1|25|butomo1989/docker-android-arm-7.1.1|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-arm-7.1.1.svg)](https://microbadger.com/images/butomo1989/docker-android-arm-7.1.1 "Get your own image badge on microbadger.com")|
|All |-|-|butomo1989/docker-android-real-device|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-real-device.svg)](https://microbadger.com/images/butomo1989/docker-android-real-device "Get your own image badge on microbadger.com")|
List of Devices List of Devices
--------------- ---------------
@@ -127,10 +132,13 @@ If you want to use appium to test UI of your android application, you need to sh
docker run --privileged -d -p 6080:6080 -p 4723:4723 -p 5554:5554 -p 5555:5555 -v $PWD/example/sample_apk:/root/tmp -e DEVICE="Nexus 5" -e APPIUM=True -e CONNECT_TO_GRID=True -e APPIUM_HOST="127.0.0.1" -e APPIUM_PORT=4723 -e SELENIUM_HOST="172.17.0.1" -e SELENIUM_PORT=4444 --name android-container butomo1989/docker-android-x86-7.1.1 docker run --privileged -d -p 6080:6080 -p 4723:4723 -p 5554:5554 -p 5555:5555 -v $PWD/example/sample_apk:/root/tmp -e DEVICE="Nexus 5" -e APPIUM=True -e CONNECT_TO_GRID=True -e APPIUM_HOST="127.0.0.1" -e APPIUM_PORT=4723 -e SELENIUM_HOST="172.17.0.1" -e SELENIUM_PORT=4444 --name android-container butomo1989/docker-android-x86-7.1.1
``` ```
### Video Recording
You can deactivate auto_record by changing the value to "False" in docker-compose file. e.g. change value to "False" in this [line].
### Docker-Compose ### Docker-Compose
![][compose] ![][compose]
![][connected_devices]
There is [example of compose file] to run complete selenium grid and docker-android container as nodes. [docker-compose] version [1.13.0] or higher is required to be able to execute that compose file. There is [example of compose file] to run complete selenium grid and docker-android container as nodes. [docker-compose] version [1.13.0] or higher is required to be able to execute that compose file.
@@ -195,15 +203,21 @@ All logs inside container are stored under folder **/var/log/supervisor**. you c
docker exec -it android-container tail -f /var/log/supervisor/docker-android.stdout.log docker exec -it android-container tail -f /var/log/supervisor/docker-android.stdout.log
``` ```
Special Thanks
--------------
- [Gian Christanto] for creating a great logo!
[appium]: <https://appium.io> [appium]: <https://appium.io>
[espresso]: <https://google.github.io/android-testing-support-library/docs/espresso/> [espresso]: <https://google.github.io/android-testing-support-library/docs/espresso/>
[robotium]: <https://github.com/RobotiumTech/robotium> [robotium]: <https://github.com/RobotiumTech/robotium>
[docker android samsung]: <images/docker_android_samsung.png> [emulator samsung]: <images/emulator_samsung_galaxy_s6.png>
[docker android nexus]: <images/docker_android_nexus.png> [emulator nexus]: <images/emulator_nexus_5.png>
[real device]: <images/real_device.png>
[compose]: <images/compose.png> [compose]: <images/compose.png>
[connected_devices]: <images/connected_devices.png> [line]: <https://github.com/butomo1989/docker-android/blob/master/docker-compose.yml#L30>
[example of compose file]: <docker-compose.yml> [example of compose file]: <docker-compose.yml>
[docker-compose]: <https://docs.docker.com/compose/install/> [docker-compose]: <https://docs.docker.com/compose/install/>
[1.13.0]: <https://github.com/docker/compose/releases/tag/1.13.0> [1.13.0]: <https://github.com/docker/compose/releases/tag/1.13.0>
[adb_connection]: <images/adb_connection.png> [adb_connection]: <images/adb_connection.png>
[sms]: <images/SMS.png> [sms]: <images/SMS.png>
[gian christanto]: <https://www.linkedin.com/in/gian-christanto-0b398b131/>
Regular → Executable
+29 -1
View File
@@ -6,16 +6,38 @@ version: "2.2"
services: services:
# Selenium hub # Selenium hub
selenium_hub: selenium_hub:
image: selenium/hub:3.4.0 image: selenium/hub:3.7.1
ports: ports:
- "4444:4444" - "4444:4444"
# Real devices
real_device:
image: butomo1989/docker-android-real-device
privileged: true
depends_on:
- selenium_hub
ports:
- 6080:6080
volumes:
- ./video-real-device:/tmp/video
- /dev/bus/usb:/dev/bus/usb
- ~/.android:/root/.android
environment:
- CONNECT_TO_GRID=True
- APPIUM=true
- SELENIUM_HOST=selenium_hub
- AUTO_RECORD=True
- BROWSER_NAME=chrome
# Docker-Android for Android application testing # Docker-Android for Android application testing
nexus_7.1.1: nexus_7.1.1:
image: butomo1989/docker-android-x86-7.1.1 image: butomo1989/docker-android-x86-7.1.1
privileged: true privileged: true
# Increase scale number if needed # Increase scale number if needed
scale: 1 scale: 1
depends_on:
- selenium_hub
- real_device
ports: ports:
- 6080 - 6080
# Change path of apk that you want to test. I use sample_apk that I provide in folder "example" # Change path of apk that you want to test. I use sample_apk that I provide in folder "example"
@@ -36,6 +58,9 @@ services:
privileged: true privileged: true
# Increase scale number if needed # Increase scale number if needed
scale: 1 scale: 1
depends_on:
- selenium_hub
- real_device
ports: ports:
- 6080 - 6080
volumes: volumes:
@@ -55,6 +80,9 @@ services:
privileged: true privileged: true
# Increase scale number if needed # Increase scale number if needed
scale: 1 scale: 1
depends_on:
- selenium_hub
- real_device
ports: ports:
- 6080 - 6080
volumes: volumes:
+6 -4
View File
@@ -1,4 +1,4 @@
FROM appium/appium:1.6.6-beta-p0 FROM appium/appium:1.7.2-p1
LABEL maintainer "Budi Utomo <budi.ut.1989@gmail.com>" LABEL maintainer "Budi Utomo <budi.ut.1989@gmail.com>"
@@ -83,10 +83,12 @@ ENV ANDROID_VERSION=$ANDROID_VERSION \
IMG_TYPE=$IMG_TYPE \ IMG_TYPE=$IMG_TYPE \
BROWSER=$BROWSER BROWSER=$BROWSER
ENV PATH ${PATH}:${ANDROID_HOME}/build-tools ENV PATH ${PATH}:${ANDROID_HOME}/build-tools
RUN echo y | sdkmanager "platforms;android-${API_LEVEL}" && \
echo y | sdkmanager "system-images;android-${API_LEVEL};${IMG_TYPE};${SYS_IMG}" && \
echo y | sdkmanager "emulator"
RUN rm ${ANDROID_HOME}/tools/emulator \ RUN rm ${ANDROID_HOME}/tools/emulator \
&& ln -s ${ANDROID_HOME}/tools/emulator64-${PROCESSOR} ${ANDROID_HOME}/tools/emulator && ln -s ${ANDROID_HOME}/emulator/emulator64-${PROCESSOR} ${ANDROID_HOME}/tools/emulator
RUN echo y | android update sdk --no-ui -a -t android-${API_LEVEL},sys-img-${SYS_IMG}-${IMG_TYPE}-${API_LEVEL} ENV LD_LIBRARY_PATH=$ANDROID_HOME/emulator/lib64:$ANDROID_HOME/emulator/lib64/qt/lib
#============================================== #==============================================
# Download chrome driver v2.26 # Download chrome driver v2.26
+7 -4
View File
@@ -1,4 +1,4 @@
FROM appium/appium:1.6.6-beta-p0 FROM appium/appium:1.7.2-p1
LABEL maintainer "Budi Utomo <budi.ut.1989@gmail.com>" LABEL maintainer "Budi Utomo <budi.ut.1989@gmail.com>"
@@ -96,10 +96,13 @@ ENV ANDROID_VERSION=$ANDROID_VERSION \
IMG_TYPE=$IMG_TYPE \ IMG_TYPE=$IMG_TYPE \
BROWSER=$BROWSER BROWSER=$BROWSER
ENV PATH ${PATH}:${ANDROID_HOME}/build-tools ENV PATH ${PATH}:${ANDROID_HOME}/build-tools
RUN echo y | sdkmanager "platforms;android-${API_LEVEL}" && \
echo y | sdkmanager "system-images;android-${API_LEVEL};${IMG_TYPE};${SYS_IMG}" && \
echo y | sdkmanager "emulator"
RUN rm ${ANDROID_HOME}/tools/emulator \ RUN rm ${ANDROID_HOME}/tools/emulator \
&& ln -s ${ANDROID_HOME}/tools/emulator64-${PROCESSOR} ${ANDROID_HOME}/tools/emulator && ln -s ${ANDROID_HOME}/emulator/emulator64-${PROCESSOR} ${ANDROID_HOME}/tools/emulator
RUN echo y | android update sdk --no-ui -a -t android-${API_LEVEL},sys-img-${SYS_IMG}-${IMG_TYPE}-${API_LEVEL} ENV LD_LIBRARY_PATH=$ANDROID_HOME/emulator/lib64:$ANDROID_HOME/emulator/lib64/qt/lib
#============================================== #==============================================
# Download chrome driver v2.26 # Download chrome driver v2.26
+3 -9
View File
@@ -1,4 +1,4 @@
FROM appium/appium:1.6.6-beta-p0 FROM appium/appium:1.7.2-p1
LABEL maintainer "Budi Utomo <budi.ut.1989@gmail.com>" LABEL maintainer "Budi Utomo <budi.ut.1989@gmail.com>"
@@ -67,14 +67,7 @@ RUN wget -nv -O noVNC.zip "https://github.com/kanaka/noVNC/archive/${NOVNC_SHA}
&& rm websockify.zip \ && rm websockify.zip \
&& ln noVNC/vnc_auto.html noVNC/index.html && ln noVNC/vnc_auto.html noVNC/index.html
#============================================== #================================================
# Download Adb remote screen
#==============================================
RUN wget -nv -O asm.zip "http://adakoda.github.io/android-screen-monitor/download/3.0.0/ASM_3_00.zip" \
&& unzip asm.zip \
&& rm asm.zip
#================================================
# noVNC Default Configurations # noVNC Default Configurations
# These Configurations can be changed through -e # These Configurations can be changed through -e
#================================================ #================================================
@@ -110,6 +103,7 @@ EXPOSE 4723 6080 5555
#=================== #===================
# Run docker-appium # Run docker-appium
#=================== #===================
COPY sm/asm.jar /root/
COPY src /root/src COPY src /root/src
COPY supervisord.conf /root/ COPY supervisord.conf /root/
RUN chmod -R +x /root/src && chmod +x /root/supervisord.conf RUN chmod -R +x /root/src && chmod +x /root/supervisord.conf
Binary file not shown.

Before

Width:  |  Height:  |  Size: 131 KiB

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 244 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

+1 -1
View File
@@ -163,7 +163,7 @@ function build() {
for v in "${versions[@]}"; do for v in "${versions[@]}"; do
# Find image type and default web browser # Find image type and default web browser
if [ "$v" == "5.0.1" ] || [ "$v" == "5.1.1" ]; then if [ "$v" == "5.0.1" ] || [ "$v" == "5.1.1" ]; then
IMG_TYPE=android IMG_TYPE=default
BROWSER=browser BROWSER=browser
elif [ "$v" == "6.0" ]; then elif [ "$v" == "6.0" ]; then
# It is because there is no ARM EABI v7a System Image for 6.0 # It is because there is no ARM EABI v7a System Image for 6.0
Executable
BIN
View File
Binary file not shown.
+19 -20
View File
@@ -4,22 +4,24 @@ import json
import logging import logging
import os import os
import subprocess import subprocess
import errno
from src import CONFIG_FILE, ROOT, CHROME_DRIVER from src import CHROME_DRIVER, CONFIG_FILE, ROOT
from src import log from src import log
log.init() log.init()
logger = logging.getLogger('app') logger = logging.getLogger('app')
def symlink_force(target, link_name): def symlink_force(target, link_name):
try: try:
os.symlink(target, link_name) os.symlink(target, link_name)
except OSError as e: except OSError as e:
import errno
if e.errno == errno.EEXIST: if e.errno == errno.EEXIST:
os.remove(link_name) os.remove(link_name)
os.symlink(target, link_name) os.symlink(target, link_name)
def get_or_raise(env: str) -> str: def get_or_raise(env: str) -> str:
""" """
Check if needed environment variables are given. Check if needed environment variables are given.
@@ -69,22 +71,9 @@ def prepare_avd(device: str, avd_name: str):
:param device: Device name :param device: Device name
:param avd_name: Name of android virtual device / emulator :param avd_name: Name of android virtual device / emulator
""" """
cmd = 'echo no | android create avd -f -n {name} -t android-{api} -b {img_type}{sys_img}'.format(
name=avd_name, api=API_LEVEL, img_type='google_apis/' if IMG_TYPE == 'google_apis' else '',
sys_img=SYS_IMG)
# Link emulator skins
skin_rsc_path = os.path.join(ROOT, 'devices', 'skins')
logger.info('Skin ressource path: {rsc}'.format(rsc=skin_rsc_path))
skin_dst_path = os.path.join(ANDROID_HOME, 'platforms', 'android-{api}'.format(api=API_LEVEL), 'skins')
logger.info('Skin destination path: {dst}'.format(dst=skin_dst_path))
for s in os.listdir(skin_rsc_path):
symlink_force(os.path.join(skin_rsc_path, s), os.path.join(skin_dst_path, s))
# Hardware and its skin
device_name_bash = device.replace(' ', '\ ') device_name_bash = device.replace(' ', '\ ')
skin_name = device.replace(' ', '_').lower() skin_name = device.replace(' ', '_').lower()
logger.info('Device name in bash: {db}, Skin name: {skin}'.format(db=device_name_bash, skin=skin_name))
# For custom hardware profile # For custom hardware profile
profile_dst_path = os.path.join(ROOT, '.android', 'devices.xml') profile_dst_path = os.path.join(ROOT, '.android', 'devices.xml')
@@ -95,10 +84,19 @@ def prepare_avd(device: str, avd_name: str):
logger.info('Hardware profile destination path: {dst}'.format(dst=profile_dst_path)) logger.info('Hardware profile destination path: {dst}'.format(dst=profile_dst_path))
symlink_force(profile_src_path, profile_dst_path) symlink_force(profile_src_path, profile_dst_path)
# Append command avd_path = '/'.join([ANDROID_HOME, 'android_emulator'])
cmd += ' -d {device} -s {skin}'.format(device=device_name_bash, skin=skin_name) creation_cmd = 'avdmanager create avd -f -n {name} -b {img_type}/{sys_img} -k "system-images;android-{api_lvl};' \
logger.info('AVD creation command: {cmd}'.format(cmd=cmd)) '{img_type};{sys_img}" -d {device} -p {path}'.format(name=avd_name, img_type=IMG_TYPE, sys_img=SYS_IMG,
subprocess.check_call(cmd, shell=True) api_lvl=API_LEVEL, device=device_name_bash,
path=avd_path)
logger.info('Command to create avd: {command}'.format(command=creation_cmd))
subprocess.check_call(creation_cmd, shell=True)
skin_path = '/'.join([ANDROID_HOME, 'devices', 'skins', skin_name])
config_path = '/'.join([avd_path, 'config.ini'])
with open(config_path, 'a') as file:
file.write('skin.path={sp}'.format(sp=skin_path))
logger.info('Skin was added in config.ini')
def appium_run(avd_name: str): def appium_run(avd_name: str):
@@ -184,8 +182,9 @@ def run():
logger.info('Preparing emulator...') logger.info('Preparing emulator...')
prepare_avd(device, avd_name) prepare_avd(device, avd_name)
logger.info('Run emulator...') logger.info('Run emulator...')
cmd = 'emulator -avd {name}'.format(name=avd_name) cmd = 'emulator -avd {name} -gpu off'.format(name=avd_name)
subprocess.Popen(cmd.split()) subprocess.Popen(cmd.split())
appium = convert_str_to_bool(str(os.getenv('APPIUM', False))) appium = convert_str_to_bool(str(os.getenv('APPIUM', False)))
+14 -12
View File
@@ -10,22 +10,24 @@ from src import app
class TestApp(TestCase): class TestApp(TestCase):
"""Unit test class to test other methods in the app.""" """Unit test class to test other methods in the app."""
#create symlink
@classmethod @classmethod
def test_symlink_correct(self): def test_symlink(self):
os.mknod(os.path.join("./","testFile1.txt")) res = os.path.join('testFile1.txt')
app.symlink_force(os.path.join("./","testFile1.txt"),os.path.join("./","link_testFile1.txt")) dest = os.path.join('link_testFile1.txt')
os.remove(os.path.join("./","testFile1.txt")) open(res, 'a').close()
os.remove(os.path.join("./","link_testFile1.txt")) app.symlink_force(res, dest)
os.remove(res)
os.remove(dest)
#link already exist
@classmethod @classmethod
def test_symlink_already_exist(self): def test_symlink_already_exist(self):
os.mknod(os.path.join("./","testFile2.txt")) res = os.path.join('testFile1.txt')
os.mknod(os.path.join("./","link_testFile2.txt")) dest = os.path.join('link_testFile1.txt')
app.symlink_force(os.path.join("./","testFile2.txt"),os.path.join("./","link_testFile2.txt")) open(res, 'a').close()
os.remove(os.path.join("./","testFile2.txt")) open(dest, 'a').close()
os.remove(os.path.join("./","link_testFile2.txt")) app.symlink_force(res, dest)
os.remove(res)
os.remove(dest)
def test_valid_env(self): def test_valid_env(self):
key = 'ENV_1' key = 'ENV_1'
+17 -21
View File
@@ -8,34 +8,30 @@ from src import app
@mock.patch('subprocess.check_call') @mock.patch('subprocess.check_call')
@mock.patch('os.symlink')
class TestAvd(TestCase): class TestAvd(TestCase):
"""Unit test class to test method create_avd.""" """Unit test class to test method create_avd."""
def setUp(self): def setUp(self):
self.avd_name = 'test_avd' self.avd_name = 'test_avd'
def test_nexus_avd_as_default(self, mocked_suprocess, mocked_sys_link): @mock.patch("builtins.open", create=True)
with mock.patch('os.listdir') as mocked_list_dir: def test_nexus_avd_as_default(self, mocked_suprocess, mocked_open):
mocked_list_dir.return_value = ['file1', 'file2'] self.assertFalse(mocked_suprocess.called)
self.assertFalse(mocked_list_dir.called) self.assertFalse(mocked_open.called)
self.assertFalse(mocked_sys_link.called) app.prepare_avd('Nexus 5', self.avd_name)
self.assertFalse(mocked_suprocess.called) self.assertTrue(mocked_suprocess.called)
app.prepare_avd('Nexus 5', self.avd_name) self.assertTrue(mocked_open.called)
self.assertTrue(mocked_list_dir.called)
self.assertTrue(mocked_sys_link.called)
self.assertTrue(mocked_suprocess.called)
def test_samsung_avd(self, mocked_suprocess, mocked_sys_link): @mock.patch('os.symlink')
with mock.patch('os.listdir') as mocked_list_dir: @mock.patch("builtins.open", create=True)
mocked_list_dir.return_value = ['file1', 'file2'] def test_samsung_avd(self, mocked_suprocess, mocked_sys_link, mocked_open):
self.assertFalse(mocked_list_dir.called) self.assertFalse(mocked_sys_link.called)
self.assertFalse(mocked_sys_link.called) self.assertFalse(mocked_suprocess.called)
self.assertFalse(mocked_suprocess.called) self.assertFalse(mocked_open.called)
app.prepare_avd('Samsung Galaxy S6', self.avd_name) app.prepare_avd('Samsung Galaxy S6', self.avd_name)
self.assertTrue(mocked_list_dir.called) self.assertTrue(mocked_sys_link.called)
self.assertTrue(mocked_sys_link.called) self.assertTrue(mocked_suprocess.called)
self.assertTrue(mocked_suprocess.called) self.assertTrue(mocked_open.called)
def tearDown(self): def tearDown(self):
if os.getenv('DEVICE'): if os.getenv('DEVICE'):