# HG changeset patch # User Andrey Skvortsov # Date 1505200911 -10800 # Node ID 4f7a0c40a7c36b7bd24dc7f4540ea59deb64b089 # Parent e27d253bd0ba1824edfdf754bebeae601cd853cf 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 diff -r e27d253bd0ba -r 4f7a0c40a7c3 Beremiz.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() diff -r e27d253bd0ba -r 4f7a0c40a7c3 bitbucket-pipelines.yml --- 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 diff -r e27d253bd0ba -r 4f7a0c40a7c3 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()