Usually “TDD” is short for “Test Driven Development”, which is a method that some people use for developing code where you write the tests before you write the actual code that implements what you want to have happen. There are tons of books and articles about this. Here’s a random one from the web that will give you the idea of how to do it in Python.
You don’t have to use TDD to get well-tested code, though I have tried it and it can be kind of fun. A less extreme way is to write “unit tests” right after writing your code. These are programmed tests that call small parts of your program and test that the results are as expected. Python distributions include the unittest module, which makes it easy to write and run unit tests.
Modern development in software companies typically requires or strongly encourages developers to write unit tests for their code. This is certainly true of Google, where I work. So I would encourage Blender developers to do so too. In my current personal project for Blender (Vector file import) I have been writing unit tests as I go along.
Not that this will mean much without context of what my functions are doing, but just to give you proof that I do do this, here is part of the test file for the triangulator/quadrangulator:
"""This module tests the triangulate family of functions provided by triquad.py"""
import unittest
import math
import vec
from vec import geom
from vec import triquad
from vec import showfaces
Show = True # set True if want to see display of triangulations
# Some test data sets
# Points in pattern:
# 4 3
#
#
# 2
# 0 1
Vs1 = geom.Points([(0.0,0.0),
(1.0,0.0),
(0.5,0.25),
(1.0,1.0),
(0.0,1.0)])
F1tri = [0,1,2]
F1square = [0,1,3,4]
F1concave = [0,2,1,3,4]
F1crosses = [0,1,4,3]
# Points in pattern
# 0 1
# 2 3 4 5
# 6 7
# 8 9 10 11
# 12 13 14 15
Vs2 = geom.Points([(0.0,1.0), (1.75,1.0),
(0.25,0.75), (0.5,0.75), (1.25,0.75), (1.5,0.75),
(0.75,0.5), (1.0,0.5),
(0.25,0.25), (0.5,0.25), (1.25,0.25), (1.5,0.25),
(0.0,0.0), (0.75,0.0), (1.0,0.0), (1.75,0.0)])
F2outer = [0,12,13,6,7,14,15,1]
F2hole1 = [2,3,9,8]
F2hole2 = [5,11,10,4]
# 16 points in circle
Vs3 = geom.Points([(1.00000,0.0),
(0.923880,0.382683),
(0.707107,0.707107),
(0.382683,0.923880),
(2.67949e-8,1.000000),
(-0.382683,0.923880),
(-0.707107,0.707107),
(-0.923880,0.382683),
(-1.000000,5.35898e-8),
(-0.923880,-0.382683),
(-0.707107,-0.707107),
(-0.382684,-0.923880),
(-8.03847e-8,-1.000000),
(0.382683,-0.923880),
(0.707107,-0.707107),
(0.923879,-0.382684)])
F3circle = list(range(0,16))
# Points for lowercase Arial m
Vsm =geom.Points([(0.131836,0.0),
(0.307617,0.0),
(0.307617,0.538086),
(0.335938,0.754883),
(0.427246,0.869141),
(0.564453,0.908203),
(0.705078,0.849609),
(0.748047,0.673828),
(0.748047,0.0),
(0.923828,0.0),
(0.923828,0.602539),
(0.996094,0.835449),
(1.17773,0.908203),
(1.28320,0.879883),
(1.34521,0.805176),
(1.36230,0.653320),
(1.36230,0.0),
(1.53711,0.0),
(1.53711,0.711914),
(1.45410,0.975098),
(1.21680,1.06055),
(0.896484,0.878906),
(0.792480,1.01270),
(0.603516,1.06055),
(0.418945,1.01416),
(0.289063,0.891602),
(0.289063,1.03711),
(0.131836,1.03711)])
Fsm = list(range(0,28))
class TestTriangulateFace(unittest.TestCase):
def testTriangle(self):
ans = triquad.TriangulateFace(F1tri, Vs1)
if Show:
showfaces.ShowFaces(ans, Vs1, "F1tri - tri")
self.assertEqual(ans, [tuple(F1tri)])
def testSquare(self):
ans = triquad.TriangulateFace(F1square, Vs1)
if Show:
showfaces.ShowFaces(ans, Vs1, "F1square - tri")
self.assertEqual(len(ans), 2)
def testCircle(self):
ans = triquad.TriangulateFace(F3circle, Vs3)
if Show:
showfaces.ShowFaces(ans, Vs3, "F3circle - tri")
self.assertEqual(len(ans), 14)
def testM(self):
ans = triquad.TriangulateFace(Fsm, Vsm)
if Show:
showfaces.ShowFaces(ans, Vsm, "Fsm - tri")
self.assertEqual(len(ans), 26)
def testHoles(self):
ans = triquad.TriangulateFaceWithHoles(F2outer, [F2hole1, F2hole2], Vs2)
if Show:
showfaces.ShowFaces(ans, Vs2, "F2 - tri")
class TestQuadrangulateFace(unittest.TestCase):
def testTriangle(self):
ans = triquad.QuadrangulateFace(F1tri, Vs1)
if Show:
showfaces.ShowFaces(ans, Vs1, "F1tri - quad")
self.assertEqual(ans, [tuple(F1tri)])
def testSquare(self):
ans = triquad.QuadrangulateFace(F1square, Vs1)
if Show:
showfaces.ShowFaces(ans, Vs1, "F1square - quad")
self.assertEqual(len(ans), 1)
def testCircle(self):
ans = triquad.QuadrangulateFace(F3circle, Vs3)
if Show:
showfaces.ShowFaces(ans, Vs3, "F3circle - quad")
self.assertEqual(len(ans), 9)
def testM(self):
ans = triquad.QuadrangulateFace(Fsm, Vsm)
if Show:
showfaces.ShowFaces(ans, Vsm, "Fsm - quad")
self.assertEqual(len(ans), 14)
def testHoles(self):
ans = triquad.QuadrangulateFaceWithHoles(F2outer, [F2hole1, F2hole2], Vs2)
if Show:
showfaces.ShowFaces(ans, Vs2, "F2 - quad")
class TestAngle(unittest.TestCase):
def testAngle1(self):
ans = triquad.Angle(0, 1, 3, Vs1)
self.assertAlmostEqual(ans, 90.0)
def testAngle2(self):
ans = triquad.Angle(3, 1, 0, Vs1)
self.assertAlmostEqual(ans, 90.0)
def testAngle3(self):
ans = triquad.Angle(0, 2, 1, Vs1)
self.assertAlmostEqual(ans, 126.86989764584402)