Testing forPragmatic PeopleMichael DavisDevelopment LeaderPlone Conference5th November 2011
Theory • Code without tests is broken code • 100% test coverage is a minimum • God kills a kitten every time someone check...
Reality  •   Testing is hard  •   Expensive  •   Slow to run  •   Maintaining  •   Test framework keeps changing  •   Refa...
Confused Much?                 http://www.f ickr.com/photos/39585662@N00/5331407243                            l
Realism• Tests are not mandatory• However, they are ...    • Advocated    • Best practice    • Helpful    • Eminently sens...
Testing is a    tool
Cost/Value                                  Value of Test                                  Cost of Test             Testin...
What do we meanby Tests •   Unit tests •   Integration tests •   Mock tests •   Doc tests •   Regression tests
Unit tests  •   Much faster than integration tests  •   For testing a small element of the code base  •   Testing individu...
Doc tests  • Primarily for describing functionality using python    calls  • Fails at first failure  • Difficult to write ...
Regression Tests  • Not actually a test  • About when and why
Mock Testing  •   Using mock objects to run tests  •   Useful in unit testing to mock required objects  •   Can mock getTo...
Integration Tests  • Often called unit tests  • Full Plone instance setup
What about Test   Driven Development
Mindsets  • Writing code - how  • Writing test – what  • Effects versus Mechanics
Keep It Simple  • Minimise effort  • Maximise reuse
Test Framework class TestCase(PloneSandboxLayer):   defaultBases = (PLONE_FIXTURE,)   def setUpZope(self, app, confguratio...
Test Framework from plone.app.testing import PloneSandboxLayer from plone.app.testing import PLONE_FIXTURE from plone.app....
Simple Test class TestReinstall(unittest.TestCase):   """Ensure product can be reinstalled safely"""   layer = INTEGRATION...
Running Tests  bin/test -s my.product   Ran 2 tests with 0 failures and 0 errors in 1.050 seconds.  Tearing down left over...
Browser Layer class TestInstallation(unittest.TestCase):   """Ensure product is properly installed"""   layer = INTEGRATIO...
Skin Layer class TestInstallation(unittest.TestCase):   """Ensure product is properly installed"""   layer = INTEGRATION_T...
Portal Type class TestInstallation(unittest.TestCase):   """Ensure product is properly installed"""   layer = INTEGRATION_...
Portal Types class TestContentType(unittest.TestCase):   """Test content type"""   layer = INTEGRATION_TESTING   def setUp...
Schema class TestContentSchema(unittest.TestCase):   """Test content type schema"""   layer = INTEGRATION_TESTING   def se...
Form Validation class TestValidation(unittest.TestCase):   """Test validation"""   layer = INTEGRATION_TESTING   def setUp...
Validation Test   def testValidates(self):      dummy_controller_state = ControllerState(                        id=my_for...
Test Patterns   def testValidatePrisoner(self):     app.REQUEST.form[name] = 6     …     assert len(controller_state.getEr...
Test Patterns   def testValidateClint(self):     app.REQUEST.form[name] =      …     assert len(controller_state.getErrors...
CI Server
Use your tools responsibly                 http://www.f ickr.com/photos/12803689@N02/4402962654                            l
Upcoming SlideShare
Loading in...5
×

Testing for Pragmatic People

321

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
321
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
5
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
  1. Gostou de algum slide específico?

    Recortar slides é uma maneira fácil de colecionar informações para acessar mais tarde.

×