Current situation

I'm developing a test-framework in python for end-to-end tests for a large ERP application. The AUT (application under test = ERP system) is structured in modules and provides a lot of different forms (e.g. to place an order), which need to be tested. The test-framework provides a high level API to execute some business processes (e.g. create a new order for a specific customer).

ERP System Architecture (AUT)

  • The GUI is a bunch of forms (more than 2000 differnt forms) and some tables or diagrams to display the data

  • Most forms have some basic buttons, that share some functionality across the whole system (e.g. close form, save form etc.), so there is a basic Form class which almost all other classes inherit from.

  • A lot of forms in the sales module share some functionality, so there is a SalesForm class, which provides this specific functionality.

  • Some forms which are in different modules share some functionality, this functionality is moved to it's own class and added with multiple inheritance.

Test Framework Architecture

Current Architecture

There is also a demo of the current architecture available on repl.it.


I want to extend the Framework, to support customized variants of the ERP-System. This variants can change the structure of the dialogs or introduce additional steps in a business process. The idea is that if you want to test such a modified application, you create an "extension" to the framework, with the same structure as the "base", replacing specific methods with an alternative implementation.

Applying this to the demo on repl.it: I want to create a mytest2.py where I can overwrite the extension1.base.SomeExtension.new_feature() method, without breaking the rest of the architecture.

Expected outcome of mytest2.py

Test 2:
called Form.basic_feature() from default
called SalesForm.sales_method() from default
called Form.basic_feature() from default
called SomeExtension.new_feature() from extension1       <-- important line
called SalesOrder.sales_order_method() from default

How would you approach this problem? Do you have any design patterns in mind and/or programming techniques that would be useful?

I currently tend to use the monkey patching ability of python to change the classes on runtime, by searching for available modules, classes, methods and so on. Order and dependencies of those extensions that need to patched would be stored in a dictionary. Monkey patching seem to be a pretty good fit for my use case...


Some people say monkey patching is evil and I tend to agree. Maybe there are better solutions for this problem, but I can not see them because I already have a (partial) solution already.


  • I want to override a specific class method, this is mainly a problem if the class is deeper in the inheritance tree (e.g. I want to overwrite a method of the Form class.

  • The order of plugins/extension does matter. E.g. you can have two extensions combined.

  • Doesn't break code completion in PyCharm IDE (but I am OK with instance level type hinting in a comment, so this shouln't be too complicated)

The general structure of the framework can be altered! Keeping the existing structure is only nice to have.

  • 1
    This seems very exotic for an ordinary software pattern to be useful. "Strategy" and other patterns might inform your design, but they certainly won't dictate it. – Robert Harvey May 24 at 14:25
  • I updated the question part, I am not a native speaker and my question was bad. It is clear to me, that there is not one design pattern to solve this problem, otherwise I just would have used one, I am pretty familiar with most of them. – Frieder May 24 at 14:54
  • I know the question is still broad, but that is why I used software engineering and not stackoverflow. If I need to ask a very specific question it would be: Is monkey patching a viable approach considering maintainability? [Couldn't edit my comment] – Frieder May 24 at 15:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.