Skip to content

Commit f52cfc3

Browse files
authored
Merge pull request #1636 from inclement/on_device_unit_test_app
Added app for on-device unit tests, refs #1637
2 parents 8d9f1e3 + ae35da8 commit f52cfc3

File tree

4 files changed

+377
-0
lines changed

4 files changed

+377
-0
lines changed
Lines changed: 282 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,282 @@
1+
[app]
2+
3+
# (str) Title of your application
4+
title = p4a unit tests
5+
6+
# (str) Package name
7+
package.name = p4aunittests
8+
9+
# (str) Package domain (needed for android/ios packaging)
10+
package.domain = org.kivy
11+
12+
# (str) Source code where the main.py live
13+
source.dir = test_app
14+
15+
# (list) Source files to include (let empty to include all the files)
16+
source.include_exts = py,png,jpg,kv,atlas
17+
18+
# (list) List of inclusions using pattern matching
19+
#source.include_patterns = assets/*,images/*.png
20+
21+
# (list) Source files to exclude (let empty to not exclude anything)
22+
#source.exclude_exts = spec
23+
24+
# (list) List of directory to exclude (let empty to not exclude anything)
25+
#source.exclude_dirs = tests, bin
26+
27+
# (list) List of exclusions using pattern matching
28+
#source.exclude_patterns = license,images/*/*.jpg
29+
30+
# (str) Application versioning (method 1)
31+
version = 0.1
32+
33+
# (str) Application versioning (method 2)
34+
# version.regex = __version__ = ['"](.*)['"]
35+
# version.filename = %(source.dir)s/main.py
36+
37+
# (list) Application requirements
38+
# comma separated e.g. requirements = sqlite3,kivy
39+
requirements = python3,kivy,openssl,numpy,sqlite3
40+
41+
# (str) Custom source folders for requirements
42+
# Sets custom source for any requirements with recipes
43+
# requirements.source.kivy = ../../kivy
44+
45+
# (list) Garden requirements
46+
#garden_requirements =
47+
48+
# (str) Presplash of the application
49+
#presplash.filename = %(source.dir)s/data/presplash.png
50+
51+
# (str) Icon of the application
52+
#icon.filename = %(source.dir)s/data/icon.png
53+
54+
# (str) Supported orientation (one of landscape, sensorLandscape, portrait or all)
55+
orientation = portrait
56+
57+
# (list) List of service to declare
58+
#services = NAME:ENTRYPOINT_TO_PY,NAME2:ENTRYPOINT2_TO_PY
59+
60+
#
61+
# OSX Specific
62+
#
63+
64+
#
65+
# author = © Copyright Info
66+
67+
# change the major version of python used by the app
68+
osx.python_version = 3
69+
70+
# Kivy version to use
71+
osx.kivy_version = 1.9.1
72+
73+
#
74+
# Android specific
75+
#
76+
77+
# (bool) Indicate if the application should be fullscreen or not
78+
fullscreen = 0
79+
80+
# (string) Presplash background color (for new android toolchain)
81+
# Supported formats are: #RRGGBB #AARRGGBB or one of the following names:
82+
# red, blue, green, black, white, gray, cyan, magenta, yellow, lightgray,
83+
# darkgray, grey, lightgrey, darkgrey, aqua, fuchsia, lime, maroon, navy,
84+
# olive, purple, silver, teal.
85+
#android.presplash_color = #FFFFFF
86+
87+
# (list) Permissions
88+
#android.permissions = INTERNET
89+
90+
# (int) Target Android API, should be as high as possible.
91+
#android.api = 27
92+
93+
# (int) Minimum API your APK will support.
94+
#android.minapi = 21
95+
96+
# (int) Android SDK version to use
97+
#android.sdk = 20
98+
99+
# (str) Android NDK version to use
100+
#android.ndk = 17c
101+
102+
# (int) Android NDK API to use. This is the minimum API your app will support, it should usually match android.minapi.
103+
#android.ndk_api = 21
104+
105+
# (bool) Use --private data storage (True) or --dir public storage (False)
106+
#android.private_storage = True
107+
108+
# (str) Android NDK directory (if empty, it will be automatically downloaded.)
109+
#android.ndk_path =
110+
111+
# (str) Android SDK directory (if empty, it will be automatically downloaded.)
112+
#android.sdk_path =
113+
114+
# (str) ANT directory (if empty, it will be automatically downloaded.)
115+
#android.ant_path =
116+
117+
# (bool) If True, then skip trying to update the Android sdk
118+
# This can be useful to avoid excess Internet downloads or save time
119+
# when an update is due and you just want to test/build your package
120+
# android.skip_update = False
121+
122+
# (str) Android entry point, default is ok for Kivy-based app
123+
#android.entrypoint = org.renpy.android.PythonActivity
124+
125+
# (list) Pattern to whitelist for the whole project
126+
android.whitelist = unittest/*
127+
128+
# (str) Path to a custom whitelist file
129+
#android.whitelist_src =
130+
131+
# (str) Path to a custom blacklist file
132+
#android.blacklist_src =
133+
134+
# (list) List of Java .jar files to add to the libs so that pyjnius can access
135+
# their classes. Don't add jars that you do not need, since extra jars can slow
136+
# down the build process. Allows wildcards matching, for example:
137+
# OUYA-ODK/libs/*.jar
138+
#android.add_jars = foo.jar,bar.jar,path/to/more/*.jar
139+
140+
# (list) List of Java files to add to the android project (can be java or a
141+
# directory containing the files)
142+
#android.add_src =
143+
144+
# (list) Android AAR archives to add (currently works only with sdl2_gradle
145+
# bootstrap)
146+
#android.add_aars =
147+
148+
# (list) Gradle dependencies to add (currently works only with sdl2_gradle
149+
# bootstrap)
150+
#android.gradle_dependencies =
151+
152+
# (list) Java classes to add as activities to the manifest.
153+
#android.add_activites = com.example.ExampleActivity
154+
155+
# (str) python-for-android branch to use, defaults to master
156+
#p4a.branch = master
157+
158+
# (str) OUYA Console category. Should be one of GAME or APP
159+
# If you leave this blank, OUYA support will not be enabled
160+
#android.ouya.category = GAME
161+
162+
# (str) Filename of OUYA Console icon. It must be a 732x412 png image.
163+
#android.ouya.icon.filename = %(source.dir)s/data/ouya_icon.png
164+
165+
# (str) XML file to include as an intent filters in <activity> tag
166+
#android.manifest.intent_filters =
167+
168+
# (str) launchMode to set for the main activity
169+
#android.manifest.launch_mode = standard
170+
171+
# (list) Android additional libraries to copy into libs/armeabi
172+
#android.add_libs_armeabi = libs/android/*.so
173+
#android.add_libs_armeabi_v7a = libs/android-v7/*.so
174+
#android.add_libs_x86 = libs/android-x86/*.so
175+
#android.add_libs_mips = libs/android-mips/*.so
176+
177+
# (bool) Indicate whether the screen should stay on
178+
# Don't forget to add the WAKE_LOCK permission if you set this to True
179+
#android.wakelock = False
180+
181+
# (list) Android application meta-data to set (key=value format)
182+
#android.meta_data =
183+
184+
# (list) Android library project to add (will be added in the
185+
# project.properties automatically.)
186+
#android.library_references =
187+
188+
# (str) Android logcat filters to use
189+
#android.logcat_filters = *:S python:D
190+
191+
# (bool) Copy library instead of making a libpymodules.so
192+
#android.copy_libs = 1
193+
194+
# (str) The Android arch to build for, choices: armeabi-v7a, arm64-v8a, x86
195+
android.arch = armeabi-v7a
196+
197+
#
198+
# Python for android (p4a) specific
199+
#
200+
201+
# (str) python-for-android git clone directory (if empty, it will be automatically cloned from github)
202+
#p4a.source_dir =
203+
204+
# (str) The directory in which python-for-android should look for your own build recipes (if any)
205+
#p4a.local_recipes =
206+
207+
# (str) Filename to the hook for p4a
208+
#p4a.hook =
209+
210+
# (str) Bootstrap to use for android builds
211+
# p4a.bootstrap = sdl2
212+
213+
# (int) port number to specify an explicit --port= p4a argument (eg for bootstrap flask)
214+
#p4a.port =
215+
216+
217+
#
218+
# iOS specific
219+
#
220+
221+
# (str) Path to a custom kivy-ios folder
222+
#ios.kivy_ios_dir = ../kivy-ios
223+
224+
# (str) Name of the certificate to use for signing the debug version
225+
# Get a list of available identities: buildozer ios list_identities
226+
#ios.codesign.debug = "iPhone Developer: <lastname> <firstname> (<hexstring>)"
227+
228+
# (str) Name of the certificate to use for signing the release version
229+
#ios.codesign.release = %(ios.codesign.debug)s
230+
231+
232+
[buildozer]
233+
234+
# (int) Log level (0 = error only, 1 = info, 2 = debug (with command output))
235+
log_level = 2
236+
237+
# (int) Display warning if buildozer is run as root (0 = False, 1 = True)
238+
warn_on_root = 1
239+
240+
# (str) Path to build artifact storage, absolute or relative to spec file
241+
# build_dir = ./.buildozer
242+
243+
# (str) Path to build output (i.e. .apk, .ipa) storage
244+
# bin_dir = ./bin
245+
246+
# -----------------------------------------------------------------------------
247+
# List as sections
248+
#
249+
# You can define all the "list" as [section:key].
250+
# Each line will be considered as a option to the list.
251+
# Let's take [app] / source.exclude_patterns.
252+
# Instead of doing:
253+
#
254+
#[app]
255+
#source.exclude_patterns = license,data/audio/*.wav,data/images/original/*
256+
#
257+
# This can be translated into:
258+
#
259+
#[app:source.exclude_patterns]
260+
#license
261+
#data/audio/*.wav
262+
#data/images/original/*
263+
#
264+
265+
266+
# -----------------------------------------------------------------------------
267+
# Profiles
268+
#
269+
# You can extend section / key with a profile
270+
# For example, you want to deploy a demo version of your application without
271+
# HD content. You could first change the title to add "(demo)" in the name
272+
# and extend the excluded directories to remove the HD content.
273+
#
274+
#[app@demo]
275+
#title = My Application (demo)
276+
#
277+
#[app:source.exclude_patterns@demo]
278+
#images/hd/*
279+
#
280+
# Then, invoke the command line with the "demo" profile:
281+
#
282+
#buildozer --profile demo android debug
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import sys
2+
if sys.version_info.major < 3:
3+
print(('Running under Python {} but these tests '
4+
'require Python 3+').format(sys.version_info.major))
5+
6+
import unittest
7+
import importlib
8+
9+
print('Imported unittest')
10+
11+
12+
class PythonTestMixIn(object):
13+
14+
module_import = None
15+
16+
def test_import_module(self):
17+
"""Test importing the specified Python module name. This import test
18+
is common to all Python modules, it does not test any further
19+
functionality.
20+
"""
21+
self.assertIsNotNone(
22+
self.module_import,
23+
'module_import is not set (was default None)')
24+
25+
importlib.import_module(self.module_import)
26+
27+
def test_run_module(self):
28+
"""Import the specified module and do something with it as a minimal
29+
check that it actually works.
30+
31+
This test fails by default, it must be overridden by every
32+
child test class.
33+
"""
34+
35+
self.fail('This test must be overridden by {}'.format(self))
36+
37+
print('Defined test case')
38+
39+
import sys
40+
sys.path.append('./')
41+
from tests import test_requirements
42+
suite = unittest.TestLoader().loadTestsFromModule(test_requirements)
43+
unittest.TextTestRunner().run(suite)
44+
45+
print('Ran tests')

testapps/on_device_unit_tests/test_app/tests/__init__.py

Whitespace-only changes.
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
2+
from main import PythonTestMixIn
3+
from unittest import TestCase
4+
5+
6+
class NumpyTestCase(PythonTestMixIn, TestCase):
7+
module_import = 'numpy'
8+
9+
def test_run_module(self):
10+
import numpy as np
11+
12+
arr = np.random.random((3, 3))
13+
det = np.linalg.det(arr)
14+
15+
16+
class OpensslTestCase(PythonTestMixIn, TestCase):
17+
module_import = '_ssl'
18+
19+
def test_run_module(self):
20+
import ssl
21+
22+
ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
23+
ctx.options &= ~ssl.OP_NO_SSLv3
24+
25+
26+
class SqliteTestCase(PythonTestMixIn, TestCase):
27+
module_import = 'sqlite3'
28+
29+
def test_run_module(self):
30+
import sqlite3
31+
32+
conn = sqlite3.connect('example.db')
33+
conn.cursor()
34+
35+
36+
class KivyTestCase(PythonTestMixIn, TestCase):
37+
module_import = 'kivy'
38+
39+
def test_run_module(self):
40+
# This import has side effects, if it works then it's an
41+
# indication that Kivy is okay
42+
from kivy.core.window import Window
43+
44+
45+
class PyjniusTestCase(PythonTestMixIn, TestCase):
46+
module_import = 'jnius'
47+
48+
def test_run_module(self):
49+
from jnius import autoclass
50+
autoclass('org.kivy.PythonActivity')

0 commit comments

Comments
 (0)