使用单元测试进行继承的小助手
liskov的Python项目详细描述
用于检查子类型是否通过超类型测试的实用程序。
liskov替代在固体原理中是相关的。 它是由芭芭拉·利斯科夫和珍妮特·荣格制定的。 以便更准确地定义子类型的概念。
有关详细信息,请阅读:http://reports-archive.adm.cs.cmu.edu/anon/1999/CMU-CS-99-156.ps
为了确保在你的程序中尊重liskov替换原则, 您可以简单地使子类型测试扩展父类型测试,但是 直接在子类型文件中导入父类型测试 被单元测试运行程序识别并运行多次。
你可以把它导入一个函数,但不要每次都重复, 我做了一个小的util,wich提供了3种声明子类型测试的方法。
- 每个解决方案根据您的偏好提供不同的表现力:
- “subtype”函数,它只从作为字符串参数给定的模块中导入并返回类。
- “behave_as”元类生成器函数,从给定模块返回元类。
- “can_substitute”decorator wich返回作为参数给定的类扩展模块。
- Liskov和Wing分类的两大类子类型关系:
- 扩展子类型:向超类型添加方法或最终状态
- 约束子类型:当父类型启用子类型中的变体时
从0.2版开始,您可以找到一些帮助程序来定义约束(请参见示例4)
目录
安装
只需从pypi安装即可:
pip install liskov
或来源:
git clone git@github.com:apieum/liskov.git cd liskov python setup.py install
用法
示例1-“子类型”:
Use a lambda if too long.
fromliskovimportsubtypeBasicCalc=lambda:subtype('testCalc.BasicCalcTest')BaseConverter=lambda:subtype('testConvert.BaseConverterTest')classScientificCalcTest(BasicCalc(),BaseConverter()):deftest_it_is_a_subtype_of_BasicCalc(self):fromtestCalcimportBasicCalcTestassertisinstance(self,BasicCalcTest)deftest_it_is_a_subtype_of_BaseConverter(self):fromtestConvertimportBaseConverterTestassertisinstance(self,BaseConverterTest)
例2-“表现为”:
python 2版本
fromliskovimportbehave_asclassScientificCalcTest(object):__metaclass__=behave_as('testCalc.BasicCalcTest','testConvert.BaseConverterTest')deftest_it_is_a_subtype_of_BasicCalc(self):fromtestCalcimportBasicCalcTestassertisinstance(self,BasicCalcTest)deftest_it_is_a_subtype_of_BaseConverter(self):fromtestConvertimportBaseConverterTestassertisinstance(self,BaseConverterTest)
python 3版本
fromliskovimportbehave_asmetaclass=behave_as('testCalc.BasicCalcTest','testConvert.BaseConverterTest')classScientificCalcTest(object,metaclass=metaclass):deftest_it_is_a_subtype_of_BasicCalc(self):fromtestCalcimportBasicCalcTestassertisinstance(self,BasicCalcTest)deftest_it_is_a_subtype_of_BaseConverter(self):fromtestConvertimportBaseConverterTestassertisinstance(self,BaseConverterTest)
示例3-“Can_Substitute”:
fromliskovimportcan_substitute@can_substitute('testCalc.BasicCalcTest','testConvert.BaseConverterTest')classScientificCalcTest(object):deftest_it_is_a_subtype_of_BasicCalc(self):fromtestCalcimportBasicCalcTestassertisinstance(self,BasicCalcTest)deftest_it_is_a_subtype_of_BaseConverter(self):fromtestConvertimportBaseConverterTestassertisinstance(self,BaseConverterTest)
示例4-约束:
此示例遵循liskov和wing约束的子类型大象层次示例 从“使用不变量和约束的行为子类型”(以上链接)
大象可以是白色、绿色或蓝色 皇家象总是蓝色的 白化病患者总是白色的
象形文字中的每一个大象实例都是用“新象形文字”制作的 象形文字测试大象是白色、绿色还是蓝色。
使用decorator声明约束
使用元类声明约束 python 2版本 python 3版本fromliskovimportcan_substitute,under_constraintimportelephant@can_substitute('elephant.ElephantTest')@under_constraint('test_it_can_be_grey','test_it_can_be_white')classRoyalElephantTest(object):defnew_elephant(self,*args):returnelephant.RoyalElephant()
fromliskovimportbehave_asimportelephantclassRoyalElephantTest(object):__metaclass__=behave_as('elephant.ElephantTest').except_for('test_it_can_be_grey','test_it_can_be_white')defnew_elephant(self,*args):returnelephant.RoyalElephant()
fromliskovimportbehave_asimportelephantmetaclass=behave_as('elephant.ElephantTest').except_for('test_it_can_be_grey','test_it_can_be_white')classRoyalElephantTest(object,metaclass=metaclass):defnew_elephant(self,*args):returnelephant.RoyalElephant()
fromliskovimportsubtype,constrainimportelephantConstrainedElephantTest=lambda:subtype('elephant.ElephantTest')&constrain('test_it_can_be_grey','test_it_can_be_white')classRoyalElephantTest(ConstrainedElephantTest()):defnew_elephant(self,*args):returnelephant.RoyalElephant()
开发
自由地给予反馈或改进。
启动测试:
git clone git@github.com:apieum/liskov.git cd liskov nosetests --with-spec --spec-color