add couple Beremiz application tests
authorAndrey Skvortsov <andrej.skvortzov@gmail.com>
Tue, 12 Sep 2017 10:21:51 +0300
changeset 1796 4f7a0c40a7c3
parent 1795 e27d253bd0ba
child 1797 40a5fbaf0038
add couple Beremiz application tests

These tests trigger around 45% of python code.
Used in tests docker files are avaiable here:
https://bitbucket.org/skvorl/beremiz-dockerfiles
Beremiz.py
bitbucket-pipelines.yml
tests/tools/test_application.py
--- a/Beremiz.py	Fri Sep 08 11:53:48 2017 +0300
+++ b/Beremiz.py	Tue Sep 12 10:21:51 2017 +0300
@@ -33,6 +33,8 @@
 
 class BeremizIDELauncher:
     def __init__(self):
+        self.app = None
+        self.frame = None
         self.updateinfo_url = None
         self.extensions = []
         self.app_dir = paths.AbsDir(__file__)
@@ -126,7 +128,6 @@
 
         self.ShowSplashScreen()
         self.BackgroundInitialization()
-        self.app.MainLoop()
 
     def BackgroundInitialization(self):
         self.InitI18n()
@@ -184,10 +185,17 @@
             self.splash.Close()
         self.frame.Show()
 
-    def Start(self):
+    def PreStart(self):
         self.ProcessCommandLineArgs()
         self.CreateApplication()
 
+    def MainLoop(self):
+        self.app.MainLoop()
+
+    def Start(self):
+        self.PreStart()
+        self.MainLoop()
+
 
 if __name__ == '__main__':
     beremiz = BeremizIDELauncher()
--- a/bitbucket-pipelines.yml	Fri Sep 08 11:53:48 2017 +0300
+++ b/bitbucket-pipelines.yml	Tue Sep 12 10:21:51 2017 +0300
@@ -1,22 +1,17 @@
-image: python:2.7
+image: skvorl/beremiz-requirements
 
 pipelines:
   custom: # Pipelines that are triggered manually
     checks: # The name that is displayed in the list in the Bitbucket Cloud GUI
         - step:
-            caches:
-                - pip
             script: # Modify the commands below to build your repository.
-              - pip install pycodestyle
               - python --version
               - ./tests/tools/check_source.sh
-
+              - /usr/bin/python ./tests/tools/test_application.py
 
   default:
     - step:
-        caches:
-          - pip
         script: # Modify the commands below to build your repository.
-          - pip install pycodestyle
           - python --version
-          - ./tests/tools/check_source.sh
\ No newline at end of file
+          - ./tests/tools/check_source.sh
+          - /usr/bin/python ./tests/tools/test_application.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/tools/test_application.py	Tue Sep 12 10:21:51 2017 +0300
@@ -0,0 +1,146 @@
+import os
+import sys
+import unittest
+import wx
+import time
+import traceback
+from xvfbwrapper import Xvfb
+
+vdisplay = None
+
+
+def setUpModule():
+    vdisplay = Xvfb(width=1280, height=720)
+    vdisplay.start()
+
+
+def tearDownModule():
+    if vdisplay is not None:
+        vdisplay.stop()
+
+
+class UserApplicationTest(unittest.TestCase):
+    def InstallExceptionHandler(self):
+        def handle_exception(e_type, e_value, e_traceback):
+            # 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()
+        # time.sleep(0.2)
+        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
+            raise self.exc_info[0], self.exc_info[1], self.exc_info[2]
+
+    def ProcessEvents(self):
+        for i in range(0, 30):
+            self.CheckForErrors()
+            wx.Yield()
+            time.sleep(0.01)
+
+
+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.PreStart()
+
+    def FinishApp(self):
+        wx.CallAfter(self.app.frame.Close)
+        self.app.MainLoop()
+        time.sleep(1)
+        self.app = None
+
+    def OpenAllProjectElements(self):
+        # open every object in the project tree
+        self.app.frame.ProjectTree.ExpandAll()
+        self.ProcessEvents()
+        item = self.app.frame.ProjectTree.GetRootItem()
+        while item is not None:
+            self.app.frame.ProjectTree.SelectItem(item, True)
+            self.ProcessEvents()
+            id = self.app.frame.ProjectTree.GetId()
+            event = wx.lib.agw.customtreectrl.TreeEvent(
+                wx.lib.agw.customtreectrl.wxEVT_TREE_ITEM_ACTIVATED,
+                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.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],
+        ]
+
+        # user_actions.append([self.app.frame.OnCloseProjectMenu, None])
+        self.RunUIActions(user_actions)
+        self.FinishApp()
+
+    def GetProjectPath(self, project):
+        return os.path.abspath(os.path.join(os.path.dirname(__file__), "..", project))
+
+    # @unittest.skip("")
+    def testStartUp(self):
+        """Checks whether the app starts and finishes correctly"""
+        self.StartApp()
+        self.FinishApp()
+
+    # @unittest.skip("")
+    def testOpenExampleProjects(self):
+        """Opens, builds and runs user PLC examples from tests directory"""
+        prj = [
+            "first_steps",
+            "logging",
+            "svgui",
+            "traffic_lights",
+            "wxGlade",
+            "python",
+            "wiimote",
+            "wxHMI",
+        ]
+        for name in prj:
+            project = self.GetProjectPath(name)
+            print "Testing example " + name
+            self.CheckTestProject(project)
+
+
+if __name__ == '__main__':
+    if __package__ is None:
+        sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..')))
+        global Beremiz
+        import Beremiz
+    unittest.main()