8
votes

I'm using Delphi XE and I've got a project group containing the main application and a DUnit test application. From time to time, I go to the DUnit test application to add some tests and run existing one.

Some test code generates exceptions which are handled by the application, but displayed multiple time by the Delphi Debugger as I'm used to running the test application using the F9 shortcut like I do with standard application: this is not very handy in that case.

I know about the SHIFT+CTRL+F9 shortcut to run without debugging and that's great when I remember to use it but I often find myself hitting F9, then grunting, then closing the test application, then hitting SHIFT+CTRL+F9. What a lost of time.

So my question: is there a better way ? Can I define some settings or use some expert to make that particular application run without debugging by default ? Surely I'm not the only one having this issue.

Thanks in advance.

5
+1 same here. It would be great if one could disable this behaviour with a compiler flag. Something like {$DoNotBreakOn EArgumentException}jpfollenius
The program already supports "Run without debugging" and the "Notify on language exceptions" switch. These are the right way to do what you need. If you add a compiler flag as Smasher suggests then just think how annoying it would be when you want to debug, but you can't.David Heffernan
As david suggests, you're perhaps wishing for the ability to run without debug, without running without debug. Run without debug, if you want to run without debug. If your brain's habits are the problem, work on the brain's habits. I get stuck exactly as you get stuck, and that worked for me.Warren P
@Smasher: I'm not sure compiler flag would be the right way to do it as David is right, it could be annoying if you want to debug later on. @David: Right way in the current state indeed, but it could be improved. I'm thinking about XCode where the compile button changes based on your last action, compile without or with debugging. Perhaps a configurable compile button per project could be the solution here. @Warren: My brain is the problem but as a developer I'm used to try to find solution to that kind of problems, and it appears that my brain is not alone with that problem ;)jonjbar

5 Answers

5
votes

Nope (at least not up until D2009). Run without debugging is an IDE thing. A comiler flag would not help as it is the IDE that hooks the exe, not the other way around. The only place where you could have such an option would be in the project settings. But having it could make the IDE slightly confusing as the normal distinction between Run and Run without debugging would be overruled. You would then need a third option I guess, "Run", "Run with debugging" and "Run without debugging" where the simple "Run" would take its cue from the project options.

2
votes

Add the run-without-debugging icon to the toolbar. Your problem is you forget the hotkey, and click the icon. So remove the other icon, or move them both around, like this:enter image description here

The bigger your application grows, I find, the slower the debugger startup gets. I run without debugging about 99% of the time now, because the startup time of my app goes from 2 seconds, to 2 minutes, because it uses a lot of runtime packages, and every BPL load in the debugger comes at a huge hit to my productivity. So long, slow painful experience has re-educated me to ask myself "Do I really need to debug?". If I don't, I click the nice green icon (in XE) that replaces the exclamation mark icon in older versions. (A smart UI improvement I think.). In previous delphi versions, the green play button meant "run with debugging".

2
votes

Disable "notify on language exceptions".

Disable notify on language exceptions

0
votes

Well kind of. You can use non-breaking breakpoints[McKeeth][Jensen] to ignore the exceptions you are forcing in your tests. The only way to save breakpoints I know of is to enable Tools > Options > Autosave > Project desktop.

0
votes

I understand your problem, but personally I don't think it's that useful having an option to change the default behaviour of F9.

You have some test cases which are expected to raise exceptions. (NOTE: I'm actually thinking tests that check for particular exceptions when bad inputs are given. Not exceptions being 'handled' by application.) And I agree there is no point in being alerted to these in most circumstances. However, an exception in other test cases would be a problem that I'd like to be alerted to as quickly as possible.

So my preferred running mode is to usually be notified of exceptions. And have explicit code in certain test cases that explicitly disables exception notification only within the context of the tests that will trigger production code exceptions.

I have a technique that works very well for this.

In a test that's expected to raise exceptions I write the following code:

begin
  TIDEDebugTools.DisableBreakOnExceptions;
  try
    //Test code ...
  finally
    TIDEDebugTools.EnableBreakOnExceptions;
  end;
end;

I guess you want the source code for those 2 methods? :)

unit IDEDebugTools;

interface

type
  TIDEDebugTools = class(TObject)
  public
    class procedure DisableBreakOnExceptions;
    class procedure EnableBreakOnExceptions;
  end;

implementation

{ TIDEDebugTools }

class procedure TIDEDebugTools.DisableBreakOnExceptions;
begin

end;

class procedure TIDEDebugTools.EnableBreakOnExceptions;
begin

end;

end.

Where's the rest you ask?
There isn't any - that's it!

... but there are a few instructions you need to follow:

  • Add a breakpoint to each of the method.
  • Edit the breakpoint-properties.
  • Select advanced options.
  • Turn off the "Break" option
  • And turn on the "Ignore subsequent exceptions" and "Handle subsequent exceptions" options for the appropriate respective method.

This is close to jpfollenius' idea for compiler directive options. It also addresses David's concern about how you enable those exceptions again. All you need to do is disable the breakpoints to get all exceptions reported again.


Additional thoughts:

You mention:

Some test code generates exceptions which are handled by the application.

If your application is handling all these exceptions, then:

  • Are your tests localised enough? If you're testing such large chunks of functionality, the tests are more like system tests - and can be very difficult to maintain.
  • Are you making too much use of exceptions for main-line business processing?
  • Is your application doing a whole lot of inappropriate exception swallowing?

Basically it seems fishy to me that your wording suggested "a bunch of exceptions you're not too concerned about because they're 'handled'". Many people make the mistake of thinking they're handling a exceptions when really they're just swallowing them and hiding the root problems.