You raise a very important point. It is easy to write a scripted module that “works” and it is very tempting to stop there - and not spend time with implementing automatic tests, saving of module state to the scene, etc.
Developers are supposed to save all information that is necessary to recreate the current state of the module in nodes in the MRML scene. You can find some useful general information about this in the first part of PerkLab Scripted Module Development tutorial. This practice is strictly followed in all Slicer core modules, but since they are mostly implemented in C++ they are not useful examples for scripted module developers.
For scripted modules, we added vtkMRMLScriptedModuleNode, a generic MRML node to store data persistently in the scene. There is a getParameterNode
helper function in scripted module logic class to retrieve a parameter node. The parameter node can be chosen to be a singleton (one instance per scene) or a non-singleton node (in that case a isSingletonParameterNode
member has to be set to False in module logic and parameter node selector has to be added to the module widget). See VectorToScalarVolume module as an example of a scripted module with non-singleton parameter node.