0% found this document useful (0 votes)
8 views3 pages

AutoCAD Custom Command Testing Guide With Blue Code

The document provides a guide for creating unit tests for AutoCAD custom commands using AcCoreConsole and various programming languages, including C++ and Python. It includes code samples for command wrappers, unit tests with GoogleTest, validation scripts in AutoLISP, CI assertions in PowerShell, and a C# NUnitLite test harness. Additionally, it features a Python script for comparing DXF files, highlighting the importance of automated testing in AutoCAD development.

Uploaded by

Er vipin Sharma
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views3 pages

AutoCAD Custom Command Testing Guide With Blue Code

The document provides a guide for creating unit tests for AutoCAD custom commands using AcCoreConsole and various programming languages, including C++ and Python. It includes code samples for command wrappers, unit tests with GoogleTest, validation scripts in AutoLISP, CI assertions in PowerShell, and a C# NUnitLite test harness. Additionally, it features a Python script for comparing DXF files, highlighting the importance of automated testing in AutoCAD development.

Uploaded by

Er vipin Sharma
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Creating Unit Tests for AutoCAD Custom Commands

(ObjectARX/CRX) with AcCoreConsole — with Blue Code


Formatting
This edition highlights all code blocks in blue for improved readability.

Sample: C++ ObjectARX/CRX Command Wrapper (Skeleton)


// core_logic.h
struct Placement { double x, y; };
std::vector<Placement> ComputePlacements(const std::vector<int>& partIds);

// [Link]
#include "core_logic.h"
#include "aced.h"
#include "dbents.h"
#include <vector>

static void myCommand()


{
std::vector<int> parts = {101, 102, 103};
auto placements = ComputePlacements(parts);

AcDbBlockTable* pBT; AcDbBlockTableRecord* pBTR;


acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBT, AcDb::kForRead);
pBT->getAt(ACDB_MODEL_SPACE, pBTR, AcDb::kForWrite); pBT->close();

for (auto& pl : placements) {


AcDbCircle* c = new AcDbCircle(AcGePoint3d(pl.x, pl.y, 0.0), AcGeVector3d::kZAxis, 10.0);
AcDbObjectId id; pBTR->appendAcDbEntity(id, c); c->close();
}
pBTR->close();
}

extern "C" AcRx::AppRetCode acrxEntryPoint(AcRx::AppMsgCode msg, void* pkt)


{
if (msg == AcRx::kInitAppMsg) {
acrxUnlockApplication(pkt); acrxRegisterAppMDIAware(pkt);
acedRegCmds->addCommand("MY_CMDS","MYCOMMAND","MYCOMMAND",ACRX_CMD_DEFAULT,&myCommand);
}
else if (msg == AcRx::kUnloadAppMsg) {
acedRegCmds->removeGroup("MY_CMDS");
}
return AcRx::kRetOK;
}

Sample: Native Unit Test of Pure C++ Logic (GoogleTest)


#include <gtest/gtest.h>
#include "core_logic.h"

TEST(ComputePlacementsTests, ReturnsThreePlacements)
{
std::vector<int> parts{101,102,103};
auto out = ComputePlacements(parts);
ASSERT_EQ(3u, [Link]());
EXPECT_DOUBLE_EQ(0.0, out[0].x);
}

Run the Command Headlessly with AcCoreConsole (.scr + cmd)


;; tests/scripts/[Link]
(arxload "D:/cad/[Link]")
MYCOMMAND
_.QSAVE
_.QUIT
"C:\Program Files\Autodesk\AutoCAD 2026\[Link]" ^
/i "D:\cad\tests\input\[Link]" ^
/s "D:\cad\tests\scripts\[Link]" ^
/l en-US ^
/isolate

Validation: AutoLISP Checker (prints verifiable output)


;; tests/scripts/[Link]
(defun c:CHECK ()
(princ (strcat "\nLAYER_EXISTS=" (if (tblsearch "LAYER" "ResultLayer") "YES" "NO")))
(princ (strcat "\nBLOCK_COUNT=" (itoa (length (ssget "_X" '((2 . "ResultBlock")))))))
(princ))
;; tests/scripts/[Link]
(load "D:/cad/tests/scripts/[Link]")
CHECK
_.QUIT

CI Assertion (PowerShell)
$acc = "C:\Program Files\Autodesk\AutoCAD 2026\[Link]"
& $acc /i "D:\cad\tests\input\[Link]" /s "D:\cad\tests\scripts\[Link]" /isolate |
Tee-Object -FilePath "D:\cad\tests\logs\[Link]"

$log = Get-Content "D:\cad\tests\logs\[Link]" -Raw


if ($log -match "LAYER_EXISTS=YES" -and $log -match "BLOCK_COUNT=3") { exit 0 } else { exit 1 }

Optional: NUnitLite Test Harness Inside Core Console (C#)


using [Link];
using [Link];
using [Link]; using NUnitLite;

[TestFixture]
public class DwgTests {
[Test]
public void LayerExists() {
var db = [Link];
using (var tr = [Link]()) {
var lt = (LayerTable)[Link]([Link], [Link]);
[Link]([Link]("ResultLayer"), "ResultLayer missing");
[Link]();
}
}
}

public class Program {


[CommandMethod("RUNCADTESTS")]
public static void Run() => new AutoRun().Execute(new string[]{});
}

DXF Comparison (Python + ezdxf) — Example


import ezdxf
import sys

def snapshot(doc):
layers = set([Link]())
blocks = set([[Link] for b in [Link] if not [Link]("*")])
return {"layers": layers, "blocks": blocks}

def main(a, b):


d1 = [Link](a); d2 = [Link](b)
s1, s2 = snapshot(d1), snapshot(d2)
print("Layers only in A:", sorted(s1["layers"] - s2["layers"]))
print("Layers only in B:", sorted(s2["layers"] - s1["layers"]))
print("Blocks only in A:", sorted(s1["blocks"] - s2["blocks"]))
print("Blocks only in B:", sorted(s2["blocks"] - s1["blocks"]))

if __name__ == "__main__":
main([Link][1], [Link][2])

You might also like