mirror of https://github.com/kivy/kivy.git
Add tests for pyinstaller.
This commit is contained in:
parent
b68a8e73c4
commit
7b8a397089
|
@ -67,7 +67,7 @@ build_script:
|
|||
Check-Error
|
||||
|
||||
|
||||
$PYTHONPATH = "$env:APPVEYOR_BUILD_FOLDER;$PYTHONPATH"
|
||||
$env:PYTHONPATH = "$env:APPVEYOR_BUILD_FOLDER;$PYTHONPATH"
|
||||
|
||||
echo "Build folder: $env:APPVEYOR_BUILD_FOLDER. Wheel folder: $env:WHEEL_DIR."
|
||||
|
||||
|
@ -155,7 +155,7 @@ build_script:
|
|||
Check-Error
|
||||
}
|
||||
|
||||
pip install mock cython pygments docutils pytest kivy_deps.glew_dev kivy_deps.glew kivy_deps.gstreamer_dev kivy_deps.sdl2_dev kivy_deps.sdl2
|
||||
pip install mock cython pygments docutils pytest pyinstaller kivy_deps.glew_dev kivy_deps.glew kivy_deps.gstreamer_dev kivy_deps.sdl2_dev kivy_deps.sdl2
|
||||
|
||||
pip --no-cache-dir install kivy_deps.gstreamer
|
||||
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
import pytest
|
||||
|
||||
|
||||
def pytest_runtest_makereport(item, call):
|
||||
# from https://docs.pytest.org/en/latest/example/simple.html
|
||||
if "incremental" in item.keywords:
|
||||
if call.excinfo is not None:
|
||||
parent = item.parent
|
||||
parent._previousfailed = item
|
||||
|
||||
|
||||
def pytest_runtest_setup(item):
|
||||
# from https://docs.pytest.org/en/latest/example/simple.html
|
||||
if "incremental" in item.keywords:
|
||||
previousfailed = getattr(item.parent, "_previousfailed", None)
|
||||
if previousfailed is not None:
|
||||
pytest.xfail("previous test failed (%s)" % previousfailed.name)
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
|
||||
from project.widget import MyWidget
|
||||
|
||||
if __name__ == '__main__':
|
||||
w = MyWidget()
|
||||
|
||||
assert w.x == w.y
|
||||
w.y = 868
|
||||
assert w.x == 868
|
||||
w.y = 370
|
||||
assert w.x == 370
|
|
@ -0,0 +1,37 @@
|
|||
# -*- mode: python -*-
|
||||
|
||||
block_cipher = None
|
||||
from kivy_deps import sdl2, glew
|
||||
from kivy.tools.packaging.pyinstaller_hooks import runtime_hooks, hookspath
|
||||
import os
|
||||
|
||||
|
||||
a = Analysis(['main.py'],
|
||||
pathex=[os.environ['__KIVY_PYINSTALLER_DIR']],
|
||||
binaries=[],
|
||||
datas=[],
|
||||
hiddenimports=[],
|
||||
hookspath=[os.environ['__KIVY_PYINSTALLER_DIR']],
|
||||
runtime_hooks=runtime_hooks(),
|
||||
excludes=['numpy', 'ffpyplayer'],
|
||||
win_no_prefer_redirects=False,
|
||||
win_private_assemblies=False,
|
||||
cipher=block_cipher)
|
||||
pyz = PYZ(a.pure, a.zipped_data,
|
||||
cipher=block_cipher)
|
||||
exe = EXE(pyz,
|
||||
a.scripts,
|
||||
exclude_binaries=True,
|
||||
name='main',
|
||||
debug=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
console=True )
|
||||
coll = COLLECT(exe,
|
||||
a.binaries,
|
||||
a.zipfiles,
|
||||
a.datas,
|
||||
*[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)],
|
||||
strip=False,
|
||||
upx=True,
|
||||
name='main')
|
|
@ -0,0 +1,12 @@
|
|||
from kivy.uix.widget import Widget
|
||||
|
||||
|
||||
class MyWidget(Widget):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(MyWidget, self).__init__(**kwargs)
|
||||
|
||||
def callback(*l):
|
||||
self.x = self.y
|
||||
self.fbind('y', callback)
|
||||
callback()
|
|
@ -0,0 +1,115 @@
|
|||
import pytest
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import shutil
|
||||
|
||||
if sys.platform != 'win32':
|
||||
pytestmark = pytest.mark.skip(
|
||||
"PyInstaller is currently only tested on Windows")
|
||||
else:
|
||||
try:
|
||||
import PyInstaller
|
||||
except ImportError:
|
||||
pytestmark = pytest.mark.skip("PyInstaller is not available")
|
||||
|
||||
|
||||
@pytest.mark.incremental
|
||||
class PyinstallerBase(object):
|
||||
|
||||
pinstall_path = ''
|
||||
|
||||
env = None
|
||||
|
||||
@classmethod
|
||||
def setup_class(cls):
|
||||
cls.env = cls.get_env()
|
||||
|
||||
@classmethod
|
||||
def get_env(cls):
|
||||
env = os.environ.copy()
|
||||
env['__KIVY_PYINSTALLER_DIR'] = cls.pinstall_path
|
||||
|
||||
if 'PYTHONPATH' not in env:
|
||||
env['PYTHONPATH'] = cls.pinstall_path
|
||||
else:
|
||||
env['PYTHONPATH'] = cls.pinstall_path + os.sep + env['PYTHONPATH']
|
||||
return env
|
||||
|
||||
@classmethod
|
||||
def get_run_env(cls):
|
||||
return os.environ.copy()
|
||||
|
||||
def test_project(self):
|
||||
try:
|
||||
# check that the project works normally before packaging
|
||||
subprocess.check_output(
|
||||
[sys.executable or 'python',
|
||||
os.path.join(self.pinstall_path, 'main.py')],
|
||||
stderr=subprocess.STDOUT, env=self.env)
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(e.output.decode('utf8'))
|
||||
raise
|
||||
|
||||
def test_packaging(self):
|
||||
dist = os.path.join(self.pinstall_path, 'dist')
|
||||
build = os.path.join(self.pinstall_path, 'build')
|
||||
try:
|
||||
# create pyinstaller package
|
||||
subprocess.check_output(
|
||||
[sys.executable or 'python', '-m', 'PyInstaller',
|
||||
os.path.join(self.pinstall_path, 'main.spec'),
|
||||
'--distpath', dist, '--workpath', build],
|
||||
stderr=subprocess.STDOUT, env=self.env)
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(e.output.decode('utf8'))
|
||||
raise
|
||||
|
||||
def test_packaged_project(self):
|
||||
try:
|
||||
# test package
|
||||
subprocess.check_output(
|
||||
os.path.join(self.pinstall_path, 'dist', 'main', 'main'),
|
||||
stderr=subprocess.STDOUT, env=self.get_run_env())
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(e.output.decode('utf8'))
|
||||
raise
|
||||
|
||||
@classmethod
|
||||
def teardown_class(cls):
|
||||
shutil.rmtree(
|
||||
os.path.join(cls.pinstall_path, '__pycache__'),
|
||||
ignore_errors=True)
|
||||
shutil.rmtree(
|
||||
os.path.join(cls.pinstall_path, 'build'), ignore_errors=True)
|
||||
shutil.rmtree(
|
||||
os.path.join(cls.pinstall_path, 'dist'), ignore_errors=True)
|
||||
shutil.rmtree(
|
||||
os.path.join(cls.pinstall_path, 'project', '__pycache__'),
|
||||
ignore_errors=True)
|
||||
|
||||
|
||||
class TestSimpleWidget(PyinstallerBase):
|
||||
|
||||
pinstall_path = os.path.join(os.path.dirname(__file__), 'simple_widget')
|
||||
|
||||
|
||||
class TestVideoWidget(PyinstallerBase):
|
||||
|
||||
pinstall_path = os.path.join(os.path.dirname(__file__), 'video_widget')
|
||||
|
||||
@classmethod
|
||||
def get_env(cls):
|
||||
env = super(TestVideoWidget, cls).get_env()
|
||||
env['__KIVY_VIDEO_TEST_FNAME'] = os.path.abspath(os.path.join(
|
||||
os.path.dirname(__file__), "..", "..", "..", "examples",
|
||||
"widgets", "cityCC0.mpg"))
|
||||
return env
|
||||
|
||||
@classmethod
|
||||
def get_run_env(cls):
|
||||
env = super(TestVideoWidget, cls).get_run_env()
|
||||
env['__KIVY_VIDEO_TEST_FNAME'] = os.path.abspath(os.path.join(
|
||||
os.path.dirname(__file__), "..", "..", "..", "examples",
|
||||
"widgets", "cityCC0.mpg"))
|
||||
return env
|
|
@ -0,0 +1,6 @@
|
|||
from project import VideoApp
|
||||
|
||||
if __name__ == '__main__':
|
||||
from kivy.core.video import Video
|
||||
assert Video is not None
|
||||
VideoApp().run()
|
|
@ -0,0 +1,50 @@
|
|||
# -*- mode: python -*-
|
||||
|
||||
block_cipher = None
|
||||
from kivy_deps import sdl2, glew
|
||||
from kivy.tools.packaging.pyinstaller_hooks import runtime_hooks, hookspath
|
||||
import os
|
||||
|
||||
deps = list(sdl2.dep_bins + glew.dep_bins)
|
||||
try:
|
||||
import ffpyplayer
|
||||
deps.extend(ffpyplayer.dep_bins)
|
||||
except ImportError:
|
||||
pass
|
||||
try:
|
||||
from kivy_deps import gstreamer
|
||||
deps.extend(gstreamer.dep_bins)
|
||||
except ImportError:
|
||||
pass
|
||||
print('deps are: ', deps)
|
||||
|
||||
|
||||
a = Analysis(['main.py'],
|
||||
pathex=[os.environ['__KIVY_PYINSTALLER_DIR']],
|
||||
binaries=[],
|
||||
datas=[],
|
||||
hiddenimports=[],
|
||||
hookspath=[os.environ['__KIVY_PYINSTALLER_DIR']],
|
||||
runtime_hooks=runtime_hooks(),
|
||||
excludes=['numpy',],
|
||||
win_no_prefer_redirects=False,
|
||||
win_private_assemblies=False,
|
||||
cipher=block_cipher)
|
||||
pyz = PYZ(a.pure, a.zipped_data,
|
||||
cipher=block_cipher)
|
||||
exe = EXE(pyz,
|
||||
a.scripts,
|
||||
exclude_binaries=True,
|
||||
name='main',
|
||||
debug=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
console=True )
|
||||
coll = COLLECT(exe,
|
||||
a.binaries,
|
||||
a.zipfiles,
|
||||
a.datas,
|
||||
*[Tree(p) for p in deps],
|
||||
strip=False,
|
||||
upx=True,
|
||||
name='main')
|
|
@ -0,0 +1,30 @@
|
|||
from kivy.app import App
|
||||
from kivy.uix.videoplayer import VideoPlayer
|
||||
from kivy.clock import Clock
|
||||
import os
|
||||
|
||||
|
||||
class VideoApp(App):
|
||||
|
||||
player = None
|
||||
|
||||
def build(self):
|
||||
self.player = player = VideoPlayer(
|
||||
source=os.environ['__KIVY_VIDEO_TEST_FNAME'], volume=0)
|
||||
|
||||
self.player.fbind('position', self.check_position)
|
||||
Clock.schedule_once(self.start_player, 0)
|
||||
Clock.schedule_once(self.stop_player, 5)
|
||||
return player
|
||||
|
||||
def start_player(self, *args):
|
||||
self.player.state = 'play'
|
||||
|
||||
def check_position(self, *args):
|
||||
if self.player.position > 0.1:
|
||||
self.stop_player()
|
||||
|
||||
def stop_player(self, *args):
|
||||
assert self.player.duration > 0
|
||||
assert self.player.position > 0
|
||||
self.stop()
|
Loading…
Reference in New Issue