Package: django-test-tools
Simple tests tools to make testing faster and easier. Most of the tools are to do a quick scaffolding for tests.The tools presume a naming convention:Tests:Are named with the conventionTestCaseModelName. For a model namedPollthe test would be generated
as the testing class would beTestCasePollFactories:Are named with the conventionModelName. For a model namedPollthe test would be generated
as the testing class would bePollFactorySerializers:Are named with the conventionTestCaseSerializer. For a model namedPollthe test would be generated
as the testing class would bePollSerializerCompatibility matrix:Python versionDjango 1.11.xDjango 2.2.xDjango 3.0.x3.7xxx3.6xxxDocumentationThe full documentation is athttps://django-test-tools.readthedocs.io.QuickstartInstall Django Test Tools:pipinstalldjango-test-toolsIn your settings.py file add it to yourINSTALLED_APPSINSTALLED_APPS=(...'django_test_tools.apps.DjangoTestToolsConfig',...)Create an output folder in the root folder of you project, name it what ever you want, and add the settings
variableTEST_OUTPUT_PATHpointing to it. Make sure to add this folder to your.gitignorefile.importenvironROOT_DIR=(environ.Path(__file__)-3)# (my_project/config/settings/base.py - 3 = alpha_clinic/)APPS_DIR=ROOT_DIR.path("my_project")TEST_OUTPUT_PATH=ROOT_DIR.path("output").rootFeaturesFactory GeneratorTo createFactory Boystyle factories.For a django project named polling_app with an app name poll the following command will generate the scaffolding for
the tests for all the models in th app polls.$pythonmanage.pygenerate_factoriespolling_app.pollsFor the following modelsclassOperatingSystem(models.Model):name=models.CharField(max_length=20)version=models.CharField(max_length=5)licenses_available=models.IntegerField()cost=models.DecimalField(decimal_places=2,max_digits=7)classMeta:unique_together=('name','version')classServer(models.Model):PRODUCTION='PROD'DEVELOPMENT='DEV'USE_CHOICES=((PRODUCTION,'Prod'),(DEVELOPMENT,'Dev'))name=models.CharField(max_length=20,unique=True)notes=models.TextField()virtual=models.BooleanField()ip_address=models.GenericIPAddressField()created=models.DateTimeField()online_date=models.DateField()operating_system=models.ForeignKey(OperatingSystem,related_name='servers',on_delete=models.CASCADE)server_id=models.CharField(max_length=6)use=models.CharField(max_length=4,choices=USE_CHOICES,default=DEVELOPMENT)comments=models.TextField(null=True,blank=True)runningpython manage.py generate_factories example.servers > ./output/factories.pywill create the following factoriesimportstringfromrandomimportrandintfrompytzimporttimezonefromdjango.confimportsettingsfromfactoryimportIteratorfromfactoryimportLazyAttributefromfactoryimportSubFactoryfromfactoryimportlazy_attributefromfactory.djangoimportDjangoModelFactory,FileFieldfromfactory.fuzzyimportFuzzyText,FuzzyIntegerfromfakerimportFactoryasFakerFactoryfromexample.servers.modelsimportOperatingSystem,Serverfaker=FakerFactory.create()classOperatingSystemFactory(DjangoModelFactory):classMeta:model=OperatingSystemname=LazyAttribute(lambdax:faker.text(max_nb_chars=20))version=LazyAttribute(lambdax:faker.text(max_nb_chars=5))licenses_available=LazyAttribute(lambdao:randint(1,100))cost=LazyAttribute(lambdax:faker.pydecimal(left_digits=5,right_digits=2,positive=True))classServerFactory(DjangoModelFactory):classMeta:model=Servername=LazyAttribute(lambdax:faker.text(max_nb_chars=20))notes=LazyAttribute(lambdax:faker.paragraph(nb_sentences=3,variable_nb_sentences=True))virtual=Iterator([True,False])ip_address=LazyAttribute(lambdao:faker.ipv4(network=False))created=LazyAttribute(lambdax:faker.date_time_between(start_date="-1y",end_date="now",tzinfo=timezone(settings.TIME_ZONE)))online_date=LazyAttribute(lambdax:faker.date_time_between(start_date="-1y",end_date="now",tzinfo=timezone(settings.TIME_ZONE)))operating_system=SubFactory(OperatingSystemFactory)server_id=LazyAttribute(lambdax:FuzzyText(length=6,chars=string.digits).fuzz())use=Iterator(Server.CHOICES,getter=lambdax:x[0])comments=LazyAttribute(lambdax:faker.paragraph(nb_sentences=3,variable_nb_sentences=True))Important the use attribute is created incorrectly.When you use choices you need to manually change itto USE_CHOICES.use=Iterator(Server.USE_CHOICES,getter=lambdax:x[0])Model Test Case Generator$pythonmanage.pygenerate_model_test_casesproject.appSerializer Generator$pythonmanage.pygenerate_serializersproject.app-sModelSerializerWriting assertionsOne of the most boring steps of writing tests is checking the content of static dictionaries.
You now the content of the dictionary and you need to compare it with a result.In the following code the assertions for thedatadictionary will be generated in thefnfile. IMPORTANT the name of the dictionary in this casedatamust be the same as
the second argument of the method in order to generate the correct assertions.fn='./output/_my_assertions.py'data=[{'name':'kilo','password':9999,'groups':['admin','users'],'config':{'server':'all','bulding':116}},{'name':'pasto','password':'nogo','groups':['users'],'config':{'server':'database','bulding':None},'created_date':date(2016,1,3),'modified':'2016-10-01'}]filename=write_assertions(data,'data',filename=fn,type_only=True,excluded_keys=['config']))The result of this script:self.assertEqual(len(data),2)self.assertEqual(len(data[0]['groups']),2)self.assertEqual(data[0]['groups'][0],'admin')self.assertEqual(data[0]['groups'][1],'users')self.assertEqual(data[0]['name'],'kilo')self.assertEqual(data[0]['password'],9999)self.assertEqual(len(data[1]['groups']),1)self.assertEqual(data[1]['groups'][0],'users')self.assertEqual(data[1]['name'],'pasto')self.assertEqual(data[1]['password'],'nogo')Running TestsDoes the code actually work?source <YOURVIRTUALENV>/bin/activate
(myenv) $ python runtests.py testsPushing code to PypiSetup environmentsource./venv/bin/activateUpdated version. Instead of patch you could also usemajorominordepending on the level of the release.$makepatchCheck the .travis.yml to make sure the versions of Django are the latests. Check inhttps://www.djangoproject.com/download/for the latest versions.Check setup.py for Django and Python versions.Close the git-flow release manually.Push to repo, Travis CI should deploy to pypimaketravis-pushCreditsTools used in rendering this package:Cookiecuttercookiecutter-djangopackageHistory0.1.0 (2017-04-26)First release on PyPI.