Clarifying Python TDD Practices with pytest – Am I on the Right Track?
I’m trying to better understand Python TDD (Test-Driven Development) principles while building my project using pytest
.
So far, writing tests early has helped me reason about code behavior more pragmatically. However, in my current workflow, all functionality was written before the tests except for 3 class variables. Technically, does this mean I’m not really following TDD?
I’m particularly curious about a few things related to Python TDD:
- Should I be writing full tests for a method before implementing any of its logic?
- Is the goal to ensure all tests pass regardless of test data changes (as long as functionality remains intact)?
- Should the number of tests scale significantly with the complexity/size of the class?
I’ve included my current pytest-based test suite for reference (below).
Code for your reference
import pytest
import os
import sys
path = os.path.dirname(os.path.abspath(__file__))
path = path.replace("\\pytest", "")
sys.path.append(path)
path += "\\pyffi"
sys.path.append(path)
from NifExplorer import NifExplorer
from NifExplorer import NifFormat
@pytest.fixture(autouse=True, scope='session')
def setup_nifExplorer():
Explorers = []
explorer = NifExplorer()
explorer.SetBlockType(NifFormat.NiNode)
explorer.SetResultPath("\\pytest\\results")
explorer.SetSearchPath("\\pytest\\nif\\base")
explorer2 = NifExplorer()
explorer2.SetBlockType(NifFormat.ATextureRenderData)
explorer2.SetResultPath("\\pytest\\results")
explorer2.SetSearchPath("\\pytest\\nif\\base")
explorer3 = NifExplorer()
explorer3.SetBlockType("NiNode")
explorer3.SetResultPath("\\pytest\\testResults")
explorer3.SetSearchPath("\\pytest\\nif\\base")
Explorers.append(explorer)
Explorers.append(explorer2)
Explorers.append(explorer3)
return Explorers
@pytest.mark.usefixtures("setup_nifExplorer")
class TestNifExplorer:
def NifExlorer_BlockType_Is_Not_None(self, setup_nifExplorer):
assert setup_nifExplorer.BlockType != None
def NifExplorer_SearchPath_Is_Not_None(self, setup_nifExplorer):
assert setup_nifExplorer.SearchPath != None
def NifExplorer_ResultPath_Is_Not_None(self, setup_nifExlorer):
assert setup_nifExlorer.ResultPath != None
@pytest.mark.parametrize('funcs', (NifExplorer_SearchPath_Is_Not_None, NifExplorer_ResultPath_Is_Not_None, NifExlorer_BlockType_Is_Not_None))
def test_NifExplorer_Variables_Equal_Not_None(self, setup_nifExplorer, funcs):
for obj in setup_nifExplorer:
funcs(self,obj)
def NifExplorer_ResultPath_Directory_Exists(self, setup_nifExplorer):
assert os.path.exists(setup_nifExplorer.ResultPath) == True
def NifExplorer_SearchPath_Directory_Exists(self, setup_nifExplorer):
assert os.path.exists(setup_nifExplorer.SearchPath) == True
def NifExplorer_SearchPath_Directory_Contains_No_Forward_Slashes(self, setup_nifExplorer):
assert setup_nifExplorer.SearchPath.count('/') < 1
def NifExplorer_ResultPath_Directory_Contains_No_Forward_Slashes(self, setup_nifExplorer):
assert setup_nifExplorer.ResultPath.count('/') < 1
@pytest.mark.parametrize('funcs', [NifExplorer_ResultPath_Directory_Exists, NifExplorer_SearchPath_Directory_Exists, NifExplorer_SearchPath_Directory_Contains_No_Forward_Slashes, NifExplorer_ResultPath_Directory_Contains_No_Forward_Slashes])
def test_NifExplorer_Directories_Exist_And_Paths_Contain_No_Forward_Slashes(self, setup_nifExplorer, funcs):
for obj in setup_nifExplorer:
funcs(self,obj)
def NifExplorer_SearchPath_Contains_Nif_Files_Recursively(self, setup_nifExplorer):
assert setup_nifExplorer.DirectoryContainsNifRecursively(setup_nifExplorer.SearchPath) == True
@pytest.mark.parametrize('funcs', [NifExplorer_SearchPath_Contains_Nif_Files_Recursively])
def test_NifExplorer_SearchPath_Contains_Nif_Files(self, setup_nifExplorer, funcs):
for obj in setup_nifExplorer:
funcs(self,obj)
if __name__ == "__main__":
pytest.main()
Based on this, would you say I’m headed in the right direction with Python TDD, or am I misunderstanding something fundamental?
Would appreciate any feedback from those with more experience in this area!