OPS tests - CReSIS/OLD_OPS GitHub Wiki

This page covers the basics of automated testing of the OPS django application.

The Documentation on Django tests can be found here. Python's unittest documentation can be found here. Both should be reviewed before adding or modifying tests.


Paths

How to run tests

When to run tests

When to add new tests

How to add new tests


Paths

The resources that make OPS automated testing possible are located at /var/django/ops/opsTests/.

How to run tests

The following lines of code can be entered into a terminal and will initiate ALL of the tests defined in /var/django/ops/opsTests/testOps.py:

cd /var/django/ops
source /usr/bin/venv/bin/activate
python manage.py test

If asked, enter "yes" if it asks you to delete the test database. This happens when the test code fails catastrophically and did not clean up the test database on the last run.

A group of tests, such as those shown below:

class createPathTests(TestCase):
	fixtures = testFixtures()
	#Test only the status of createPath
	def test_createPath_status(self):
		setUp(self)
		# Set the json string
		jsonStr = '...'
		
		#Create the request from the above app & jsonStr
		request = self.factory.post('create/path',{'app':'rds', 'data':jsonStr})
		#Get the response
		response = views.createPath(request)
		
		#Check the status
		checkStatus(self,response)
	
	#Test non-self intersecting crossovers
	def test_createPath_non_self_crossovers(self):
		setUp(self)
		jsonStr = '...'
		

		#Create the request from the above app & jsonStr
		request = self.factory.post('create/path',{'app':'rds', 'data':jsonStr})
		#Get the response
		response = views.createPath(request)
		
		#Check the status
		checkStatus(self,response)
		
		#Check that the correct number of crossovers exist
		crossovers = self.models.crossovers.objects.count()
		
		#Check that the total number of crossovers equals 6. 
		# (5 crossovers from fixture + 1 from this test = 6)
		self.assertEqual(crossovers,6)

can be run using python manage.py opsTests.testOps.createPathTests. A single test from the above group can be run using python manage.py opsTests.testOps.createPathTests.test_createPath_non_self_crossovers

  • Errors will be output to the terminal if any are encountered.

When to run tests

Tests are used to ensure the application functions as expected. Running automated tests should not completely replace normal testing of changes to OPS that may produce unexpected behavior. Nevertheless, it is a good idea to run tests for a variety of reasons, including:

  • Whenever major changes to code are made.
  • Before pushing commits.
  • For testing modifications to code.
  • Debugging revisions or additions to existing Django views.

When to add new tests

New tests should be added as frequently as the need arises. It is suggested that there can never be too many tests! Tests should provide a relatively comprehensive means of ensuring the application functions as expected. The continuous addition of new tests creates a more robust system of testing the OPS. Some of the reasons new tests should be added:

  • A new Django view is defined
  • An existing view is modified to change or add input/output (existing tests may also need to be altered).
  • When unexpected behavior is discovered in an existing view (write a test to make sure it never happens again).

How to add new tests

New tests should be defined in /var/django/ops/opsTests/testOps.py.

New tests should follow approximately the same pattern as existing tests. A test for the deleteLayer() view is shown below:

class deleteLayerTests(TestCase):
	fixtures = testFixtures()
	def test_deleteLayer(self):
		setUp(self)
		# Set the json string that will be sent to the view
		jsonStr = '{ "properties": { "lyr_name": "fixtureTest" } }'
		
		#Create the request from the above app & jsonStr
		request = self.factory.post('delete/layer',{'app':'rds','data':jsonStr})
		#Get the response
		response = views.deleteLayer(request)
		
		#Check the status
		checkStatus(self,response)
		
		#Make sure the layer now has a deleted status.
		self.assertEqual(self.models.layers.objects.filter(name__exact='fixtureTest',deleted=True).count(),1)
  • Each view should have its own class. Each class can have multiple individual tests defined.

  • A test database is created at the beginning of testing and is freshly populated with data defined in /var/django/ops/opsTests/testFixtures.json for each test. All data is cleared from the test database at the conclusion of each test, thus ensuring that each test is independent.

  • The checkStatus() function checks for good server (200) and OPS (1) response statuses from the view being tested. If either does not pass the check, an error is logged to the terminal. Note, therefore, that the most simple test one can define is one that makes sure a view executed without any explicit errors. More sophisticated testing should be implemented if one wishes to ensure a response has the correct result given known input.

  • Every test is passed or failed depending on the outcome of calls to one or more assertions. These include self.assertEqual(), self.assertTrue(), and self.assertFalse(). More information on these assertions are found here and here.