Testing for Pragmatic People

513 views

Published on

Published in: Technology, Education
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
513
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
6
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Testing for Pragmatic People

  1. 1. Testing forPragmatic PeopleMichael DavisDevelopment LeaderPlone Conference5th November 2011
  2. 2. Theory • Code without tests is broken code • 100% test coverage is a minimum • God kills a kitten every time someone checks in code without a test • Testing will make you more attractive to the opposite sex • Theres a special place in hell for people who code without tests
  3. 3. Reality • Testing is hard • Expensive • Slow to run • Maintaining • Test framework keeps changing • Refactoring • Tests wrong
  4. 4. Confused Much? http://www.f ickr.com/photos/39585662@N00/5331407243 l
  5. 5. Realism• Tests are not mandatory• However, they are ... • Advocated • Best practice • Helpful • Eminently sensible
  6. 6. Testing is a tool
  7. 7. Cost/Value Value of Test Cost of Test Testing Experience
  8. 8. What do we meanby Tests • Unit tests • Integration tests • Mock tests • Doc tests • Regression tests
  9. 9. Unit tests • Much faster than integration tests • For testing a small element of the code base • Testing individual methods • getToolByName is always a problem • Get complex quickly • Expensive to maintain
  10. 10. Doc tests • Primarily for describing functionality using python calls • Fails at first failure • Difficult to write • Good for documentation
  11. 11. Regression Tests • Not actually a test • About when and why
  12. 12. Mock Testing • Using mock objects to run tests • Useful in unit testing to mock required objects • Can mock getToolByName to return the right tool • Used to test the untestable
  13. 13. Integration Tests • Often called unit tests • Full Plone instance setup
  14. 14. What about Test Driven Development
  15. 15. Mindsets • Writing code - how • Writing test – what • Effects versus Mechanics
  16. 16. Keep It Simple • Minimise effort • Maximise reuse
  17. 17. Test Framework class TestCase(PloneSandboxLayer): defaultBases = (PLONE_FIXTURE,) def setUpZope(self, app, confgurationContext): import my.product self.loadZCML(package=my.product) z2.installProduct(app, PROJECTNAME) def setUpPloneSite(self, portal): self.applyProfle(portal, %s:default % PROJECTNAME) def tearDownZope(self, app): z2.uninstallProduct(app, PROJECTNAME)
  18. 18. Test Framework from plone.app.testing import PloneSandboxLayer from plone.app.testing import PLONE_FIXTURE from plone.app.testing import IntegrationTesting from plone.testing import z2 from my.product.confg import PROJECTNAME class TestCase(PloneSandboxLayer): .... FIXTURE = TestCase() INTEGRATION_TESTING = IntegrationTesting(bases=(FIXTURE,), name="fxture:Integration")
  19. 19. Simple Test class TestReinstall(unittest.TestCase): """Ensure product can be reinstalled safely""" layer = INTEGRATION_TESTING def setUp(self): self.portal = self.layer[portal] def testReinstall(self): portal_setup = getToolByName(self.portal, portal_setup) portal_setup.runAllImportStepsFromProfle(profle-%s:default % PROJECTNAME)
  20. 20. Running Tests bin/test -s my.product Ran 2 tests with 0 failures and 0 errors in 1.050 seconds. Tearing down left over layers: Tear down collective.wfform.tests.base.fixture:Integration in 0.000 seconds. Tear down collective.wfform.tests.base.TestCase in 0.013 seconds. Tear down plone.app.testing.layers.PloneFixture in 0.380 seconds. Tear down plone.testing.z2.Startup in 0.024 seconds. Tear down plone.testing.zca.LayerCleanup in 0.006 seconds.
  21. 21. Browser Layer class TestInstallation(unittest.TestCase): """Ensure product is properly installed""" layer = INTEGRATION_TESTING def setUp(self): self.portal = self.layer[portal] def testBrowserLayerRegistered(self): sm = getSiteManager(self.portal) layers = [o.__name__ for o in registered_layers()] assert IMyProduct in layers
  22. 22. Skin Layer class TestInstallation(unittest.TestCase): """Ensure product is properly installed""" layer = INTEGRATION_TESTING def setUp(self): self.portal = self.layer[portal] def testSkinLayersInstalled(self): assert my_skin in self.portal.portal_skins.objectIds() assert my_template in self.portal.portal_skins.my_skin.objectIds()
  23. 23. Portal Type class TestInstallation(unittest.TestCase): """Ensure product is properly installed""" layer = INTEGRATION_TESTING def setUp(self): self.portal = self.layer[portal] def testTypesInstalled(self): portal_types = getToolByName(self.portal, portal_types) assert MyType in portal_types.objectIds(), portal_types.objectIds()
  24. 24. Portal Types class TestContentType(unittest.TestCase): """Test content type""" layer = INTEGRATION_TESTING def setUp(self): self.portal = self.layer[portal] def testAddType(self): setRoles(self.portal, TEST_USER_ID, [Manager]) self.portal.invokeFactory(MyType, mt1) mt1 = getattr(self.portal, mt1) mt1.setTitle(The Title of My Object) Assert mt1.Title() == The Title of My Object, mt1.Title()
  25. 25. Schema class TestContentSchema(unittest.TestCase): """Test content type schema""" layer = INTEGRATION_TESTING def setUp(self): self.portal = self.layer[portal] setRoles(self.portal, TEST_USER_ID, [Manager]) self.portal.invokeFactory(MyType, mt1) self.mt1 = getattr(self.portal, mt1) def testSchema(self): schema = self.mt1.schema feld_ids = schema.keys() assert referenceNumber in feld_ids
  26. 26. Form Validation class TestValidation(unittest.TestCase): """Test validation""" layer = INTEGRATION_TESTING def setUp(self): self.portal = self.layer[portal] setRoles(self.portal, TEST_USER_ID, [Manager]) self.portal.invokeFactory(MyType, mt1) self.mt1 = getattr(self.portal, mt1) app = makerequest(self.app) app.REQUEST.form[name] = Michael Davis
  27. 27. Validation Test def testValidates(self): dummy_controller_state = ControllerState( id=my_form, context=s1, button=submit, status=success, errors={}, next_action=None,) controller = self.portal.portal_form_controller object controller_state = controller.validate(dummy_controller_state, app.REQUEST, [my_validate,]) assert controller_state.getErrors() == {}, controller_state.getErrors()
  28. 28. Test Patterns def testValidatePrisoner(self): app.REQUEST.form[name] = 6 … assert len(controller_state.getErrors()) == 1 assert controller_state.getErrors().has_key(name) assert controller_state.getErrors()[name] == You are not a number
  29. 29. Test Patterns def testValidateClint(self): app.REQUEST.form[name] = … assert len(controller_state.getErrors()) == 1 assert controller_state.getErrors().has_key(name) assert controller_state.getErrors()[name] == You are not the man with no name
  30. 30. CI Server
  31. 31. Use your tools responsibly http://www.f ickr.com/photos/12803689@N02/4402962654 l

×