PDA

View Full Version : QtTest with Plugin based application



volcano
4th April 2017, 09:30
Hi,

Could you help me how to write unit test for an application which is based on plugins?

ChrisW67
4th April 2017, 10:21
There is nothing different about a unit test for the QObject that implements a plugin or another bit of code. Was there some particular issue that you needed addressed?

volcano
4th April 2017, 10:24
I am using the pluginloader to load the plugins dynamically.

The problem I'm facing is to structure the code so I could run unit test within the code. The purpose is to have a test configuration as well as run configuration.

Kindly advice

high_flyer
4th April 2017, 12:16
run unit test within the code
Could you elaborate more on how you mean that?
Usually tests are not part of the production code so what do you mean exactly by "within the code"?

One why to do it right would be to start with writing the tests BEFORE the plugin code as in - Test Driven Development.
Write your test code such that it depends only on interfaces, not implementation it will increase your code being decoupled which helps concentrate on little areas at at time.
It will also help you advance with the code structuring as you move along.
Ask if you have more specific questions.

volcano
4th April 2017, 13:17
Thanks high_flyer..

Sorry for the misunderstanding regarding the line "run unit test within the code", what I meant is that test code be present in the same project and I could change the config accordingly and run test / run the app.

As the application uses plugins which are loaded dynamically. How can I write test code which could load the plugins and run test on them?

Kindly advice

high_flyer
4th April 2017, 13:55
Sorry for the misunderstanding regarding the line "run unit test within the code", what I meant is that test code be present in the same project and I could change the config accordingly and run test / run the app.
No need to be sorry, I just didn't understand, now I think I do undertsnad what you mean, not sure I do understand "why" :-)
So I'll ask it differently:
If you have your tests in a separate project/subproject - what WONT you be able to do in contrast to when they are part of your project?
There are various advantages of having the production code and test code separated, for example build time, better decoupling etc.

As the application uses plugins which are loaded dynamically. How can I write test code which could load the plugins and run test on them?
Just as you do it in the application using these plugins.
Only this application is the test application not the real one.
QtTest application is a regular application, you only link QtTest which adds some test specific functionality that is all.

volcano
4th April 2017, 16:07
Thanks high_flyer for your advice


advantages of having the production code and test code separated this would lead to making an extra copy and an overhead of ensuring code copying when the source file is modified in the production code base

How about creating a config which could ensure that the test code doesn't get build when building the production source code?

Kindly advice

high_flyer
6th April 2017, 14:36
this would lead to making an extra copy and an overhead of ensuring code copying when the source file is modified in the production code base
Why is that?
Can you explain?
Extra copy of what?

As I said, the cleanest way is to have your test (and not just the test) depend on interface not on implementation.
This makes it easy to test against mocups and decouples your implementations.

d_stranz
6th April 2017, 18:20
this would lead to making an extra copy and an overhead of ensuring code copying when the source file is modified in the production code base

As high_flyer asks, why? You create your test project and add the same files that live in your production directory. No need to copy anything. Modify the file in either place, it will get rebuilt when you rebuild either project. The only thing that gets "copied" is the object file that results from compiling - in one case it is built to the intermediate directory of the test project, and in the other it goes to the production project.

If you want to actually include the dynamic loading as part of the test, here is how I do it in my Windows projects: I have a separate test project that loads these DLLs the same way the actual app does. In Visual Studio, you debug a DLL by specifying an executable to be run when the debugger starts. In my case, the executable is the test program. Clicking "debug" in the DLL project starts the debugger, loads the test program, runs it, when then loads my DLL. I can set breakpoints anywhere in the DLL which do not become "valid" until the DLL is dynamically loaded.

You could do the same thing, except that instead of breakpoints, your test app runs unit tests on your DLL or the code in it if you add links to the source to your test project. I am not so familiar with Qt Creator, but if you use that I am sure there is a similar mechanism.

The reason for keeping your test suites separate from your production code is mainly to minimize confusion over which files belong where. You don't need special project configurations and conditional builds.

volcano
7th April 2017, 11:03
Thanks high_flyer and d_stranz for all your suggestion.


Extra copy of what? I miss interpreted
you have your tests in a separate project/subproject
I understood what you were trying to say.

I just have one more query as the application I have has a GUI component i.e. QWidgets and QDialog in the dll and QtTest is a console based, how do we take care of this?

Kindly advice

high_flyer
7th April 2017, 12:46
QWidgets and QDialog in the dll and QtTest is a console based, how do we take care of this
That is a good question and one of the "messy" issues when it comes to testability.
The text book answer (which means, its correct but not always applicable in real world situations) is that the UI should be as dumb as possible.
This means that the UI should not contain any logic, just be fully controlled by the back end, thus needs no testing.
As I said, this is not always applicable but at the same time should be the design goal to get to that situation as close as possible.
At the other extreme, which is often the case (and should not be) - many applications create a to strong coupling of business logic and UI.
And because of signals and slots - its very easy to fall in that trap with Qt.
This is again where TDD or testing in general comes handy - if you have a problem testing business logic because it is too coupled to your UI, then you have a design problem and should refactor to solve it.
Again, my advice of previous posts here:
Make sure any module depends on interfaces not on implementation.
This will mean both your UI and your businesses logic depend on the same interfaces not on their implementations.
This will allow you to write "fake" non visible UI where you can programmatically emulate UI interaction.

How to go about it:
I would start with testing your business logic (back end).
You should not need UI for that - if you do, your design is too coupled.
Then, you can see how much UI is to be tested and what exactly in the UI needs testing.
There are several UI testing tools but the one which specifically targets Qt applications is Squish (https://www.froglogic.com/squish/).
There are other UI testing frameworks, though I have no experience with them.

The way your wrote this question already suggests that your code couples UI and backend which is not good.
I would strong suggest you decouple your code such that you can cleanly seperate your UI code from the non UI code, resulting in two DLL's.
This has many advantages beyond testing.