2017-10-04 9:50 GMT+02:00 Eike Ziller <[email protected]>:
>
>> On 2. Oct 2017, at 09:29, Elvis Stansvik <[email protected]> wrote:
>>
>> 2017-09-11 10:00 GMT+02:00 Elvis Stansvik <[email protected]>:
>>> 2017-09-11 9:50 GMT+02:00 Eike Ziller <[email protected]>:
>>>>
>>>>> On Sep 11, 2017, at 09:24, Elvis Stansvik <[email protected]> wrote:
>>>>>
>>>>> 2017-09-10 11:31 GMT+02:00 Elvis Stansvik <[email protected]>:
>>>>>> 2017-09-10 11:03 GMT+02:00 Elvis Stansvik <[email protected]>:
>>>>>>> Hi all,
>>>>>>>
>>>>>>> In a quest to find inspiration for good Qt application architectures,
>>>>>>> I've been looking at the plugin based one you're using in Qt Creator.
>>>>>>> It strikes me as a really nice design.
>>>>>>>
>>>>>>> I've been reading the available docs on it, and dug into the code a
>>>>>>> bit. This may be a bit much to ask, but I was wondering if any of you
>>>>>>> devs could answer a few questions that popped up? It would be much
>>>>>>> appreciated!
>>>>>>>
>>>>>>> It's really just two questions, about two different topics:
>>>>>>>
>>>>>>> 1. The Invoker / invoke<...> Thingie:
>>>>>>>
>>>>>>> You have ExtensionSystem::Invoker and the associated invoke<..>
>>>>>>> helper, which are syntactic sugar for achieving "soft" extension
>>>>>>> points. It seems it's not used that much (?). I grepped for
>>>>>>> "Invoker|invoke<" in the code and could only find a few uses of it. I
>>>>>>> also grepped for "invokeMethod" to see if the approach was being used
>>>>>>> "manually" so to speak (without the sugar), and found a few more hits.
>>>>>>>
>>>>>>> What was the motivation for adding this? I assume it's for cases where
>>>>>>> you want a looser coupling between plugins (no linking, no shared
>>>>>>> header), but can you give an example of when you really wanted that
>>>>>>> looser coupling and why?
>>>>>>>
>>>>>>> 2. The Plugin System in General:
>>>>>>>
>>>>>>> Is there anything about the plugin system in its current form, or how
>>>>>>> it is used, that you would do fundamentally different if you could do
>>>>>>> it all over again? Any areas that you find messy/awkward, that need a
>>>>>>> re-think/makeover? In short: What are the biggest warts in the code in
>>>>>>> your opinion?
>>>>>>
>>>>>> As soon as I hit send, I realized I have a third question:
>>>>>>
>>>>>> 3. Communication Between Plugins:
>>>>>>
>>>>>> There seems to be two main mechanisms through which plugins
>>>>>> communicate: Either objects that implement shared interfaces are added
>>>>>> to the plugin manager object pool and picked up by downstream or
>>>>>> upstream plugins (in the top-down or bottom-up phase of plugin
>>>>>> initialization, respectively), or a singleton instance is acquired and
>>>>>> calls made on it.
>>>>>>
>>>>>> Is the former approach used when dependants provide functionality to
>>>>>> their dependees (which are unknown), and the latter approach used when
>>>>>> dependees use their dependants (which are known)? Is that the deciding
>>>>>> factor?
>>>>>
>>>>> And finally, a couple of more down-to-earth questions:
>>>>>
>>>>> 1. ICore, the class is concrete, so why the I in the name? Was it
>>>>> abstract at one point?
>>>>
>>>> Yes historically.
>>>>
>>>>> How do you decide whether a class should get
>>>>> the interface 'I' in its name?
>>>>
>>>> It’s a mess ;)
>>>> I suppose the trend goes to not prepend the ‘I’.
>>>
>>> Ok, I figured there was a history :)
>>>
>>>>
>>>>> The same with e.g. IContext, though
>>>>> that one at least has a few virtuals and is used as a base class (but
>>>>> no pure ones AFAICS, so still concrete).
>>>>
>>>> Historically these classes where “pure” virtual (except for the QObject 
>>>> base).
>>>> We moved to a more “configurable” approach then to avoid the need to 
>>>> create subclasses for every little thing, while keeping the option open in 
>>>> many cases.
>>>
>>> Alright, this is what I suspected. Thanks for confirming.
>>>
>>>>
>>>>> 2. The relatively liberal use of singleton classes. We all know that
>>>>> is a debated subject, and I don't have an opinion either way. I'm just
>>>>> interested in if you have some (spoken or unspoken) policy regarding
>>>>> singletons in the project. Do you want to minimize the use of them, or
>>>>> is it OK for newer code, or is it judged on a case-by-case basis? Have
>>>>> you had any moments where you really wish you hadn't used singletons?
>>>>> (e.g. I know it can sometimes hurt testability).
>>>>
>>>> We always had a liberal amount of singletons in Qt Creator, and we even 
>>>> moved most of them to be classes with mostly static methods a while ago. 
>>>> There are no plans to move away from that. If you have a central hub for 
>>>> “managing” something, feel free to use a singleton/static methods.
>>
>> Getting back to this semi-old thread with another question if that's OK:
>>
>> Did the liberal use of singletons never get in the way of
>> testability/mockability? Was there ever a moment when you though "o
>> boy, I wish this thing didn't reach out to so many static things"
>> while writing tests? If so, did you find a way to deal with that, or
>> is it always just a compromise?
>
> We use a whole lot of different testing methods which allow a different 
> amount of integration between parts, and also developers usually only add 
> tests where they think their usefulness outweigh the effort involved 
> implementing them.
> Also, different people in the project weigh the importance of tests 
> differently, so you’ll probably get different answers from different 
> developers.
>
> - Auto tests: Standalone in tests/auto/... . This is where access to global 
> state hurts most, and where UI is not great to test either. For auto tests 
> you have to separate the individual functionality from “connecting 
> everything” anyhow though. The global state often falls into that latter 
> part, and with Qt’s signals and slots the separation can be done through 
> that. E.g. for a new “advanced search” filter, you need to access global 
> state to create a search result panel, adding search results there and 
> reacting on user input through it. Testing the actual search, given a set of 
> parameters is easy by simply separating that and using signals to report 
> results.

Ah, that is true, provided you are careful to separate the "hooking
everything" up part.

> It is hard to test e.g. if repeating a search works correctly when the 
> “search again” button is pressed, with this approach. Note that since 
> basically all code of Qt Creator is in libraries, these can also be used in 
> auto tests.
>
> - Plugin tests: Can be triggered by running qtcreator -test MyPlugin. Plugins 
> can have test methods which are then run _within_ Qt Creator after Qt Creator 
> startup. This makes it possible to test functionality that integrates 
> different parts / where global state is essential for the functionality. Its 
> e.g. possible to load a project and throw your new advanced search filter on 
> the project, and repeat a search. Or open a project, wait for parsing to 
> finish, open a specific file, move the cursor to a location, trigger “follow 
> symbol” and check the resulting location.
>
> - Automated UI tests: Using Squish. Starts Qt Creator and simulates e.g. 
> button presses by finding the buttons through the widget hierarchy, object 
> names, etc. Used by a small number of QA dedicated people for automated tests 
> in the style of “create new Qt Widget project, build & run, and check the 
> state afterwards”.

Thanks a lot for sharing your approach to testing.

I guess any project using a plugin based architecture needs to think
about how to test the plugins in the context of the application. I saw
your `qtcreator -test` approach earlier, but I think I'll have a
little closer look now.

In conclusion, I guess thorough testing is hard, as it always has been :)

Elvis

>
> Br, Eike
>
>> I'm asking because in my current project, I'm trying to think about
>> testability, using mocks where it makes sense, and one thing that
>> really hurts testing in isolation is when code simply reaches out for
>> something global (like a static instance/helper).
>>
>> Elvis
>>
>>>
>>> Okay. I also personally think the convenience of singletons outweighs
>>> their drawbacks in many cases. Nice to see this liberating attitude.
>>>
>>> Thanks for sharing Eike.
>>>
>>> Elvis
>>>
>>>>
>>>> Br, Eike
>>>>
>>>> --
>>>> Eike Ziller
>>>> Principal Software Engineer
>>>>
>>>> The Qt Company GmbH
>>>> Rudower Chaussee 13
>>>> D-12489 Berlin
>>>> [email protected]
>>>> http://qt.io
>>>> Geschäftsführer: Mika Pälsi,
>>>> Juha Varelius, Mika Harjuaho
>>>> Sitz der Gesellschaft: Berlin, Registergericht: Amtsgericht 
>>>> Charlottenburg, HRB 144331 B
>
_______________________________________________
Qt-creator mailing list
[email protected]
http://lists.qt-project.org/mailman/listinfo/qt-creator

Reply via email to