Author Topic: TDD for Bricscad examples  (Read 9954 times)

0 Members and 1 Guest are viewing this topic.

MickD

  • King Gator
  • Posts: 3636
  • (x-in)->[process]->(y-out) ... simples!
Re: TDD for Bricscad examples
« Reply #15 on: August 05, 2014, 12:13:26 AM »
Hi Kerry,
the problem isn't really with Gallio, it's with the Gallio extension for testing AutoCAD. It is written only for AutoCAD and thus doesn't work with Bricscad as the AutoCAD lib's are tied to the build.
Getting it running is easy on AutoCAD once the bat file is set up.

I have a few more things to try with the Bricscad extension before I give up altogether.
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

CADbloke

  • Bull Frog
  • Posts: 342
  • Crash Test Dummy
Re: TDD for Bricscad examples
« Reply #16 on: August 05, 2014, 06:07:26 PM »
Just a thought and not necessarily an good one ... is running tests inside AutoCAD / Bricscad is more like integration testing than unit testing? Perhaps is is more like behavio(u)ral testing too? ie. Do you want to test the result of the operation rather than the units of the operation? This is still testing and therefore valid but what I am trying to say (badly) is that the approach should be driven by what you are actually testing so there is probably a need for different types of tests for the same code.

Related to this - has anyone tried a Coded UI test in AutoCAD / Bricscad?

Hey, it's 8am and I've only just finished my first coffee.  :-P

MickD

  • King Gator
  • Posts: 3636
  • (x-in)->[process]->(y-out) ... simples!
Re: TDD for Bricscad examples
« Reply #17 on: August 05, 2014, 07:48:30 PM »
Just a thought and not necessarily an good one ... is running tests inside AutoCAD / Bricscad is more like integration testing than unit testing? ....

Yes, you are right there and that was the reason for using the mocks to isolate the actual implementation code. We should be able to write the implementation for out tests and mock them out as needed to make the tests pass and confirm our design/behaviour.

I think TDD includes all types of testing and integration testing is just as important as unit testing, it's just another hurdle I want to hobble over before I get too far along the process and testing against the cad api is the hardest.

I've made a bit of progress though, I've actually embedded the tests in the class library (these could be loaded separately of course) and it works fine, I just need to re-route the test output to a file or the command line somehow.

This code works fine and wouldn't be hard to automate the calls to each test from one command. You can see I'm not using mocks and it places the circle and then no circle but I have no feedback to whether it is a pass or fail.
Code - C#: [Select]
  1. namespace CadEngine
  2. {
  3.     [TestFixture]
  4.    
  5.     class CadEngineDrawingTests
  6.     {
  7.         [CommandMethod("Test1")]
  8.         public void AddObject_ToDrawing_ReturnsNonEmptyString()
  9.         {
  10.             var drawingObject = new MyCircle(50);
  11.  
  12.             // create our Drawing object passing in the mock dependency:
  13.             var cadEngine = new CadEngine();
  14.             var drawing = new Drawing(cadEngine);
  15.  
  16.             string objectId = drawing.AddObject(drawingObject);
  17.  
  18.             Assert.AreNotEqual(String.Empty, objectId);
  19.         }
  20.  
  21.  
  22.         [Test]
  23.         [CommandMethod("Test2")]
  24.         public void AddObject_ToDrawing_ReturnsEmptyString()
  25.         {
  26.             // no need to implement the mock return as it shouldn't reach the call:
  27.             var cadEngine = new CadEngine();
  28.             var drawing = new Drawing(cadEngine);
  29.  
  30.             // just pass in a null object, no need to 'null' anything to get the same result:
  31.             string objectId = drawing.AddObject(null);
  32.  
  33.             Assert.AreEqual(String.Empty, objectId);
  34.         }
  35.     }
  36.  
  37.     /****** Class implementations for testing *********/
  38.     public class Drawing : IDrawing
  39.     {
  40.         private ICadEngine _cadEngine;
  41.  
  42.         public Drawing(ICadEngine cadEngine)
  43.         {
  44.             _cadEngine = cadEngine;
  45.         }
  46.  
  47.         public string AddObject(IDrawingObject drawingObject)
  48.         {
  49.             if (drawingObject != null)
  50.                 return _cadEngine.AddObjectToDB(drawingObject);
  51.             else
  52.                 return String.Empty;
  53.         }
  54.     }
  55. }
  56.  

<edit> I think I might just write my own assertions and be done with it, they aren't that complicated really and can be more finely tuned to the cad api</edit.
« Last Edit: August 05, 2014, 07:55:45 PM by MickD »
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

MickD

  • King Gator
  • Posts: 3636
  • (x-in)->[process]->(y-out) ... simples!
Re: TDD for Bricscad examples
« Reply #18 on: August 05, 2014, 08:50:11 PM »
I've written a basic assert class as proof of concept, seems to work ok :)

Code - C#: [Select]
  1.     public class Assert
  2.     {
  3.         private static string GetCaller()
  4.         {
  5.             // this stack trace may have performance penalties later, it's a hack for now:
  6.             System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace();
  7.             int caller = 2;
  8.             System.Diagnostics.StackFrame frame = trace.GetFrame(caller);
  9.             return frame.GetMethod().Name;
  10.         }
  11.  
  12.         public static void AreEqual(string testValue, string returnedValue)
  13.         {
  14.             // if string is empty, format it so we can see:
  15.             if (testValue == String.Empty) testValue = "\"\"";
  16.             if (returnedValue == String.Empty) returnedValue = "\"\"";
  17.  
  18.             if (testValue != returnedValue)
  19.             {
  20.                 _AcAp.Application.DocumentManager
  21.                     .MdiActiveDocument
  22.                     .Editor
  23.                     .WriteMessage(GetCaller() + " passed");
  24.             }
  25.             else
  26.             {
  27.                 _AcAp.Application.DocumentManager
  28.                     .MdiActiveDocument
  29.                     .Editor
  30.                     .WriteMessage(GetCaller() + " FAILED: Expected "
  31.                     + testValue + " - actual result: " + returnedValue);
  32.             }
  33.         }
  34.  
  35.         public static void AreNotEqual(string testValue, string returnedValue)
  36.         {
  37.             // if string is empty, format it so we can see:
  38.             if (testValue == String.Empty) testValue = "\"\"";
  39.             if (returnedValue == String.Empty) returnedValue = "\"\"";
  40.  
  41.             if (testValue == returnedValue)
  42.             {
  43.                 _AcAp.Application.DocumentManager
  44.                     .MdiActiveDocument
  45.                     .Editor
  46.                     .WriteMessage(GetCaller() + " passed");
  47.             }
  48.             else
  49.             {
  50.                 _AcAp.Application.DocumentManager
  51.                     .MdiActiveDocument
  52.                     .Editor
  53.                     .WriteMessage(GetCaller() + " FAILED: Expected "
  54.                     + testValue + " - actual result: " + returnedValue);
  55.             }
  56.         }
  57.     }
  58.  

I added a 3rd test to fail on purpose that expected an empty string to see the output was correct.
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

JohnK

  • Administrator
  • Seagull
  • Posts: 10627
Re: TDD for Bricscad examples
« Reply #19 on: August 05, 2014, 09:37:54 PM »
Just stopping in to say that this subject has lead me down a rabbit hole. I need to get back to my reading so I can write up some of my ideas. …great thread Mick.
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: TDD for Bricscad examples
« Reply #20 on: August 05, 2014, 09:48:45 PM »
Just stopping in to say that this subject has lead me down a rabbit hole. I need to get back to my reading so I can write up some of my ideas. …great thread Mick.

Yes John, I've had to stop reading the thread (other than casual perusal) .. I was getting sucked in too.

This IS a great thread Mick !  ... I hope to catch up with it after I've slain a few dragons.
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

MickD

  • King Gator
  • Posts: 3636
  • (x-in)->[process]->(y-out) ... simples!
Re: TDD for Bricscad examples
« Reply #21 on: August 05, 2014, 09:50:37 PM »
Glad you like it, just hope it's helping and not confusing the issue too much :)

I am tidying up the whole working solution and will put it on github later today/tonight, got a bit of real work to do this afternoon.
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: TDD for Bricscad examples
« Reply #22 on: August 05, 2014, 09:56:59 PM »
Just for interest,
Have you tried UnitTests in Resharper inside Visual Studio Mick ?
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

MickD

  • King Gator
  • Posts: 3636
  • (x-in)->[process]->(y-out) ... simples!
Re: TDD for Bricscad examples
« Reply #23 on: August 05, 2014, 10:13:17 PM »
Just for interest,
Have you tried UnitTests in Resharper inside Visual Studio Mick ?

I have but I'm not going to fork out 150 clams for it, it is great for refactoring but I also found it annoying (worse than VS) with the contextual help popups etc when you don't really want them.
Running the NUnit gui is easy and I just have it to the side of VS in the other window.
If you need any help setting it up I'll post up a quick tut but you basically just 'Open Project' from the NUnit gui menu and load the test assembly and hit run, of course this doesn't work within the cad system hence the above posts.
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

Keith Brown

  • Swamp Rat
  • Posts: 601
Re: TDD for Bricscad examples
« Reply #24 on: August 06, 2014, 08:07:35 AM »
As someone who is very new to Unit Testing (i.e. I had to read up on it to know what it means) I wonder if someone could post a very simple VS solution that has a small AutoCAD project and a unit testing project as an example?  I read the code excerpts in this thread and now I feel as if my IQ has dropped about 20 pts because I am completely lost.  Thanks in advance.
Keith Brown | AutoCAD MEP Blog | RSS Feed
AutoCAD MEP 2014 / Revit MEP 2014 / EastCoast CAD/CAM addon / Visual Studio 2013

MickD

  • King Gator
  • Posts: 3636
  • (x-in)->[process]->(y-out) ... simples!
Re: TDD for Bricscad examples
« Reply #25 on: August 06, 2014, 06:35:59 PM »
No prob's Keith, I'll clean this one up and post it a bit later.

Here's a link to Roy Osherove's vid's, the first one's a bit slow getting going but all are well worth the watch. Try to do some coding and then watch again :)

http://artofunittesting.com/

"Understanding Test Driven Development" is the first one to watch and a few others from that talk are also on that page, should be enough to get started with. As mentioned before, anything from 'Uncle Bob' on SOLID development will help as well when it comes to design problems.

« Last Edit: August 06, 2014, 06:49:10 PM by MickD »
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

MickD

  • King Gator
  • Posts: 3636
  • (x-in)->[process]->(y-out) ... simples!
Re: TDD for Bricscad examples
« Reply #26 on: August 06, 2014, 07:58:02 PM »
Here's a VS2010 solution as it stands today, it is using Bricscad v14 lib's but you should be able to switch them out for AutoCAD with little work.

Tools required:
NuGet package manager should be installed in VS to manage the Nunit and Moq packages, this is a lot easier than loading all the requirements manually.
NUnit - download and install, I run it in the 'mini' setup which hides the output progress and messages, you can find the output by right clicking on the test to see any errors etc.

To run the tests in NUnit, start NUnit and go 'Open Project' and browse to the bin folder and select the dll with <ProjectName>.Tests.dll and you should be able to see and run the tests.
Repeat for the other test project/s.

<edit> Another confusing aspect of testing is 'how do you debug?', it can be done but really, the process of testing and running tests takes you straight to the problem if it fails anyway, you shouldn't need to debug at all, if you do your tests (or implementation code) have too much logic, another "code smell" if you like</edit>
« Last Edit: August 06, 2014, 08:06:59 PM by MickD »
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

Keith Brown

  • Swamp Rat
  • Posts: 601
Re: TDD for Bricscad examples
« Reply #27 on: August 07, 2014, 09:35:54 AM »
MickD,


Thank you very much for the links and the test project.  I will have some time in the next few weeks to consume this information and hopefully will have a much better understanding of how it all works.  My end goal is of course being able to write good tests but also better understand the process of separating the business layer from the data layer of the software.  And in the long run be able to write more reusable code.  It seems i am constantly coding the same things over and over again with new bugs every time i code it.
Keith Brown | AutoCAD MEP Blog | RSS Feed
AutoCAD MEP 2014 / Revit MEP 2014 / EastCoast CAD/CAM addon / Visual Studio 2013

MickD

  • King Gator
  • Posts: 3636
  • (x-in)->[process]->(y-out) ... simples!
Re: TDD for Bricscad examples
« Reply #28 on: August 07, 2014, 06:01:15 PM »
No problems Keith, it's not easy (else everyone would be doing it  :-P ) but well worth the effort. I was a doubter until I kept seeing it pop up and read/watched a few talks for it to sink in, actually doing some coding really helps it hit home.

Just by writing the test first forces you to design and code better as a happy side effect and Interfaces (IoC) are the key. Even if you only watch/read one good talk on SOLID code and it's a bit daunting, start writing tests then the SOLID principles start to make sense as well.
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

Jeff H

  • Needs a day job
  • Posts: 6150
Re: TDD for Bricscad examples
« Reply #29 on: August 07, 2014, 06:50:31 PM »
Hey Mick,

Did you ever have moment where you were thinking TDD seems like it is not useful then you looked at project and realized Holy Sh*t I have almost a complete working code base for project and I did not spend hours(while driving, at night, etc..) thinking about what classes to create, abstractions, how each object will talk with one another, etc..... it just happened?