views:

555

answers:

2

Hi,

We are developing applications for use within AutoCAD. Basically we create a Class Library Project, and load the .dll in autoCAD with a command (NETLOAD).

As so, we can use commands, "palettes", user controls, forms etc...

AutoDesk provides an API through some dll's, running in their program directory. When referencing these dll's you can only call the dll's at runtime while loading your app in AutoCAD (This is a licensing security from AutoDesk).

For us, while developing, this is not a problem, we need to visually test within the context of AutoCAD, so we just set the Debug Properties so that they start acad.exe and load our dll with a script in the acad.exe parameters.

The problem is, when trying to unit test our code, NUnit or mstest are not running from within the AutoCAD context and they also cannot start it. There exist a tool called Gallio, wich has provided an interface with AutoCAD, so that it can run Unit test through IPC with Named Pipes.

However, this solution is, for me, too much of a hassle. I want to be able to quickly write tests without having to leave my beloved IDE.

So, what, from a "good design view" would be a good approach to this problem? I'm thinking I would basically need a testable codebase wich is not referencing the AutoCAD dll's and a non-testable that does references the untestable AutoCAD dll's.

I'm sure there are ways to get this to work: ( IOC, DI, Adapter Pattern, ...) I just don't these principles in depth and thus I don't know wich route will best suit my purposes and goals.

Any guidance would be very much appreciated!

+4  A: 

The first step is to triage your code for parts which need AutoCAD and parts which are really independent. Create unit tests for the independent parts as you usually would.

For the other parts, you need mockups which behave like AutoCAD. Make them as simple as possible (for example, just return the correct answers in the methods without doing any calculations). Now, you need several sets of classes:

  1. A set of interfaces which your code uses to achieve something (for example, load a drawing).

  2. A set of implementations for said set of interfaces which call the AutoCAD dlls.

  3. A set of classes which try the implementations within the context of AutoCAD. Just create a small UI with a couple of buttons where you can run this code. It is used to reassure yourself that your mockups do the right thing. Log method parameters and results to some file so you can try how AutoCAD responds. If a mockup breaks, you can use this code to verify what AutoCAD is doing and you can use it as a reference when developing the mockups.

  4. When you know how AutoCAD responds, create the mockups. In your tests, create them with the desired results (and errors, so you can test error handling, too). So when you have boolean loadDrawing(File filename), create a mockup which returns true for the filename exists.dxf and false for anything else.

  5. Use a factory or DI to tell your application code which implementation to use. I tend to have a big global config class with a lot of public fields where I simply store the objects to use. I can set this up in the beginning, it's fast, it's easy to understand. If you need to create objects at runtime, then put factories in the config class which generate the objects for you, so you can swap them out.

Aaron Digulla
Thanks for your answer. I'll look into that direction. I do have a problem with your 3d remark: Since we are not simply opening a file but using transactions, editing objects etc... Should I create a wrapper for each Acad object then?
Bertvan
@Bertvan: Find the answer to this question: How sure are you that your code will break for each ACad object? If you are unsure, write a test. When it gets boring, stop. When you find new bugs and become unsure again, add more tests. You must find *your* best path.
Aaron Digulla
A: 

thirdparty exe should run under my panel in asp.net

so please provide the code has soon posible

karthikeyan
-1:1. I'm asking for AutoCAD, not asp.net 2. Question has been answered correctly
Bertvan