diff --git a/tests/regressiontests/forms/localflavor/ca.py b/tests/regressiontests/forms/localflavor/ca.py
index 7f4b3ac89c..575f41c8be 100644
--- a/tests/regressiontests/forms/localflavor/ca.py
+++ b/tests/regressiontests/forms/localflavor/ca.py
@@ -1,239 +1,14 @@
-# -*- coding: utf-8 -*-
-# Tests for the contrib/localflavor/ CA form fields.
+from django.contrib.localflavor.ca.forms import (CAPostalCodeField,
+        CAPhoneNumberField, CAProvinceField, CAProvinceSelect,
+        CASocialInsuranceNumberField)
 
-tests = r"""
-# CAPostalCodeField ##############################################################
+from utils import LocalFlavorTestCase
 
-CAPostalCodeField validates that the data is a six-character Canadian postal code.
->>> from django.contrib.localflavor.ca.forms import CAPostalCodeField
->>> f = CAPostalCodeField()
->>> f.clean('T2S 2H7')
-u'T2S 2H7'
->>> f.clean('T2S 2H')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a postal code in the format XXX XXX.']
->>> f.clean('2T6 H8I')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a postal code in the format XXX XXX.']
->>> f.clean('T2S2H')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a postal code in the format XXX XXX.']
->>> f.clean(90210)
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a postal code in the format XXX XXX.']
->>> f.clean(None)
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
->>> f.clean('')
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
->>> f = CAPostalCodeField(required=False)
->>> f.clean('T2S 2H7')
-u'T2S 2H7'
->>> f.clean('T2S2H7')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a postal code in the format XXX XXX.']
->>> f.clean('T2S 2H')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a postal code in the format XXX XXX.']
->>> f.clean('2T6 H8I')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a postal code in the format XXX XXX.']
->>> f.clean('T2S2H')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a postal code in the format XXX XXX.']
->>> f.clean(90210)
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a postal code in the format XXX XXX.']
->>> f.clean(None)
-u''
->>> f.clean('')
-u''
->>> f.clean('W2S 2H3')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a postal code in the format XXX XXX.']
->>> f.clean('T2W 2H7')
-u'T2W 2H7'
->>> f.clean('T2S 2W7')
-u'T2S 2W7'
->>> f.clean('Z2S 2H3')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a postal code in the format XXX XXX.']
->>> f.clean('T2Z 2H7')
-u'T2Z 2H7'
->>> f.clean('T2S 2Z7')
-u'T2S 2Z7'
->>> f.clean('F2S 2H3')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a postal code in the format XXX XXX.']
->>> f.clean('A2S 2D3')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a postal code in the format XXX XXX.']
->>> f.clean('A2I 2R3')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a postal code in the format XXX XXX.']
->>> f.clean('A2I 2R3')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a postal code in the format XXX XXX.']
->>> f.clean('A2Q 2R3')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a postal code in the format XXX XXX.']
->>> f.clean('U2B 2R3')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a postal code in the format XXX XXX.']
->>> f.clean('O2B 2R3')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a postal code in the format XXX XXX.']
 
-# CAPhoneNumberField ##########################################################
-
-CAPhoneNumberField validates that the data is a valid Canadian phone number,
-including the area code. It's normalized to XXX-XXX-XXXX format.
-Note: This test is exactly the same as the USPhoneNumberField except using a real
-Candian area code
-
->>> from django.contrib.localflavor.ca.forms import CAPhoneNumberField
->>> f = CAPhoneNumberField()
->>> f.clean('403-555-1212')
-u'403-555-1212'
->>> f.clean('4035551212')
-u'403-555-1212'
->>> f.clean('403 555-1212')
-u'403-555-1212'
->>> f.clean('(403) 555-1212')
-u'403-555-1212'
->>> f.clean('403 555 1212')
-u'403-555-1212'
->>> f.clean('403.555.1212')
-u'403-555-1212'
->>> f.clean('403.555-1212')
-u'403-555-1212'
->>> f.clean(' (403) 555.1212 ')
-u'403-555-1212'
->>> f.clean('555-1212')
-Traceback (most recent call last):
-...
-ValidationError: [u'Phone numbers must be in XXX-XXX-XXXX format.']
->>> f.clean('403-55-1212')
-Traceback (most recent call last):
-...
-ValidationError: [u'Phone numbers must be in XXX-XXX-XXXX format.']
->>> f.clean(None)
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
->>> f.clean('')
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
-
->>> f = CAPhoneNumberField(required=False)
->>> f.clean('403-555-1212')
-u'403-555-1212'
->>> f.clean('4035551212')
-u'403-555-1212'
->>> f.clean('403 555-1212')
-u'403-555-1212'
->>> f.clean('(403) 555-1212')
-u'403-555-1212'
->>> f.clean('403 555 1212')
-u'403-555-1212'
->>> f.clean('403.555.1212')
-u'403-555-1212'
->>> f.clean('403.555-1212')
-u'403-555-1212'
->>> f.clean(' (403) 555.1212 ')
-u'403-555-1212'
->>> f.clean('555-1212')
-Traceback (most recent call last):
-...
-ValidationError: [u'Phone numbers must be in XXX-XXX-XXXX format.']
->>> f.clean('403-55-1212')
-Traceback (most recent call last):
-...
-ValidationError: [u'Phone numbers must be in XXX-XXX-XXXX format.']
->>> f.clean(None)
-u''
->>> f.clean('')
-u''
-
-# CAProvinceField ################################################################
-
-CAProvinceField validates that the data is either an abbreviation or name of a
-Canadian province.
->>> from django.contrib.localflavor.ca.forms import CAProvinceField
->>> f = CAProvinceField()
->>> f.clean('ab')
-u'AB'
->>> f.clean('BC')
-u'BC'
->>> f.clean('nova scotia')
-u'NS'
->>> f.clean('  manitoba ')
-u'MB'
->>> f.clean(' new brunswick ')
-u'NB'
->>> f.clean('NB')
-u'NB'
->>> f.clean('T2S 2H7')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a Canadian province or territory.']
->>> f.clean(None)
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
->>> f.clean('')
-Traceback (most recent call last):
-...
-ValidationError: [u'This field is required.']
-
->>> f = CAProvinceField(required=False)
->>> f.clean('ab')
-u'AB'
->>> f.clean('BC')
-u'BC'
->>> f.clean('nova scotia')
-u'NS'
->>> f.clean('  manitoba ')
-u'MB'
->>> f.clean('T2S 2H7')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a Canadian province or territory.']
->>> f.clean(None)
-u''
->>> f.clean('')
-u''
-
-# CAProvinceSelect ###############################################################
-
-CAProvinceSelect is a Select widget that uses a list of Canadian provinces/territories
-as its choices.
->>> from django.contrib.localflavor.ca.forms import CAProvinceSelect
->>> w = CAProvinceSelect()
->>> print w.render('province', 'AB')
-<select name="province">
+class CALocalFlavorTests(LocalFlavorTestCase):
+    def test_CAProvinceSelect(self):
+        f = CAProvinceSelect()
+        out = u'''<select name="province">
 <option value="AB" selected="selected">Alberta</option>
 <option value="BC">British Columbia</option>
 <option value="MB">Manitoba</option>
@@ -247,23 +22,74 @@ as its choices.
 <option value="QC">Quebec</option>
 <option value="SK">Saskatchewan</option>
 <option value="YK">Yukon</option>
-</select>
+</select>'''
+        self.assertEqual(f.render('province', 'AB'), out)
 
-# CASocialInsuranceNumberField #################################################
->>> from django.contrib.localflavor.ca.forms import CASocialInsuranceNumberField
->>> f = CASocialInsuranceNumberField()
->>> f.clean('046-454-286')
-u'046-454-286'
->>> f.clean('046-454-287')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid Canadian Social Insurance number in XXX-XXX-XXX format.']
->>> f.clean('046 454 286')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid Canadian Social Insurance number in XXX-XXX-XXX format.']
->>> f.clean('046-44-286')
-Traceback (most recent call last):
-...
-ValidationError: [u'Enter a valid Canadian Social Insurance number in XXX-XXX-XXX format.']
-"""
+    def test_CAPostalCodeField(self):
+        error_format = [u'Enter a postal code in the format XXX XXX.']
+        valid = {
+            'T2S 2H7': 'T2S 2H7',
+            'T2S 2W7': 'T2S 2W7',
+            'T2S 2Z7': 'T2S 2Z7',
+            'T2Z 2H7': 'T2Z 2H7',
+
+        }
+        invalid = {
+            'T2S2H7' : error_format,
+            'T2S 2H' : error_format,
+            '2T6 H8I': error_format,
+            'T2S2H' : error_format,
+            90210 : error_format,
+            'W2S 2H3': error_format,
+            'Z2S 2H3': error_format,
+            'F2S 2H3': error_format,
+            'A2S 2D3': error_format,
+            'A2I 2R3': error_format,
+            'A2Q 2R3': error_format,
+            'U2B 2R3': error_format,
+            'O2B 2R3': error_format,
+        }
+        self.assertFieldOutput(CAPostalCodeField, valid, invalid)
+
+    def test_CAPhoneNumberField(self):
+        error_format = [u'Phone numbers must be in XXX-XXX-XXXX format.']
+        valid = {
+            '403-555-1212': '403-555-1212',
+            '4035551212': '403-555-1212',
+            '403 555-1212': '403-555-1212',
+            '(403) 555-1212': '403-555-1212',
+            '403 555 1212': '403-555-1212',
+            '403.555.1212': '403-555-1212',
+            '403.555-1212': '403-555-1212',
+            ' (403) 555.1212 ': '403-555-1212',
+        }
+        invalid = {
+           '555-1212': error_format,
+           '403-55-1212': error_format,
+        }
+        self.assertFieldOutput(CAPhoneNumberField, valid, invalid)
+
+    def test_CAProvinceField(self):
+        error_format = [u'Enter a Canadian province or territory.']
+        valid = {
+            'ab': 'AB',
+            'BC': 'BC',
+            'nova scotia': 'NS',
+            '  manitoba ': 'MB',
+        }
+        invalid = {
+            'T2S 2H7': error_format,
+        }
+        self.assertFieldOutput(CAProvinceField, valid, invalid)
+
+    def test_CASocialInsuranceField(self):
+        error_format = [u'Enter a valid Canadian Social Insurance number in XXX-XXX-XXX format.']
+        valid = {
+            '046-454-286': '046-454-286',
+        }
+        invalid = {
+            '046-454-287': error_format,
+            '046 454 286': error_format,
+            '046-44-286': error_format,
+        }
+        self.assertFieldOutput(CASocialInsuranceNumberField, valid, invalid)
diff --git a/tests/regressiontests/forms/localflavortests.py b/tests/regressiontests/forms/localflavortests.py
index b882dd35e5..51d51765ad 100644
--- a/tests/regressiontests/forms/localflavortests.py
+++ b/tests/regressiontests/forms/localflavortests.py
@@ -1,5 +1,4 @@
 # -*- coding: utf-8 -*-
-from localflavor.ca import tests as localflavor_ca_tests
 from localflavor.ch import tests as localflavor_ch_tests
 from localflavor.cl import tests as localflavor_cl_tests
 from localflavor.cz import tests as localflavor_cz_tests
@@ -30,12 +29,12 @@ from localflavor.de import DELocalFlavorTests
 from localflavor.au import AULocalFlavorTests
 from localflavor.be import BELocalFlavorTests
 from localflavor.br import BRLocalFlavorTests
+from localflavor.ca import CALocalFlavorTests
 from localflavor.il import ILLocalFlavorTests
 from localflavor.tr import TRLocalFlavorTests
 
 
 __test__ = {
-    'localflavor_ca_tests': localflavor_ca_tests,
     'localflavor_ch_tests': localflavor_ch_tests,
     'localflavor_cl_tests': localflavor_cl_tests,
     'localflavor_cz_tests': localflavor_cz_tests,
diff --git a/tests/regressiontests/forms/tests/__init__.py b/tests/regressiontests/forms/tests/__init__.py
index 64d03175ef..9969a68628 100644
--- a/tests/regressiontests/forms/tests/__init__.py
+++ b/tests/regressiontests/forms/tests/__init__.py
@@ -18,6 +18,7 @@ from regressiontests.forms.localflavortests import (
     AULocalFlavorTests,
     BELocalFlavorTests,
     BRLocalFlavorTests,
+    CALocalFlavorTests,
     DELocalFlavorTests,
     ILLocalFlavorTests,
     TRLocalFlavorTests,