tests/tools/test_application.py
branchwxPython4
changeset 3438 24fbd4d1fe80
parent 3437 ce366d67a5b7
child 3442 29dbdb09da2e
equal deleted inserted replaced
3437:ce366d67a5b7 3438:24fbd4d1fe80
     1 #!/usr/bin/env python
       
     2 # -*- coding: utf-8 -*-
       
     3 
       
     4 # This file is part of Beremiz, a Integrated Development Environment for
       
     5 # programming IEC 61131-3 automates supporting plcopen standard and CanFestival.
       
     6 #
       
     7 # Copyright (C) 2017: Andrey Skvortsov
       
     8 #
       
     9 # See COPYING file for copyrights details.
       
    10 #
       
    11 # This program is free software; you can redistribute it and/or
       
    12 # modify it under the terms of the GNU General Public License
       
    13 # as published by the Free Software Foundation; either version 2
       
    14 # of the License, or (at your option) any later version.
       
    15 #
       
    16 # This program is distributed in the hope that it will be useful,
       
    17 # but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    19 # GNU General Public License for more details.
       
    20 #
       
    21 # You should have received a copy of the GNU General Public License
       
    22 # along with this program; if not, write to the Free Software
       
    23 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
       
    24 
       
    25 
       
    26 from __future__ import absolute_import
       
    27 from __future__ import print_function
       
    28 import os
       
    29 import sys
       
    30 import unittest
       
    31 import time
       
    32 
       
    33 import six
       
    34 import pytest
       
    35 import wx
       
    36 import ddt
       
    37 
       
    38 import conftest
       
    39 import Beremiz
       
    40 import PLCOpenEditor
       
    41 
       
    42 
       
    43 class UserApplicationTest(unittest.TestCase):
       
    44     def InstallExceptionHandler(self):
       
    45         def handle_exception(e_type, e_value, e_traceback, exit=False):
       
    46             # traceback.print_exception(e_type, e_value, e_traceback)
       
    47             self.exc_info = [e_type, e_value, e_traceback]
       
    48         self.exc_info = None
       
    49         self.old_excepthook = sys.excepthook
       
    50         sys.excepthook = handle_exception
       
    51 
       
    52     def StartApp(self):
       
    53         self.app = None
       
    54 
       
    55     def FinishApp(self):
       
    56         wx.CallAfter(self.app.frame.Close)
       
    57         self.app.MainLoop()
       
    58         self.app = None
       
    59 
       
    60     def setUp(self):
       
    61         self.app = None
       
    62 
       
    63     def tearDown(self):
       
    64         if self.app is not None and self.app.frame is not None:
       
    65             self.FinishApp()
       
    66 
       
    67     def RunUIActions(self, actions):
       
    68         for act in actions:
       
    69             wx.CallAfter(*act)
       
    70             self.ProcessEvents()
       
    71 
       
    72     def CheckForErrors(self):
       
    73         if self.exc_info is not None:
       
    74             # reraise catched previously exception
       
    75             exc_type = self.exc_info[0]
       
    76             exc_value = self.exc_info[1]
       
    77             exc_traceback = self.exc_info[2]
       
    78             six.reraise(exc_type, exc_value, exc_traceback)
       
    79 
       
    80     def ProcessEvents(self):
       
    81         for dummy in range(0, 30):
       
    82             self.CheckForErrors()
       
    83             wx.Yield()
       
    84             time.sleep(0.01)
       
    85 
       
    86 
       
    87 @ddt.ddt
       
    88 class BeremizApplicationTest(UserApplicationTest):
       
    89     """Test Beremiz as whole application"""
       
    90 
       
    91     def StartApp(self):
       
    92         self.app = Beremiz.BeremizIDELauncher()
       
    93         # disable default exception handler in Beremiz
       
    94         self.app.InstallExceptionHandler = lambda: None
       
    95         self.InstallExceptionHandler()
       
    96         self.app.handle_exception = sys.excepthook
       
    97         self.app.PreStart()
       
    98         self.ProcessEvents()
       
    99         self.app.frame.Show()
       
   100         self.ProcessEvents()
       
   101         self.app.frame.ShowFullScreen(True)
       
   102         self.ProcessEvents()
       
   103 
       
   104     def FinishApp(self):
       
   105         wx.CallAfter(self.app.frame.Close)
       
   106         self.app.MainLoop()
       
   107         time.sleep(1)
       
   108         self.app = None
       
   109 
       
   110     def GetSkippedProjectTreeItems(self):
       
   111         """
       
   112         Returns the list of skipped items in the project tree.
       
   113 
       
   114         Beremiz test don't need to skip any elemnts in the project tree.
       
   115         """
       
   116         return []
       
   117 
       
   118     def OpenAllProjectElements(self):
       
   119         """Open editor for every object in the project tree"""
       
   120         self.app.frame.ProjectTree.ExpandAll()
       
   121         self.ProcessEvents()
       
   122         item = self.app.frame.ProjectTree.GetRootItem()
       
   123         skip = self.GetSkippedProjectTreeItems()
       
   124         tree_id = self.app.frame.ProjectTree.GetId()
       
   125         while item is not None:
       
   126             self.app.frame.ProjectTree.SelectItem(item, True)
       
   127             self.ProcessEvents()
       
   128             if item not in skip:
       
   129                 event = wx.lib.agw.customtreectrl.TreeEvent(
       
   130                     wx.lib.agw.customtreectrl.wxEVT_TREE_ITEM_ACTIVATED,
       
   131                     tree_id, item)
       
   132                 self.app.frame.OnProjectTreeItemActivated(event)
       
   133             self.ProcessEvents()
       
   134             item = self.app.frame.ProjectTree.GetNextVisible(item)
       
   135 
       
   136     def CheckTestProject(self, project):
       
   137         sys.argv = ["", project]
       
   138         self.StartApp()
       
   139         self.OpenAllProjectElements()
       
   140         user_actions = self.GetUserActions()
       
   141         self.RunUIActions(user_actions)
       
   142         self.FinishApp()
       
   143 
       
   144     def GetProjectPath(self, project):
       
   145         return os.path.abspath(os.path.join(os.path.dirname(__file__), "..", project))
       
   146 
       
   147     def GetUserActions(self):
       
   148         """
       
   149         Returns list of user actions that will be executed
       
   150         on every test project by testCheckProject test.
       
   151         """
       
   152         user_actions = [
       
   153             [self.app.frame.SwitchFullScrMode, None],
       
   154             [self.app.frame.SwitchFullScrMode, None],
       
   155             [self.app.frame.CTR._Clean],
       
   156             [self.app.frame.CTR._Build],
       
   157             [self.app.frame.CTR._Connect],
       
   158             [self.app.frame.CTR._Transfer],
       
   159             [self.app.frame.CTR._Run],
       
   160             [self.app.frame.CTR._Stop],
       
   161             [self.app.frame.CTR._Disconnect],
       
   162             [self.app.frame.CTR._Clean],
       
   163         ]
       
   164         return user_actions
       
   165 
       
   166     def testStartUp(self):
       
   167         """Checks whether the app starts and finishes correctly"""
       
   168         sys.argv = [""]
       
   169         self.StartApp()
       
   170         self.FinishApp()
       
   171 
       
   172     @ddt.data(
       
   173         "first_steps",
       
   174         "logging",
       
   175         "traffic_lights",
       
   176         "wxGlade",
       
   177         "python",
       
   178         "wiimote",
       
   179         "wxHMI",
       
   180     )
       
   181     @pytest.mark.timeout(30)
       
   182     def testCheckProject(self, name):
       
   183         """
       
   184         Checks that test PLC project can be open,
       
   185         compiled and run on SoftPLC.
       
   186         """
       
   187         project = self.GetProjectPath(name)
       
   188         print("Testing example " + name)
       
   189         self.CheckTestProject(project)
       
   190 
       
   191 
       
   192 class PLCOpenEditorApplicationTest(BeremizApplicationTest):
       
   193     """Test PLCOpenEditor as whole application"""
       
   194 
       
   195     def StartApp(self):
       
   196         self.app = PLCOpenEditor.PLCOpenEditorApp()
       
   197         # disable default exception handler in application
       
   198         self.app.InstallExceptionHandler = lambda: None
       
   199         self.InstallExceptionHandler()
       
   200         self.app.Show()
       
   201         self.ProcessEvents()
       
   202         self.app.frame.ShowFullScreen(True)
       
   203         self.ProcessEvents()
       
   204 
       
   205     def FinishApp(self):
       
   206         wx.CallAfter(self.app.frame.Close)
       
   207         self.app.MainLoop()
       
   208         time.sleep(1)
       
   209         self.app = None
       
   210 
       
   211     def GetSkippedProjectTreeItems(self):
       
   212         """
       
   213         Returns the list of skipped items in the project tree.
       
   214 
       
   215         Root item opens dialog window for project settings.
       
   216         To avoid code that handles closing dialog windows just skip this item.
       
   217         """
       
   218         return [self.app.frame.ProjectTree.GetRootItem()]
       
   219 
       
   220     def GetUserActions(self):
       
   221         return []
       
   222 
       
   223     def GetProjectPath(self, project):
       
   224         """Open PLC program in every Beremiz test project"""
       
   225         project_dir = BeremizApplicationTest.GetProjectPath(self, project)
       
   226         return os.path.join(project_dir, "plc.xml")
       
   227 
       
   228 
       
   229 if __name__ == '__main__':
       
   230     conftest.init_environment()
       
   231     unittest.main()