Package: tddflow
tddflowinstallation|usageA finger exercise for Python.  Following:beautiful is better then ugly (Tim Peters)easy things should be easy, and hard things possible (Larry Wall)The more often a message with the same content is received the less
information it contains (Claude Shannon)Design for the common caseDon't Repeat YourselfKeep It Simple Stupidthe basic example of python's unittest module...importunittestclassTestStringMethods(unittest.TestCase):deftest_upper(self):self.assertEqual('foo'.upper(),'FOO')deftest_isupper(self):self.assertTrue('FOO'.isupper())self.assertFalse('Foo'.isupper())deftest_split(self):s='hello world'self.assertEqual(s.split(),['hello','world'])# check that s.split fails when the separator is not a stringwithself.assertRaises(TypeError):s.split(2)if__name__=='__main__':unittest.main()... could become:fromtddflowimportrun,TclassAString:defcan_be_capitalized(self,t:T):t.equal('foo'.upper(),'FOO')def_a_helper_function(self):passdefcan_determine_if_it_is_upper_case(self,t:T):t.truthy('FOO'.isupper())t.falsy('Foo'.isupper())defcan_be_split_into_a_list_of_strings_at_spaces(self,t:T):s='hello world't.equal(s.split(),['hello','world'])defsplit_fails_if_a_given_separator_is_not_a_string(self,t:T):t.raises(lambda:s.split(2),TypeError)if__name__=='__main__':run(AString)Not repeating eight times the word 'test' or four times the word
'assert'.  By factoring features for assertion and test control flow out
from the test suite in its own type (inspired by the Go testing
framework) cluttering of the test suite's namespace is avoided, no need
for inheritance, no need for uppercase methods, no need for "marking"
tests; i.e. noise through repetition is down to a minimum while our IDE
will still offer us the T-API because of the type hinting.To make this little exercise (more) useful I want to add also a tddflow
commandpython -m tddflowwhich should watch the modules of the package it was executed in
together with its sub-packages for modifications on test or production
modules.  Is a test module modified it should be automatically executed
and the result of the test run should be reported.  As well as all test
modules importing absolute a modified production module should be
executes on its modification.  If all tests succeed we get the "green
bar" if not we get the "red bar" and failed tests are reported.  It also
should report "logging tests", i.e. if a test is executed containing a
linet.log(type(interesting_value))it will report the test with the logged text which comes in handy in
my experience.Kent Beck writes in "Test-Driven Development By Example": "Driving a
testing tool using the testing tool itself to run the tests may seem a
bit like performing brain surgery on yourself." Doesn't that sound like
fun?Tag alongif you feel like it.Installationpip install tddflowUsagepython -m tddflowstarts the package watcherpython -m tddflow helpdocuments tddflow's command line arguments.  The typical usage of
tddflow for testing:from tddflow.testing import run, T

class TestedSubject:

    def init(self, t: T):
        """setup fixtures which all tests have in common."""
        pass

    def setup(self, t: T):
        """setup fixtures for each test individually."""
        pass

    def tear_down(self, t: T):
        """clear resources obtained by setup."""
        pass

    def has_tested_behavior(self, t: T):
        """
        implement tests using t for test control flow and
        assertions
        """
        t.fatal_if_not(t.truthy(True))

    def finalize(self, t: T):
        """clear resources obtained by init"""
        pass

if __name__ == '__main__':
    run(TestedSubject)See also tddflow.testing.Config for how to configure a tests-suite run.