Different EurekaLog settings for ‘Debug’ and ‘Release’ profiles

This article is supposed to answer on one common question asked by our customers. They want to use different EurekaLog settings for different compilation profiles. Sometimes even no use EurekaLog at all for some specific profile. This article will explain how to do this. Important Note: please see most recent version of this documentation here. Well, first - unfortunately, there is no IDE solution for certain technical reasons. But this doesn't mean that you can't do this. You can't use automatic solution, but you can perfectly set all options manually. For the purposes of this article I will use EurekaLog 7.0.1 and Delphi XE. The discussed features may be unavailable in older versions. Step 1: get working solution for single profile First, I created a new VCL application and place a button to raise exception. Then I go to Project/EurekaLog options, enabled EurekaLog and specified type of my application (VCL Forms). You can also set other options as you desire. Now run the application and confirm it's working as expected. Step 2: reconfigure project for manual control For the next step you should go to Project/EurekaLog options and use "Export" button to create .eof file. Place it in the same folder as your project (by default "Profiles" folder is suggested). Name it as your project + name of your configuration. For example: Project1_Debug.eof. Now, don't close options dialog, but go to Advanced/Custom/Manual and add "DoNotTouch=1" line (without quotes) in any place (as new line). This will disable any assist for your project from IDE expert. Close settings and save your project. You can confirm if option is taking effect by disabling EurekaLog, saving your project and observing that there are no changes in your .dpr file - all units are still included even if no EurekaLog is enabled. Now, it's time to restore post-processing for your application. Go to Project/Options (not EurekaLog options) and look for build events options. Add the following command as post-build event which is invoked on successful compilation: IF EXIST "$(BDS)\Bin\ecc32.exe" "$(BDS)\Bin\ecc32.exe" --el_alter_exe"$(PROJECTPATH);$(OUTPUTPATH)" --el_config"Project1_$(Config).eof" Replace "Project1" with your real project name or change the whole argument to match your .eof file. The $(Config) is a variable, which will be substituted with the name of build configuration - such as "Debug" or "Release" or any other custom configuration name. So, the resulting command-line may look like this when run: IF EXIST "C:\Program Files (x86)\Embarcadero\RAD Studio\8.0\Bin\ecc32.exe" "C:\Program Files (x86)\Embarcadero\RAD Studio\8.0\Bin\ecc32.exe" --el_alter_exe"C:\Projects\Project1.dproj;C:\Projects\Debug\Win32\Project1.exe" --el_config"Project1_Debug.eof" Note that this is an example of final command as it will be executed by IDE. You should NOT use this form of command (with already expanded variables) - please use the first example with $(Config) variable. Note: you can also find the $(Platform) variable useful. It will be replaced with short name of the platform - such as Win32, Win64, OSX. So you can have file like Project1_Win32_Debug.eof and use --el_config"Project1_$(Platform)_$(Config).eof switch. Now compile your project and run it. If you done everything correctly - the result must be the same as on step 1 - the correct EurekaLog-enabled application with expected behavior as set in external .eof file (even though the EurekaLog was disabled in project). In case of any build errors - take a look at compiler output as shown in "Messages" window. It's docked at the bottom of IDE window by default. "Output" tab is near "Build" tab, which is active by default. If you don't see "Messages" window - use View/Messages command to show it, then switch to output window. The correct compilation will get you such messages: Build started 2012.06.29 16:58:04. __________________________________________________ Project "C:\Projects\Project1.dproj" (Build target(s)): Target _PasCoreCompile: C:\program files (x86)\embarcadero\rad studio\8.0\bin\dcc32.exe //-- options cut to save space --// Project1.dpr Target PostBuildEvent: IF EXIST "C:\program files (x86)\embarcadero\rad studio\8.0\Bin\ecc32.exe" "C:\program files (x86)\embarcadero\rad studio\8.0\Bin\ecc32.exe" --el_alter_exe"C:\Projects\Project1.dproj;.\Debug\Win32\Project1.exe" --el_config"Project1_Debug.eof" EurekaLog Command-Line Compiler v7.0.1.0 for Delphi 15.0 ---------------------------------------------------------------- Loading EurekaLog options... EurekaLog postprocessor start... EurekaLog's code was added EurekaLog's options were added EurekaLog's data was added File size before: 2'159'616 File size after: 2'185'216 File size diff: +25'600 Debug info size: 287'554 Symbols size: 58 Functions size: 4 Stripped size: -138'240 Number of units: 209 Number of procedures: 10'136 Number of lines: 28'124 Total time: 00:00:00.639 Compilation time: 00:00:00.026 Prepare time: 00:00:00.015 Post-process time: 00:00:00.597 Events time: 00:00:00.001 Memory usage: Allocated: 7'576'806 RAM: 29'999'104 Private: 27'066'368 Virtual: 105'299'968 EurekaLog postprocessor end Build succeeded. 0 Warning(s) 0 Error(s) Time Elapsed 00:00:01.91 Step 3: configuring alternative profiles Now it's time to set up configuration of alternative profiles (finally). The first thing you need to do - is to decide if you want EurekaLog for this configuration or not. The difference is that you need different project options set for different cases. As well as different unit set. Let's do this one step at time. First, conditional directives. They are not used by EurekaLog, but it will come in handy for your own purposes. So, go to Project/Options and look to Delphi Compiler/Conditional Defines option. Now, if you want EurekaLog for this profile - add "EL" conditional define. If you don't want EurekaLog for this profile - remove EL conditional define. The name of symbol is any text. You can use other name instead of EL. Repeat this step for each profile of your project that you're going to use. Note: currently 7.0.1 removes conditional define with name of "EUREKALOG". I think this should be fixed in the next minor update. Second, the options of the project. EurekaLog requires certain options to be set in order to work. Also, some option may increase or decrease detalization of EurekaLog. So, if you want to use EurekaLog in certain profile - then you have to setup all required options manually. Please, read this article to know what options must be set. For other profiles (in which EurekaLog will not be used) you can set options as you desire, there are no limitations. Third, the included units. Use Project/View source command to open your .dpr file in code editor. You should see EurekaLog units included. If you don't want EurekaLog for certain configurations - then you (probably) don't need to include EurekaLog code. So, you can make this like this: program Project1; uses {$IFDEF EL} EMemLeaks, EResLeaks, EDialogWinAPIMSClassic, EDialogWinAPIEurekaLogDetailed, EDialogWinAPIStepsToReproduce, EDebugExports, EDebugJCL, EAppVCL, ExceptionLog7, {$ENDIF} Forms, Unit1 in 'Unit1.pas' {Form1}; {$R *.res} begin Application.Initialize; Application.MainFormOnTaskbar := True; Application.CreateForm(TForm1, Form1); Application.Run; end. Please note that exact included units depends on your selected options. For example, if you set error dialog to "None" - then EDialogXYZ units may be removed. So if you change original options - you may have to include/remove units manually. If you are not very well familiar with EurekaLog 7 - I recommend to create a new application for testing. Setup EurekaLog options and see which unit will be included. Note: you can skip steps 1 and 3 if you want EurekaLog to be enabled for each profile (just with different settings). Note: you can also use EBase unit to test whenever EurekaLog was enabled for your application or not. This unit is specially designed to be included in any application without including EurekaLog's code. Fourth, you have to create .eof file for each configuration profile and save it with corresponding name (such as Project1_Release.eof in our example, but you may use any other naming scheme). Be aware that you also need to create .eof file for profiles with disabled EurekaLog! You need to disable EurekaLog in such .eof files. You can use IDE options dialog: use Import/Export buttons to open/save settings. Or you can use standalone settings editor tool (you can add it to Tools menu for quick access). Note: the result of using IDE expert and settings editor tool is a bit different. IDE expert only saves settings which are different from defaults. Settings editor saves all options. At last - make sure that post-build event that we set in options at previous step is applied for all profiles (you can do this by entering command to Base profile and checking that it wasn't overwritten by another profiles). Now, do a test - switch to different configuration profiles, make a build, run application and test it. Note: it's recommended to make a full rebuild when changing profiles or target platform. Conclusion This article explained the basics of manual control over configuration of your project. I really hope that it's not that hard and that it answers many questions. As a side note - I want to discuss relation between settings and configuration profile names. In classic application: the debug profile has maximum debug options set, and the release profile has minimum debug options set. For applications with exceptions tracers it's different. Exception tracer requires more info than you usually use for debugging sessions (think about "Use Debug DCUs" option). So typically it's reversed now: you want maximum options for release version of your application and medium (moderate) options for debugging. Therefore, you can either swap profiles (i.e. use "debug" profile for the release version of your application) or to completely re-setup options between profiles.
Read More

EurekaLog 7.0.0 is out

We are pleased to announce the availability of the EurekaLog 7.0.0 stable release

Key EurekaLog 7 features:

  • Win64 support
  • FireMonkey support
  • WER (Windows Error Reporting) support
  • WCT (Wait Chain Traversal) support
  • Resource leaks support
  • Memory leaks and catch handled exceptions for C++ Builder
  • Improved stack tracing
  • Proper Unicode support
  • Improved compatibility with packers and protectors
  • Extensive documentation
  • Easy customization
  • Web-API support for FogBugz, Mantis, BugZilla
  • Improved SSL/TLS
  • Implemented A LOT of your suggestions
  • Full backward compatibility with EurekaLog 6
See full features list here (Help / Introduction / Features). 
Full changelog for EurekaLog 7:
·Improved: Main change – EurekaLog’s core was rewritten (refactored) to allow more easy modification and remove hacks.
·Improved: New plugin-like architecture now allows you to exclude unused code.
·Improved: New plugin-like architecture now allows you to easily extends EurekaLog.
·Improved: Greatly extended documentation.
·Improved: Installer is now localized.
·Improved: Greatly speed ups creation of minimal bug report (with most information disabled).
·Changed: EurekaLog’s root IDE menu was relocated to under Tools and extended with new items.
·Added: New examples.
·Added: New tools (address lookup, error lookup, threads snapshot, standalone settings editor).
·Added: Support for DBG/PDB formats of debug information (including symbol server support and auto-downloading).
·Added: Support for madExcept debug information (experimental).
·Added: WER (Windows Error Reporting) support.
·Added: Full unicode support.
·Added: Professional and Trial editions: added source code (interface sections only)
·Improved: Dialogs – new options and new customization possibilities:
·Added: All GUI dialogs: ability to test dialog directly from configuration dialog by displaying a sample window with currently specified settings.
·Improved: All GUI dialogs: dialogs are DPI-awared now (auto-scale for different DPI).
·Added: MessageBox dialog: added detailed mode (shows a compact call stack).
·Added: MessageBox dialog: added ability for asking a send consent.
·Added: MessageBox dialog: added support to switch to “native” message box for application.
·Added: MS Classic dialog: added control over “user e-mail” edit’s visibility.
·Added: MS Classic dialog: added ability to personalize dialog view with application’s name and icon.
·Added: MS Classic dialog: added ability to show terminate/restart checkbox initially checked.
·Added: EurekaLog dialog: added ability to personalize dialog view with application’s name and icon.
·Added: EurekaLog dialog: added ability to show terminate/restart checkbox initially checked.
·Added: EurekaLog dialog: added ability to switch back to non-detailed view.
·Added: WEB dialog: added new tags to customize bug report page.
·Improved: WEB dialog: improved support for unicode and charset.
·Added: New dialog type: RTL dialog.
·Added: New dialog type: console output.
·Added: New dialog type: system logging.
·Added: New dialog type: Windows Error Reporting.
·Improved: Sending – new options and new customization possibilities:
·Added: All send methods: added ability to setup multiply send methods.
·Added: All send methods: added ability to change send method order.
·Added: All send methods: added separate settings for each send method.
·Added: All send methods: ability to test send method directly from configuration dialog by sending a demo bug report.
·Added: SMTP client send method: added SSL support.
·Added: SMTP client send method: added TLS support.
·Added: SMTP client send method: added option for using real e-mail address.
·Added: SMTP server send method: added option for using real e-mail address.
·Added: HTTP upload send method: added support for custom backward feedback messages.
·Added: FTP upload send method: added creating folders on FTP (like remote ForceDirectories).
·Added: Mantis send method: added API support (MantisConnect, out-of-the-box since Mantis 1.1.0, available as add-on for previous versions).
·Added: Mantis send method: added support for custom “Count” field.
·Added: Mantis send method: added options for controlling duplicates.
·Added: Mantis send method: added support for SSL/TLS.
·Added: FogBugz send method: added API support (out-of-the-box since ForBugz 7, available as add-on for FogBugz 6).
·Added: FogBugz send method: EurekaLog will update “Occurrences” field (count of bugs).
·Added: FogBugz send method: EurekaLog will respect “Stop reporting” option (BugzScout’s setting).
·Added: FogBugz send method: EurekaLog will respect “Scout message” option (BugzScout’s setting).
·Added: FogBugz send method: EurekaLog will store client’s e-mail as issue’s correspondent.
·Added: FogBugz send method: added options for controlling duplicates.
·Added: FogBugz send method: added support for “Area” field.
·Added: FogBugz send method: added support for SSL/TLS.
·Added: BugZilla send method: added API support.
·Added: BugZilla send method: added support for custom “Count” field.
·Added: BugZilla send method: added options for controlling duplicates.
·Added: BugZilla send method: added support for SSL/TLS.
·Added: New send method: Shell (mailto protocol).
·Added: New send method: extended MAPI.
·Added: Support for separate code and debug info injection.
·Added: Ability to use custom units before EurekaLog’s units.
·Added: Support for external configuration file in IDE expert.
·Added: Now EurekaLog stores only those project options which are different from defaults (to save disk space and reduce noise in project file).
·Added: Now EurekaLog stores project options sorted (alphabet order).
·Added: Separate settings for saving modules and processes lists to bug report.
·Added: Support for taking screenshots of multiply monitors.
·Added: More screenshot customization options.
·Added: More control over bug report’s file names.
·Added: New environment variables.
·Added: Deleting .map file after compilation.
·Added: Support for different .dpr and .dproj file names.
·Improved: memory leaks detection feature – new options and new customization possibilities:
·Added: Ability to track memory problems without activation of leaks checking.
·Added: Support for sharing memory manager.
·Added: Support for tracking leaks in applications built with run-time packages.
·Added: Option to zero-fill freed memory.
·Added: Option to enable leaks detection only when running under debugger.
·Added: Option for manual activation control for leaks detection (via command-line switches).
·Added: Option to select stack tracing method for memory problems.
·Added: Option to trigger memory leak reporting only for large leaked memory’s size.
·Added: Option to control limit of number of reported leak.
·Added: CheckHeap function to force check of heap’s consistency.
·Added: DumpAllocationsToFile function to save information about allocated memory to log file.
·Added: Registered leaks feature.
·Added: Run-time control over memory leak registering.
·Added: New recognized leak type: String (both ANSI and Unicode are supported).
·Added: Memory features support for C++ Builder.
·Added: Resource leaks detection feature.
·Improved: Compilation speed increased.
·Added: Support for generics in debug information.
·Added: Chained/nested exceptions support.
·Added: Wait Chain Traversal support.
·Added: Support for named threads.
·Added: Additional information for threads in call stack.
·Improved: EurekaLog Viewer Tool:

·Now Viewer has its own help file
·Viewer now supports a FireBird based database on local file or remote server.
·You can have more that one user account for FireBird based database.
·Viewer now can be launched in View mode (Viewer can be configured to any DB or View mode).
·Viewer’s database now supports storing files, associated with the report (you can also add and remove files manually).
·Viewer supports “Import” and “View” commands for report files.
·Extended support for more log formats (XML, packed ELF, etc).
·Columns in report’s list now can be configured (you can hide and show them).
·There are a plenty of new columns added to report’s list.
·Added ability of auto-download reports from e-mail account.
·Improved printing: now you can print the entire report (including screenshots). Old behaviour of printing just one tab (call stack only, for example) also remains.
·Viewer can now have more that one run-time instance.
·File import status dialog is now configurable (you can disable it, if you want to).
·There is a preview area for screenshots, available in reports.
·Now Viewer is more Vista-friendly (i.e. file associations are managed in HKCU, rather that in HKLM, storing configuration in user’s Application Data, etc, etc).
·Report’s list now supports multi-select, so operations can be performed on many reports at time.
·There are plenty of new command line abilities, like specifying several files and new switches.
·Bunch of minor changes and improvements.



Guarantee.
FULL MONEY BACK GUARANTEE.
All EurekaLog versions are covered by 60-day money-back guarantee.
If you are not satisfied with your purchase for any reason, just ask for your money back and you will be refunded.

Update Policy.
  • All updates for the same major version are freely downloadable.
  • Updates to a different license type of the same major version are sold at only price difference (example: from Single Professional version to Company Enterprise).
  • Updates between two different major version are sold at 50% discount (free for all customers who have bought a copy in the last 90 days before the release date).

EurekaLog 7 Free License Winners
We’re glad to announce the winners of our “Win Licenses” offer:

  • Alexander Bagel
  • Alexander Mihnevich
  • Ken Schafer
  • Kevin G. McCoy
  • Paul Voelker
  • Salvatore Besso

Each winner will get a free EurekaLog 7 Enterprise Single Developer License. All winners will be contacted by e-mail.
Soon to come
Roadmap for EurekaLog 7.1:
  • JIRA, Redmine, YouTrack support
  • MacOS support
  • Remaining suggestions from our customers

Read More

Read More

EDN Mobile: Maintenant avec la localisation française!

Thanks to a totally unsolicited email from EDN community member Whiler, I am pleased to announce that EDN Mobile now supports the French locale.

I now invite other community members to provide localizations in any of the supported languages. As of Android 4.0.3, this list is available here. The localization process is pretty simple, and involves […] … Read More

Read More

Last Chance for Delphi Developer Days 2012

If you haven't already signed up for this year's Delphi Developer Days with Marco Cantù and me, your opportunity is quickly slipping away. We begin the last leg of our six city tour in just two weeks, and the Frankfurt event is already sold out. This means that our event in Rome, on May 17th and 18th, is your last chance to attend Delphi Developer Days this year.As in the past, the response this year has been fantastic. It has been especially fun given all the new features that shipped with Delphi XE2. Marco's extensive exploration of the new FireMonkey component library has been one of the most favored tracks, and I have received a lot of positive feedback about my sessions on LiveBindings and DataSnap. Our attendees have also given high marks to our examinations of Delphi's wide range of database capabilities and options for building Internet-based applications. There's also a healthy dose of iOS development, with examples of applications built for iPads (and iPhone) as well as Android devices.But just because there's a lot of new features in Delphi doesn't mean that we're ignoring earlier versions. I have had consistently large audiences for my ClientDataSet and Unicode sessions. Likewise, Marco's session on RTTI (runtime type information) and Attributes, as well as his dbExpress Deep Dive session have also been high on many of our attendee's lists.If you've been to one of our Delphi Developer Days events in the past, you already know about the course book that each attendee receives. The book contains papers for every one of the sessions that we present, which is especially valuable when you consider that half of our sessions are breakout sessions, meaning that you have two choose between Marco's presentation or mine. The extensive course book means that you don’t miss a thing.This course book is almost 450 pages in length, and we're not talking about slide reproductions here. Each paper is narrative in style and contains detailed explanations and code samples. Indeed, the course book is larger than most Delphi books you can buy. Consider this, my last book, Delphi in Depth: ClientDataSets, which is 350 pages in length, contained around 85,000 words. Our Delphi Developer Days course book is almost 150,000 words in length. That's a big book, and its only available to attendees.As I said, the response has been terrific. Not only have we sold out Frankfurt, but Chicago was sold out as well, and Amsterdam got close. The Rome location is very convenient. It is a short 200 meters walk from the Termini Train station in central Rome, and there are trains from Roma Ciampino Airport (15 minutes travel time) and Leonardo da Vinci-Fiumicino Airport (30 minutes travel time) throughout the day.In case you need additional reasons to come to Rome, here are two more. Daniele Teti of BitTime is our guest speaker in Rome. There he will present his talk titled "Improving Code Testability Through Dependency Injection," a talk I am looking forward to with great anticipation. And if that weren't enough, Marco Cantù will personally guide a walking tour of Rome for all who are interested after the first day of sessions.For more information on Delphi Developer Days, and to register for Rome, please visit http://www.DelphiDeveloperDays.com. I hope to see you there!
Read More

FireMonkey Development Setup for iOS: Delphi XE2 Update 4

Introduction

This topic shows how to setup FireMonkey Development environment for iOS – Apple’s mobile device platform for iPhone, iPAD or iPod touch.

To continue installation, Xcode 4.2 should be ready in Mac OS X machine.

Install FireMonkey – iOS SDK

The FireMonkey iOS SDK is available in Delphi XE2 folder FireMonkey-iOS.  The following folder is a shared folder from VMware machine: %ProgramFiles(x86)\Embarcadero\RAD Studio\9.0:

Locate FireMonkey-iOS.dmg disk image in the folder:

Open or mount the disk image:

Install both packages in the following sequence:

  1. fpc-2.6.0.intel-macosx.pkg
  2. FireMonkey-iOS-XE2.pkg

A new folder: Embarcadero should be created in Developer folder:

The FireMonkey iOS SDK is ready for Xcode to compile FireMonkey iOS project now.

Reference

  1. FireMonkey Development Setup for iOS. URL: http://docwiki.embarcadero.com/RADStudio/en/FireMonkey_Development_Setup_for_iOS

Read More

Read More

DataSnap iOS Mobile Connectors and case sensitive file names

Delphi XE2 Update #4 was released a few weeks ago, and actually introduced a new features: adding Mobile Connectors support for FreePascal for iOS 4.2 and 5.0, although not without a little issue that may confuse some people (and demos)... DataSnap REST Applications that export mobile connectors, can be used to download an archive with proxy source code and support units.
Read More

iOS 5.1 device upgrade gotchas

Earlier this week, I used a Mac Mini with OS X 10.6.8 (Snow Leopard) and Xcode 4.2 with iOS SDKs and devices support ranging from 4.2.1 and 4.3 to 5.0 - before my iPhone alerted me that a minor software update to iOS 5.1 was ready to be installed. This blog post is mainly meant to "warn" Delphi XE2 FireMonkey for iOS developers who have not yet upgraded their iOS devices to 5.1.
Read More

FireMonkey Fonts and Native Look & Feel

Since XE2 Update 4 was released, there have been a few online complaints (1, 2) about FireMonkey's fonts on Windows.  I had most of a blog post written explaining why it actually was fine, when I read that there will be a hot fix targeting this and other issues.  I guess it is an issue after all, then! But when it comes to FireMonkey's text, there are more important things than antialiasing or
Read More

Test Driven Development in Delphi: The Basics

I intend to write a Test Driven Development (TDD) series, targeted for Delphi developers. I will use DUnit, the unit testing framework for Delphi.Note folks that the purpose of this is NOT to discuss the Pros and Cons of TDD, Unit Testing or whatsoever. The purpose is just to give a few examples. I would love if you help me when the complexity starts climbing.If needed, for a quick understanding of what TDD or Unit Testing is, refer to the links above, or check out the book at the end of the article.In TDD you don’t write the application code first, instead you write the test cases first. The TDD cycle is as follows:At the beginning you just write one test, and later on, more tests can be added.Make sure the initial test fails; this will validate the test harness. Write some code to pass the test. Important: don’t over-code. Just add the code needed to pass the test and period. The code does not have to be elegant at this point.Run the test: if it fails, then you have to go back to step 3 and fix your code in order to pass the test. When you succeed, then move on to step 5.Improve and optimize your code: make it elegant, more efficient, avoid duplications, etc, etc. This is called code refactoring.When refactoring your code, maybe, by accident, you break the functionality. How can you be sure that everything is working as it should? Just re-run your test and it will tell you if the previous refactoring introduced a failure or not.Go to step 1 and add a new test if needed.The example: let’s consider the chess game. The goal will be to implement the code to verify whether a piece is placed in a valid position within the board. We are only going to implement one test: SetPositionTest.I will number the columns (X coordinate) from 1 to 8 starting at the bottom left-hand corner. In the same way, I will number the rows (Y coordinate) from 1 to 8 starting at the bottom left-hand corner. 87654321 2 3 4 5 6 7 8 For a step by step tutorial of how to use, configure and setup DUnit you can read the English or Chinese versions of the tutorial.Initially, the testing code should look like this:unit ChessPiecesTests;interfaceuses   TestFrameWork;type  TPieceTest = class(TTestCase)  published    procedure SetPositionTest;  end;implementationuses  ChessPieces;{ TPieceTest }procedure TPieceTest.SetPositionTest;beginend;initialization  TestFramework.RegisterTest(TPieceTest.Suite);end.If you run that test, it will succeed since no checks are being performed within the SetPositionTest procedure. Each test is composed by one or more checks. I suggest adding the checks little by little. Every time you add a check, you should add business code to pass the corresponding test.Now, let’s make the test fail on purpose. For that, let’s add one check to the SetPositionTest procedure. procedure TPieceTest.SetPositionTest;begin  Check(True = False, '');end;True is never False. So, this test will fail. If it doesn’t fail, then something is wrong with you test harness. Fix it. You can remove this initial check once you run the test and it fails.Now, let’s add a real check to our test. Something like this:procedure TPieceTest.SetPositionTest;var  Piece: TPiece;begin  Piece:= TPiece.Create;  try    //Test trivial (normal) workflow    Check(Piece.SetPosition(4, 4) = True, '');  finally    Piece.Free;  end;end;If you run this test, you will get a compilation error! Yes, that’s right. You don’t have business code yet. You just have the test. This is what TDD is all about: test first, business code later. Get the point?To avoid the compilation error, we will code a separate unit (ChessPieces) and we will add it to the uses clause of our ChessPiecesTests unit. unit ChessPieces;interfacetype  TPiece = class  private  public    function SetPosition(aX, aY: Integer): Boolean;  end;implementation{ TPiece }function TPiece.SetPosition(aX, aY: Integer): Boolean;beginend;end.Run the test again and now the compilation error is gone. Nonetheless, the test fails, because the Piece.SetPosition(4, 4) evaluates to False. Let’s add the minimum business code possible to pass this test:function TPiece.SetPosition(aX, aY: Integer): Boolean;begin  Result:= True;end;This passes the test. What? Yes, this passes the test, right? OK, what now? Well, we keep adding new checks to the test and every time this happens, we need to add new business code in order to pass it. It is very important to add checks to test the boundaries of whatever we are trying to code. I think you are getting the point, so I will just add a bunch of checks at once:procedure TPieceTest.SetPositionTest;var  Piece: TPiece;begin  Piece:= TPiece.Create;  try    //Test trivial (normal) workflow    Check(Piece.SetPosition(4, 4) = True, '');    //Tests boundaries    Check(Piece.SetPosition(1, 1) = True, '');    Check(Piece.SetPosition(1, 8) = True, '');    Check(Piece.SetPosition(8, 1) = True, '');    Check(Piece.SetPosition(8, 8) = True, '');    //Test beyond the boundaries    Check(Piece.SetPosition(3, 15) = False, '');    Check(Piece.SetPosition(3, -15) = False, '');    Check(Piece.SetPosition(15, 3) = False, '');    Check(Piece.SetPosition(15, 15) = False, '');    Check(Piece.SetPosition(15, -15) = False, '');    Check(Piece.SetPosition(-15, 3) = False, '');    Check(Piece.SetPosition(-15, 15) = False, '');    Check(Piece.SetPosition(-15, -15) = False, '');  finally    Piece.Free;end;The test above is even checking for the attempts of positioning a piece outside the chess board.To pass that test let’s write some business code:function TPiece.SetPosition(aX, aY: Integer): Boolean;begin  Result:= True;  if (aY < 1) or (aY > 8) then Result:= False  else if (aX < 1) or (aX > 8) then Result:= False;end;Run the test and see how it passes. The code above could be refactored or even rewritten. The tests will remain the same, allowing us to catch any bugs introduced with the code change.For instance, we could write the procedure above as follows:function TPiece.SetPosition(aX, aY: Integer): Boolean;begin  Result:= (aX > 0) and           (aX < 9) and            (aY > 0) and           (aY < 9);end;Run the test, and it will tell you if this refactoring (or reimplementation) works ok. It’s important to note that a good test should cover all possible scenarios and workflows. Pay special attention to the boundaries. At this point, a good understanding of the requisites is indispensable. Finally, more and more tests will be needed in a real world application. Each test will have its own checks. Each test will cover one piece of the functionality: this is what unit testing is intended for.I wrote a second article about TDD, code refactoring and design patterns in Delphi (click here). I would appreciate any comments you could provide about it.For further reading I recommend you Test Driven Development: By Example by Kent Beck. Check it out just below:CodeProject
Read More