2014-12-27 61 views
2

我現在有一個「ok」測試套件,但我想改進它。會發生什麼是我不得不重複設置(限制示例的模型)用戶,財產,學校和城市對象。Django模塊化測試

這裏的東西我現在有,其工作的例子(注:因爲爲了簡化該示例的變化有可能被打破,但邏輯是什麼,我以後):

class MainTestSetup(TestCase): 
    def setUp(self): 
     self.manage_text = 'Manage' 

     User = get_user_model() 

     # set up all types of users to be used 
     self.staff_user = User.objects.create_user('staff_user', '[email protected]', 'testpassword') 
     self.staff_user.is_staff = True 
     self.staff_user.save() 

     self.user = User.objects.create_user('user', '[email protected]', 'testpassword') 

     self.city = City.objects.create(name="Test Town", state="TX") 
     self.school = School.objects.create(city=self.city, name="RE Test University", 
         long=-97.1234123, lat=45.78) 
     self.company = Company.objects.create(name="Test Company", default_school=self.school) 

    def login(self): 
     self.client.login(username=self.user.username, 
      password='testpassword') 

    def login_admin(self): 
     self.client.login(username=self.staff_user, password="testpassword") 


class MainViewTests(MainTestSetup): 
    def test_home(self): 
     url = reverse('home-list') 
     manage_url = reverse('manage-property') 

     anon_response = self.client.get(url) 
     self.assertEqual(anon_response.status_code, 200) 
     self.assertNotContains(anon_response, self.manage_text) 

     self.login_admin() 
     admin_response = self.client.get(url) 
     self.assertContains(admin_response, self.manage_text) 

    def test_search(self): 
     url = reverse('search') 
     response = self.client.get(url) 
     self.assertEqual(response.status_code, 200) 

    ...more tests 

由於你可以看到MainViewTest繼承MainTestSetup類的setUp和login函數。這工作正常,但我有很多應用程序,並不是都需要設置所有模型。我試圖做的是設置一組mixin,在我需要的TestSetups中只包含用戶,學校,公司等內容。

這MainTestSetup會變成這樣的:

class SchoolMixin(object): 
    def setUp(self): 
     self.city = City.objects.create(name="Test Town", state="TX") 
     self.school = School.objects.create(city=self.city, name="RE Test University", 
         long=-97.1234123, lat=45.78) 


class CompanyMixin(SchoolMixin): 
    def setUp(self): 
     self.company = Company.objects.create(name="Test Company", default_school=self.school) 


class UserMixin(object): 
    def setUp(self): 
     User = get_user_model() 

     # set up all types of users to be used 
     self.staff_user = User.objects.create_user('staff_user', '[email protected]', 'testpassword') 
     self.staff_user.is_staff = True 
     self.staff_user.save() 

     self.user = User.objects.create_user('user', '[email protected]', 'testpassword') 

    def login(self): 
     self.client.login(username=self.user.username, 
      password='testpassword') 

    def login_admin(self): 
     self.client.login(username=self.staff_user, password="testpassword") 


class MainTestSetup(UserMixin, CompanyMixin, TestCase): 
    def setUp(self): 
     self.manage_text = 'Manage' 

這將允許更多的靈活性爲我的測試套件 - 這只是一個小例子。它會讓我在其他應用程序中只包含必要的Mixins。例如,如果公司不需要,我只包括上面例子中的SchoolMixin。

我相信我的問題在於使用setUp函數。我不知道如何正確地繼承(通過超級,或通過其他東西?)。我試過使用超級,但一直沒有能夠得到它的工作。我不得不承認,我還沒有用class/mixins那麼棒,所以任何幫助/指針都會非常感謝。

+1

它保持單元測試簡單的效率比或柔性的通常是更重要的(一個點,當然),之所以這麼說,這聽起來像你正試圖完成一些非常類似於py.test的裝置(http://pytest.org/latest/fixture.html)。如果你想用Django嘗試py.test,我會建議嘗試pytest-django(http://pytest-django.readthedocs.org/en/latest/index.html)。 – thebjorn 2015-01-01 15:44:35

回答

3

您可以通過使用2個庫來簡化和減少代碼量:WebTest和FactoryBoy。你將不需要這些Mixins。

  1. https://pypi.python.org/pypi/django-webtest
  2. https://github.com/rbarrois/factory_boy

做一步變化步:

開始與WebTest的,所以你可以擺脫login_方法(和你不會還需要準備密碼)。通過WebTest,您可以在加載頁面時指定登錄用戶。例如,你將取代:

self.login_admin() 
admin_response = self.client.get(url) 

有:

admin_response = = self.app.get(url, user=self.admin) 

2.然後使用factory_boy創建你所需要的所有對象。例如,你將取代:

self.staff_user = User.objects.create_user('staff_user', '[email protected]', 'testpassword') 
    self.staff_user.is_staff = True 
    self.staff_user.save() 

有:

self.staff_user = StaffFactory.create() 

混合起來。擺脫self.admin。將其替換爲:

admin = AdminFactory.create() 
    response = = self.app.get(url, user=admin) 

一旦你完成了所有這些,你的代碼會變得更短,更容易閱讀。你根本不需要這些mixin。例如您SchoolMixin可以替換:

self.city = City.objects.create(name="Test Town", state="TX") 
    self.school = School.objects.create(city=self.city, name="RE Test University", 
        long=-97.1234123, lat=45.78) 

替換:

school = SchoolFactory.create() 

這是因爲工廠可以自動創建相關的實體與「SubFactories」。

下面是使用工廠測試的完整非常簡單的例子:http://codeku.co/testing-in-django-1

+0

美麗,正是我所期待的。謝謝 – awwester 2015-01-03 16:37:41