Tests: Re-introduced pytest based tests. Fixed them a bit, commented-out otherwise. Application tests only runs with logging test, and PLCOpenEditor tests seem broken. wxPython4
authorEdouard Tisserant <edouard.tisserant@gmail.com>
Fri, 11 Mar 2022 14:43:37 +0100
branchwxPython4
changeset 3438 24fbd4d1fe80
parent 3437 ce366d67a5b7
child 3442 29dbdb09da2e
Tests: Re-introduced pytest based tests. Fixed them a bit, commented-out otherwise. Application tests only runs with logging test, and PLCOpenEditor tests seem broken.
tests/Makefile
tests/ide_tests/conftest.py
tests/ide_tests/load_and_build_tests.pytest/test_application.py
tests/ide_tests/wx_widgets.pytest/test_CustomIntCtrl.py
tests/tools/Docker/beremiz-sikuli/Dockerfile
tests/tools/conftest.py
tests/tools/run_python_tests.sh
tests/tools/test_CustomIntCtrl.py
tests/tools/test_application.py
--- a/tests/Makefile	Sat Mar 05 11:14:00 2022 +0100
+++ b/tests/Makefile	Fri Mar 11 14:43:37 2022 +0100
@@ -47,6 +47,7 @@
 #   Any change in Matiec and Beremiz directory triggers copy of source code
 #   to $(test_dir)/build.
 #
+#   BEREMIZPYTHONPATH is expected to be absolute path to python interpreter
 #
 #   Please note:
 #       In order to run asside a freshly build Matiec, tested beremiz instance
@@ -99,12 +100,22 @@
 own_apps: $(build_dir)/matiec/iec2c $(build_dir)/beremiz/$(beremiz_checksum).sha1
 	touch $@
 
-ide_tests = $(subst $(src)/ide_tests/,,$(wildcard $(src)/ide_tests/*.sikuli))
+ide_test_dir = $(src)/ide_tests
+sikuli_ide_tests = $(subst $(ide_test_dir)/,,$(wildcard $(ide_test_dir)/*.sikuli))
+pytest_ide_tests = $(subst $(ide_test_dir)/,,$(wildcard $(ide_test_dir)/*.pytest))
 
-define idetest_command
+define sikuli_idetest_command
 	(fluxbox >/dev/null 2>&1 &); BEREMIZPATH=$(build_dir)/beremiz sikulix -r $(src)/ide_tests/$(1) | tee test_stdout.txt; exit $$$${PIPESTATUS[0]}
 endef
 
+
+DELAY=400
+KILL_DELAY=430
+PYTEST=$(dir $(BEREMIZPYTHONPATH))/pytest
+define pytest_idetest_command
+	(fluxbox >/dev/null 2>&1 &); PYTHONPATH=$(ide_test_dir) timeout -k $(KILL_DELAY) $(DELAY) $(PYTEST) --maxfail=1 --timeout=100  $(src)/ide_tests/$(1) | tee test_stdout.txt; exit $$$${PIPESTATUS[0]}
+endef
+
 # Xnest based interactive sessions for tests edit and debug. 
 # Would be nice with something equivalent to xvfb-run, waiting for USR1.
 # Arbitrary "sleep 1" is probably enough for interactive use
@@ -122,7 +133,7 @@
 
 define make_idetest_rule
 $(test_dir)/$(1)_idetest/.passed: own_apps
-	$(call prep_test,$(1)); $(xserver_command) bash -c '$(call idetest_command,$(1))'
+	$(call prep_test,$(1)); $(xserver_command) bash -c '$(call $(2),$(1))'
 	touch $$@
 
 # Manually invoked rule {testname}.sikuli
@@ -131,11 +142,12 @@
 # Manually invoked rule xnest_{testname}.sikuli
 # runs test in xnest so that one can see what happens
 xnest_$(1): own_apps
-	$(call prep_test,$(1)); $$(call xnest_run, bash -c '$(call idetest_command,$(1))')
+	$(call prep_test,$(1)); $$(call xnest_run, bash -c '$(call $(2),$(1))')
 
 ide_tests_targets += $(test_dir)/$(1)_idetest/.passed
 endef
-$(foreach idetest,$(ide_tests),$(eval $(call make_idetest_rule,$(idetest))))
+$(foreach idetest,$(sikuli_ide_tests),$(eval $(call make_idetest_rule,$(idetest),sikuli_idetest_command)))
+$(foreach idetest,$(pytest_ide_tests),$(eval $(call make_idetest_rule,$(idetest),pytest_idetest_command)))
 
 ide_tests : $(ide_tests_targets)
 	echo "$(ide_tests_targets) : Passed"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/ide_tests/conftest.py	Fri Mar 11 14:43:37 2022 +0100
@@ -0,0 +1,78 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# This file is part of Beremiz, a Integrated Development Environment for
+# programming IEC 61131-3 automates supporting plcopen standard and CanFestival.
+#
+# Copyright (C) 2017: Andrey Skvortsov
+#
+# See COPYING file for copyrights details.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+
+from __future__ import absolute_import
+import os
+import sys
+
+# import pytest
+# import xvfbwrapper
+
+
+def init_environment():
+    """Append module root directory to sys.path"""
+    try:
+        import Beremiz as _Beremiz
+    except ImportError:
+        sys.path.append(
+            os.path.abspath(
+                os.path.join(
+                    os.path.dirname(__file__), '..', '..')
+            )
+        )
+
+
+init_environment()
+
+#
+# Something seems to be broken in Beremiz application,
+# because after tests in test_application.py during Xvfb shutdown
+# pytest returns error message:
+# pytest: Fatal IO error 11 (Die Ressource ist zur Zeit nicht verfügbar) on X server :2821.
+#
+# As a result of that pytest returns code 1 as some tests were failed,
+# but they aren't.
+#
+# To avoid this Xvfb is launched and killed not by pytest.
+# $ Xvfb :42 -screen 0 1280x1024x24 &
+# $ export DISPLAY=:42
+# $ pytest --timeout=10 ./tests/tools
+# $ pkill -9 Xvfb
+#
+# TODO: find root of this problem.
+
+
+# vdisplay = None
+#
+# @pytest.fixture(scope="session", autouse=True)
+# def start_xvfb_server(request):
+#     global vdisplay
+#     vdisplay = xvfbwrapper.Xvfb(width=1280, height=720)
+#     vdisplay.start()
+#     request.addfinalizer(stop_xvfb_server)
+#
+# def stop_xvfb_server():
+#     if vdisplay is not None:
+#         vdisplay.stop()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/ide_tests/load_and_build_tests.pytest/test_application.py	Fri Mar 11 14:43:37 2022 +0100
@@ -0,0 +1,232 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# This file is part of Beremiz, a Integrated Development Environment for
+# programming IEC 61131-3 automates supporting plcopen standard and CanFestival.
+#
+# Copyright (C) 2017: Andrey Skvortsov
+#
+# See COPYING file for copyrights details.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+
+from __future__ import absolute_import
+from __future__ import print_function
+import os
+import sys
+import unittest
+import time
+
+import six
+import pytest
+import wx
+import ddt
+
+import conftest
+import Beremiz
+import PLCOpenEditor
+
+
+class UserApplicationTest(unittest.TestCase):
+    def InstallExceptionHandler(self):
+        def handle_exception(e_type, e_value, e_traceback, exit=False):
+            # traceback.print_exception(e_type, e_value, e_traceback)
+            self.exc_info = [e_type, e_value, e_traceback]
+        self.exc_info = None
+        self.old_excepthook = sys.excepthook
+        sys.excepthook = handle_exception
+
+    def StartApp(self):
+        self.app = None
+
+    def FinishApp(self):
+        wx.CallAfter(self.app.frame.Close)
+        self.app.MainLoop()
+        self.app = None
+
+    def setUp(self):
+        self.app = None
+
+    def tearDown(self):
+        if self.app is not None and self.app.frame is not None:
+            self.FinishApp()
+
+    def RunUIActions(self, actions):
+        for act in actions:
+            wx.CallAfter(*act)
+            self.ProcessEvents()
+
+    def CheckForErrors(self):
+        if self.exc_info is not None:
+            # reraise catched previously exception
+            exc_type = self.exc_info[0]
+            exc_value = self.exc_info[1]
+            exc_traceback = self.exc_info[2]
+            six.reraise(exc_type, exc_value, exc_traceback)
+
+    def ProcessEvents(self):
+        for dummy in range(0, 30):
+            self.CheckForErrors()
+            wx.Yield()
+            time.sleep(0.01)
+
+
+@ddt.ddt
+class BeremizApplicationTest(UserApplicationTest):
+    """Test Beremiz as whole application"""
+
+    def StartApp(self):
+        self.app = Beremiz.BeremizIDELauncher()
+        # disable default exception handler in Beremiz
+        self.app.InstallExceptionHandler = lambda: None
+        self.InstallExceptionHandler()
+        self.app.handle_exception = sys.excepthook
+        self.app.PreStart()
+        self.ProcessEvents()
+        self.app.frame.Show()
+        self.ProcessEvents()
+        self.app.frame.ShowFullScreen(True)
+        self.ProcessEvents()
+
+    def FinishApp(self):
+        wx.CallAfter(self.app.frame.Close)
+        self.app.MainLoop()
+        time.sleep(1)
+        self.app = None
+
+    def GetSkippedProjectTreeItems(self):
+        """
+        Returns the list of skipped items in the project tree.
+
+        Beremiz test don't need to skip any elemnts in the project tree.
+        """
+        return []
+
+    def OpenAllProjectElements(self):
+        """Open editor for every object in the project tree"""
+        self.app.frame.ProjectTree.ExpandAll()
+        self.ProcessEvents()
+        item = self.app.frame.ProjectTree.GetRootItem()
+        skip = self.GetSkippedProjectTreeItems()
+        tree_id = self.app.frame.ProjectTree.GetId()
+        while item is not None:
+            self.app.frame.ProjectTree.SelectItem(item, True)
+            self.ProcessEvents()
+            if item not in skip:
+                event = wx.lib.agw.customtreectrl.TreeEvent(
+                    wx.lib.agw.customtreectrl.wxEVT_TREE_ITEM_ACTIVATED,
+                    tree_id, item)
+                self.app.frame.OnProjectTreeItemActivated(event)
+            self.ProcessEvents()
+            item = self.app.frame.ProjectTree.GetNextVisible(item)
+
+    def CheckTestProject(self, project):
+        sys.argv = ["", project]
+        self.StartApp()
+        self.OpenAllProjectElements()
+        user_actions = self.GetUserActions()
+        self.RunUIActions(user_actions)
+        self.FinishApp()
+
+    def GetProjectPath(self, project):
+        return os.path.abspath(os.path.join(os.path.dirname(__file__), "..","..","projects", project))
+
+    def GetUserActions(self):
+        """
+        Returns list of user actions that will be executed
+        on every test project by testCheckProject test.
+        """
+        user_actions = [
+            [self.app.frame.SwitchFullScrMode, None],
+            [self.app.frame.SwitchFullScrMode, None],
+            [self.app.frame.CTR._Clean],
+            [self.app.frame.CTR._Build],
+            [self.app.frame.CTR._Connect],
+            [self.app.frame.CTR._Transfer],
+            [self.app.frame.CTR._Run],
+            [self.app.frame.CTR._Stop],
+            [self.app.frame.CTR._Disconnect],
+            [self.app.frame.CTR._Clean],
+        ]
+        return user_actions
+
+    def testStartUp(self):
+        """Checks whether the app starts and finishes correctly"""
+        sys.argv = [""]
+        self.StartApp()
+        self.FinishApp()
+
+    # TODO: also use "exemples/*" projects
+    @ddt.data(
+        #"first_steps",
+        "logging",
+        #"traffic_lights",
+        #"wxGlade",
+        #"python",
+        #"wiimote",
+        # "wxHMI",
+    )
+    @pytest.mark.timeout(300)
+    def testCheckProject(self, name):
+        """
+        Checks that test PLC project can be open,
+        compiled and run on SoftPLC.
+        """
+        project = self.GetProjectPath(name)
+        print("Testing example " + name)
+        self.CheckTestProject(project)
+
+
+# class PLCOpenEditorApplicationTest(BeremizApplicationTest):
+#     """Test PLCOpenEditor as whole application"""
+# 
+#     def StartApp(self):
+#         self.app = PLCOpenEditor.PLCOpenEditorApp()
+#         # disable default exception handler in application
+#         self.app.InstallExceptionHandler = lambda: None
+#         self.InstallExceptionHandler()
+#         self.app.Show()
+#         self.ProcessEvents()
+#         self.app.frame.ShowFullScreen(True)
+#         self.ProcessEvents()
+# 
+#     def FinishApp(self):
+#         wx.CallAfter(self.app.frame.Close)
+#         self.app.MainLoop()
+#         time.sleep(1)
+#         self.app = None
+# 
+#     def GetSkippedProjectTreeItems(self):
+#         """
+#         Returns the list of skipped items in the project tree.
+# 
+#         Root item opens dialog window for project settings.
+#         To avoid code that handles closing dialog windows just skip this item.
+#         """
+#         return [self.app.frame.ProjectTree.GetRootItem()]
+# 
+#     def GetUserActions(self):
+#         return []
+# 
+#     def GetProjectPath(self, project):
+#         """Open PLC program in every Beremiz test project"""
+#         project_dir = BeremizApplicationTest.GetProjectPath(self, project)
+#         return os.path.join(project_dir, "plc.xml")
+# 
+
+if __name__ == '__main__':
+    conftest.init_environment()
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/ide_tests/wx_widgets.pytest/test_CustomIntCtrl.py	Fri Mar 11 14:43:37 2022 +0100
@@ -0,0 +1,140 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# This file is part of Beremiz, a Integrated Development Environment for
+# programming IEC 61131-3 automates supporting plcopen standard and CanFestival.
+#
+# Copyright (C) 2017: Andrey Skvortsov
+#
+# See COPYING file for copyrights details.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+
+from __future__ import absolute_import
+from __future__ import division
+import unittest
+import time
+
+import wx
+import conftest
+import controls.CustomIntCtrl
+
+
+class TestCustomIntCtrl(unittest.TestCase):
+    def setUp(self):
+        self.app = wx.App()
+        self.frame = wx.Frame(None)
+
+    def tearDown(self):
+        self.frame.Destroy()
+        wx.CallAfter(wx.Exit)
+        self.app.MainLoop()
+
+    def testMaxLimit(self):
+        """Test working upper bound"""
+        self.AddControls()
+        self.int_ctrl.SetValue(self.max_val + 100)
+        self.ProcessEvents()
+
+        self.txt_ctrl.SetFocus()
+        self.ProcessEvents()
+        self.assertEqual(self.int_ctrl.GetValue(), self.max_val)
+
+    def testMinLimit(self):
+        """Test working lower bound"""
+        self.AddControls()
+        self.int_ctrl.SetValue(self.min_val - 100)
+        self.ProcessEvents()
+
+        self.txt_ctrl.SetFocus()
+        self.ProcessEvents()
+
+        self.assertEqual(self.int_ctrl.GetValue(), self.min_val)
+
+    def testCorrectValue(self):
+        """Test case if no limiting is necessary"""
+        self.AddControls()
+        val = (self.max_val + self.min_val) // 2
+        self.int_ctrl.SetValue(val)
+        self.ProcessEvents()
+
+        self.txt_ctrl.SetFocus()
+        self.ProcessEvents()
+
+        self.assertEqual(self.int_ctrl.GetValue(), val)
+
+    def testEventBinding(self):
+        """Test event sending after edit and bound checks are done"""
+        self.AddControls()
+        self.event_happend = False
+
+        def EventHandler(event):
+            self.event_happend = True
+            event.Skip()
+
+        self.int_ctrl.Bind(controls.CustomIntCtrl.EVT_CUSTOM_INT, EventHandler)
+
+        val = (self.max_val + self.min_val) // 2
+
+        self.int_ctrl.SetValue(val)
+        self.ProcessEvents()
+        self.txt_ctrl.SetFocus()
+
+        self.ProcessEvents()
+        self.txt_ctrl.SetFocus()
+        self.ProcessEvents()
+
+        self.assertEqual(self.int_ctrl.GetValue(), val)
+        self.assertTrue(self.event_happend)
+
+    def testLongNumbers(self):
+        """Test support of long integer"""
+        self.AddControls()
+        val = 40000000000
+        self.int_ctrl.SetMax(val)
+        self.int_ctrl.SetValue(val)
+        self.ProcessEvents()
+
+        self.txt_ctrl.SetFocus()
+        self.ProcessEvents()
+
+        self.assertEqual(val, val)
+
+    def ProcessEvents(self):
+        for dummy in range(0, 10):
+            wx.Yield()
+            time.sleep(0.01)
+
+    def AddControls(self):
+        vs = wx.BoxSizer(wx.VERTICAL)
+        self.int_ctrl = controls.CustomIntCtrl(self.frame)
+        self.txt_ctrl = wx.TextCtrl(self.frame)
+        vs.Add(self.int_ctrl, 0, wx.ALIGN_CENTRE | wx.ALL, 5)
+        vs.Add(self.txt_ctrl, 0, wx.ALIGN_CENTRE | wx.ALL, 5)
+        self.frame.SetSizer(vs)
+        vs.Fit(self.frame)
+        self.frame.Show()
+        self.frame.Raise()
+
+        self.min_val = 50
+        self.max_val = 100
+        self.int_ctrl.SetBounds(self.min_val, self.max_val)
+        self.ProcessEvents()
+
+
+if __name__ == '__main__':
+    conftest.init_environment()
+    unittest.main()
--- a/tests/tools/Docker/beremiz-sikuli/Dockerfile	Sat Mar 05 11:14:00 2022 +0100
+++ b/tests/tools/Docker/beremiz-sikuli/Dockerfile	Fri Mar 11 14:43:37 2022 +0100
@@ -54,6 +54,7 @@
 RUN virtualenv --python=$(which python2) ~/beremizenv
 
 RUN ~/beremizenv/bin/pip install \
+        pytest pytest-timeout ddt \
         lxml future matplotlib zeroconf2 enum34 pyro sslpsk posix_spawn \
         twisted nevow autobahn \
         wxPython==4.1.1
--- a/tests/tools/conftest.py	Sat Mar 05 11:14:00 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-# This file is part of Beremiz, a Integrated Development Environment for
-# programming IEC 61131-3 automates supporting plcopen standard and CanFestival.
-#
-# Copyright (C) 2017: Andrey Skvortsov
-#
-# See COPYING file for copyrights details.
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-
-from __future__ import absolute_import
-import os
-import sys
-
-# import pytest
-# import xvfbwrapper
-
-
-def init_environment():
-    """Append module root directory to sys.path"""
-    try:
-        import Beremiz as _Beremiz
-    except ImportError:
-        sys.path.append(
-            os.path.abspath(
-                os.path.join(
-                    os.path.dirname(__file__), '..', '..')
-            )
-        )
-
-
-init_environment()
-
-#
-# Something seems to be broken in Beremiz application,
-# because after tests in test_application.py during Xvfb shutdown
-# pytest returns error message:
-# pytest: Fatal IO error 11 (Die Ressource ist zur Zeit nicht verfügbar) on X server :2821.
-#
-# As a result of that pytest returns code 1 as some tests were failed,
-# but they aren't.
-#
-# To avoid this Xvfb is launched and killed not by pytest.
-# $ Xvfb :42 -screen 0 1280x1024x24 &
-# $ export DISPLAY=:42
-# $ pytest --timeout=10 ./tests/tools
-# $ pkill -9 Xvfb
-#
-# TODO: find root of this problem.
-
-
-# vdisplay = None
-#
-# @pytest.fixture(scope="session", autouse=True)
-# def start_xvfb_server(request):
-#     global vdisplay
-#     vdisplay = xvfbwrapper.Xvfb(width=1280, height=720)
-#     vdisplay.start()
-#     request.addfinalizer(stop_xvfb_server)
-#
-# def stop_xvfb_server():
-#     if vdisplay is not None:
-#         vdisplay.stop()
--- a/tests/tools/run_python_tests.sh	Sat Mar 05 11:14:00 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-#!/bin/sh
-
-
-
-cleanup()
-{
-    find $PYTEST_DIR -name '*.pyc' -delete
-}
-
-
-
-print_help()
-{
-    echo "Usage: run_python_tests.sh [--on-local-xserver]"
-    echo ""
-    echo "--on-local-xserver"
-    echo "                all tests are run on local X-server. "
-    echo "                User can see test in action."
-    echo "                Any interaction (mouse, keyboard) should be avoided"
-    echo "                By default without arguments script runs pytest on virtual X serverf."
-    echo ""
-
-    exit 1
-}
-
-main()
-{
-    LC_ALL=ru_RU.utf-8
-    PYTEST_DIR=./tests/tools
-
-    if [ ! -d $PYTEST_DIR ]; then
-	echo "Script should be run from top directory in repository"
-	exit 1;
-    fi
-
-    use_xvfb=0
-    if [ "$1" != "--on-local-xserver" ]; then
-	export DISPLAY=:42
-	use_xvfb=1
-	Xvfb $DISPLAY -screen 0 1280x1024x24 &
-	sleep 1
-    fi
-
-
-    cleanup
-
-    ret=0
-    DELAY=400
-    KILL_DELAY=$(($DELAY + 30))
-    timeout -k $KILL_DELAY $DELAY pytest --timeout=10 ./tests/tools
-    ret=$?
-
-    cleanup
-
-    [ $use_xvfb = 1 ] && pkill -9 Xvfb
-    exit $ret
-}
-
-
-[ "$1" = "--help" -o "$1" = "-h" ] && print_help
-main $@
--- a/tests/tools/test_CustomIntCtrl.py	Sat Mar 05 11:14:00 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,140 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-# This file is part of Beremiz, a Integrated Development Environment for
-# programming IEC 61131-3 automates supporting plcopen standard and CanFestival.
-#
-# Copyright (C) 2017: Andrey Skvortsov
-#
-# See COPYING file for copyrights details.
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-
-from __future__ import absolute_import
-from __future__ import division
-import unittest
-import time
-
-import wx
-import conftest
-import controls.CustomIntCtrl
-
-
-class TestCustomIntCtrl(unittest.TestCase):
-    def setUp(self):
-        self.app = wx.App()
-        self.frame = wx.Frame(None)
-
-    def tearDown(self):
-        self.frame.Destroy()
-        wx.CallAfter(self.app.Exit)
-        self.app.MainLoop()
-
-    def testMaxLimit(self):
-        """Test working upper bound"""
-        self.AddControls()
-        self.int_ctrl.SetValue(self.max_val + 100)
-        self.ProcessEvents()
-
-        self.txt_ctrl.SetFocus()
-        self.ProcessEvents()
-        self.assertEqual(self.int_ctrl.GetValue(), self.max_val)
-
-    def testMinLimit(self):
-        """Test working lower bound"""
-        self.AddControls()
-        self.int_ctrl.SetValue(self.min_val - 100)
-        self.ProcessEvents()
-
-        self.txt_ctrl.SetFocus()
-        self.ProcessEvents()
-
-        self.assertEqual(self.int_ctrl.GetValue(), self.min_val)
-
-    def testCorrectValue(self):
-        """Test case if no limiting is necessary"""
-        self.AddControls()
-        val = (self.max_val + self.min_val) // 2
-        self.int_ctrl.SetValue(val)
-        self.ProcessEvents()
-
-        self.txt_ctrl.SetFocus()
-        self.ProcessEvents()
-
-        self.assertEqual(self.int_ctrl.GetValue(), val)
-
-    def testEventBinding(self):
-        """Test event sending after edit and bound checks are done"""
-        self.AddControls()
-        self.event_happend = False
-
-        def EventHandler(event):
-            self.event_happend = True
-            event.Skip()
-
-        self.int_ctrl.Bind(controls.CustomIntCtrl.EVT_CUSTOM_INT, EventHandler)
-
-        val = (self.max_val + self.min_val) // 2
-
-        self.int_ctrl.SetValue(val)
-        self.ProcessEvents()
-        self.txt_ctrl.SetFocus()
-
-        self.ProcessEvents()
-        self.txt_ctrl.SetFocus()
-        self.ProcessEvents()
-
-        self.assertEqual(self.int_ctrl.GetValue(), val)
-        self.assertTrue(self.event_happend)
-
-    def testLongNumbers(self):
-        """Test support of long integer"""
-        self.AddControls()
-        val = 40000000000
-        self.int_ctrl.SetMax(val)
-        self.int_ctrl.SetValue(val)
-        self.ProcessEvents()
-
-        self.txt_ctrl.SetFocus()
-        self.ProcessEvents()
-
-        self.assertEqual(val, val)
-
-    def ProcessEvents(self):
-        for dummy in range(0, 10):
-            wx.Yield()
-            time.sleep(0.01)
-
-    def AddControls(self):
-        vs = wx.BoxSizer(wx.VERTICAL)
-        self.int_ctrl = controls.CustomIntCtrl(self.frame)
-        self.txt_ctrl = wx.TextCtrl(self.frame)
-        vs.Add(self.int_ctrl, 0, wx.ALIGN_CENTRE | wx.ALL, 5)
-        vs.Add(self.txt_ctrl, 0, wx.ALIGN_CENTRE | wx.ALL, 5)
-        self.frame.SetSizer(vs)
-        vs.Fit(self.frame)
-        self.frame.Show()
-        self.frame.Raise()
-
-        self.min_val = 50
-        self.max_val = 100
-        self.int_ctrl.SetBounds(self.min_val, self.max_val)
-        self.ProcessEvents()
-
-
-if __name__ == '__main__':
-    conftest.init_environment()
-    unittest.main()
--- a/tests/tools/test_application.py	Sat Mar 05 11:14:00 2022 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,231 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-# This file is part of Beremiz, a Integrated Development Environment for
-# programming IEC 61131-3 automates supporting plcopen standard and CanFestival.
-#
-# Copyright (C) 2017: Andrey Skvortsov
-#
-# See COPYING file for copyrights details.
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-
-from __future__ import absolute_import
-from __future__ import print_function
-import os
-import sys
-import unittest
-import time
-
-import six
-import pytest
-import wx
-import ddt
-
-import conftest
-import Beremiz
-import PLCOpenEditor
-
-
-class UserApplicationTest(unittest.TestCase):
-    def InstallExceptionHandler(self):
-        def handle_exception(e_type, e_value, e_traceback, exit=False):
-            # traceback.print_exception(e_type, e_value, e_traceback)
-            self.exc_info = [e_type, e_value, e_traceback]
-        self.exc_info = None
-        self.old_excepthook = sys.excepthook
-        sys.excepthook = handle_exception
-
-    def StartApp(self):
-        self.app = None
-
-    def FinishApp(self):
-        wx.CallAfter(self.app.frame.Close)
-        self.app.MainLoop()
-        self.app = None
-
-    def setUp(self):
-        self.app = None
-
-    def tearDown(self):
-        if self.app is not None and self.app.frame is not None:
-            self.FinishApp()
-
-    def RunUIActions(self, actions):
-        for act in actions:
-            wx.CallAfter(*act)
-            self.ProcessEvents()
-
-    def CheckForErrors(self):
-        if self.exc_info is not None:
-            # reraise catched previously exception
-            exc_type = self.exc_info[0]
-            exc_value = self.exc_info[1]
-            exc_traceback = self.exc_info[2]
-            six.reraise(exc_type, exc_value, exc_traceback)
-
-    def ProcessEvents(self):
-        for dummy in range(0, 30):
-            self.CheckForErrors()
-            wx.Yield()
-            time.sleep(0.01)
-
-
-@ddt.ddt
-class BeremizApplicationTest(UserApplicationTest):
-    """Test Beremiz as whole application"""
-
-    def StartApp(self):
-        self.app = Beremiz.BeremizIDELauncher()
-        # disable default exception handler in Beremiz
-        self.app.InstallExceptionHandler = lambda: None
-        self.InstallExceptionHandler()
-        self.app.handle_exception = sys.excepthook
-        self.app.PreStart()
-        self.ProcessEvents()
-        self.app.frame.Show()
-        self.ProcessEvents()
-        self.app.frame.ShowFullScreen(True)
-        self.ProcessEvents()
-
-    def FinishApp(self):
-        wx.CallAfter(self.app.frame.Close)
-        self.app.MainLoop()
-        time.sleep(1)
-        self.app = None
-
-    def GetSkippedProjectTreeItems(self):
-        """
-        Returns the list of skipped items in the project tree.
-
-        Beremiz test don't need to skip any elemnts in the project tree.
-        """
-        return []
-
-    def OpenAllProjectElements(self):
-        """Open editor for every object in the project tree"""
-        self.app.frame.ProjectTree.ExpandAll()
-        self.ProcessEvents()
-        item = self.app.frame.ProjectTree.GetRootItem()
-        skip = self.GetSkippedProjectTreeItems()
-        tree_id = self.app.frame.ProjectTree.GetId()
-        while item is not None:
-            self.app.frame.ProjectTree.SelectItem(item, True)
-            self.ProcessEvents()
-            if item not in skip:
-                event = wx.lib.agw.customtreectrl.TreeEvent(
-                    wx.lib.agw.customtreectrl.wxEVT_TREE_ITEM_ACTIVATED,
-                    tree_id, item)
-                self.app.frame.OnProjectTreeItemActivated(event)
-            self.ProcessEvents()
-            item = self.app.frame.ProjectTree.GetNextVisible(item)
-
-    def CheckTestProject(self, project):
-        sys.argv = ["", project]
-        self.StartApp()
-        self.OpenAllProjectElements()
-        user_actions = self.GetUserActions()
-        self.RunUIActions(user_actions)
-        self.FinishApp()
-
-    def GetProjectPath(self, project):
-        return os.path.abspath(os.path.join(os.path.dirname(__file__), "..", project))
-
-    def GetUserActions(self):
-        """
-        Returns list of user actions that will be executed
-        on every test project by testCheckProject test.
-        """
-        user_actions = [
-            [self.app.frame.SwitchFullScrMode, None],
-            [self.app.frame.SwitchFullScrMode, None],
-            [self.app.frame.CTR._Clean],
-            [self.app.frame.CTR._Build],
-            [self.app.frame.CTR._Connect],
-            [self.app.frame.CTR._Transfer],
-            [self.app.frame.CTR._Run],
-            [self.app.frame.CTR._Stop],
-            [self.app.frame.CTR._Disconnect],
-            [self.app.frame.CTR._Clean],
-        ]
-        return user_actions
-
-    def testStartUp(self):
-        """Checks whether the app starts and finishes correctly"""
-        sys.argv = [""]
-        self.StartApp()
-        self.FinishApp()
-
-    @ddt.data(
-        "first_steps",
-        "logging",
-        "traffic_lights",
-        "wxGlade",
-        "python",
-        "wiimote",
-        "wxHMI",
-    )
-    @pytest.mark.timeout(30)
-    def testCheckProject(self, name):
-        """
-        Checks that test PLC project can be open,
-        compiled and run on SoftPLC.
-        """
-        project = self.GetProjectPath(name)
-        print("Testing example " + name)
-        self.CheckTestProject(project)
-
-
-class PLCOpenEditorApplicationTest(BeremizApplicationTest):
-    """Test PLCOpenEditor as whole application"""
-
-    def StartApp(self):
-        self.app = PLCOpenEditor.PLCOpenEditorApp()
-        # disable default exception handler in application
-        self.app.InstallExceptionHandler = lambda: None
-        self.InstallExceptionHandler()
-        self.app.Show()
-        self.ProcessEvents()
-        self.app.frame.ShowFullScreen(True)
-        self.ProcessEvents()
-
-    def FinishApp(self):
-        wx.CallAfter(self.app.frame.Close)
-        self.app.MainLoop()
-        time.sleep(1)
-        self.app = None
-
-    def GetSkippedProjectTreeItems(self):
-        """
-        Returns the list of skipped items in the project tree.
-
-        Root item opens dialog window for project settings.
-        To avoid code that handles closing dialog windows just skip this item.
-        """
-        return [self.app.frame.ProjectTree.GetRootItem()]
-
-    def GetUserActions(self):
-        return []
-
-    def GetProjectPath(self, project):
-        """Open PLC program in every Beremiz test project"""
-        project_dir = BeremizApplicationTest.GetProjectPath(self, project)
-        return os.path.join(project_dir, "plc.xml")
-
-
-if __name__ == '__main__':
-    conftest.init_environment()
-    unittest.main()