Test Development Design (TDD) in Blender/python?

Hey Scripters,

At present, I am sacrificing my spare time in building my website. As you know there is a lot of php involved and not python but bare with me. I recently redid my whole site code as I was still coding procedurally. Now, using classes and objects, I recently discovered you should, when writing a class (or unit), test it before you use, or test it before you even wrote for that matter. We call this test development design. I have a couple of questions regarding this latter fact:

  • Is this TDD indeed the proper way of coding classes/Units
  • If yes, it is the proper way, why then have I never seen it being used in python or blender
  • are there other big things I should know as a noob to prevent me from having to re-write the whole class system every time I discover something majorly new and important?
  • Does anyone have any idea of where to find nice examples of this TDD in use for building websites (or tuts)

Hope someone can guide me through this.

kindest regards

Hewi

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)

Hey Howardt,

Thank you very much for this comprehensive reply. I had serious big time trouble to get through your example and understand a bit how it is all working. Your input has left me with only two more questions:

  • Is this Test Driven Development indeed the ‘final milestone’ a noob programmer has to adress in order to be a good coder, or are there other ‘Major’ things to be taken into account.

  • Does anyone have any idea of where to find nice examples of this TDD in use for building websites (or tuts) or even just to start coding from scratch for noobs using TDD

thanks for the time

kindest regards

Hewi

No, I wouldn’t say that, for two reasons:

  1. Test Driven Development is just one way that some good coders use to develop. But it is not really a ‘mainstream’ way, and most good coders use a ‘code first, then test’ style of development. Note here: I’m talking about ‘Test Driven Development’, meaning the ‘write tests first, then only write the minimal amount of code to make the test pass’ method. Many more (I hope most) good developers write automated tests for their code.
  2. There are many milestones to becoming a good coder, and the ‘final’ one is whatever one you haven’t done yet. Besides testing, some things to be mastered: algorithms, data structures, ‘good design’, refactoring, and writing readable and maintainable code.
  • Does anyone have any idea of where to find nice examples of this TDD in use for building websites (or tuts) or even just to start coding from scratch for noobs using TDD

I don’t know of any offhand, but I did a web search (which you could do too) and found this, for example.
http://www.lastcraft.com/first_test_tutorial.php

Hey Howardt,

“The last milestone to corner is the one you haven’t done yet”; very,very nicely put and absolutely true.

I did indeed Google’d this issue long before I actually posed the question (submitted this thread) and as there are many nice sole standing examples of tests, there is not, unfortunately, a nice complete summary of how actually to build a site from scratch and implement the Simpletest library. That’s what I am looking for, of course. Maybe a good idea for a nice tut … (on my todo list).

Other Scripters

For those who are also interested in this Simpletest library and implementation of it, I listed some of the documents I like to work with most, especially the http://www.simpletest.org/api/ is very comprehensive.

the others:

http://www.simpletest.org/api/
http://www.simpletest.org/en/first_test_tutorial.html
http://www.lastcraft.com/
http://www.lastcraft.com/first_test_tutorial.php
http://www.phpeveryday.com/articles/Simple-Test-Testing-Your-Code-Part-1--P56.html

http://www.youtube.com/watch?v=jdY0cEFHmws == Basic TDD in PHP Demo, 1 of 3 by cruizerph

kindest regards

Hewi