- what do people use for automated testing of C++ Windows app ? - 2 Updates
- STL container of functions? - 5 Updates
- C++ Middleware Writer - 4 Updates
legalize+jeeves@mail.xmission.com (Richard): Aug 21 07:15PM [Please do not mail me a copy of your followup] Lynn McGuire <lynnmcguire5@gmail.com> spake the secret code >What do people use for automated testing of C++ Windows apps ? I suppose it depends on what you mean by automated testing. The general approach is to test the business logic of the application with unit tests and acceptance tests (integration tests). If your business logic is intimately coupled to the UI (i.e. business logic is embedded in event handlers), then the tight coupling makes it difficult to write unit tests. Acceptance tests in this situation must be written as some sort of event synthesis in order to pretend to be a user because there's no other way to exercise the business logic than to get the event handlers to fire. This is fine as long as the UI is stable and what you're after is a regression test suite that verifies that internal changes haven't indirectly broken stable functionality. However, if you're talking about an application that is evolving and having new features added, then coupling your acceptance tests to the UI is very fragile IMO. The UI is the part of the application that changes at the highest frequency. When you couple your acceptance tests directly to the UI, then your tests are constantly needing to be updated. However, it is likely that the underlying business logic or computational process is changing at a much slower rate. Couple your tests to the business logic and your tests become less of a burden. For complex UI where there is coupling of behavior between controls (i.e. disable this input field when that checkbox is checked), you will want to have some automated test around that logic. If your UI follows a model-view-controller pattern of separation, you can unit test the controller. If you code is tightly coupled where the UI logic is directly in the event handler and you can't exercise the logic without instanting the GUI itself, then you can refactor it into a Mediator pattern. This is just extracting the UI logic into a new class (the mediator) and interacting with the UI through an interface which is implemented by your dialog, window, etc. Then you can unit test the mediator. This is what I do when making new dialogs with more than trivial behavior (i.e. just a bunch of input fields and OK/Cancel buttons) in our large Qt application. >Our app has 200+ dialogs, a calculation engine, 600K lines of code of C++, >We have some automated single stage testing now but I would like to add >some automated multiple stage testing. For acceptance tests I like FitNesse <http://www.fitnesse.org>. It let's you express your acceptance tests through wiki pages with embedded tables of test instructions. This lets you add all kinds of ancillary documentation to the tests along with the tests. It is heavily used in the Java and .NET communities for automated acceptance testing. It is written in Java and has a bridge for executing C/C++ code. Our application is a large 3D graphics Qt application with ~1M statements and lots of UI. Fortunately it has also been scriptable from the beginning with the Qt javascript variant. We add unit tests for new features and acceptance tests covering new features as well as broadening our acceptance tests to cover more legacy features. We try to test at the level of functionality and not GUI (the GUI just drives the same underlying functionality). With new dialogs we write mediators and test the logic in the mediator. I cover the Mediator idea in my set of blog posts on TDD: <https://legalizeadulthood.wordpress.com/2009/07/05/c-unit-tests-with-boost-test-part-4/> You can see me refactor some existing C# code into Mediator pattern here: <http://confreaks.tv/videos/agileroots2009-test-driven-development-and-refactoring-part-two> -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Computer Graphics Museum <http://computergraphicsmuseum.org> The Terminals Wiki <http://terminals.classiccmp.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
Lynn McGuire <lynnmcguire5@gmail.com>: Aug 21 06:30PM -0500 On 8/20/2016 5:34 PM, Öö Tiib wrote: > My impression is that you need to reserve couple of programmers > full time to script those tests since GUI tends to change most > rapidly. Thanks for the list! Wow, my shop is me and three programmers, plus other support personnel. I am going to need something a little less manpower intensive. Thanks, Lynn |
eva galois <eva.galois@yandex.ru>: Aug 20 11:43PM -0400 Is it possible, through templates/aliasing('using')/etc, to create a container of functions with arbitrary return value and parameters? I know this code is basically gibberish, but the idea would be something like: | template <typename T, typename ...Args> | typedef std::vector<std::function<T(Args...)>> functions; Maybe through aliasing (since I know you can't template a typedef statement)? |
"Öö Tiib" <ootiib@hot.ee>: Aug 21 04:38AM -0700 On Sunday, 21 August 2016 06:43:50 UTC+3, eva galois wrote: > Is it possible, through templates/aliasing('using')/etc, to create a > container of functions with arbitrary return value and parameters? It is hard to tell from one sentence what it is that you want. People have several times made container of one of anything in C++. Most popular of those is perhaps 'boost::any'. IMHO that thing is bordering on uselessness, but we can certainly make a 'vector' of those resulting with 'vector' of anything. C++ thing borrowed from C that can be one of compile-time known set is 'union'. Like most things borrowed from C it is constrained and unsafe, but union of function pointers can still be what you want and those can be put into 'vector'. Lot of libraries have invented 'variant' classes that do same what 'union' but more safely and with less constraints. Those are rather useful; I have used 'boost::variant' in several projects. > | typedef std::vector<std::function<T(Args...)>> functions; > Maybe through aliasing (since I know you can't template a typedef > statement)? That code tries to declare that "something" you want. That does not actually illustrate what it is what you want. Also it is the angle from what I rarely approach a problem. I commonly try to write down how I want to use that "something". IOW ... what is the motivating example to have that thing at all? |
Richard Damon <Richard@Damon-Family.org>: Aug 21 08:11AM -0400 On 8/20/16 11:43 PM, eva galois wrote: > | typedef std::vector<std::function<T(Args...)>> functions; > Maybe through aliasing (since I know you can't template a typedef > statement)? I thin the bigger issue is going to be how to USE the function (pointers). It is easy to store them all in a container, you just need to void (*)(void) and it is a simple container to store them. The problem is that if you have stored an int f(int) and a float g(float) in the container, this means that to use these the first you need to pass and retrieve and int, and in the second a float. Thus the usage site needs to know all the calling patterns to use it. The alternative is, if the usage warrants it, is to wrap all the functions in a templated wrapper that presents a uniform API, so the call site is consistent, and now the container is storing all the same type of function pointers. |
Gert-Jan de Vos <gert-jan.de.vos@onsneteindhoven.nl>: Aug 21 09:46AM -0700 int add(int a, int b) { return a + b; } void f() { std::vector<std::function<void ()> vec; int sum = 0; vec.push_back([&]() { sum = add(1, 2); }); vec[0](); } |
Barry Schwarz <schwarzb@dqel.com>: Aug 21 12:16PM -0700 On Sun, 21 Aug 2016 09:46:25 -0700 (PDT), Gert-Jan de Vos >void f() >{ > std::vector<std::function<void ()> vec; You need another > before vec -- Remove del for email |
Stuart Redmann <DerTopper@web.de>: Aug 21 01:04AM +0200 > I know I shouldn't click on the C++ Middleware Writer thread, but having done > so, I have to say your post made excellent reading, thanks for that. > Daniel +1 Stuart |
jacob navia <jacob@jacob.remcomp.fr>: Aug 21 11:19AM +0200 Le 21/08/2016 à 01:20, David Brown a écrit : >> That would be excellent description of the C++ projects with legacy of >> 15+ years I often see at my clients. > Isn't it just a description of anyone else's code? :-) If after 15+ years the code is like that, imagine after just a few MILLION years... |
"Öö Tiib" <ootiib@hot.ee>: Aug 21 04:46AM -0700 On Sunday, 21 August 2016 02:09:12 UTC+3, Paavo Helde wrote: > the sun was minimized. Sounds plausible to me (at least explains hair). > Not many animals could walk upright though because keeping the balance > takes a lot of spare processing power. These are all hypotheses of course; we may happen never find out how it was actually. But our origins will certainly keep us puzzled. For example one related hypothesis: https://en.wikipedia.org/wiki/Endurance_running_hypothesis > Walking upright has nothing to with seeing stars, anyway. For seeing > stars it would help to have eyes on top of your head, like crocodiles. The important factor is not in seeing stars but in ability to stare at those sagaciously. ;) |
Paavo Helde <myfirstname@osa.pri.ee>: Aug 21 07:06PM +0300 On 21.08.2016 14:46, Öö Tiib wrote: >> takes a lot of spare processing power. > These are all hypotheses of course; we may happen never find out how it > was actually. Or vice versa, some hypothesis may be confirmed or even proved. Lots of we-will-never-know biological hypotheses have been proved or disproved recently via genetic analysis, for example. >> stars it would help to have eyes on top of your head, like crocodiles. > The important factor is not in seeing stars but in ability to stare at > those sagaciously. ;) I had to look up this word ;-) And yes, that's exactly what crocodiles seem to do, most of the time :-) Cheers Paavo |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment